Пример #1
0
 def update_groups(self, ldap_id, groups):
     """Update users account"""
     url = '{0}/{1}/users/update_groups'.format(self.url, self.version)
     headers = {
         "Content-Type": "application/json",
         "Accept": "application/json"
     }
     data = {
         'ldap_id': ldap_id,
         'groups': groups
     }
     try:
         response = g.requests.patch(url, json=data, headers=headers, timeout=self.timeout)
         response.raise_for_status()
     except requests.exceptions.HTTPError as error:
         current_app.logger.error('Encountered non 2xx http code from account_api for updating groups')
         raise ApplicationError(*errors.get("ulapd_api", "ACCOUNT_API_HTTP_ERROR", filler=str(error)))
     except requests.exceptions.ConnectionError as error:
         current_app.logger.error('Encountered an error connecting to account_api for updating group')
         raise ApplicationError(*errors.get("ulapd_api", "ACCOUNT_API_CONN_ERROR", filler=str(error)))
     except requests.exceptions.Timeout as error:
         current_app.logger.error('Encountered a timeout when writing to account_api for updating group')
         raise ApplicationError(*errors.get("ulapd_api", "ACCOUNT_API_TIMEOUT", filler=str(error)))
     else:
         app.logger.info("groups updated for user {}".format(ldap_id))
         return {'message': 'groups updated'}
Пример #2
0
    def create(self, data):
        """Activate user."""
        url = '{0}/{1}/users'.format(self.url, self.version)
        headers = {
            "Content-Type": "application/json",
            "Accept": "application/json"
        }

        payload = _create_user_data(data)

        try:
            response = g.requests.post(url, json=payload, headers=headers, timeout=self.timeout)
            response.raise_for_status()
        except requests.exceptions.HTTPError as error:
            current_app.logger.error('Encountered non 2xx http code from account_api for user activation')
            raise ApplicationError(*errors.get("ulapd_api", "ACCOUNT_API_HTTP_ERROR", filler=str(error)))
        except requests.exceptions.ConnectionError as error:
            current_app.logger.error('Encountered an error connecting to account_api for user activation')
            raise ApplicationError(*errors.get("ulapd_api", "ACCOUNT_API_CONN_ERROR", filler=str(error)))
        except requests.exceptions.Timeout as error:
            current_app.logger.error('Encountered a timeout when writing to account_api for user activation')
            raise ApplicationError(*errors.get("ulapd_api", "ACCOUNT_API_TIMEOUT", filler=str(error)))
        else:
            app.logger.info("Created user {}".format(payload['email']))
            return response.json()
Пример #3
0
def get_user_by_key(user_data):
    if user_data['key'] == 'user_details_id':
        user = UserDetails.get_user_details_by_id(user_data['value'])
    elif user_data['key'] == 'email':
        user = UserDetails.get_user_details_by_email(user_data['value'])
    elif user_data['key'] == 'api_key':
        user = UserDetails.get_user_details_by_api_key(user_data['value'])
    elif user_data['key'] == 'ldap_id':
        user = UserDetails.get_user_details_by_ldap_id(user_data['value'])
    else:
        raise ApplicationError('Incorrect key: {}'.format(user_data['key']),
                               'E101',
                               http_code=404)

    if user:
        user_details = user.as_dict()
        user_type = get_user_type(user_details['user_type_id'])
        user_details['user_type'] = user_type
        contact_preferences = _build_contact_preferences(
            _extract_rows(
                Contact.get_contact_preferences_for_user(
                    user_details['user_details_id'])))
        user_details['contact_preferences'] = contact_preferences
        user_dict = {
            'user_details': user_details,
            'datasets': _build_users_datasets(user_details['user_details_id'])
        }
        return user_dict
    else:
        raise ApplicationError(*errors.get('ulapd_api',
                                           'USER_NOT_FOUND',
                                           filler=user_data['value']),
                               http_code=404)
Пример #4
0
def delete_user(user_id):
    try:
        UserTermsLink.delete_user_by_user_id(user_id)
        Activity.delete_user_by_user_id(user_id)
        Contact.delete_contact_preferences_for_user(user_id)

        user = UserDetails.get_user_details_by_id(user_id)
        if user:
            db.session.delete(user)
        else:
            app.logger.error("No user: {} found for deletion".format(user_id))
            db.session.rollback()
            db.session.close()
            raise ApplicationError(*errors.get('ulapd_api',
                                               'USER_NOT_FOUND',
                                               filler=user_id),
                                   http_code=404)
        db.session.commit()
        return {'user_id': user_id, 'message': 'user deleted'}
    except Exception as e:
        db.session.rollback()
        db.session.close()
        raise ApplicationError(*errors.get('ulapd_api',
                                           'DELETE_USER_ERROR',
                                           filler=e),
                               http_code=400)
Пример #5
0
 def test_update_historical_cache_exception(self, mock_prefixes, mock_s3,
                                            *_):
     mock_s3.return_value = MagicMock()
     mock_s3.return_value.BUCKET_NAME.return_value = 'bucket'
     mock_s3.return_value.BUCKET_RESTRICTED.return_value = 'other_bucket'
     mock_prefixes.return_value = ['ccod/']
     mock_s3.return_value.fetch_s3_file.side_effect = ApplicationError(
         'Some error', 400)
     mock_s3.return_value.write_to_s3.side_effect = ApplicationError(
         'Some error', 400)
     result = service.update_historical_cache()
     self.assertEqual(
         result, {'result': 'Failed to write cache, please check logs'})
Пример #6
0
def manage_licence_agreement(data):
    try:
        user = UserDetails.get_user_details_by_id(data['user_details_id'])
        if not user:
            app.logger.error("No user found for id {}".format(
                data['user_details_id']))
            raise ApplicationError(*errors.get('ulapd_api',
                                               'USER_NOT_FOUND',
                                               filler=data['user_details_id']),
                                   http_code=404)

        # check to see if user already has this type of licence
        ldap_update_needed = True
        licence_data = _extract_rows(
            Licence.get_licences_by_dataset_name(data['licence_id']))
        for rows in licence_data:
            user_licence = UserTermsLink.get_user_terms_by_licence_name(
                user.user_details_id, rows['licence_id'])
            if user_licence:
                app.logger.info(
                    'User {} already has the role {} so not updating ldap...'.
                    format(user.user_details_id, data['licence_id']))
                ldap_update_needed = False

        stored_licence_id = data['licence_id']
        if _check_freemium(data['licence_id']):
            data['licence_id'] += '_direct'
        licence = UserTermsLink(data)
        db.session.add(licence)

        if ldap_update_needed:
            app.logger.info(
                'User {} does not have the role {} so update ldap...'.format(
                    user.user_details_id, stored_licence_id))
            _handle_ldap_group(stored_licence_id, user.ldap_id, True)

        db.session.commit()
        data['link_id'] = licence.user_terms_link_id
        return data
    except Exception as e:
        app.logger.error(
            'Failed to manage licence for user {} with error - {}'.format(
                data['user_details_id'], str(e)))
        db.session.rollback()
        db.session.close()
        raise ApplicationError(*errors.get('ulapd_api',
                                           'LICENCE_AGREE_ERROR',
                                           filler=e),
                               http_code=400)
def get_current_timestamp():
    try:
        conn = psycopg2.connect(current_app.config['SQLALCHEMY_DATABASE_URI'])
        cur = conn.cursor()
        cur.execute("SELECT CURRENT_TIMESTAMP;")
        result = cur.fetchone()
        cur.close()
        conn.close()
        return result[0]
    except psycopg2.DataError as e:
        raise ApplicationError(
            'Input data error: ' + str(e), 'DB', http_code=400)
    except (psycopg2.OperationalError, psycopg2.ProgrammingError) as e:
        raise ApplicationError(
            'Database error: ' + str(e), 'DB', http_code=400)
Пример #8
0
def create_new_user(user_data):
    try:
        account = AccountAPI()
        verification = VerificationAPI()
        app.logger.info('Creating user in ldap for {}'.format(
            user_data['email']))
        response = account.create(user_data)
        user_data['ldap_id'] = response['user_id']

        user_data = _process_new_user_data(user_data)
        app.logger.info('Adding user {} to the ulapd database...'.format(
            user_data['email']))
        new_user_details = UserDetails(user_data)
        db.session.add(new_user_details)
        db.session.commit()
        user_data['user_details_id'] = new_user_details.user_details_id

        if user_data['contactable']:
            app.logger.info(
                'Inserting the contact preferences for {}...'.format(
                    user_data['email']))
            for preference in user_data['contact_preferences']:
                contact = {
                    'user_details_id': user_data['user_details_id'],
                    'contact_type': preference
                }
                contact_preference = Contact(contact)
                db.session.add(contact_preference)
        db.session.commit()
        app.logger.info(
            'Finished adding user {} to the ulapd database...'.format(
                user_data['email']))

        # Add the user details to verification database for DST
        app.logger.info('Adding user {} to verification db...'.format(
            user_data['email']))
        verification.create(user_data)

        # Call to account-api to activate or acknowledge user
        is_uk_org = 'organisation-uk' in user_data['user_type']

        if is_uk_org:
            app.logger.info('Acknowledging user')
            account.acknowledge(user_data['ldap_id'])
        else:
            app.logger.info('Activating user')
            account.activate(user_data['ldap_id'])

        db.session.close()
        return user_data
    except Exception as e:
        app.logger.error('Failed to create user with error - {}'.format(
            str(e)))
        db.session.rollback()
        _delete_user_data(account, user_data)
        db.session.close()
        raise ApplicationError(*errors.get('ulapd_api',
                                           'CREATE_USER_ERROR',
                                           filler=e),
                               http_code=400)
def get_dataset_history(name):
    dataset = Dataset.get_dataset_by_name(name)
    if dataset:
        return _metadata_extend_history(dataset.as_dict())
    else:
        raise ApplicationError(*errors.get('ulapd_api',
                                           'DATASET_NOT_FOUND',
                                           filler=name),
                               http_code=404)
Пример #10
0
def update_api_key(user_id):
    try:
        user = UserDetails.get_user_details_by_id(user_id)
        if user:
            user.api_key = _create_api_key()
            db.session.commit()
            return get_user_details(user_id)
        else:
            raise ApplicationError(*errors.get('ulapd_api',
                                               'USER_NOT_FOUND',
                                               filler=user_id),
                                   http_code=404)

    except Exception as e:
        raise ApplicationError(*errors.get('ulapd_api',
                                           'RESET_API_KEY_ERROR',
                                           filler=e),
                               http_code=400)
Пример #11
0
def get_dataset_activity(user_id):
    user = UserDetails.get_user_details_by_id(user_id)
    if user:
        return _build_user_dataset_activity(user_id)
    else:
        app.logger.error("No user found for id {}".format(user_id))
        raise ApplicationError(*errors.get('ulapd_api',
                                           'USER_NOT_FOUND',
                                           filler=user_id),
                               http_code=404)
Пример #12
0
 def get(self, ldap_id):
     url = '{0}/{1}/users?id={2}'.format(self.url, self.version, ldap_id)
     headers = {
         "Accept": "application/json"
     }
     try:
         response = g.requests.get(url, headers=headers, timeout=self.timeout)
         response.raise_for_status()
     except requests.exceptions.HTTPError as error:
         current_app.logger.error('Encountered non 2xx http code from account_api for retrieving user details')
         raise ApplicationError(*errors.get("ulapd_api", "ACCOUNT_API_HTTP_ERROR", filler=str(error)))
     except requests.exceptions.ConnectionError as error:
         current_app.logger.error('Encountered an error connecting to account_api for retrieving user details')
         raise ApplicationError(*errors.get("ulapd_api", "ACCOUNT_API_CONN_ERROR", filler=str(error)))
     except requests.exceptions.Timeout as error:
         current_app.logger.error('Encountered a timeout when writing to account_api for retrieving user details')
         raise ApplicationError(*errors.get("ulapd_api", "ACCOUNT_API_TIMEOUT", filler=str(error)))
     else:
         return response.json()
 def test_update_groups_for_ldap_error(self, mock_account):
     error = ApplicationError(
         *errors.get("ulapd_api", "ACCOUNT_API_HTTP_ERROR"))
     mock_account.return_value.update_groups.side_effect = error
     with app.app_context() as ac:
         update_groups_retry = current_app.config["UPDATE_GROUPS_RETRY"]
         ac.g.trace_id = None
         update_groups_for_ldap('112-122', {'nps': True})
     self.assertEqual(mock_account.return_value.update_groups.call_count,
                      int(update_groups_retry))
Пример #14
0
    def test_get_dataset_by_name_error(self, mock_service):
        mock_service.get_dataset_by_name.side_effect = ApplicationError(
            'some error', 500)

        response = self.app.get('/v1/datasets/test', headers=self.headers)

        self.assertEqual(500, response.status_code)
        response_body = response.get_json()
        self.assertEqual(
            response_body,
            {'error': 'Failed to get dataset: test - error: some error'})
Пример #15
0
    def test_get_activity_error(self, mock_service):
        mock_service.get_user_activity_list.side_effect = ApplicationError(
            'some error', 500)

        response = self.app.get('/v1/activities/1', headers=self.headers)

        self.assertEqual(500, response.status_code)
        response_body = response.get_json()
        self.assertEqual(
            response_body,
            {'error': 'Failed to get user activity: 1 - error: some error'})
Пример #16
0
def get_user_details(user_id):
    user_details = UserDetails.get_user_details_by_id(user_id)
    if user_details:
        result = user_details.as_dict()
    else:
        app.logger.error("User '{}' not found".format(user_id))
        raise ApplicationError(*errors.get('ulapd_api',
                                           'USER_NOT_FOUND',
                                           filler=user_id),
                               http_code=404)

    return result
Пример #17
0
def get_user_type(type_id):
    user_type = UserType.get_user_type_by_id(type_id)
    if user_type:
        result = user_type.as_dict()
    else:
        app.logger.error("User type '{}' not found".format(type_id))
        raise ApplicationError(*errors.get('ulapd_api',
                                           'USER_TYPE_NOT_FOUND',
                                           filler=type_id),
                               http_code=404)

    return result
Пример #18
0
    def test_historical_cache_error(self, mock_service):
        mock_service.update_historical_cache.side_effect = ApplicationError(
            'some error', 500)

        response = self.app.put('/v1/datasets/historical_cache',
                                headers=self.headers)

        self.assertEqual(500, response.status_code)
        response_body = response.get_json()
        self.assertEqual(
            response_body,
            {'error': 'Failed to update historical cache:  some error '})
    def test_add_activity_error(self, mock_service):
        mock_service.create_licence.side_effect = ApplicationError(
            'some error', 500)

        response = self.app.post('/v1/licence',
                                 json={"licence_id": "ccod"},
                                 headers=self.headers)

        self.assertEqual(500, response.status_code)
        response_body = response.get_json()
        self.assertEqual(
            response_body,
            {'error': 'Failed to create licence ccod - error: some error'})
Пример #20
0
    def test_create_dataset_error(self, mock_service):
        mock_service.create_dataset.side_effect = ApplicationError(
            'some error', 500)

        response = self.app.post('/v1/datasets',
                                 json={"name": "aaaa"},
                                 headers=self.headers)

        self.assertEqual(500, response.status_code)
        response_body = response.get_json()
        self.assertEqual(
            response_body,
            {'error': 'Failed to create dataset: aaaa - error: some error'})
Пример #21
0
    def test_add_activity_error(self, mock_service):
        mock_service.add_user_activity.side_effect = ApplicationError(
            'some error', 500)

        response = self.app.post('/v1/activities',
                                 json={"foo": "bar"},
                                 headers=self.headers)

        self.assertEqual(500, response.status_code)
        response_body = response.get_json()
        self.assertEqual(
            response_body,
            {'error': 'Failed to add activity - error: some error'})
Пример #22
0
    def handle_role(self, data):
        """Add or remove role for user."""
        url = '{0}/{1}/users/handle_role'.format(self.url, self.version)
        headers = {
            "Content-Type": "application/json",
            "Accept": "application/json"
        }

        try:
            response = g.requests.post(url, json=data, headers=headers, timeout=self.timeout)
            response.raise_for_status()
        except requests.exceptions.HTTPError as error:
            current_app.logger.error('Encountered non 2xx http code from account_api for adding a role')
            raise ApplicationError(*errors.get("ulapd_api", "ACCOUNT_API_HTTP_ERROR", filler=str(error)))
        except requests.exceptions.ConnectionError as error:
            current_app.logger.error('Encountered an error connecting to account_api for adding a role')
            raise ApplicationError(*errors.get("ulapd_api", "ACCOUNT_API_CONN_ERROR", filler=str(error)))
        except requests.exceptions.Timeout as error:
            current_app.logger.error('Encountered a timeout when writing to account_api adding a role')
            raise ApplicationError(*errors.get("ulapd_api", "ACCOUNT_API_TIMEOUT", filler=str(error)))
        else:
            app.logger.info("Added role for user {}".format(data['ldap_id']))
            return {'message': 'success'}
Пример #23
0
    def activate(self, ldap_id):
        """Activate user."""
        url = '{0}/{1}/users/{2}/activate'.format(self.url, self.version, ldap_id)
        headers = {
            "Content-Type": "application/json",
            "Accept": "application/json"
        }

        try:
            response = g.requests.post(url, headers=headers, timeout=self.timeout)
            response.raise_for_status()
        except requests.exceptions.HTTPError as error:
            current_app.logger.error('Encountered non 2xx http code from account_api for user activation')
            raise ApplicationError(*errors.get("ulapd_api", "ACCOUNT_API_HTTP_ERROR", filler=str(error)))
        except requests.exceptions.ConnectionError as error:
            current_app.logger.error('Encountered an error connecting to account_api for user activation')
            raise ApplicationError(*errors.get("ulapd_api", "ACCOUNT_API_CONN_ERROR", filler=str(error)))
        except requests.exceptions.Timeout as error:
            current_app.logger.error('Encountered a timeout when writing to account_api for user activation')
            raise ApplicationError(*errors.get("ulapd_api", "ACCOUNT_API_TIMEOUT", filler=str(error)))
        else:
            app.logger.info("Activated user {}".format(ldap_id))
            return {'message': 'activated'}
 def run_and_handle(*args, **kwargs):
     try:
         return func(*args, **kwargs)
     except SQLAlchemyError as e:
         error_code = 500 if is_get else 422
         raise ApplicationError(*errors.get('ulapd_api',
                                            'SQLALCHEMY_ERROR',
                                            filler=e),
                                http_code=error_code)
     except ApplicationError as error:
         raise error
     finally:
         if not is_get:
             db.session.rollback()
         db.session.close()
Пример #25
0
def get_users_dataset_access(user_id):
    user = UserDetails.get_user_details_by_id(user_id)
    if user:
        datasets = Dataset.get_all()
        dataset_access = []

        for row in datasets:
            if row.type != 'open':
                dataset_dict = {
                    'id': row.dataset_id,
                    'name': row.name,
                    'title': row.title,
                    'type': row.type
                }
                licence_names = _extract_rows(
                    Licence.get_licences_by_dataset_name(row.name))

                licence_dict = {}
                for licence_rows in licence_names:
                    licence = get_licence_agreement(user_id,
                                                    licence_rows['licence_id'])
                    licence_dict[licence_rows['licence_id']] = {
                        'title': licence_rows['title'],
                        'agreed': licence['valid_licence']
                    }

                dataset_dict['licences'] = licence_dict
                dataset_access.append(dataset_dict)

        dataset_access = _sort_out_sample(dataset_access)

        licenced_datasets = [
            d for d in dataset_access if d['type'] == 'licenced'
        ]
        non_licenced_datasets = [
            d for d in dataset_access if d['type'] != 'licenced'
        ]

        full_access = non_licenced_datasets
        full_access.append(_sort_out_licenced_datasets(licenced_datasets))
        return full_access
    else:
        app.logger.error("No user found for id {}".format(user_id))
        raise ApplicationError(*errors.get('ulapd_api',
                                           'USER_NOT_FOUND',
                                           filler=user_id),
                               http_code=404)
Пример #26
0
def update_contact_preference(user_data):
    user = UserDetails.get_user_details_by_id(user_data['user_id'])
    if user:
        app.logger.info('Deleting contact preferences for user {}'.format(
            user_data['user_id']))

        Contact.delete_contact_preferences_for_user(user_data['user_id'])
        for contacts in user_data['contact_preferences']:
            contact = {
                'user_details_id': user_data['user_id'],
                'contact_type': contacts
            }
            contact_preference = Contact(contact)
            db.session.add(contact_preference)

        user.contactable = user_data['contactable']
        db.session.commit()
        user_details = user.as_dict()
        user_details['contact_preferences'] = user_data['contact_preferences']
        return user_details
    else:
        raise ApplicationError(*errors.get('ulapd_api', 'USER_NOT_FOUND',
                                           user_data['user_id']),
                               http_code=404)
    def test_update_groups_app_error(self, mock_account, mock_app):
        error = ('ulapd_api', 'ACCOUNT_API_HTTP_ERROR')
        mock_account.side_effect = ApplicationError(*errors.get(*error))

        update_groups_for_ldap('112-122', {'nps': True})
        mock_app.logger.error.assert_called_once()
Пример #28
0
def manage_multi_licence_agreement(data):
    try:
        user = UserDetails.get_user_details_by_id(data['user_details_id'])
        if not user:
            app.logger.error("No user found for id {}".format(
                data['user_details_id']))
            raise ApplicationError(*errors.get('ulapd_api',
                                               'USER_NOT_FOUND',
                                               filler=data['user_details_id']),
                                   http_code=404)

        current_licences = _extract_rows(
            UserTermsLink.get_user_terms_by_user_id(data['user_details_id']))
        current_list = [d['licence_id'] for d in current_licences]

        all_licences = Licence.get_all_licences()
        licence_dict = {}
        for rows in all_licences:
            licence_dict[rows.licence_name] = rows.dataset_name

        groups = {}
        for row in data['licences']:
            if row['licence_id'] not in current_list and row['agreed']:
                app.logger.info('Adding licence {} to db and ldap'.format(
                    row['licence_id']))
                role = licence_dict[row['licence_id']]
                groups[role] = row['agreed']
                new_user_licence = UserTermsLink({
                    'user_details_id':
                    user.user_details_id,
                    'licence_id':
                    row['licence_id']
                })
                db.session.add(new_user_licence)
            elif row['licence_id'] in current_list and not row['agreed']:
                app.logger.info('Removing licence {} from db and ldap'.format(
                    row['licence_id']))
                role = licence_dict[row['licence_id']]
                groups[role] = row['agreed']
                UserTermsLink.delete_user_licence_agreement(
                    user.user_details_id, row['licence_id'])
            else:
                app.logger.info('There is no change for licence {}'.format(
                    row['licence_id']))

        # sort out freemium
        res_covs = [
            d for d in data['licences'] if 'res_cov' in d['licence_id']
        ]
        groups = _handle_ldap_freemium_updates('res_cov', res_covs, groups,
                                               current_list)

        if bool(groups):
            app.logger.info(
                'Sending these groups - {}, for ldap update for user {}'.
                format(groups, user.user_details_id))
            update_groups_for_ldap(user.ldap_id, groups)
        else:
            app.logger.info('No groups to update in ldap for user {}'.format(
                user.user_details_id))

        db.session.commit()
        return groups
    except Exception as e:
        app.logger.error(
            'Failed to manage multi licences for user {} with error - {}'.
            format(data['user_details_id'], str(e)))
        db.session.rollback()
        db.session.close()
        raise ApplicationError(*errors.get('ulapd_api',
                                           'LICENCE_AGREE_ERROR',
                                           filler=e),
                               http_code=400)