Exemplo n.º 1
0
def test_get(app):
    """Test Get."""
    with app.app_context():
        mock_get_token = patch('pay_api.services.oauth_service.requests.Session.get')
        mock_get = mock_get_token.start()
        mock_get.return_value = Mock(status_code=201)
        mock_get.return_value.json.return_value = {}

        get_token_response = OAuthService.get('http://google.com/', '', AuthHeaderType.BEARER, ContentType.JSON)

        mock_get_token.stop()

        assert get_token_response.json() == {}
Exemplo n.º 2
0
    def _create_site(access_token, account, contact_info, receipt_method):
        """Create site in PayBC."""
        current_app.logger.debug('<Creating site ')
        if not contact_info:
            contact_info = {}
        site_url = current_app.config.get('CFS_BASE_URL') + '/cfs/parties/{}/accs/{}/sites/' \
            .format(account.get('party_number', None), account.get('account_number', None))
        site: Dict[str, Any] = {
            'site_name':
            'Site 1',  # Make it dynamic if we ever need multiple sites per account
            'city':
            get_non_null_value(contact_info.get('city'), DEFAULT_CITY),
            'address_line_1':
            get_non_null_value(contact_info.get('addressLine1'),
                               DEFAULT_ADDRESS_LINE_1),
            'postal_code':
            get_non_null_value(contact_info.get('postalCode'),
                               DEFAULT_POSTAL_CODE).replace(' ', ''),
            'province':
            get_non_null_value(contact_info.get('province'),
                               DEFAULT_JURISDICTION),
            'country':
            get_non_null_value(contact_info.get('country'), DEFAULT_COUNTRY),
            'customer_site_id':
            '1',
            'primary_bill_to':
            'Y',
            'customer_profile_class':
            CFS_CUSTOMER_PROFILE_CLASS
        }
        if receipt_method:
            site['receipt_method'] = receipt_method

        try:
            site_response = OAuthService.post(site_url, access_token,
                                              AuthHeaderType.BEARER,
                                              ContentType.JSON, site).json()
        except HTTPError as e:
            # If the site creation fails with 400, query and return site
            if e.response.status_code == 400:
                site_response = \
                    OAuthService.get(site_url, access_token, AuthHeaderType.BEARER, ContentType.JSON).json().get(
                        'items')[0]
            else:
                raise e
        current_app.logger.debug('>Creating site ')
        return site_response
Exemplo n.º 3
0
def check_auth(business_identifier: str, jwt: JwtManager, **kwargs):
    """Authorize the user for the business entity."""
    bearer_token = jwt.get_token_auth_header() if jwt else None
    auth_url = current_app.config.get(
        'AUTH_API_ENDPOINT') + f'entities/{business_identifier}/authorizations'
    auth_response = RestService.get(auth_url, bearer_token,
                                    AuthHeaderType.BEARER, ContentType.JSON)

    is_authorized: bool = False
    if auth_response:
        roles: list = auth_response.json().get('roles', [])
        if kwargs.get('one_of_roles', None):
            is_authorized = list(set(kwargs.get('one_of_roles'))
                                 & set(roles)) != []
        if kwargs.get('contains_role', None):
            is_authorized = kwargs.get('contains_role') in roles

    if not is_authorized:
        abort(403)
Exemplo n.º 4
0
def check_auth(business_identifier: str, **kwargs):
    """Authorize the user for the business entity."""
    user: UserContext = kwargs['user']
    is_authorized: bool = False
    if Role.SYSTEM.value in user.roles:
        is_authorized = bool(Role.EDITOR.value in user.roles)
    else:
        bearer_token = user.bearer_token
        auth_url = current_app.config.get(
            'AUTH_API_ENDPOINT'
        ) + f'entities/{business_identifier}/authorizations'
        auth_response = RestService.get(auth_url, bearer_token,
                                        AuthHeaderType.BEARER,
                                        ContentType.JSON)

        roles: list = auth_response.json().get('roles', [])
        if kwargs.get('one_of_roles', None):
            is_authorized = list(set(kwargs.get('one_of_roles'))
                                 & set(roles)) != []
        if kwargs.get('contains_role', None):
            is_authorized = kwargs.get('contains_role') in roles

    if not is_authorized:
        abort(403)
Exemplo n.º 5
0
def check_auth(business_identifier: str,
               account_id: str = None,
               corp_type_code: str = None,
               **kwargs):  # pylint: disable=unused-argument
    """Authorize the user for the business entity and return authorization response."""
    user: UserContext = kwargs['user']
    is_authorized: bool = False
    auth_response = None
    is_business_auth = True
    is_service_account = False
    if not account_id:
        account_id = user.account_id
    if Role.SYSTEM.value in user.roles:
        is_authorized = bool(Role.EDITOR.value in user.roles)
        is_service_account = True
    else:
        bearer_token = user.bearer_token
        if business_identifier:
            auth_url = current_app.config.get(
                'AUTH_API_ENDPOINT'
            ) + f'entities/{business_identifier}/authorizations?expanded=true'
            auth_response = RestService.get(auth_url, bearer_token,
                                            AuthHeaderType.BEARER,
                                            ContentType.JSON).json()

            roles: list = auth_response.get('roles', [])
            if kwargs.get('one_of_roles', None):
                is_authorized = list(
                    set(kwargs.get('one_of_roles')) & set(roles)) != []
            if kwargs.get('contains_role', None):
                is_authorized = kwargs.get('contains_role') in roles

        elif account_id:
            is_business_auth = False
            # TODO For now, just make a call to /orgs/<id> to see if the user has access to the account
            # When product level subscription is in place, use the below commented code.
            # auth_url = current_app.config.get(
            #     'AUTH_API_ENDPOINT') + f'accounts/{account_id}/products/{corp_type_code}/authorizations?expanded=true'
            # auth_response = RestService.get(auth_url, bearer_token, AuthHeaderType.BEARER, ContentType.JSON).json()
            # roles: list = auth_response.get('roles', [])
            # if roles:
            #     is_authorized = True

            # TODO Remove the below call and uncomment the above code once product subscription is in place.
            account_url = current_app.config.get(
                'AUTH_API_ENDPOINT') + f'orgs/{account_id}'
            account_response = RestService.get(account_url,
                                               bearer_token,
                                               AuthHeaderType.BEARER,
                                               ContentType.JSON,
                                               retry_on_failure=True).json()
            auth_response = {}
            is_authorized = True

    if not is_authorized:
        abort(403)
    # TODO Remove this code once the authorizations endpoint returns the account details
    if not is_service_account:
        if is_business_auth:
            account_url = current_app.config.get(
                'AUTH_API_ENDPOINT'
            ) + f'orgs?affiliation={business_identifier}'
            account_response = RestService.get(
                account_url,
                bearer_token,
                AuthHeaderType.BEARER,
                ContentType.JSON,
                retry_on_failure=True).json().get('orgs')[0]
        # else:
        #     account_url = current_app.config.get(
        #         'AUTH_API_ENDPOINT') + f'orgs/{account_id}'
        #     account_response = RestService.get(account_url, bearer_token, AuthHeaderType.BEARER, ContentType.JSON,
        #                                        retry_on_failure=True).json()
        auth_response['account'] = {'paymentPreference': {}}
        auth_response['account']['id'] = account_response['id']
        auth_response['account']['name'] = account_response['name']
        auth_response['account']['paymentPreference'][
            'methodOfPayment'] = account_response['preferred_payment']
        auth_response['account']['paymentPreference'][
            'bcOnlineUserId'] = account_response.get('bc_online_user_id', None)
    return auth_response
Exemplo n.º 6
0
def upgrade():
    # ### commands auto generated by Alembic - please adjust! ###
    op.create_table(
        'bcol_payment_account',
        sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
        sa.Column('bcol_user_id', sa.String(length=50), nullable=True),
        sa.Column('bcol_account_id', sa.String(length=50), nullable=True),
        sa.Column('account_id', sa.Integer(), nullable=True),
        sa.ForeignKeyConstraint(
            ['account_id'],
            ['payment_account.id'],
        ), sa.PrimaryKeyConstraint('id'))
    op.create_index(op.f('ix_bcol_payment_account_account_id'),
                    'bcol_payment_account', ['account_id'],
                    unique=False)
    op.create_index(op.f('ix_bcol_payment_account_bcol_account_id'),
                    'bcol_payment_account', ['bcol_account_id'],
                    unique=False)
    op.create_index(op.f('ix_bcol_payment_account_bcol_user_id'),
                    'bcol_payment_account', ['bcol_user_id'],
                    unique=False)
    op.create_table(
        'credit_payment_account',
        sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
        sa.Column('corp_number', sa.String(length=20), nullable=True),
        sa.Column('corp_type_code', sa.String(length=10), nullable=True),
        sa.Column('paybc_account', sa.String(length=50), nullable=True),
        sa.Column('paybc_party', sa.String(length=50), nullable=True),
        sa.Column('paybc_site', sa.String(length=50), nullable=True),
        sa.Column('account_id', sa.Integer(), nullable=True),
        sa.ForeignKeyConstraint(
            ['account_id'],
            ['payment_account.id'],
        ), sa.ForeignKeyConstraint(
            ['corp_type_code'],
            ['corp_type.code'],
        ), sa.PrimaryKeyConstraint('id'))
    op.create_index(op.f('ix_credit_payment_account_account_id'),
                    'credit_payment_account', ['account_id'],
                    unique=False)
    op.create_index(op.f('ix_credit_payment_account_paybc_account'),
                    'credit_payment_account', ['paybc_account'],
                    unique=False)
    op.create_table(
        'internal_payment_account',
        sa.Column('id', sa.Integer(), autoincrement=True, nullable=False),
        sa.Column('corp_number', sa.String(length=20), nullable=True),
        sa.Column('corp_type_code', sa.String(length=10), nullable=True),
        sa.Column('account_id', sa.Integer(), nullable=True),
        sa.ForeignKeyConstraint(
            ['account_id'],
            ['payment_account.id'],
        ), sa.ForeignKeyConstraint(
            ['corp_type_code'],
            ['corp_type.code'],
        ), sa.PrimaryKeyConstraint('id'))
    op.create_index(op.f('ix_internal_payment_account_account_id'),
                    'internal_payment_account', ['account_id'],
                    unique=False)
    op.add_column('invoice',
                  sa.Column('bcol_account_id', sa.Integer(), nullable=True))
    op.add_column('invoice',
                  sa.Column('credit_account_id', sa.Integer(), nullable=True))
    op.add_column(
        'invoice', sa.Column('internal_account_id',
                             sa.Integer(),
                             nullable=True))
    op.drop_constraint('invoice_account_id_fkey',
                       'invoice',
                       type_='foreignkey')
    op.create_foreign_key(None, 'invoice', 'bcol_payment_account',
                          ['bcol_account_id'], ['id'])
    op.create_foreign_key(None, 'invoice', 'credit_payment_account',
                          ['credit_account_id'], ['id'])
    op.create_foreign_key(None, 'invoice', 'internal_payment_account',
                          ['internal_account_id'], ['id'])

    op.add_column(
        'invoice',
        sa.Column('business_identifier', sa.String(length=20), nullable=True))
    op.add_column(
        'invoice',
        sa.Column('corp_type_code', sa.String(length=10), nullable=True))
    op.create_foreign_key(None, 'invoice', 'corp_type', ['corp_type_code'],
                          ['code'])

    # Create temp variable to keep the payment accounts
    payment_accounts: [] = []
    conn = op.get_bind()
    res = conn.execute(
        f"select id,corp_number,corp_type_code,payment_system_code,account_number,party_number,site_number from payment_account;"
    )
    results = res.fetchall()
    for result in results:
        payment_accounts.append({
            "id": result[0],
            "corp_number": result[1],
            "corp_type_code": result[2],
            "payment_system_code": result[3],
            "account_number": result[4],
            "party_number": result[5],
            "site_number": result[6]
        })

    # Now drop the columns from payment_account table
    op.drop_index('ix_payment_account_account_number',
                  table_name='payment_account')
    op.drop_index('ix_payment_account_bcol_account_id',
                  table_name='payment_account')
    op.drop_index('ix_payment_account_bcol_user_id',
                  table_name='payment_account')
    op.drop_constraint('payment_account_payment_system_code_fkey',
                       'payment_account',
                       type_='foreignkey')
    op.drop_constraint('payment_account_corp_type_code_fkey',
                       'payment_account',
                       type_='foreignkey')
    op.drop_column('payment_account', 'payment_system_code')
    op.drop_column('payment_account', 'corp_type_code')
    op.drop_column('payment_account', 'site_number')
    op.drop_column('payment_account', 'bcol_user_id')
    op.drop_column('payment_account', 'account_number')
    op.drop_column('payment_account', 'bcol_account_id')
    op.drop_column('payment_account', 'corp_number')
    op.drop_column('payment_account', 'party_number')

    # Delete all records from payment_account
    op.execute('delete from  payment_account;')

    # Create admin token to call auth-api
    config = current_app.config
    token_url = config.get(
        'JWT_OIDC_ISSUER'
    ) + '/protocol/openid-connect/token'  # https://sso-dev.pathfinder.gov.bc.ca/auth/realms/fcf0kpqr/protocol/openid-connect/token
    basic_auth_encoded = base64.b64encode(
        bytes(
            config.get('KEYCLOAK_SERVICE_ACCOUNT_ID') + ':' +
            config.get('KEYCLOAK_SERVICE_ACCOUNT_SECRET'),
            'utf-8')).decode('utf-8')
    data = 'grant_type=client_credentials'
    token_response = OAuthService.post(token_url, basic_auth_encoded,
                                       AuthHeaderType.BASIC,
                                       ContentType.FORM_URL_ENCODED, data)
    token = token_response.json().get('access_token')

    payment_account_table = table('payment_account',
                                  column('auth_account_id', String))
    credit_payment_account_table = table('credit_payment_account',
                                         column('corp_number', String),
                                         column('corp_type_code', String),
                                         column('paybc_account', String),
                                         column('paybc_party', String),
                                         column('paybc_site', String),
                                         column('account_id', Integer))

    internal_payment_account_table = table('internal_payment_account',
                                           column('corp_number', String),
                                           column('corp_type_code', String),
                                           column('account_id', Integer))

    for payment_account in payment_accounts:
        corp_number = payment_account.get('corp_number')
        payment_system_code = payment_account.get('payment_system_code')
        corp_type_code = payment_account.get('corp_type_code')
        account_number = payment_account.get('account_number')
        party_number = payment_account.get('party_number')
        site_number = payment_account.get('site_number')
        id = payment_account.get('id')

        if corp_number:
            # Call Auth-API to get the auth_account id
            auth_search_url = config.get(
                'AUTH_API_ENDPOINT') + 'orgs?affiliation=' + corp_number.upper(
                )
            orgs_response = None
            try:
                orgs_response = OAuthService.get(
                    auth_search_url, token, AuthHeaderType.BEARER,
                    ContentType.JSON).json().get('orgs')
            except Exception as e:
                print(
                    f'--- Error Occured while getting org for affiliation {corp_number}'
                )

            if orgs_response and orgs_response[0]:
                auth_account_id = str(orgs_response[0].get('id'))
            else:
                auth_account_id = f'PASSCODE_ACCOUNT_{corp_number}'

            res = conn.execute(
                f"select id from payment_account where auth_account_id = '{auth_account_id}'"
            )
            results = res.fetchall()

            credit_payment_account_id = None
            internal_payment_account_id = None
            if results and results[0]:
                payment_account_id = results[0][0]
            else:
                op.bulk_insert(payment_account_table,
                               [{
                                   "auth_account_id": auth_account_id
                               }])
                res = conn.execute(
                    f"select id from payment_account where auth_account_id = '{auth_account_id}'"
                )
                results = res.fetchall()
                payment_account_id = results[0][0]

            if payment_system_code == 'PAYBC':
                print(f'Creating credit account for {payment_account_id}')
                op.bulk_insert(credit_payment_account_table,
                               [{
                                   "corp_number": corp_number,
                                   "corp_type_code": corp_type_code,
                                   "paybc_account": account_number,
                                   "paybc_party": party_number,
                                   "paybc_site": site_number,
                                   "account_id": payment_account_id
                               }])
                res = conn.execute(
                    f"select id from credit_payment_account where account_id = '{payment_account_id}' and corp_number='{corp_number}' and paybc_account='{account_number}'"
                )
                results = res.fetchall()
                credit_payment_account_id = results[0][0]
            elif payment_system_code == 'INTERNAL':
                print(
                    f'Creating internal payment account for {payment_account_id}'
                )
                op.bulk_insert(internal_payment_account_table,
                               [{
                                   "corp_number": corp_number,
                                   "corp_type_code": corp_type_code,
                                   "account_id": payment_account_id
                               }])
                res = conn.execute(
                    f"select id from internal_payment_account where account_id = '{payment_account_id}' and corp_number='{corp_number}' and corp_type_code='{corp_type_code}'"
                )
                results = res.fetchall()
                internal_payment_account_id = results[0][0]
            print('Internal ', internal_payment_account_id)
            print('Credit ', credit_payment_account_id)
            if internal_payment_account_id:
                op.execute(
                    f"update invoice set internal_account_id = '{internal_payment_account_id}', corp_type_code='{corp_type_code}', business_identifier='{corp_number}' where account_id = '{id}'"
                )
            elif credit_payment_account_id:
                op.execute(
                    f"update invoice set credit_account_id = '{credit_payment_account_id}', corp_type_code='{corp_type_code}', business_identifier='{corp_number}' where account_id = '{id}'"
                )

    op.drop_column('invoice', 'account_id')