def _register_user(): session, reg_obj = fetch_registration() ulapd_api = UlapdAPI() user_type = 'personal-' + ('uk' if reg_obj['country'] == 'UK' else 'overseas') data_dict = { 'user_type': user_type, 'email': reg_obj['email'], 'title': reg_obj['title'], 'first_name': reg_obj['first_name'], 'last_name': reg_obj['last_name'], # 'contactable': True if reg_obj['research'] == 'yes' else False, 'contact_preferences': reg_obj.get('contact_preferences', []), 'telephone_number': reg_obj['phone'], 'address_line_1': reg_obj['street_line_1'], 'address_line_2': reg_obj['street_line_2'], 'city': reg_obj['city'], 'postcode': reg_obj['postcode'], 'county': reg_obj['county'], 'country': reg_obj['country'] } user_response = ulapd_api.create_user(data_dict) session.pop('registration', None) dps_session.commit() return user_response
def get_api_datasets(external=False): ulapd_api = UlapdAPI() dataset_list = ulapd_api.get_datasets() user_details = _authenticate(ulapd_api) user_access = user_details['datasets'] if dataset_list: # Filter out 'open' datasets dataset_list = [d for d in dataset_list if d['type'] != 'open'] result_data = [] for dataset in dataset_list: # Don't show 'confidential' datasets unless user has access if dataset['type'] == 'confidential': if user_access.get(dataset['name']): result_data.append( dict(name=dataset['name'], title=dataset['title'])) else: result_data.append( dict(name=dataset['name'], title=dataset['title'])) response = {"success": True, "result": result_data} return response else: raise ApplicationError(*errors.get('ulapd_ui', 'NO_DATASETS_FOUND'), http_code=404)
def test_create_activity(self, mock_post): user_id = '1' activity_type = 'download' ip_address = '10.0.0.1' api = True file = 'ccod_full.csv' dataset_id = 'ccod' data = { 'user_details_id': user_id, 'activity_type': activity_type, 'ip_address': ip_address, 'api': api, 'file': file, 'dataset_id': dataset_id } mock_post.return_value.json.return_value = data mock_post.return_value.status_code = 201 ulapd_api = UlapdAPI() response = ulapd_api.create_activity(user_id, activity_type, ip_address, api, file, dataset_id) self.assertEqual(response, data) args, kwargs = mock_post.call_args_list[0] self.assertEqual(kwargs['data'], json.dumps(data))
def decorated(*args, **kwargs): try: ulapd_api = UlapdAPI() api_key = request.headers.get('Authorization') name = kwargs['dataset'] dataset = ulapd_api.get_dataset_by_name(name) # Prevent 'open' datasets being accessed via API if dataset['type'] == 'open': raise ApplicationError(*errors.get('ulapd_ui', 'DATASET_NOT_FOUND', filler=name), http_code=404) # Prevent 'confidential' datasets being available via API if user doesn't have access if dataset['type'] == 'confidential': try: user_access = ulapd_api.get_user_details( 'api_key', api_key)['datasets'] except ApplicationError: raise ApplicationError(*errors.get('ulapd_ui', 'API_KEY_ERROR', filler=api_key), http_code=404) if not user_access.get(name, False): raise ApplicationError(*errors.get('ulapd_ui', 'DATASET_NOT_FOUND', filler=name), http_code=404) return f(*args, **kwargs) except ApplicationError as e: return jsonify({'success': False, 'error': e.message}), e.http_code
def _register_user(): session, reg_obj = fetch_registration() ulapd_api = UlapdAPI() current_app.logger.info("!!!!!: " + str(reg_obj)) data_dict = { 'user_type': 'organisation-uk', 'email': reg_obj['email'], 'title': reg_obj['title'], 'first_name': reg_obj['first_name'], 'last_name': reg_obj['last_name'], 'contact_preferences': reg_obj.get('contact_preferences', []), 'telephone_number': reg_obj['uk_org_phone'], 'organisation_name': reg_obj['uk_org_name'], 'organisation_type': reg_obj['uk_org_type'], 'registration_number': reg_obj.get('uk_org_reg_no', None), 'address_line_1': reg_obj['uk_org_street_line_1'], 'address_line_2': reg_obj['uk_org_street_line_2'], 'city': reg_obj['uk_org_city'], 'county': reg_obj['uk_org_county'], 'postcode': reg_obj['uk_org_postcode'], 'country': 'UK' } print(data_dict) user_response = ulapd_api.create_user(data_dict) session.pop('registration', None) dps_session.commit() return user_response
def _register_user(): session, reg_obj = fetch_registration() ulapd_api = UlapdAPI() data_dict = { 'user_type': 'organisation-overseas', 'email': reg_obj['email'], 'title': reg_obj['title'], 'first_name': reg_obj['first_name'], 'last_name': reg_obj['last_name'], 'contact_preferences': reg_obj.get('contact_preferences', []), 'telephone_number': reg_obj['overseas_org_phone'], 'organisation_name': reg_obj['overseas_org_name'], 'country_of_incorporation': reg_obj['overseas_org_country_incorp'], 'country': reg_obj['overseas_org_country'], 'address_line_1': reg_obj['overseas_org_street_line_1'], 'address_line_2': reg_obj['overseas_org_street_line_2'], 'city': reg_obj['overseas_org_city'], 'postcode': reg_obj['overseas_org_postcode'] } user_response = ulapd_api.create_user(data_dict) session.pop('registration', None) dps_session.commit() return user_response
def get_api_dataset_history(name): ulapd_api = UlapdAPI() # authenticate _authenticate(ulapd_api) history_details = ulapd_api.get_dataset_history(name) if history_details: history_data = [] for history in history_details['dataset_history']: for file in history['resource_list']: history_info = { "last_updated": history["last_updated"], "unsorted_date": history["unsorted_date"], "filename": file['file_name'], "file_size": file['file_size'] } history_data.append(history_info) response = { "success": True, "dataset": name, "dataset_history": history_data } return response else: current_app.logger.error('Dataset {} not found'.format(name)) raise ApplicationError(*errors.get('ulapd_ui', 'DATASET_NOT_FOUND', filler=name), http_code=404)
def test_get_user_details(self, mock_get): mock_get.return_value.json.return_value = {'user_details': 'details'} mock_get.return_value.status_code = 200 ulapd_api = UlapdAPI() response = ulapd_api.get_user_details('email', '*****@*****.**') self.assertEqual(response, {'user_details': 'details'})
def test_get_download_link(self, mock_get): mock_get.return_value.json.return_value = {'link': 'https://s3.com'} mock_get.return_value.status_code = 200 ulapd_api = UlapdAPI() response = ulapd_api.get_download_link('ccod', 'ccod_full.csv') self.assertEqual(response, {'link': 'https://s3.com'})
def test_get_external_datasets(self, mock_get): mock_get.return_value.json.return_value = [{'name': 'hpi'}] mock_get.return_value.status_code = 200 ulapd_api = UlapdAPI() response = ulapd_api.get_external_datasets() self.assertEqual(response, [{'name': 'hpi'}])
def test_get_user_download_activity(self, mock_get): mock_get.return_value.json.return_value = [{'activity_id': 123}] mock_get.return_value.status_code = 200 ulapd_api = UlapdAPI() response = ulapd_api.get_user_download_activity('43') self.assertEqual(response, [{'activity_id': 123}])
def test_get_dataset_history(self, mock_get): mock_get.return_value.json.return_value = {'name': 'ccod'} mock_get.return_value.status_code = 200 ulapd_api = UlapdAPI() response = ulapd_api.get_dataset_history('ccod') self.assertEqual(response, {'name': 'ccod'})
def test_update_api_key(self, mock_post): mock_post.return_value.json.return_value = {'api_key': '1234'} mock_post.return_value.status_code = 201 ulapd_api = UlapdAPI() response = ulapd_api.update_api_key('1') self.assertEqual(response, {'api_key': '1234'}) args, kwargs = mock_post.call_args_list[0] self.assertEqual(kwargs['data'], json.dumps({}))
def test_create_licence_agreement(self, mock_post): data = {"user_details_id": 1, "licence_id": "ccod"} mock_post.return_value.json.return_value = data mock_post.return_value.status_code = 201 ulapd_api = UlapdAPI() response = ulapd_api.create_licence_agreement(data) self.assertEqual(response, data) args, kwargs = mock_post.call_args_list[0] self.assertEqual(kwargs['data'], json.dumps(data))
def test_create_user(self, mock_post): data = {"email": "*****@*****.**", "name": "testy"} mock_post.return_value.json.return_value = data mock_post.return_value.status_code = 201 ulapd_api = UlapdAPI() response = ulapd_api.create_user(data) self.assertEqual(response, data) args, kwargs = mock_post.call_args_list[0] self.assertEqual(kwargs['data'], json.dumps(data))
def get_agree_licence(dataset_id): try: ulapd_api = UlapdAPI() dataset_details = ulapd_api.get_dataset_by_name(dataset_id) accepted = check_agreement(dataset_id) if dataset_details['type'] == 'freemium': accepted = True session = dps_session.get_state() dataset = session['user']['datasets'].get(dataset_id) if not dataset: accepted = False if dataset: if 'Direct Use' not in dataset['licences']: accepted = False if len(dataset['licences']) == 1: if 'Direct' in dataset['licences'][ 0] and not dataset['valid_licence']: accepted = False if not accepted: return render_template("app/datasets/licence.html", agree=True, dataset_id=dataset_id, licence_type='direct') if accepted: current_app.logger.info( 'Redirecting to download page for dataset: {}'.format( dataset_id)) return redirect(url_for('.get_details', dataset_id=dataset_id)) licence_file = open( os.path.join( directory, '../documents/datasets/{}/licence.md').format(dataset_id), "r") md_licence = licence_file.read() md_renderer = markdown.Markdown() md_html = md_renderer.convert(md_licence) current_app.logger.info( 'Displaying agree licence page for dataset: {}'.format(dataset_id)) return render_template("app/datasets/licence.html", agree=True, dataset_id=dataset_id, md=md_html) except Exception as e: raise ApplicationError( 'Something went wrong when retrieving licence agree page: {}'. format(e))
def reset_api_key(): try: session = dps_session.get_state() ulapd_api = UlapdAPI() user_id = session['user']['user_details']['user_details_id'] ulapd_api.update_api_key(user_id) return redirect('/#my-api-key') except ApplicationError as e: raise ApplicationError( 'Something went wrong when resetting API key - error: {}'.format( e))
def post_agree_licence(dataset_id): try: ulapd_api = UlapdAPI() dataset_details = ulapd_api.get_dataset_by_name(dataset_id) if request.form.get('agree-licence') is None: is_freemium = dataset_details['type'] == 'freemium' md_html = '' # Until we convert licence MD files to HTML if not is_freemium: licence_file = open( os.path.join( directory, f'../documents/datasets/{dataset_id}/licence.md'), "r") md_licence = licence_file.read() md_renderer = markdown.Markdown() md_html = md_renderer.convert(md_licence) current_app.logger.info( 'Displaying licence page with errors for dataset: {}'.format( dataset_id)) error_msg = 'You need to agree to the terms and conditions to download data' return render_template( "app/datasets/licence.html", agree=True, dataset_id=dataset_id, licence_type='direct', md=md_html, error_title="There are errors on this page", fields={'agree-licence': { 'data': '', 'error': [error_msg] }}) else: # Prevent users signing licences for nps/dad etc via the service if dataset_details['type'] not in ['confidential', 'restricted']: accept_licence(dataset_id) current_app.logger.info( 'Redirecting to download page for dataset: {}'.format( dataset_id)) session = dps_session.get_state() if dataset_id == 'nps_sample': return redirect(url_for('.get_details', dataset_id='nps')) return redirect(url_for('general.get_list')) except Exception as e: raise ApplicationError( 'Something went wrong when retrieving licence agree page: {}'. format(e))
def decorated(*args, **kwargs): try: if g.user: ulapd_api = UlapdAPI() session = dps_session.get_state() user_details = ulapd_api.get_user_details('email', g.user) session['user'].update(user_details) dps_session.commit() return f(*args, **kwargs) except Exception as e: raise ApplicationError( 'Something went wrong when refreshing user session: {}'.format( e))
def test_timeout_error(self, mock_get): error = ('ulapd_ui', 'API_TIMEOUT') response = Mock() response.status_code = 500 response.raise_for_status.side_effect = Timeout(self.error_msg) mock_get.return_value = response with self.assertRaises(ApplicationError) as cm: ulapd_api = UlapdAPI() ulapd_api.get_datasets() self.assertEqual(cm.exception.message, errors.get_message(*error, filler=self.error_msg)) self.assertEqual(cm.exception.code, errors.get_code(*error)) self.assertEqual(cm.exception.http_code, 500)
def get_api_dataset_by_name(name): ulapd_api = UlapdAPI() # authenticate _authenticate(ulapd_api) dataset_details = ulapd_api.get_dataset_by_name(name) if dataset_details: response = {"success": True, "result": dataset_details} return response else: raise ApplicationError(*errors.get('ulapd_ui', 'DATASET_NOT_FOUND', filler=name), http_code=404)
def accept_licence(dataset_id): session = dps_session.get_state() try: ulapd_api = UlapdAPI() user_details = session['user']['user_details'] send_metric(dataset_id, 'licence agreed', user_details['user_details_id'], user_details, None) data = { 'user_details_id': user_details['user_details_id'], 'licence_id': dataset_id } ulapd_api.create_licence_agreement(data) except Exception as e: raise ApplicationError('Error accepting licence: {}'.format(str(e)))
def build_download_history(): download_history = [] session = dps_session.get_state() if g.user: try: ulapd_api = UlapdAPI() user_id = session['user']['user_details']['user_details_id'] download_activities = ulapd_api.get_user_download_activity(user_id) download_activities = get_latest_download_activities(download_activities) if download_activities: for download_activity in download_activities: dataset_id = download_activity['dataset_id'] package_details = ulapd_api.get_dataset_by_name(dataset_id) download_datetime = datetime.strptime(download_activity['timestamp'], '%a, %d %b %Y %H:%M:%S %Z') last_update_datetime = datetime.strptime(package_details['last_updated'], '%d %B %Y') is_latest_download = False if download_datetime < last_update_datetime else True licence_agree_string = None license_exists = package_details.get('licence_id') if license_exists: licence_agree_date = session['user']['datasets'][dataset_id]['date_agreed'] licence_agree_datetime = datetime.strptime(licence_agree_date, '%a, %d %b %Y %H:%M:%S %Z') licence_agree_string = datetime.strftime(licence_agree_datetime, '%d %B %Y') download_history.append({ 'dataset_id': dataset_id, 'dataset_title': package_details['title'], 'last_download_date': datetime.strftime(download_datetime, '%d %B %Y'), 'last_update_date': datetime.strftime(last_update_datetime, '%d %B %Y'), 'licence_exists': license_exists, 'is_latest_download': is_latest_download, 'licence_agree_date': licence_agree_string, 'is_licence_agreed': check_agreement(dataset_id), 'resources': package_details['resources'] }) except Exception as e: raise ApplicationError('Error building download history: {}'.format(e)) current_app.logger.info('Returning history of file downloads: {}'.format(download_history)) return download_history
def get_download_page(dataset_id): ulapd_api = UlapdAPI() if dataset_id == 'rfi': dataset, history = build_rfi_dataset_for_download( ulapd_api.get_dataset_by_name(dataset_id), ulapd_api.get_dataset_history(dataset_id)) else: dataset = ulapd_api.get_dataset_by_name(dataset_id) history = ulapd_api.get_dataset_history(dataset_id) breadcrumb_links = [{ "label": "Home", "href": "/" }, { "label": dataset['title'], "href": "/datasets/" + dataset['name'] }, { "label": "Download dataset", "href": None }] return render_template('app/datasets/{}/download.html'.format(dataset_id), dataset=dataset, history=history, breadcrumb_links=breadcrumb_links)
def before_request(self): g.user = None if dps_session.is_valid(): sess = dps_session.populate_state(session) if 'user' in sess: email = sess['user']['principle']['email'] g.user = email if not sess['user'].get('user_details'): user_details = UlapdAPI().get_user_details('email', email) sess['user'].update(user_details) dps_session.commit() return if dps_session.is_set(): current_app.logger.info('Session is already set') else: if dps_session.is_valid(): dps_session.populate_state(session) current_app.logger.info('Session created') else: current_app.logger.info('Token expired')
def get_api_download_link(dataset_name, file_name, date=None): try: ulapd_api = UlapdAPI() dataset_details = ulapd_api.get_dataset_by_name(dataset_name) # authenticate user_details = _authenticate(ulapd_api) # check agreement agreement = user_details['datasets'].get(dataset_name) if not agreement: if dataset_details['private'] is True: raise ApplicationError(*errors.get('ulapd_ui', 'NO_DATASET_ACCESS', filler=dataset_name), http_code=403) raise ApplicationError(*errors.get('ulapd_ui', 'NO_LICENCE_SIGNED', filler=dataset_name), http_code=403) if agreement['valid_licence'] is False: raise ApplicationError(*errors.get('ulapd_ui', 'NO_LICENCE_SIGNED', filler=dataset_name), http_code=403) # check to see if the filename exists for history files if date: resource_exists = False history_details = ulapd_api.get_dataset_history(dataset_name) for history in history_details['dataset_history']: exist = any( map(lambda resource: resource['file_name'] == file_name, history['resource_list'])) if exist: resource_exists = True break else: # check to see if the filename exists for latest files resource_exists = any( map(lambda resource: resource['file_name'] == file_name, dataset_details['resources'])) if not resource_exists: # check to see if the filename exists for public files if 'public_resources' in dataset_details: public_exists = any( map(lambda public: public['file_name'] == file_name, dataset_details['public_resources'])) if not public_exists: raise ApplicationError(*errors.get('ulapd_ui', 'FILE_DOES_NOT_EXIST', filler=file_name), http_code=404) else: raise ApplicationError(*errors.get('ulapd_ui', 'FILE_DOES_NOT_EXIST', filler=file_name), http_code=404) if date: link = ulapd_api.get_history_download_link(dataset_name, file_name, date) else: link = ulapd_api.get_download_link(dataset_name, file_name) if link: response = { "success": True, "result": { "resource": file_name, "valid_for_seconds": 10, "download_url": link["link"] } } # Activity create ulapd_api.create_activity( user_details['user_details']['user_details_id'], 'download', request.remote_addr, True, file_name, dataset_name) send_metric(dataset_name, 'download api', user_details['user_details']['user_details_id'], user_details['user_details'], file_name) return response else: current_app.logger.error( 'There was a problem getting the resource: '.format(file_name)) raise ApplicationError(*errors.get('ulapd_ui', 'DATASET_NOT_FOUND', filler=dataset_name), http_code=404) except ApplicationError as error: raise error except Exception as e: raise e
def get_list(): try: ulapd_api = UlapdAPI() session = dps_session.get_state() internal_datasets = ulapd_api.get_datasets() external_datasets = ulapd_api.get_external_datasets() # Filter out sample internal_datasets = [ d for d in internal_datasets if '_sample' not in d['name'] ] # Add internal/external datasets together dataset_list = internal_datasets + external_datasets # Sort alphabetically putting datasets starting with numeric characters last dataset_list.sort( key=lambda d: 'z' if d['title'][0].isdigit() else d['title']) # User specific data user_access = {} api_key = '' user_has_activity = False if g.user: api_key = session['user']['user_details']['api_key'] # Dictionary of datasets user has access to user_access = {d: True for d in session['user']['datasets']} # Check if user has downloaded anything for 'agreed licence but not downloaded' state user_activity = ulapd_api.get_user_download_activity( session['user']['user_details']['user_details_id']) user_has_activity = bool(user_activity) # Get dataset history for agreed datasets agreed_dataset_list = [] for dataset in dataset_list: if check_agreement(dataset['name']): dataset['history'] = ulapd_api.get_dataset_history( dataset['name']) agreed_dataset_list.append(dataset) # Filter out confidential (e.g. DAD dataset) from listings page dataset_list = [d for d in dataset_list if 'confidential' != d['type']] freemium_licences = {} for dataset in user_access: if dataset == 'res_cov' or dataset == 'leases': dataset_licence = session['user']['datasets'][dataset][ 'licences'] if len(dataset_licence) == 1: licence_string = '{} licence'.format(dataset_licence[0]) freemium_licences[dataset] = licence_string else: start = ", ".join(dataset_licence[:-1]) licence_string = '{} and {} licences'.format( start, dataset_licence[-1]) freemium_licences[dataset] = licence_string return render_template('app/datasets/index.html', datasets_list=dataset_list, api_key=api_key, user_access=user_access, agreed_dataset_list=agreed_dataset_list, dps_session=session, user_has_activity=user_has_activity, freemium_licences=freemium_licences) except ApplicationError as e: raise ApplicationError( 'Something went wrong when retrieving the datasets - error: {}'. format(e))
def get_details(dataset_id): try: ulapd_api = UlapdAPI() session = dps_session.get_state() if dataset_id == 'nps_sample': return redirect(url_for('.get_details', dataset_id='nps')) # Go get the individual dataset details dataset_details = ulapd_api.get_dataset_by_name(dataset_id) # Fail nicely if the dataset doesnt exist if dataset_id not in dataset_details['name']: raise ApplicationError( 'Unable to display dataset details: dataset does not exist', http_code=404) # Now get the example json and to our dataset list extras = build_dataset_details(dataset_id) # Add details to dataset dataset_details.update(extras) # get dataset for dataset_id to check private boolean, if false is non restricted, if true is restricted is_restricted = dataset_details['private'] licence_signed = check_agreement(dataset_id) if dataset_id == 'nps': licence_signed = { 'nps': check_agreement(dataset_id), 'nps_sample': check_agreement('nps_sample') } # Handle freemium licencing: # If a user has signed exploratory/commercial licences they should still be able to sign direct licence if dataset_details['type'] == 'freemium': if g.user: licence_signed = True dataset = session['user']['datasets'].get(dataset_id) if not dataset: licence_signed = False if dataset: if 'Direct Use' not in dataset['licences']: licence_signed = False if len(dataset['licences']) == 1: if 'Direct' in dataset['licences'][ 0] and not dataset['valid_licence']: licence_signed = False current_app.logger.info( 'Displaying details for user requested dataset: {}'.format( dataset_id)) breadcrumb_links = [{ "label": "Home", "href": "/" }, { "label": dataset_details['title'], "href": None }] return render_template( "app/datasets/{}/details.html".format(dataset_id), dataset_details=dataset_details, licence_signed=licence_signed, is_restricted=is_restricted, readable_date=dataset_details['last_updated'], breadcrumb_links=breadcrumb_links) except ApplicationError as e: raise ApplicationError( 'Something went wrong when retrieving dataset details: {}'.format( e))
def download(dataset_id, file_name, last_updated): try: ulapd_api = UlapdAPI() dataset = ulapd_api.get_dataset_by_name(dataset_id) # First check to see if its a public resource if last_updated is None: for resource in dataset['public_resources']: current_app.logger.info("Public: " + str(resource['file_name'])) if resource['file_name'] == file_name: current_app.logger.info( "Public file download, skipping checks") url = ulapd_api.get_download_link(dataset_id, resource['file_name']) return redirect(url['link']) if dataset['type'] != 'open': # Need the session to get infor about the dataset and user session = dps_session.get_state() user_id = session['user']['user_details']['user_details_id'] user_data = session['user']['user_details'] # 1. Check if user is authenticated if not dps_session.is_logged_in(): return '/sign-in' # 2. Check if user has signed the correct licence if check_agreement(dataset_id) is not True: current_app.logger.info("User has no access to dataset") return url_for('datasets.get_agree_licence', dataset_id=dataset_id) # 3. Generate link if last_updated: last_updated = historic_date_formatter( last_updated, dataset['update_frequency']) url = ulapd_api.get_history_download_link( dataset_id, file_name, last_updated) activity = 'history download' else: url = ulapd_api.get_download_link(dataset_id, file_name) activity = 'download' # 4. Track the download and return (create activity) ulapd_api.create_activity( session['user']['user_details']['user_details_id'], "download", request.remote_addr, False, file_name, dataset_id) send_metric(dataset_id, activity + " ui", user_id, user_data, file_name) else: # 1. Generate link if last_updated: last_updated = historic_date_formatter( last_updated, dataset['update_frequency']) url = ulapd_api.get_history_download_link( dataset_id, file_name, last_updated) else: url = ulapd_api.get_download_link(dataset_id, file_name) return redirect(url['link']) except Exception as e: raise ApplicationError( 'Tracking download has failed - error: {}'.format(e))