diff --git a/app/dao/organisation_dao.py b/app/dao/organisation_dao.py index e5e1cbb62..eca2787b4 100644 --- a/app/dao/organisation_dao.py +++ b/app/dao/organisation_dao.py @@ -24,6 +24,20 @@ def dao_get_organisation_by_id(organisation_id): return Organisation.query.filter_by(id=organisation_id).one() +def dao_get_organisation_by_email_address(email_address): + + email_address = email_address.lower() + + for domain in Domain().query.all(): + if ( + email_address.endswith("@{}".format(domain.domain)) or + email_address.endswith(".{}".format(domain.domain)) + ): + return Organisation.query.filter_by(id=domain.organisation_id).one() + + return None + + def dao_get_organisation_by_service_id(service_id): return Organisation.query.join(Organisation.services).filter_by(id=service_id).first() diff --git a/app/dao/services_dao.py b/app/dao/services_dao.py index eb766c06b..70d7a8a83 100644 --- a/app/dao/services_dao.py +++ b/app/dao/services_dao.py @@ -11,6 +11,7 @@ from app.dao.dao_utils import ( transactional, version_class ) +from app.dao.organisation_dao import dao_get_organisation_by_email_address from app.dao.service_sms_sender_dao import insert_service_sms_sender from app.dao.service_user_dao import dao_get_service_user from app.models import ( @@ -151,14 +152,25 @@ def dao_fetch_service_by_id_and_user(service_id, user_id): @transactional @version_class(Service) -def dao_create_service(service, user, service_id=None, service_permissions=None, letter_branding=None): +def dao_create_service( + service, + user, + service_id=None, + service_permissions=None, + letter_branding=None, +): # the default property does not appear to work when there is a difference between the sqlalchemy schema and the # db schema (ie: during a migration), so we have to set sms_sender manually here. After the GOVUK sms_sender # migration is completed, this code should be able to be removed. + if not user: + raise ValueError("Can't create a service without a user") + if service_permissions is None: service_permissions = DEFAULT_SERVICE_PERMISSIONS + organisation = dao_get_organisation_by_email_address(user.email_address) + from app.dao.permissions_dao import permission_dao service.users.append(user) permission_dao.add_default_service_permissions_for_user(user, service) @@ -173,8 +185,20 @@ def dao_create_service(service, user, service_id=None, service_permissions=None, # do we just add the default - or will we get a value from FE? insert_service_sms_sender(service, current_app.config['FROM_NUMBER']) + if letter_branding: service.letter_branding = letter_branding + + if organisation: + + service.organisation = organisation + + if organisation.email_branding_id: + service.email_branding = organisation.email_branding_id + + if organisation.letter_branding_id and not service.letter_branding: + service.letter_branding = organisation.letter_branding_id + db.session.add(service) diff --git a/tests/app/dao/test_organisation_dao.py b/tests/app/dao/test_organisation_dao.py index 7e1f90e2f..6375cf7b6 100644 --- a/tests/app/dao/test_organisation_dao.py +++ b/tests/app/dao/test_organisation_dao.py @@ -6,6 +6,7 @@ from sqlalchemy.exc import IntegrityError, SQLAlchemyError from app.dao.organisation_dao import ( dao_get_organisations, + dao_get_organisation_by_email_address, dao_get_organisation_by_id, dao_get_organisation_by_service_id, dao_get_organisation_services, @@ -18,6 +19,7 @@ from app.dao.organisation_dao import ( from app.models import Organisation from tests.app.db import ( + create_domain, create_email_branding, create_letter_branding, create_organisation, @@ -197,3 +199,30 @@ def test_add_user_to_organisation_when_user_does_not_exist(sample_organisation): def test_add_user_to_organisation_when_organisation_does_not_exist(sample_user): with pytest.raises(expected_exception=SQLAlchemyError): dao_add_user_to_organisation(organisation_id=uuid.uuid4(), user_id=sample_user.id) + + +@pytest.mark.parametrize('domain, expected_org', ( + ('unknown.gov.uk', False), + ('example.gov.uk', True), +)) +def test_get_organisation_by_email_address( + admin_request, + sample_user, + domain, + expected_org, +): + + org = create_organisation() + create_domain('example.gov.uk', org.id) + create_domain('test.gov.uk', org.id) + + another_org = create_organisation(name='Another') + create_domain('cabinet-office.gov.uk', another_org.id) + create_domain('cabinetoffice.gov.uk', another_org.id) + + found_org = dao_get_organisation_by_email_address('test@{}'.format(domain)) + + if expected_org: + assert found_org is org + else: + assert found_org is None diff --git a/tests/app/dao/test_services_dao.py b/tests/app/dao/test_services_dao.py index 6461fd93c..cbc6cb24c 100644 --- a/tests/app/dao/test_services_dao.py +++ b/tests/app/dao/test_services_dao.py @@ -4,7 +4,7 @@ from datetime import datetime import pytest from freezegun import freeze_time from sqlalchemy.exc import IntegrityError -from sqlalchemy.orm.exc import FlushError, NoResultFound +from sqlalchemy.orm.exc import NoResultFound from app import db from app.dao.inbound_numbers_dao import ( @@ -167,9 +167,9 @@ def test_cannot_create_service_with_no_user(notify_db_session): message_limit=1000, restricted=False, created_by=user) - with pytest.raises(FlushError) as excinfo: + with pytest.raises(ValueError) as excinfo: dao_create_service(service, None) - assert "Can't flush None value found in collection Service.users" in str(excinfo.value) + assert "Can't create a service without a user" in str(excinfo.value) def test_should_add_user_to_service(notify_db_session): diff --git a/tests/app/db.py b/tests/app/db.py index 1b301a2f2..0b3b24c2b 100644 --- a/tests/app/db.py +++ b/tests/app/db.py @@ -51,7 +51,8 @@ from app.models import ( Complaint, InvitedUser, TemplateFolder, - LetterBranding + LetterBranding, + Domain, ) @@ -497,6 +498,16 @@ def create_annual_billing( return annual_billing +def create_domain(domain, organisation_id): + + domain = Domain(domain=domain, organisation_id=organisation_id) + + db.session.add(domain) + db.session.commit() + + return domain + + def create_organisation(name='test_org_1', active=True): data = { 'name': name, diff --git a/tests/app/service/test_rest.py b/tests/app/service/test_rest.py index 22208dd52..e216f8801 100644 --- a/tests/app/service/test_rest.py +++ b/tests/app/service/test_rest.py @@ -44,7 +44,9 @@ from tests.app.db import ( create_inbound_number, create_service_sms_sender, create_service_with_defined_sms_sender, - create_letter_branding + create_letter_branding, + create_organisation, + create_domain, ) from tests.app.db import create_user @@ -253,6 +255,51 @@ def test_create_service(admin_request, sample_user): assert service_sms_senders[0].sms_sender == current_app.config['FROM_NUMBER'] +@pytest.mark.parametrize('domain, expected_org', ( + (None, False), + ('', False), + ('unknown.gov.uk', False), + ('unknown-example.gov.uk', False), + ('example.gov.uk', True), + ('test.gov.uk', True), + ('test.example.gov.uk', True), +)) +def test_create_service_with_domain_sets_organisation( + admin_request, + sample_user, + domain, + expected_org, +): + + org = create_organisation() + create_domain('example.gov.uk', org.id) + create_domain('test.gov.uk', org.id) + + another_org = create_organisation(name='Another') + create_domain('cabinet-office.gov.uk', another_org.id) + create_domain('cabinetoffice.gov.uk', another_org.id) + + sample_user.email_address = 'test@{}'.format(domain) + + data = { + 'name': 'created service', + 'user_id': str(sample_user.id), + 'message_limit': 1000, + 'restricted': False, + 'active': False, + 'email_from': 'created.service', + 'created_by': str(sample_user.id), + 'service_domain': domain, + } + + json_resp = admin_request.post('service.create_service', _data=data, _expected_status=201) + + if expected_org: + assert json_resp['data']['organisation'] == str(org.id) + else: + assert json_resp['data']['organisation'] is None + + def test_create_service_with_domain_sets_letter_branding(admin_request, sample_user): letter_branding = create_letter_branding( name='test domain', filename='test-domain', domain='test.domain'