Browse Source

Merge pull request #158 from bcgov/DIV-1015

Div 1015 - Hook up locations API
pull/172/head
Michael Olund 5 years ago
committed by GitHub
parent
commit
c2b3616f7f
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 356 additions and 326 deletions
  1. +14
    -9
      edivorce/apps/core/templates/dashboard/final_filing.html
  2. +4
    -3
      edivorce/apps/core/templates/partials/filing_location.html
  3. +4
    -5
      edivorce/apps/core/templates/partials/tooltips/court_registry.html
  4. +58
    -0
      edivorce/apps/core/tests/test_efiling_court_locations.py
  5. +13
    -5
      edivorce/apps/core/tests/test_efiling_packaging.py
  6. +11
    -5
      edivorce/apps/core/tests/test_efiling_submission.py
  7. +79
    -0
      edivorce/apps/core/utils/efiling_court_locations.py
  8. +94
    -0
      edivorce/apps/core/utils/efiling_hub_caller_base.py
  9. +8
    -7
      edivorce/apps/core/utils/efiling_packaging.py
  10. +32
    -100
      edivorce/apps/core/utils/efiling_submission.py
  11. +0
    -184
      edivorce/apps/core/utils/question_step_mapping.py
  12. +3
    -2
      edivorce/apps/core/views/efiling.py
  13. +31
    -6
      edivorce/apps/core/views/main.py
  14. +5
    -0
      edivorce/settings/base.py

+ 14
- 9
edivorce/apps/core/templates/dashboard/final_filing.html View File

@ -178,11 +178,14 @@
<p> <p>
You have indicated that you will file at the following court registry: You have indicated that you will file at the following court registry:
</p> </p>
{% if court_registry_for_filing %}
<ul class="no-bullets"> <ul class="no-bullets">
<li>{{ court_registry_for_filing }}</li>
<li>{{ court_registry_for_filing_address }}</li>
<li>{{ court_registry_for_filing_postal_code }}</li>
<li>{{ court_registry_for_filing }} Law Courts</li>
<li>{{ court_registry_for_filing_address|safe }}</li>
<li>{{ court_registry_for_filing }}, B.C.</li>
<li>{{ court_registry_for_filing_postal_code|safe }}</li>
</ul> </ul>
{% endif %}
<p> <p>
Once filed, you will receive a {% include "partials/tooltips/court_file_number.html" %}. Once filed, you will receive a {% include "partials/tooltips/court_file_number.html" %}.
This number will be used if you need to file any additional documents. This number will be used if you need to file any additional documents.
@ -245,9 +248,10 @@
</p> </p>
<ul class="no-bullets"> <ul class="no-bullets">
{% if court_registry_for_filing %} {% if court_registry_for_filing %}
<li>{{ court_registry_for_filing }}</li>
<li>{{ court_registry_for_filing_address }}</li>
<li>{{ court_registry_for_filing_postal_code }}</li>
<li>{{ court_registry_for_filing }} Law Courts</li>
<li>{{ court_registry_for_filing_address|safe }}</li>
<li>{{ court_registry_for_filing }}, B.C.</li>
<li>{{ court_registry_for_filing_postal_code|safe }}</li>
{% else %} {% else %}
<p class="error-text"> <p class="error-text">
Go back to the questionnaire to choose a Go back to the questionnaire to choose a
@ -286,9 +290,10 @@
</p> </p>
<ul class="no-bullets"> <ul class="no-bullets">
{% if court_registry_for_filing %} {% if court_registry_for_filing %}
<li>{{ court_registry_for_filing }}</li>
<li>{{ court_registry_for_filing_address }}</li>
<li>{{ court_registry_for_filing_postal_code }}</li>
<li>{{ court_registry_for_filing }} Law Courts</li>
<li>{{ court_registry_for_filing_address|safe }}</li>
<li>{{ court_registry_for_filing }}, B.C.</li>
<li>{{ court_registry_for_filing_postal_code|safe }}</li>
{% else %} {% else %}
<p class="error-text"> <p class="error-text">
Go back to the questionnaire to choose a Go back to the questionnaire to choose a


+ 4
- 3
edivorce/apps/core/templates/partials/filing_location.html View File

@ -1,8 +1,9 @@
{% if court_registry_for_filing %} {% if court_registry_for_filing %}
<ul class="no-bullets" id="court-registry-location"> <ul class="no-bullets" id="court-registry-location">
<li id="court-registry-city"><b>{{ court_registry_for_filing }}</b></li>
<li id="court-registry-address">{{ court_registry_for_filing_address }}</li>
<li id="court-registry-postal-code">{{ court_registry_for_filing_postal_code }}</li>
<li id="court-registry-name"><b>{{ court_registry_for_filing }} Law Courts</b></li>
<li id="court-registry-address">{{ court_registry_for_filing_address|safe }}</li>
<li id="court-registry-city">{{ court_registry_for_filing }}, B.C.</li>
<li id="court-registry-postal-code">{{ court_registry_for_filing_postal_code|safe }}</li>
</ul> </ul>
{% else %} {% else %}
<div class="review-warning"> <div class="review-warning">


+ 4
- 5
edivorce/apps/core/templates/partials/tooltips/court_registry.html View File

@ -9,11 +9,10 @@
<br/> <br/>
<br/> <br/>
{% if court_registry_for_filing %} {% if court_registry_for_filing %}
{{ court_registry_for_filing }}
<br/>
{{ court_registry_for_filing_address }}
<br/>
{{ court_registry_for_filing_postal_code }}
{{ court_registry_for_filing }} Law Courts<br>
{{ court_registry_for_filing_address|safe }}
{{ court_registry_for_filing }}, B.C.<br>
{{ court_registry_for_filing_postal_code|safe }}
{% else %} {% else %}
No Court Registry was chosen No Court Registry was chosen
{% endif %} {% endif %}


+ 58
- 0
edivorce/apps/core/tests/test_efiling_court_locations.py View File

@ -0,0 +1,58 @@
import json
from unittest import mock
from django.contrib.sessions.middleware import SessionMiddleware
from django.test import TransactionTestCase
from django.test.client import RequestFactory
from edivorce.apps.core.utils.efiling_court_locations import EFilingCourtLocations
SAMPLE_COURTS_RESPONSE = {"courts": [{
"id": 19227.0734,
"identifierCode": "5871",
"name": "100 Mile House Law Courts",
"code": "OMH",
"isSupremeCourt": False,
"address": {
"addressLine1": "160 Cedar Avenue South",
"addressLine2": "Box 1060",
"addressLine3": None,
"postalCode": "V0K2E0",
"cityName": "100 Mile House",
"provinceName": "British Columbia",
"countryName": "Canada"
}
}]}
class EFilingCourtLocationsTests(TransactionTestCase):
def setUp(self):
# Every test needs access to the request factory.
self.factory = RequestFactory()
self.request = self.factory.get('/')
middleware = SessionMiddleware()
middleware.process_request(self.request)
self.request.session.save()
self.locationsApi = EFilingCourtLocations()
def _mock_response(self, text=""):
mock_resp = mock.Mock()
mock_resp.status_code = 200
mock_resp.text = text
return mock_resp
@mock.patch('edivorce.apps.core.utils.efiling_court_locations.EFilingCourtLocations._get_api')
def test_locations_success(self, mock_get_api):
self.request.session['bcgov_userguid'] = '70fc9ce1-0cd6-4170-b842-bbabb88452a9'
mock_get_api.return_value = self._mock_response(
text=json.dumps(SAMPLE_COURTS_RESPONSE))
locations = self.locationsApi.courts(self.request)
self.assertEqual(locations["100 Mile House"]["location_id"], "5871")
self.assertEqual(locations["100 Mile House"]["postal"], "V0K2E0")
self.assertEqual(locations["100 Mile House"]["address_1"], "160 Cedar Avenue South")
self.assertEqual(locations["100 Mile House"]["address_2"], "Box 1060")
self.assertIsNone(locations["100 Mile House"]["address_3"])

+ 13
- 5
edivorce/apps/core/tests/test_efiling_packaging.py View File

@ -1,3 +1,6 @@
import json
from unittest import mock
from django.contrib.sessions.middleware import SessionMiddleware from django.contrib.sessions.middleware import SessionMiddleware
from django.test import TransactionTestCase from django.test import TransactionTestCase
from django.test.client import RequestFactory from django.test.client import RequestFactory
@ -18,6 +21,7 @@ class EFilingPackagingTests(TransactionTestCase):
self.request.session.save() self.request.session.save()
self.packaging = EFilingPackaging(initial_filing=True) self.packaging = EFilingPackaging(initial_filing=True)
# court_locations={"Vancouver": {"location_id": "6011"}}
def test_format_package(self): def test_format_package(self):
files = [] files = []
@ -45,22 +49,26 @@ class EFilingPackagingTests(TransactionTestCase):
self.assertEqual(package['filingPackage']['parties'][0]['firstName'], 'Party 0') self.assertEqual(package['filingPackage']['parties'][0]['firstName'], 'Party 0')
self.assertEqual(package['filingPackage']['parties'][1]['firstName'], 'Party 1') self.assertEqual(package['filingPackage']['parties'][1]['firstName'], 'Party 1')
def test_get_location_success(self):
@mock.patch('edivorce.apps.core.utils.efiling_court_locations.EFilingCourtLocations.courts')
def test_get_location_success(self, mock_courts):
mock_courts.return_value = {"Vancouver": {"location_id": "6011"}}
responses = { responses = {
"court_registry_for_filing": "Vancouver" "court_registry_for_filing": "Vancouver"
} }
location = self.packaging._get_location(responses)
location = self.packaging._get_location(None, responses)
self.assertEqual(location, '6011') self.assertEqual(location, '6011')
def test_get_location_fail(self):
@mock.patch('edivorce.apps.core.utils.efiling_court_locations.EFilingCourtLocations.courts')
def test_get_location_fail(self, mock_courts):
mock_courts.return_value = {"Vancouver": {"location_id": "6011"}}
responses = { responses = {
"court_registry_for_filing": "Tokyo" "court_registry_for_filing": "Tokyo"
} }
location = self.packaging._get_location(responses)
location = self.packaging._get_location(None, responses)
self.assertEqual(location, '0000') self.assertEqual(location, '0000')
responses = {} responses = {}
location = self.packaging._get_location(responses)
location = self.packaging._get_location(None, responses)
self.assertEqual(location, '0000') self.assertEqual(location, '0000')
def test_get_json_data_signing_location(self): def test_get_json_data_signing_location(self):


+ 11
- 5
edivorce/apps/core/tests/test_efiling_submission.py View File

@ -46,8 +46,8 @@ class EFilingSubmissionTests(TransactionTestCase):
middleware.process_request(self.request) middleware.process_request(self.request)
self.request.session.save() self.request.session.save()
self.hub = EFilingSubmission(initial_filing=True)
self.packaging = EFilingPackaging(initial_filing=True) self.packaging = EFilingPackaging(initial_filing=True)
self.hub = EFilingSubmission(initial_filing=True, packaging=self.packaging)
def _mock_response(self, status=200, text="Text", json_data=None, raise_for_status=None): def _mock_response(self, status=200, text="Text", json_data=None, raise_for_status=None):
mock_resp = mock.Mock() mock_resp = mock.Mock()
@ -112,7 +112,7 @@ class EFilingSubmissionTests(TransactionTestCase):
self.hub.access_token = 'aslkfjadskfjd' self.hub.access_token = 'aslkfjadskfjd'
response = self.hub._get_api( response = self.hub._get_api(
self.request, 'https://somewhere.com', 'alksdjfa', 'kasdkfd', {})
self.request, 'https://somewhere.com', 'alksdjfa')
self.assertTrue(response) self.assertTrue(response)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
@ -132,7 +132,7 @@ class EFilingSubmissionTests(TransactionTestCase):
] ]
response = self.hub._get_api( response = self.hub._get_api(
self.request, 'https://somewhere.com', 'alksdjfa', 'kasdkfd', {})
self.request, 'https://somewhere.com', 'alksdjfa')
self.assertTrue(response) self.assertTrue(response)
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
@ -171,14 +171,17 @@ class EFilingSubmissionTests(TransactionTestCase):
bceid = self.hub._get_bceid(self.request) bceid = self.hub._get_bceid(self.request)
self.assertFalse(bceid) self.assertFalse(bceid)
@mock.patch('edivorce.apps.core.utils.efiling_packaging.EFilingPackaging._get_location')
@mock.patch('edivorce.apps.core.utils.efiling_submission.EFilingSubmission._get_api') @mock.patch('edivorce.apps.core.utils.efiling_submission.EFilingSubmission._get_api')
def test_upload_success(self, mock_get_api):
def test_upload_success(self, mock_get_api, mock_get_location):
self.request.session['bcgov_userguid'] = '70fc9ce1-0cd6-4170-b842-bbabb88452a9' self.request.session['bcgov_userguid'] = '70fc9ce1-0cd6-4170-b842-bbabb88452a9'
with self.settings(DEPLOYMENT_TYPE='prod'): with self.settings(DEPLOYMENT_TYPE='prod'):
mock_get_api.side_effect = [ mock_get_api.side_effect = [
self._mock_response(text=json.dumps(INITIAL_DOC_UPLOAD_RESPONSE)), self._mock_response(text=json.dumps(INITIAL_DOC_UPLOAD_RESPONSE)),
self._mock_response(text=json.dumps(GENERATE_URL_RESPONSE)) self._mock_response(text=json.dumps(GENERATE_URL_RESPONSE))
] ]
mock_get_location.return_value = "0000"
redirect, msg = self.hub.upload(self.request, {}, {}) redirect, msg = self.hub.upload(self.request, {}, {})
self.assertTrue(redirect) self.assertTrue(redirect)
@ -197,14 +200,17 @@ class EFilingSubmissionTests(TransactionTestCase):
self.assertFalse(redirect) self.assertFalse(redirect)
@mock.patch('edivorce.apps.core.utils.efiling_packaging.EFilingPackaging._get_location')
@mock.patch('edivorce.apps.core.utils.efiling_submission.EFilingSubmission._get_api') @mock.patch('edivorce.apps.core.utils.efiling_submission.EFilingSubmission._get_api')
def test_upload_failed_generate_url(self, mock_get_api):
def test_upload_failed_generate_url(self, mock_get_api, mock_get_location):
self.request.session['bcgov_userguid'] = '70fc9ce1-0cd6-4170-b842-bbabb88452a9' self.request.session['bcgov_userguid'] = '70fc9ce1-0cd6-4170-b842-bbabb88452a9'
with self.settings(DEPLOYMENT_TYPE='prod'): with self.settings(DEPLOYMENT_TYPE='prod'):
mock_get_api.side_effect = [ mock_get_api.side_effect = [
self._mock_response(text=json.dumps(INITIAL_DOC_UPLOAD_RESPONSE)), self._mock_response(text=json.dumps(INITIAL_DOC_UPLOAD_RESPONSE)),
self._mock_response(text=json.dumps(GENERATE_URL_RESPONSE_ERROR), status=403) self._mock_response(text=json.dumps(GENERATE_URL_RESPONSE_ERROR), status=403)
] ]
mock_get_location.return_value = "0000"
redirect, msg = self.hub.upload(self.request, {}, {}) redirect, msg = self.hub.upload(self.request, {}, {})
self.assertFalse(redirect) self.assertFalse(redirect)

+ 79
- 0
edivorce/apps/core/utils/efiling_court_locations.py View File

@ -0,0 +1,79 @@
import json
import logging
import requests
import uuid
from django.conf import settings
from django.core.cache import cache
from django.core.exceptions import PermissionDenied
from .efiling_hub_caller_base import EFilingHubCallerBase
logger = logging.getLogger(__name__)
class EFilingCourtLocations(EFilingHubCallerBase):
def __init__(self):
self.access_token = None
self.refresh_token = None
EFilingHubCallerBase.__init__(self)
def _get_api(self, request, url, bceid_guid, headers={}):
# make sure we have an access token
if not self.access_token:
if not self._get_token(request):
raise Exception('EFH - Unable to get API Token')
headers = self._set_headers(headers, bceid_guid, self.access_token)
response = requests.get(url, headers=headers)
logging.debug(f'EFH - Get Locations {response.status_code} {response.text}')
if response.status_code == 401:
# not authorized .. try refreshing token
if self._refresh_token(request):
headers = self._set_headers(headers, bceid_guid, self.access_token)
response = requests.get(url, headers=headers)
logging.debug(f'EFH - Get Locations Retry {response.status_code} {response.text}')
return response
def courts(self, request):
if cache.get('courts'):
return cache.get('courts')
bceid_guid = self._get_bceid(request)
# if bceid_guid is None .. we basically have an anonymous user so raise an error
if bceid_guid is None:
raise PermissionDenied()
url = f'{self.api_base_url}/courts?courtLevel=S'
print('DEBUG: ' + url)
response = self._get_api(request, url, bceid_guid, headers={})
if response.status_code == 200:
cso_locations = json.loads(response.text)
locations = {}
for location in cso_locations['courts']:
city = location['address']['cityName']
locations[city] = {
'address_1': location['address']['addressLine1'],
'address_2': location['address']['addressLine2'],
'address_3': location['address']['addressLine3'],
'postal': location['address']['postalCode'],
'location_id': location['identifierCode']
}
cache.set('courts', locations)
return locations
if response.status_code == 401:
print(response.headers.get('WWW-Authenticate', ''))
return {"Error calling court locations API": {"status_code": "401", "text": "authentication failed"}}
return {"Error calling court locations API": {"status_code": str(response.status_code), "text": response.text}}

+ 94
- 0
edivorce/apps/core/utils/efiling_hub_caller_base.py View File

@ -0,0 +1,94 @@
import json
import logging
import requests
import uuid
from django.conf import settings
from django.core.exceptions import PermissionDenied
logger = logging.getLogger(__name__)
class EFilingHubCallerBase:
def __init__(self):
self.client_id = settings.EFILING_HUB_KEYCLOAK_CLIENT_ID
self.client_secret = settings.EFILING_HUB_KEYCLOAK_SECRET
self.token_base_url = settings.EFILING_HUB_KEYCLOAK_BASE_URL
self.token_realm = settings.EFILING_HUB_KEYCLOAK_REALM
self.api_base_url = settings.EFILING_HUB_API_BASE_URL
self.access_token = None
self.refresh_token = None
def _get_token(self, request):
payload = f'client_id={self.client_id}&grant_type=client_credentials&client_secret={self.client_secret}'
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
url = f'{self.token_base_url}/auth/realms/{self.token_realm}/protocol/openid-connect/token'
response = requests.post(url, headers=headers, data=payload)
logging.debug(f'EFH - Get Token {response.status_code}')
if response.status_code == 200:
response = json.loads(response.text)
# save token as object property..
if 'access_token' in response:
self.access_token = response['access_token']
if 'refresh_token' in response:
self.refresh_token = response['refresh_token']
return True
return False
def _refresh_token(self, request):
if not self.refresh_token:
return False
payload = f'client_id={self.client_id}&grant_type=refresh_token&client_secret={self.client_secret}&refresh_token={self.refresh_token}'
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
url = f'{self.token_base_url}/auth/realms/{self.token_realm}/protocol/openid-connect/token'
response = requests.post(url, headers=headers, data=payload)
logging.debug(f'EFH - Get Refresh Token {response.status_code}')
response = json.loads(response.text)
# save in session .. lets just assume that current user is authenticated
if 'access_token' in response:
self.access_token = response['access_token']
if 'refresh_token' in response:
self.refresh_token = response['refresh_token']
return True
return False
def _get_bceid(self, request):
def _get_raw_bceid(request):
if settings.DEPLOYMENT_TYPE == 'localdev':
# to integrate with the Test eFiling Hub, we need a valid BCEID which is
# unavailable for a local eDivorce environment. Use an env specified mapping
# to figure out what we should pass through to eFiling Hub. This BCEID username
# needs to match with what you will be logging in with to the Test BCEID environment.
return settings.EFILING_BCEID
return request.session.get('bcgov_userguid', None)
guid = _get_raw_bceid(request)
if guid:
return str(uuid.UUID(guid))
return guid
def _set_headers(self, headers, bceid_guid, access_token, transaction_id=None):
if transaction_id:
headers.update({
'X-User-Id': bceid_guid,
'Authorization': f'Bearer {self.access_token}',
'X-Transaction-Id': transaction_id
})
else:
headers.update({
'X-User-Id': bceid_guid,
'Authorization': f'Bearer {self.access_token}'
})
return headers

+ 8
- 7
edivorce/apps/core/utils/efiling_packaging.py View File

@ -7,9 +7,9 @@ import re
from django.conf import settings from django.conf import settings
from django.urls import reverse from django.urls import reverse
from edivorce.apps.core.models import Document
from edivorce.apps.core.utils.question_step_mapping import list_of_registries
from edivorce.apps.core.views.pdf import images_to_pdf, pdf_form
from ..models import Document
from ..views.pdf import images_to_pdf, pdf_form
from .efiling_court_locations import EFilingCourtLocations
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -108,7 +108,7 @@ class EFilingPackaging:
def format_package(self, request, responses, files, documents): def format_package(self, request, responses, files, documents):
package = PACKAGE_FORMAT.copy() package = PACKAGE_FORMAT.copy()
package['filingPackage']['documents'] = documents package['filingPackage']['documents'] = documents
package['filingPackage']['court']['location'] = self._get_location(responses)
package['filingPackage']['court']['location'] = self._get_location(request, responses)
package['filingPackage']['parties'] = self._get_parties(responses) package['filingPackage']['parties'] = self._get_parties(responses)
file_number = self._get_file_number(responses) file_number = self._get_file_number(responses)
if file_number: if file_number:
@ -312,10 +312,11 @@ class EFilingPackaging:
return parties return parties
def _get_location(self, responses):
def _get_location(self, request, responses):
location_name = responses.get('court_registry_for_filing', '') location_name = responses.get('court_registry_for_filing', '')
return list_of_registries.get(location_name,
{'location_id': '0000'}).get('location_id')
court_locations = EFilingCourtLocations().courts(request)
return court_locations.get(location_name,
{'location_id': '0000'}).get('location_id')
def _get_file_number(self, responses): def _get_file_number(self, responses):
if not self.initial_filing: if not self.initial_filing:


+ 32
- 100
edivorce/apps/core/utils/efiling_submission.py View File

@ -6,83 +6,40 @@ import uuid
from django.conf import settings from django.conf import settings
from django.core.exceptions import PermissionDenied from django.core.exceptions import PermissionDenied
from .efiling_packaging import EFilingPackaging
from .efiling_hub_caller_base import EFilingHubCallerBase
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
class EFilingSubmission:
class EFilingSubmission(EFilingHubCallerBase):
def __init__(self, initial_filing):
self.client_id = settings.EFILING_HUB_KEYCLOAK_CLIENT_ID
self.client_secret = settings.EFILING_HUB_KEYCLOAK_SECRET
self.token_base_url = settings.EFILING_HUB_KEYCLOAK_BASE_URL
self.token_realm = settings.EFILING_HUB_KEYCLOAK_REALM
self.api_base_url = settings.EFILING_HUB_API_BASE_URL
def __init__(self, initial_filing, packaging):
self.initial_filing = initial_filing self.initial_filing = initial_filing
self.packaging = EFilingPackaging(initial_filing)
self.packaging = packaging
self.submission_id = None self.submission_id = None
self.access_token = None self.access_token = None
self.refresh_token = None self.refresh_token = None
EFilingHubCallerBase.__init__(self)
def _get_token(self, request):
payload = f'client_id={self.client_id}&grant_type=client_credentials&client_secret={self.client_secret}'
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
url = f'{self.token_base_url}/auth/realms/{self.token_realm}/protocol/openid-connect/token'
try:
response = requests.post(url, headers=headers, data=payload)
except:
return False
logging.debug(f'EFH - Get Token {response.status_code}')
if response.status_code == 200:
response = json.loads(response.text)
# save token as object property..
if 'access_token' in response:
self.access_token = response['access_token']
if 'refresh_token' in response:
self.refresh_token = response['refresh_token']
return True
return False
def _refresh_token(self, request):
if not self.refresh_token:
return False
payload = f'client_id={self.client_id}&grant_type=refresh_token&client_secret={self.client_secret}&refresh_token={self.refresh_token}'
headers = {'Content-Type': 'application/x-www-form-urlencoded'}
url = f'{self.token_base_url}/auth/realms/{self.token_realm}/protocol/openid-connect/token'
response = requests.post(url, headers=headers, data=payload)
logging.debug(f'EFH - Get Refresh Token {response.status_code}')
response = json.loads(response.text)
# save in session .. lets just assume that current user is authenticated
if 'access_token' in response:
self.access_token = response['access_token']
if 'refresh_token' in response:
self.refresh_token = response['refresh_token']
return True
return False
def _get_transaction(self, request):
"""
Get the current transaction id stored in session, otherwise generate one.
:param request:
:return:
"""
guid = request.session.get('transaction_id', None)
if not guid:
guid = str(uuid.uuid4())
request.session['transaction_id'] = guid
return guid
def _get_api(self, request, url, transaction_id, bce_id, headers, data=None, files=None):
def _get_api(self, request, url, bceid_guid, headers={}, data=None, transaction_id=None, files=None):
# make sure we have an access token # make sure we have an access token
if not self.access_token: if not self.access_token:
if not self._get_token(request): if not self._get_token(request):
raise Exception('EFH - Unable to get API Token') raise Exception('EFH - Unable to get API Token')
headers.update({
'X-Transaction-Id': transaction_id,
'X-User-Id': bce_id,
'Authorization': f'Bearer {self.access_token}'
})
headers = self._set_headers(headers, bceid_guid, self.access_token, transaction_id)
if not data: if not data:
data = {} data = {}
@ -93,45 +50,13 @@ class EFilingSubmission:
if response.status_code == 401: if response.status_code == 401:
# not authorized .. try refreshing token # not authorized .. try refreshing token
if self._refresh_token(request): if self._refresh_token(request):
headers.update({
'X-Transaction-Id': transaction_id,
'X-User-Id': bce_id,
'Authorization': f'Bearer {self.access_token}'
})
headers = self._set_headers(headers, bceid_guid, self.access_token, transaction_id)
response = requests.post(url, headers=headers, data=data, files=files) response = requests.post(url, headers=headers, data=data, files=files)
logging.debug(f'EFH - Get API Retry {response.status_code} {response.text}') logging.debug(f'EFH - Get API Retry {response.status_code} {response.text}')
return response return response
def _get_transaction(self, request):
"""
Get the current transaction id stored in session, otherwise generate one.
:param request:
:return:
"""
guid = request.session.get('transaction_id', None)
if not guid:
guid = str(uuid.uuid4())
request.session['transaction_id'] = guid
return guid
def _get_bceid(self, request):
def _get_raw_bceid(request):
if settings.DEPLOYMENT_TYPE == 'localdev':
# to integrate with the Test eFiling Hub, we need a valid BCEID which is
# unavailable for a local eDivorce environment. Use an env specified mapping
# to figure out what we should pass through to eFiling Hub. This BCEID username
# needs to match with what you will be logging in with to the Test BCEID environment.
return settings.EFILING_BCEID
return request.session.get('bcgov_userguid', None)
guid = _get_raw_bceid(request)
if guid:
return str(uuid.UUID(guid))
return guid
def upload(self, request, responses, files, documents=None, parties=None): def upload(self, request, responses, files, documents=None, parties=None):
""" """
Does an initial upload of documents and gets the generated eFiling Hub url. Does an initial upload of documents and gets the generated eFiling Hub url.
@ -144,18 +69,24 @@ class EFilingSubmission:
# will tie it to the session. # will tie it to the session.
transaction_id = self._get_transaction(request) transaction_id = self._get_transaction(request)
bce_id = self._get_bceid(request)
bceid_guid = self._get_bceid(request)
# if bce_id is None .. we basically have an anonymous user so raise an error
if bce_id is None:
# if bceid_guid is None .. we basically have an anonymous user so raise an error
if bceid_guid is None:
raise PermissionDenied() raise PermissionDenied()
url = f'{self.api_base_url}/submission/documents' url = f'{self.api_base_url}/submission/documents'
print('DEBUG: ' + url) print('DEBUG: ' + url)
try: try:
response = self._get_api(request, url, transaction_id, bce_id, headers={}, files=files)
response = self._get_api(request, url, bceid_guid, headers={},
transaction_id=transaction_id, files=files)
except: except:
return settings.FORCE_SCRIPT_NAME + "dashboard/initial_filing?no_connection=1", None
if self.initial_filing:
error_route = 'initial_filing'
else:
error_route = 'final_filing'
return settings.FORCE_SCRIPT_NAME + f"dashboard/{error_route}?no_connection=1", None
if response.status_code == 200: if response.status_code == 200:
response = json.loads(response.text) response = json.loads(response.text)
@ -170,7 +101,8 @@ class EFilingSubmission:
print('DEBUG: ' + url) print('DEBUG: ' + url)
data = json.dumps(package_data) data = json.dumps(package_data)
print('DEBUG: ' + data) print('DEBUG: ' + data)
response = self._get_api(request, url, transaction_id, bce_id, headers, data)
response = self._get_api(request, url, bceid_guid, headers=headers,
transaction_id=transaction_id, data=data)
if response.status_code == 200: if response.status_code == 200:
response = json.loads(response.text) response = json.loads(response.text)


+ 0
- 184
edivorce/apps/core/utils/question_step_mapping.py View File

@ -310,187 +310,3 @@ page_step_mapping = {
'location': 'filing_locations', 'location': 'filing_locations',
'signing_filing': 'signing_filing', 'signing_filing': 'signing_filing',
} }
""" List of court registries """
list_of_registries = {
'Abbotsford': {
'address_1': '32203 South Fraser Way',
'address_2': '',
'postal': 'V2T 1W6',
'location_id': '3561'
},
'Campbell River': {
'address_1': '500 - 13th Avenue',
'address_2': '',
'postal': 'V9W 6P1',
'location_id': '1031'
},
'Chilliwack': {
'address_1': '46085 Yale Road',
'address_2': '',
'postal': 'V2P 2L8',
'location_id': '3521'
},
'Courtenay': {
'address_1': 'Room 100',
'address_2': '420 Cumberland Road',
'postal': 'V9N 2C4',
'location_id': '1041'
},
'Cranbrook': {
'address_1': 'Room 147',
'address_2': '102 - 11th Avenue South',
'postal': 'V1C 2P3',
'location_id': '4711'
},
'Dawson Creek': {
'address_1': '1201 - 103rd Avenue',
'address_2': '',
'postal': 'V1G 4J2',
'location_id': '5731'
},
'Duncan': {
'address_1': '238 Government Street',
'address_2': '',
'postal': 'V9L 1A5',
'location_id': '1051'
},
'Fort Nelson': {
'address_1': 'Bag 1000',
'address_2': '4604 Sunset Drive',
'postal': 'V0C 1R0',
'location_id': '5751'
},
'Fort St. John': {
'address_1': '10600 - 100 Street',
'address_2': '',
'postal': 'V1J 4L6',
'location_id': '5771'
},
'Golden': {
'address_1': '837 Park Drive',
'address_2': '',
'postal': 'V0A 1H0',
'location_id': '4741'
},
'Kamloops': {
'address_1': '223 - 455 Columbia Street',
'address_2': '',
'postal': 'V2C 6K4',
'location_id': '4781'
},
'Kelowna': {
'address_1': '1355 Water Street',
'address_2': '',
'postal': 'V1Y 9R3',
'location_id': '4801'
},
'Nanaimo': {
'address_1': '35 Front Street',
'address_2': '',
'postal': 'V9R 5J1',
'location_id': '1091'
},
'Nelson': {
'address_1': '320 Ward Street',
'address_2': '',
'postal': 'V1L 1S6',
'location_id': '4871'
},
'New Westminster': {
'address_1': 'Begbie Square',
'address_2': '651 Carnarvon Street',
'postal': 'V3M 1C9',
'location_id': '3581'
},
'Penticton': {
'address_1': '100 Main Street',
'address_2': '',
'postal': 'V2A 5A5',
'location_id': '4891'
},
'Port Alberni': {
'address_1': '2999 - 4th Avenue',
'address_2': '',
'postal': 'V9Y 8A5',
'location_id': '1121'
},
'Powell River': {
'address_1': '103 - 6953 Alberni Street',
'address_2': '',
'postal': 'V8A 2B8',
'location_id': '1145'
},
'Prince George': {
'address_1': 'J.O. Wilson Square',
'address_2': '250 George Street',
'postal': 'V2L 5S2',
'location_id': '5891'
},
'Prince Rupert': {
'address_1': '100 Market Place',
'address_2': '',
'postal': 'V8J 1B8',
'location_id': '5901'
},
'Quesnel': {
'address_1': '305 - 350 Barlow Avenue',
'address_2': '',
'postal': 'V2J 2C1',
'location_id': '5921'
},
'Revelstoke': {
'address_1': '1123 West 2nd Street',
'address_2': '',
'postal': 'V0E 2S0',
'location_id': '4911'
},
'Rossland': {
'address_1': 'P.O. Box 639',
'address_2': '2288 Columbia Avenue',
'postal': 'V0G 1Y0',
'location_id': '4921'
},
'Salmon Arm': {
'address_1': '550 - 2nd Avenue NE',
'address_2': 'PO Box 100, Station Main',
'postal': 'V1E 4S4',
'location_id': '4941'
},
'Smithers': {
'address_1': 'No. 40, Bag 5000',
'address_2': '3793 Alfred Avenue',
'postal': 'V0J 2N0',
'location_id': '5931'
},
'Terrace': {
'address_1': '3408 Kalum Street',
'address_2': '',
'postal': 'V8G 2N6',
'location_id': '5951'
},
'Vancouver': {
'address_1': '800 Smithe Street',
'address_2': '',
'postal': 'V6Z 2E1',
'location_id': '6011'
},
'Vernon': {
'address_1': '3001 - 27th Street',
'address_2': '',
'postal': 'V1T 4W5',
'location_id': '4971'
},
'Victoria': {
'address_1': '850 Burdett Avenue',
'address_2': '',
'postal': 'V8W 1B4',
'location_id': '1201'
},
'Williams Lake': {
'address_1': '540 Borland Street',
'address_2': '',
'postal': 'V2G lR8',
'location_id': '5971'
}
}

+ 3
- 2
edivorce/apps/core/views/efiling.py View File

@ -10,6 +10,7 @@ from django.contrib.auth.decorators import login_required
from ..decorators import prequal_completed from ..decorators import prequal_completed
from ..models import Document, UserResponse from ..models import Document, UserResponse
from ..utils.efiling_court_locations import EFilingCourtLocations
from ..utils.efiling_documents import forms_to_file from ..utils.efiling_documents import forms_to_file
from ..utils.efiling_packaging import EFilingPackaging from ..utils.efiling_packaging import EFilingPackaging
from ..utils.efiling_submission import EFilingSubmission from ..utils.efiling_submission import EFilingSubmission
@ -109,8 +110,8 @@ def _validate_and_submit_documents(request, responses, initial=False):
def _package_and_submit(request, uploaded, generated, responses, initial): def _package_and_submit(request, uploaded, generated, responses, initial):
""" Build the efiling package and submit it to the efiling hub """ """ Build the efiling package and submit it to the efiling hub """
hub = EFilingSubmission(initial_filing=initial)
packaging = EFilingPackaging(initial_filing=initial)
packaging = EFilingPackaging(initial)
hub = EFilingSubmission(initial, packaging)
post_files, documents = packaging.get_files(request, responses, uploaded, generated) post_files, documents = packaging.get_files(request, responses, uploaded, generated)
redirect_url, msg = hub.upload(request, responses, post_files, documents) redirect_url, msg = hub.upload(request, responses, post_files, documents)
return msg, redirect_url return msg, redirect_url


+ 31
- 6
edivorce/apps/core/views/main.py View File

@ -7,8 +7,8 @@ from django.contrib.auth.decorators import login_required
from edivorce.apps.core.utils.derived import get_derived_data from edivorce.apps.core.utils.derived import get_derived_data
from ..decorators import intercept, prequal_completed from ..decorators import intercept, prequal_completed
from ..utils.efiling_court_locations import EFilingCourtLocations
from ..utils.efiling_documents import forms_to_file from ..utils.efiling_documents import forms_to_file
from ..utils.question_step_mapping import list_of_registries
from ..utils.step_completeness import get_error_dict, get_missed_question_keys, get_step_completeness, is_complete, get_formatted_incomplete_list from ..utils.step_completeness import get_error_dict, get_missed_question_keys, get_step_completeness, is_complete, get_formatted_incomplete_list
from ..utils.template_step_order import template_step_order from ..utils.template_step_order import template_step_order
from ..utils.user_response import ( from ..utils.user_response import (
@ -165,7 +165,7 @@ def dashboard_nav(request, nav_step):
responses_dict['active_page'] = nav_step responses_dict['active_page'] = nav_step
template_name = 'dashboard/%s.html' % nav_step template_name = 'dashboard/%s.html' % nav_step
if nav_step in ('print_form', 'swear_forms', 'next_steps', 'final_filing') and responses_dict.get('court_registry_for_filing'): if nav_step in ('print_form', 'swear_forms', 'next_steps', 'final_filing') and responses_dict.get('court_registry_for_filing'):
_add_court_registry_address(responses_dict)
_add_court_registry_address(request, responses_dict)
if nav_step in ('print_form', 'initial_filing', 'final_filing'): if nav_step in ('print_form', 'initial_filing', 'final_filing'):
_add_question_errors(responses_dict) _add_question_errors(responses_dict)
if nav_step in ('initial_filing', 'final_filing'): if nav_step in ('initial_filing', 'final_filing'):
@ -176,9 +176,33 @@ def dashboard_nav(request, nav_step):
return render(request, template_name=template_name, context=responses_dict) return render(request, template_name=template_name, context=responses_dict)
def _add_court_registry_address(responses_dict):
responses_dict['court_registry_for_filing_address'] = f"123 {responses_dict.get('court_registry_for_filing')} St"
responses_dict['court_registry_for_filing_postal_code'] = 'V0A 1A1'
def _add_court_registry_address(request, responses_dict):
filing_registry = responses_dict.get('court_registry_for_filing', '')
if not filing_registry:
return
locations = EFilingCourtLocations().courts(request)
if not filing_registry in locations.keys():
return
location = locations[filing_registry]
def addr(key):
val = location.get(key, '')
strVal = '' if val is None else str(val)
return strVal + "<br>" if strVal else ''
address = addr('address_1') + addr('address_2') + addr('address_3')
responses_dict['court_registry_for_filing_address'] = address.strip()
postal = addr('postal')
if len(postal) >= 10:
postal = postal[0:3] + ' ' + postal[-7:]
responses_dict['court_registry_for_filing_postal_code'] = postal
else:
responses_dict['court_registry_for_filing_postal_code'] = postal
def _add_question_errors(responses_dict): def _add_question_errors(responses_dict):
@ -232,7 +256,8 @@ def question(request, step, sub_step=None):
responses_dict['active_page'] = step responses_dict['active_page'] = step
# If page is filing location page, add registries dictionary for list of court registries # If page is filing location page, add registries dictionary for list of court registries
if step == "location": if step == "location":
responses_dict['registries'] = sorted(list_of_registries.keys())
courts = EFilingCourtLocations().courts(request)
responses_dict['registries'] = sorted(courts.keys())
responses_dict['sub_step'] = sub_step responses_dict['sub_step'] = sub_step
responses_dict['derived'] = derived responses_dict['derived'] = derived


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

@ -109,6 +109,11 @@ REST_FRAMEWORK = {
] ]
} }
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache'
}
}
LOGGING = { LOGGING = {
'version': 1, 'version': 1,


Loading…
Cancel
Save