Browse Source

Filter traffic by IP address in Django

pull/160/head
Mike Olund 8 years ago
parent
commit
cb3370e5eb
5 changed files with 103 additions and 8 deletions
  1. +30
    -7
      edivorce/apps/core/middleware/bceid_middleware.py
  2. +1
    -0
      edivorce/settings/base.py
  3. +2
    -1
      edivorce/settings/openshift.py
  4. +64
    -0
      nginx-proxy/conf.d/server.conf
  5. +6
    -0
      openshift/templates/edivorce-environment-template.yaml

+ 30
- 7
edivorce/apps/core/middleware/bceid_middleware.py View File

@ -1,14 +1,15 @@
import uuid
from ipaddress import ip_address, ip_network
from django.conf import settings
from django.shortcuts import redirect
class BceidUser(object):
def __init__(self, guid, first_name, last_name, type, is_authenticated):
def __init__(self, guid, first_name, last_name, user_type, is_authenticated):
self.guid = guid
self.first_name = first_name
self.last_name = last_name
self.type = type
self.type = user_type
self.is_authenticated = is_authenticated
@ -20,14 +21,17 @@ class BceidMiddleware(object):
localdev = settings.DEPLOYMENT_TYPE == 'localdev'
# make sure the request didn't bypass the proxy
if not localdev and not self.__request_came_from_proxy(request):
return redirect(settings.PROXY_BASE_URL + settings.FORCE_SCRIPT_NAME)
if not localdev and request.META.get('HTTP_SM_USERDN', '') != '':
# 1. Real BCeID user / logged in
request.bceid_user = BceidUser(
guid=request.META.get('HTTP_SM_USERDN', ''),
is_authenticated=True,
type='BCEID',
user_type='BCEID',
first_name='Bud',
last_name='Bundy'
)
@ -38,10 +42,11 @@ class BceidMiddleware(object):
request.bceid_user = BceidUser(
guid=request.session.get('fake-bceid-guid', ''),
is_authenticated=True,
type='FAKE',
user_type='FAKE',
first_name='Kelly',
last_name='Bundy'
)
else:
# 3. Anonymous User / not logged in
@ -51,10 +56,28 @@ class BceidMiddleware(object):
request.bceid_user = BceidUser(
guid=request.session.get('anon-guid'),
is_authenticated=False,
type='ANONYMOUS',
user_type='ANONYMOUS',
first_name='',
last_name=''
)
def process_response(self, request, response):
return response
def __request_came_from_proxy(self, request):
"""
Validate that the request is coming from inside the BC Government data centre
"""
# allow all OpenShift health checks
if request.path == settings.FORCE_SCRIPT_NAME + 'health':
return True
bcgov_network = ip_network(settings.BCGOV_NETWORK)
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR', '')
forwarded_for = x_forwarded_for.split(',')
for ip in forwarded_for:
if ip_address(ip) in bcgov_network:
return True
return False

+ 1
- 0
edivorce/settings/base.py View File

@ -109,5 +109,6 @@ STATICFILES_FINDERS = (
'compressor.finders.CompressorFinder',
)
BCGOV_NETWORK = os.environ.get('PROXY_NETWORK', '0.0.0.0/0')
FORCE_SCRIPT_NAME = '/'

+ 2
- 1
edivorce/settings/openshift.py View File

@ -68,6 +68,7 @@ FORCE_SCRIPT_NAME = PROXY_URL_PREFIX + '/'
STATIC_URL = PROXY_URL_PREFIX + '/static/'
WEASYPRINT_CSS_LOOPBACK += PROXY_URL_PREFIX
# Integration URLs
LOGOUT_URL = 'https://logon.gov.bc.ca/clp-cgi/logoff.cgi?returl=https://justice.gov.bc.ca%s&retnow=1' % PROXY_URL_PREFIX
PROXY_BASE_URL = 'https://justice.gov.bc.ca'

+ 64
- 0
nginx-proxy/conf.d/server.conf View File

@ -0,0 +1,64 @@
# This configuration works with the S2I image defined in https://github.com/BCDevOps/s2i-nginx
server {
listen 8080;
server_name _;
# Allows non-standard headers like SMGOV_USERGUID
ignore_invalid_headers off;
# default path
location / {
proxy_pass http://edivorce-django:8080;
proxy_pass_request_headers on;
# rewrite 302 redirect responses to absolute URL's so the justice proxy
# doesn't mangle them by adding double slashes to relative URL's
proxy_redirect http://edivorce-django:8080 https://justice.gov.bc.ca;
# remove directories from incoming requests;
rewrite ^/divorce-dev$ / last;
rewrite ^/divorce-test$ / last;
rewrite ^/divorce$ / last;
rewrite ^/divorce-dev(.*)$ $1 last;
rewrite ^/divorce-test(.*)$ $1 last;
rewrite ^/divorce(.*)$ $1 last;
}
merge_slashes off;
# replace merge_slashes' behavior with "rewrite double slashes"
location ~* "//" {
rewrite ^(.*)//(.*)$ $1/$2;
}
# static no rewrite (dev)
location /divorce-dev/static/ {
#todo: add caching
proxy_pass http://edivorce-django:8080;
proxy_pass_request_headers on;
}
# static no rewrite (test)
location /divorce-test/static/ {
#todo: add caching
proxy_pass http://edivorce-django:8080;
proxy_pass_request_headers on;
}
# static no rewrite (prod)
location /divorce/static/ {
#todo: add caching
proxy_pass http://edivorce-django:8080;
proxy_pass_request_headers on;
}
# For status of ngnix service
location /nginx_status {
# Enable Nginx stats
stub_status on;
# No need to log this request, its just noise
access_log off;
}
}

+ 6
- 0
openshift/templates/edivorce-environment-template.yaml View File

@ -86,6 +86,8 @@ objects:
value: "${DJANGO_SECRET_KEY}"
- name: ENVIRONMENT_TYPE
value: "${ENVIRONMENT_TYPE}"
- name: PROXY_NETWORK
value: "${PROXY_NETWORK}"
resources:
limits:
memory: "${MEMORY_LIMIT}"
@ -319,3 +321,7 @@ parameters:
- name: ENVIRONMENT_TYPE
displayName: Type of environnment (dev,test or prod).
required: true
- name: PROXY_NETWORK
displayName: Network of upstream proxy
value: 0.0.0.0/0
required: true

Loading…
Cancel
Save