Exemplo n.º 1
0
def test_create_from_dict(session):  # pylint:disable=unused-argument
    """Assert that an Org can be created from schema."""
    org_info = {'name': 'My Test Org'}

    result_org = OrgModel.create_from_dict(org_info).save()

    assert result_org.id is not None
Exemplo n.º 2
0
def test_org_create_from_dictionary(session):  # pylint:disable=unused-argument
    """Assert that an Org can be created from a dictionary."""
    org_info = {'name': 'My Test Org'}

    org_model = OrgModel.create_from_dict(org_info).save()
    assert org_model
    assert org_model.id
    assert org_model.name == org_info['name']
Exemplo n.º 3
0
    def create_org(org_info: dict, user_id):
        """Create a new organization."""
        current_app.logger.debug('<create_org ')
        existing_similar__org = OrgModel.find_similar_org_by_name(org_info['name'])
        if existing_similar__org is not None:
            raise BusinessException(Error.DATA_CONFLICT, None)

        org = OrgModel.create_from_dict(camelback2snake(org_info))
        org.save()
        current_app.logger.info(f'<created_org org_id:{org.id}')
        # create the membership record for this user
        membership = MembershipModel(org_id=org.id, user_id=user_id, membership_type_code='OWNER',
                                     membership_type_status=Status.ACTIVE.value)
        membership.save()

        return Org(org)
Exemplo n.º 4
0
    def create_org(org_info: dict, user_id, token_info: Dict = None):
        """Create a new organization."""
        current_app.logger.debug('<create_org ')
        is_staff_admin = token_info and 'staff_admin' in token_info.get(
            'realm_access').get('roles')
        if not is_staff_admin:  # staff can create any number of orgs
            count = OrgModel.get_count_of_org_created_by_user_id(user_id)
            if count >= current_app.config.get('MAX_NUMBER_OF_ORGS'):
                raise BusinessException(Error.MAX_NUMBER_OF_ORGS_LIMIT, None)
            if org_info.get('accessType', None) == AccessType.ANONYMOUS.value:
                raise BusinessException(Error.USER_CANT_CREATE_ANONYMOUS_ORG,
                                        None)

        existing_similar__org = OrgModel.find_similar_org_by_name(
            org_info['name'])
        if existing_similar__org is not None:
            raise BusinessException(Error.DATA_CONFLICT, None)
        org = OrgModel.create_from_dict(camelback2snake(org_info))
        if is_staff_admin:
            org.access_type = AccessType.ANONYMOUS.value
            org.billable = False
        else:
            org.access_type = AccessType.BCSC.value
            org.billable = True
        org.save()
        current_app.logger.info(f'<created_org org_id:{org.id}')
        # create the membership record for this user if its not created by staff and access_type is anonymous
        if not is_staff_admin and org_info.get(
                'access_type') != AccessType.ANONYMOUS:
            membership = MembershipModel(
                org_id=org.id,
                user_id=user_id,
                membership_type_code='OWNER',
                membership_type_status=Status.ACTIVE.value)
            membership.save()

            # Add the user to account_holders group
            KeycloakService.join_account_holders_group()

        # TODO Remove later, create payment settings now with default values
        AccountPaymentModel.create_from_dict({'org_id': org.id})

        return Org(org)
Exemplo n.º 5
0
def test_create_from_dict_no_schema(session):  # pylint:disable=unused-argument
    """Assert that an Org can not be created without schema."""
    result_org = OrgModel.create_from_dict(None)

    assert result_org is None
Exemplo n.º 6
0
class Org:  # pylint: disable=too-many-public-methods
    """Manages all aspects of Org data.

    This service manages creating, updating, and retrieving Org data via the Org model.
    """
    def __init__(self, model):
        """Return an Org Service."""
        self._model = model

    @ServiceTracing.disable_tracing
    def as_dict(self):
        """Return the internal Org model as a dictionary.

        None fields are not included.
        """
        org_schema = OrgSchema()
        obj = org_schema.dump(self._model, many=False)
        return obj

    @staticmethod
    def create_org(org_info: dict, user_id):
        """Create a new organization."""
        current_app.logger.debug('<create_org ')
        # bcol is treated like an access type as well;so its outside the scheme
        mailing_address = org_info.pop('mailingAddress', None)
        payment_info = org_info.pop('paymentInfo', {})
        product_subscriptions = org_info.pop('productSubscriptions', None)

        bcol_profile_flags = None
        response = Org._validate_and_raise_error(org_info)
        # If the account is created using BCOL credential, verify its valid bc online account
        bcol_details_response = response.get('bcol_response', None)
        if bcol_details_response is not None and (
                bcol_details := bcol_details_response.json()) is not None:
            Org._map_response_to_org(bcol_details, org_info)
            bcol_profile_flags = bcol_details.get('profileFlags')

        access_type = response.get('access_type')

        # set premium for GOVM accounts..TODO remove if not needed this logic
        if access_type == AccessType.GOVM.value:
            org_info.update({'typeCode': OrgType.PREMIUM.value})

        org = OrgModel.create_from_dict(camelback2snake(org_info))
        org.access_type = access_type

        # Set the status based on access type
        # Check if the user is APPROVED else set the org status to PENDING

        if access_type == AccessType.GOVM.value:
            org.status_code = OrgStatus.PENDING_INVITE_ACCEPT.value

        # If mailing address is provided, save it
        if mailing_address:
            Org.add_contact_to_org(mailing_address, org)

        # create the membership record for this user if its not created by staff and access_type is anonymous
        Org.create_membership(access_type, org, user_id)

        if product_subscriptions is not None:
            subscription_data = {'subscriptions': product_subscriptions}
            ProductService.create_product_subscription(
                org.id, subscription_data=subscription_data, skip_auth=True)

        ProductService.create_subscription_from_bcol_profile(
            org.id, bcol_profile_flags)

        Org._create_payment_for_org(mailing_address, org, payment_info, True)

        # TODO do we have to check anything like this below?
        # if payment_account_status == PaymentAccountStatus.FAILED:
        # raise BusinessException(Error.ACCOUNT_CREATION_FAILED_IN_PAY, None)

        # Send an email to staff to remind review the pending account
        is_staff_review_needed = access_type in (
            AccessType.EXTRA_PROVINCIAL.value, AccessType.REGULAR_BCEID.value,
            AccessType.GOVN.value
        ) and not AffidavitModel.find_approved_by_user_id(user_id=user_id)

        user = UserModel.find_by_jwt_token()
        if is_staff_review_needed:
            Org._create_staff_review_task(org, user)

        org.commit()

        current_app.logger.info(f'<created_org org_id:{org.id}')

        return Org(org)
Exemplo n.º 7
0
    def create_org(
            org_info: dict,
            user_id,  # pylint: disable=too-many-locals, too-many-statements, too-many-branches
            token_info: Dict = None,
            bearer_token: str = None,
            origin_url: str = None):
        """Create a new organization."""
        current_app.logger.debug('<create_org ')
        # bcol is treated like an access type as well;so its outside the scheme
        bcol_credential = org_info.pop('bcOnlineCredential', None)
        mailing_address = org_info.pop('mailingAddress', None)
        payment_info = org_info.pop('paymentInfo', {})
        selected_payment_method = payment_info.get('paymentMethod', None)
        org_type = org_info.get('typeCode', OrgType.BASIC.value)
        branch_name = org_info.get('branchName', None)
        bcol_profile_flags = None

        # If the account is created using BCOL credential, verify its valid bc online account
        if bcol_credential:
            bcol_response = Org.get_bcol_details(bcol_credential,
                                                 bearer_token).json()
            Org._map_response_to_org(bcol_response, org_info)
            bcol_profile_flags = bcol_response.get('profileFlags')

        is_staff_admin = token_info and Role.STAFF_CREATE_ACCOUNTS.value in token_info.get(
            'realm_access').get('roles')
        is_bceid_user = token_info and token_info.get(
            'loginSource', None) == LoginSource.BCEID.value

        Org.validate_account_limit(is_staff_admin, user_id)

        access_type = Org.validate_access_type(is_bceid_user, is_staff_admin,
                                               org_info)

        # Always check duplicated name for all type of account.
        Org.raise_error_if_duplicate_name(org_info['name'], branch_name)

        # set premium for GOVM accounts..TODO remove if not needed this logic
        if access_type == AccessType.GOVM.value:
            org_type = OrgType.PREMIUM.value
            org_info.update({'typeCode': OrgType.PREMIUM.value})

        org = OrgModel.create_from_dict(camelback2snake(org_info))
        org.access_type = access_type
        # If the account is anonymous or govm set the billable value as False else True
        org.billable = access_type not in [
            AccessType.ANONYMOUS.value, AccessType.GOVM.value
        ]
        # Set the status based on access type
        # Check if the user is APPROVED else set the org status to PENDING
        # Send an email to staff to remind review the pending account
        if access_type in (AccessType.EXTRA_PROVINCIAL.value, AccessType.REGULAR_BCEID.value) \
                and not AffidavitModel.find_approved_by_user_id(user_id=user_id):
            Org._handle_bceid_status_and_notification(org, origin_url,
                                                      token_info)

        if access_type == AccessType.GOVM.value:
            org.status_code = OrgStatus.PENDING_INVITE_ACCEPT.value

        # If mailing address is provided, save it
        if mailing_address:
            Org.add_contact_to_org(mailing_address, org)

        # create the membership record for this user if its not created by staff and access_type is anonymous
        Org.create_membership(access_type, is_staff_admin, org, user_id)

        # dir search and GOVM doesnt need default products
        if access_type not in (AccessType.ANONYMOUS.value,
                               AccessType.GOVM.value):
            ProductService.create_default_product_subscriptions(
                org, bcol_profile_flags, is_new_transaction=False)

        payment_method = Org._validate_and_get_payment_method(
            selected_payment_method,
            OrgType[org_type],
            access_type=access_type)

        user_name = ''
        if payment_method == PaymentMethod.PAD.value:  # to get the pad accepted date
            user: UserModel = UserModel.find_by_jwt_token(token=token_info)
            user_name = user.username

        Org._create_payment_settings(org, payment_info, payment_method,
                                     mailing_address, user_name, True)

        # TODO do we have to check anything like this below?
        # if payment_account_status == PaymentAccountStatus.FAILED:
        # raise BusinessException(Error.ACCOUNT_CREATION_FAILED_IN_PAY, None)

        org.commit()

        current_app.logger.info(f'<created_org org_id:{org.id}')

        return Org(org)
Exemplo n.º 8
0
    def create_org(
            org_info: dict,
            user_id,  # pylint: disable=too-many-locals, too-many-statements, too-many-branches
            token_info: Dict = None,
            bearer_token: str = None,
            origin_url: str = None):
        """Create a new organization."""
        current_app.logger.debug('<create_org ')
        # bcol is treated like an access type as well;so its outside the scheme
        bcol_credential = org_info.pop('bcOnlineCredential', None)
        mailing_address = org_info.pop('mailingAddress', None)
        payment_info = org_info.pop('paymentInfo', {})
        selected_payment_method = payment_info.get('paymentMethod', None)
        org_type = org_info.get('typeCode', OrgType.BASIC.value)

        # If the account is created using BCOL credential, verify its valid bc online account
        if bcol_credential:
            bcol_response = Org.get_bcol_details(bcol_credential, org_info,
                                                 bearer_token).json()
            Org._map_response_to_org(bcol_response, org_info)

        is_staff_admin = token_info and Role.STAFF_CREATE_ACCOUNTS.value in token_info.get(
            'realm_access').get('roles')
        is_bceid_user = token_info and token_info.get(
            'loginSource', None) == LoginSource.BCEID.value

        Org.validate_account_limit(is_staff_admin, user_id)

        access_type = Org.validate_access_type(is_bceid_user, is_staff_admin,
                                               org_info)

        duplicate_check = (org_type
                           == OrgType.BASIC.value) or (not bcol_credential)
        if duplicate_check:  # Allow duplicate names if premium and link to bcol
            Org.raise_error_if_duplicate_name(org_info['name'])

        org = OrgModel.create_from_dict(camelback2snake(org_info))
        org.access_type = access_type
        # If the account is anonymous set the billable value as False else True
        org.billable = access_type != AccessType.ANONYMOUS.value

        # Set the status based on access type
        # Check if the user is APPROVED else set the org status to PENDING
        # Send an email to staff to remind review the pending account
        if access_type in (AccessType.EXTRA_PROVINCIAL.value, AccessType.REGULAR_BCEID.value) \
                and not AffidavitModel.find_approved_by_user_id(user_id=user_id):
            org.status_code = OrgStatus.PENDING_AFFIDAVIT_REVIEW.value
            user = UserModel.find_by_jwt_token(token=token_info)
            Org.send_staff_review_account_reminder(user, org.id, origin_url)

        # If mailing address is provided, save it
        if mailing_address:
            Org.add_contact_to_org(mailing_address, org)

        # create the membership record for this user if its not created by staff and access_type is anonymous
        Org.create_membership(access_type, is_staff_admin, org, user_id)

        Org.add_product(org.id, token_info)
        payment_method = Org._validate_and_get_payment_method(
            selected_payment_method, OrgType[org_type])
        Org._create_payment_settings(org, payment_info, payment_method,
                                     mailing_address, True)

        # TODO do we have to check anything like this below?
        # if payment_account_status == PaymentAccountStatus.FAILED:
        # raise BusinessException(Error.ACCOUNT_CREATION_FAILED_IN_PAY, None)

        org.commit()

        current_app.logger.info(f'<created_org org_id:{org.id}')

        return Org(org)
Exemplo n.º 9
0
    def create_org(
            org_info: dict,
            user_id,  # pylint: disable=too-many-locals, too-many-statements
            token_info: Dict = None,
            bearer_token: str = None):
        """Create a new organization."""
        current_app.logger.debug('<create_org ')
        bcol_credential = org_info.pop('bcOnlineCredential', None)
        mailing_address = org_info.pop('mailingAddress', None)
        bcol_account_number = None
        bcol_user_id = None

        # If the account is created using BCOL credential, verify its valid bc online account
        if bcol_credential:
            bcol_response = Org.get_bcol_details(bcol_credential, org_info,
                                                 bearer_token).json()
            bcol_account_number = bcol_response.get('accountNumber')
            bcol_user_id = bcol_response.get('userId')

        org_info[
            'typeCode'] = OrgType.PREMIUM.value if bcol_account_number else OrgType.BASIC.value

        is_staff_admin = token_info and 'staff_admin' in token_info.get(
            'realm_access').get('roles')
        if not is_staff_admin:  # staff can create any number of orgs
            count = OrgModel.get_count_of_org_created_by_user_id(user_id)
            if count >= current_app.config.get('MAX_NUMBER_OF_ORGS'):
                raise BusinessException(Error.MAX_NUMBER_OF_ORGS_LIMIT, None)
            if org_info.get('accessType', None) == AccessType.ANONYMOUS.value:
                raise BusinessException(Error.USER_CANT_CREATE_ANONYMOUS_ORG,
                                        None)

        if not bcol_account_number:  # Allow duplicate names if premium
            Org.raise_error_if_duplicate_name(org_info['name'])

        org = OrgModel.create_from_dict(camelback2snake(org_info))
        org.add_to_session()

        if is_staff_admin:
            org.access_type = AccessType.ANONYMOUS.value
            org.billable = False
        else:
            org.access_type = AccessType.BCSC.value
            org.billable = True

        # If mailing address is provided, save it
        if mailing_address:
            Org.add_contact_to_org(mailing_address, org)

        # create the membership record for this user if its not created by staff and access_type is anonymous
        if not is_staff_admin and org_info.get(
                'access_type') != AccessType.ANONYMOUS:
            membership = MembershipModel(
                org_id=org.id,
                user_id=user_id,
                membership_type_code='OWNER',
                membership_type_status=Status.ACTIVE.value)
            membership.add_to_session()

            # Add the user to account_holders group
            KeycloakService.join_account_holders_group()

        Org.add_payment_settings(org.id, bcol_account_number, bcol_user_id)

        org.save()
        current_app.logger.info(f'<created_org org_id:{org.id}')

        return Org(org)