def test_get_party_by_business_id_fail(self): with responses.RequestsMock() as rsps: rsps.add(rsps.GET, url_get_business_party, status=400) with app.app_context(): with self.assertRaises(ApiError): party_controller.get_party_by_business_id( business_party['id'])
def test_get_party_by_business_id_fail(self): called_url = "http://localhost:8081/party-api/v1/businesses/id/be3483c3-f5c9-4b13-bdd7-244db78ff687?verbose=True" with responses.RequestsMock() as rsps: rsps.add(rsps.GET, url_get_business_party, status=400) with app.app_context(): with self.assertRaises(ApiError): party_controller.get_party_by_business_id( business_party['id'], self.app_config['PARTY_URL'], self.app_config['BASIC_AUTH']) self.assertEqual(len(rsps.calls), 1) self.assertEqual(rsps.calls[0].request.url, called_url)
def survey_confirm_organisation(_): # Get and decrypt enrolment code cryptographer = Cryptographer() encrypted_enrolment_code = request.args.get("encrypted_enrolment_code", None) enrolment_code = cryptographer.decrypt( encrypted_enrolment_code.encode()).decode() # Validate enrolment code before retrieving organisation data iac_controller.validate_enrolment_code(enrolment_code) logger.info( "Attempting to retrieve data for confirm add organisation/survey page", enrolment_code=enrolment_code) try: # Get organisation name case = case_controller.get_case_by_enrolment_code(enrolment_code) business_party_id = case["caseGroup"]["partyId"] business_party = party_controller.get_party_by_business_id( business_party_id, app.config["PARTY_URL"], app.config["BASIC_AUTH"]) # Get survey name collection_exercise_id = case["caseGroup"]["collectionExerciseId"] collection_exercise = collection_exercise_controller.get_collection_exercise( collection_exercise_id) survey_id = collection_exercise["surveyId"] survey_name = survey_controller.get_survey(app.config["SURVEY_URL"], app.config["BASIC_AUTH"], survey_id).get("longName")
def survey_confirm_organisation(_): # Get and decrypt enrolment code cryptographer = Cryptographer() encrypted_enrolment_code = request.args.get('encrypted_enrolment_code', None) enrolment_code = cryptographer.decrypt( encrypted_enrolment_code.encode()).decode() # Validate enrolment code before retrieving organisation data iac_controller.validate_enrolment_code(enrolment_code) logger.info( 'Attempting to retrieve data for confirm add organisation/survey page') try: # Get organisation name case = case_controller.get_case_by_enrolment_code(enrolment_code) business_party_id = case['caseGroup']['partyId'] business_party = party_controller.get_party_by_business_id( business_party_id, app.config['PARTY_URL'], app.config['BASIC_AUTH']) # Get survey name collection_exercise_id = case['caseGroup']['collectionExerciseId'] collection_exercise = collection_exercise_controller.get_collection_exercise( collection_exercise_id) survey_id = collection_exercise['surveyId'] survey_name = survey_controller.get_survey(app.config['SURVEY_URL'], app.config['BASIC_AUTH'], survey_id).get('longName')
def get_business_party(self, key): """ Gets the business party from redis or the party service :param key: Key in redis (for this example will be a frontstage:business-party:id) :return: Result from either the cache or party service """ redis_key = f"frontstage:business-party:{key}" try: result = redis.get(redis_key) except RedisError: logger.error("Error getting value from cache, please investigate", key=redis_key, exc_info=True) result = None if not result: logger.info("Key not in cache, getting value from party service", key=redis_key) result = get_party_by_business_id(key, app.config["PARTY_URL"], app.config["BASIC_AUTH"]) self.save(redis_key, result, self.BUSINESS_PARTY_CATEGORY_EXPIRY) return result return json.loads(result.decode("utf-8"))
def get_case_data(case_id, party_id, business_party_id, survey_short_name): logger.info("Attempting to retrieve detailed case data", case_id=case_id, party_id=party_id) # Check if respondent has permission to see case data case = get_case_by_case_id(case_id) survey = survey_controller.get_survey_by_short_name(survey_short_name) if not party_controller.is_respondent_enrolled(party_id, business_party_id, survey): raise NoSurveyPermission(party_id, case_id) case_data = { "collection_exercise": collection_exercise_controller.get_collection_exercise( case["caseGroup"]["collectionExerciseId"]), "collection_instrument": collection_instrument_controller.get_collection_instrument( case["collectionInstrumentId"], app.config["COLLECTION_INSTRUMENT_URL"], app.config["BASIC_AUTH"]), "survey": survey, "business_party": party_controller.get_party_by_business_id(business_party_id, app.config["PARTY_URL"], app.config["BASIC_AUTH"]), }
def get_case_data(case_id, party_id, business_party_id, survey_short_name): logger.info('Attempting to retrieve detailed case data', case_id=case_id, party_id=party_id) # Check if respondent has permission to see case data case = get_case_by_case_id(case_id) if not party_controller.is_respondent_enrolled(party_id, business_party_id, survey_short_name): raise NoSurveyPermission(party_id, case_id) case_data = { "collection_exercise": collection_exercise_controller.get_collection_exercise( case['caseGroup']['collectionExerciseId']), "collection_instrument": collection_instrument_controller.get_collection_instrument( case['collectionInstrumentId'], app.config['COLLECTION_INSTRUMENT_URL'], app.config['BASIC_AUTH']), "survey": survey_controller.get_survey_by_short_name(survey_short_name), "business_party": party_controller.get_party_by_business_id(business_party_id, app.config['PARTY_URL'], app.config['BASIC_AUTH']) } logger.info('Successfully retrieved all data relating to case', case_id=case_id, party_id=party_id) return case_data
def register_confirm_organisation_survey(): # Get and decrypt enrolment code cryptographer = Cryptographer() encrypted_enrolment_code = request.args.get("encrypted_enrolment_code") try: enrolment_code = cryptographer.decrypt( encrypted_enrolment_code.encode()).decode() except AttributeError: logger.error("No enrolment code supplied", exc_info=True, url=request.url) raise # Validate enrolment code before retrieving organisation data iac_controller.validate_enrolment_code(enrolment_code) logger.info( "Attempting to retrieve data for confirm organisation/survey page", enrolment_code=enrolment_code) try: # Get organisation name case = case_controller.get_case_by_enrolment_code(enrolment_code) business_party_id = case["caseGroup"]["partyId"] business_party = party_controller.get_party_by_business_id( business_party_id, app.config["PARTY_URL"], app.config["BASIC_AUTH"]) # Get survey name collection_exercise_id = case["caseGroup"]["collectionExerciseId"] collection_exercise = collection_exercise_controller.get_collection_exercise( collection_exercise_id) survey_id = collection_exercise["surveyId"] survey_name = survey_controller.get_survey(app.config["SURVEY_URL"], app.config["BASIC_AUTH"], survey_id).get("longName")
def test_get_party_by_business_id_success_with_collection_exercise_id( self): with responses.RequestsMock() as rsps: url = f"{url_get_business_party}?collection_exercise_id={collection_exercise['id']}&verbose=True" rsps.add(rsps.GET, url, json=business_party, status=200) with app.app_context(): business = party_controller.get_party_by_business_id( business_party['id'], collection_exercise['id']) self.assertEqual(business['id'], business_party['id']) self.assertEqual(business['name'], business_party['name'])
def test_get_party_by_business_id_success_with_collection_exercise_id( self): """Tests the function is successful when we supply the optional collection_excercise_id""" with responses.RequestsMock() as rsps: url = f"{url_get_business_party}?collection_exercise_id={collection_exercise['id']}&verbose=True" rsps.add(rsps.GET, url, json=business_party, status=200) with app.app_context(): business = party_controller.get_party_by_business_id( business_party['id'], self.app_config['PARTY_URL'], self.app_config['BASIC_AUTH'], collection_exercise['id']) self.assertEqual(business['id'], business_party['id']) self.assertEqual(business['name'], business_party['name'])
def test_get_party_by_business_id_success_without_collection_exercise_id( self): """Tests the function is successful when we only supply the mandatory party_id""" with responses.RequestsMock() as rsps: rsps.add(rsps.GET, url_get_business_party, json=business_party, status=200) with app.app_context(): business = party_controller.get_party_by_business_id( business_party['id'], self.app_config['PARTY_URL'], self.app_config['BASIC_AUTH']) self.assertEqual(business['id'], business_party['id']) self.assertEqual(business['name'], business_party['name'])
def add_survey_submit(session): party_id = session.get_party_id() cryptographer = Cryptographer() encrypted_enrolment_code = request.args.get("encrypted_enrolment_code") enrolment_code = cryptographer.decrypt( encrypted_enrolment_code.encode()).decode() logger.info("Assigning new survey to a user", party_id=party_id, enrolment_code=enrolment_code) try: # Verify enrolment code is active iac = iac_controller.get_iac_from_enrolment(enrolment_code) if iac is None: # Showing the client an error screen if the enrolment code is either not found or inactive isn't great # but it's better then what used to happen, which was raise TypeError and show them the generic exception # page. This lets us more easily debug the issue. Ideally we'd redirect the user to the surveys_list # page with a 'Something went wrong when signing you up for the survey, try again or call us' error. logger.error("IAC code not found or inactive", enrolment_code=enrolment_code) abort(400) # Add enrolment for user in party case_id = iac["caseId"] case = case_controller.get_case_by_enrolment_code(enrolment_code) business_party_id = case["partyId"] collection_exercise_id = case["caseGroup"]["collectionExerciseId"] # Get survey ID from collection Exercise added_survey_id = collection_exercise_controller.get_collection_exercise( case["caseGroup"]["collectionExerciseId"]).get("surveyId") info = party_controller.get_party_by_business_id( business_party_id, app.config["PARTY_URL"], app.config["BASIC_AUTH"], collection_exercise_id) already_enrolled = None if is_respondent_and_business_enrolled(info["associations"], case["caseGroup"]["surveyId"], party_id): logger.info( "User tried to enrol onto a survey they are already enrolled on", case_id=case_id, party_id=party_id, enrolment_code=enrolment_code, ) already_enrolled = True else:
def test_get_party_by_business_id_success_with_collection_exercise_id_non_verbose( self): """Tests the function calls the expected url when we turn verbose off""" called_url = ( "http://localhost:8081/party-api/v1/businesses/id/be3483c3-f5c9-4b13-bdd7-244db78ff687" "?collection_exercise_id=8d990a74-5f07-4765-ac66-df7e1a96505b") with responses.RequestsMock() as rsps: url = f"{url_get_business_party}?collection_exercise_id={collection_exercise['id']}" rsps.add(rsps.GET, url, json=business_party, status=200) with app.app_context(): business = party_controller.get_party_by_business_id( business_party['id'], self.app_config['PARTY_URL'], self.app_config['BASIC_AUTH'], collection_exercise['id'], verbose=False) self.assertEqual(business['id'], business_party['id']) self.assertEqual(business['name'], business_party['name']) self.assertEqual(len(rsps.calls), 1) self.assertEqual(rsps.calls[0].request.url, called_url)
def upload_survey(session): party_id = session.get_party_id() case_id = request.args["case_id"] business_party_id = request.args["business_party_id"] survey_short_name = request.args["survey_short_name"] logger.info("Attempting to upload collection instrument", case_id=case_id, party_id=party_id) if request.content_length > app.config["MAX_UPLOAD_LENGTH"]: return redirect( url_for( "surveys_bp.upload_failed", _external=True, case_id=case_id, business_party_id=business_party_id, survey_short_name=survey_short_name, error_info="size", )) # Check if respondent has permission to upload for this case survey = survey_controller.get_survey_by_short_name(survey_short_name) if not party_controller.is_respondent_enrolled(party_id, business_party_id, survey): raise NoSurveyPermission(party_id, case_id) case = case_controller.get_case_by_case_id(case_id) case_group = case.get("caseGroup") collection_exercise_id = case_group.get("collectionExerciseId") business_party = party_controller.get_party_by_business_id( case_group["partyId"], app.config["PARTY_URL"], app.config["BASIC_AUTH"], collection_exercise_id=collection_exercise_id, verbose=True, ) # Get the uploaded file upload_file = request.files["file"] try: # Upload the file to the collection instrument service collection_instrument_controller.upload_collection_instrument( upload_file, case, business_party, party_id, survey) except CiUploadError as ex: error_type = determine_error_type(ex) if not error_type: logger.error( "Unexpected error message returned from collection instrument service", error_message=ex.error_message, party_id=party_id, case_id=case_id, ) error_type = "unexpected" return redirect( url_for( "surveys_bp.upload_failed", _external=True, case_id=case_id, business_party_id=business_party_id, survey_short_name=survey_short_name, error_info=error_type, )) logger.info("Successfully uploaded collection instrument", party_id=party_id, case_id=case_id) unread_message_count = { "unread_message_count": conversation_controller.try_message_count_from_session(session) } return render_template( "surveys/surveys-upload-success.html", upload_filename=upload_file.filename, unread_message_count=unread_message_count, )
class EqPayload(object): def create_payload(self, case, collection_exercise, party_id: str, business_party_id: str, survey, version: str) -> dict: """ Creates the payload needed to communicate with EQ, built from the Case, Collection Exercise, Party, Survey and Collection Instrument services :param case: A dict containing information about the case :param collection_exercise: A dict containing information about the collection exercise :param party_id: The uuid of the respondent :param business_party_id: The uuid of the reporting unit :param survey: A dict containing information about the survey :param version: EQ version :returns: Payload for EQ """ tx_id = str(uuid.uuid4()) logger.info("Creating payload for JWT", case_id=case["id"], tx_id=tx_id) # Collection Instrument ci_id = case["collectionInstrumentId"] ci = collection_instrument_controller.get_collection_instrument( ci_id, current_app.config["COLLECTION_INSTRUMENT_URL"], current_app.config["BASIC_AUTH"]) if ci["type"] != "EQ": raise InvalidEqPayLoad( f"Collection instrument {ci_id} type is not EQ") classifiers = ci["classifiers"] if not classifiers or not classifiers.get( "eq_id") or not classifiers.get("form_type"): raise InvalidEqPayLoad( f"Collection instrument {ci_id} classifiers are incorrect or missing" ) eq_id = ci["classifiers"]["eq_id"] form_type = ci["classifiers"]["form_type"] # Collection Exercise collection_exercise_id = collection_exercise["id"] collex_event_dates = self._get_collex_event_dates( collection_exercise_id) # Party party = party_controller.get_party_by_business_id( business_party_id, current_app.config["PARTY_URL"], current_app.config["BASIC_AUTH"], collection_exercise_id=collection_exercise_id, ) account_service_url = current_app.config["ACCOUNT_SERVICE_URL"] account_service_log_out_url = current_app.config[ "ACCOUNT_SERVICE_LOG_OUT_URL"] iat = time.time() exp = time.time() + (5 * 60) payload = { "jti": str(uuid.uuid4()), "tx_id": tx_id, "user_id": party_id, "iat": int(iat), "exp": int(exp), "eq_id": eq_id, "period_str": collection_exercise["userDescription"], "period_id": collection_exercise["exerciseRef"], "form_type": form_type, "collection_exercise_sid": collection_exercise["id"], "ru_ref": party["sampleUnitRef"] + party["checkletter"], "ru_name": party["name"], "survey_id": survey["surveyRef"], "case_id": case["id"], "case_ref": case["caseRef"], "account_service_url": account_service_url, "account_service_log_out_url": account_service_log_out_url, "trad_as": f"{party['tradstyle1']} {party['tradstyle2']} {party['tradstyle3']}", } # Add any non null event dates that exist for this collection exercise payload.update([(key, value) for key, value in collex_event_dates.items() if value is not None]) # Add response_id for v3 if version == "v3": payload.update({ "response_id": f"{party['sampleUnitRef'] + party['checkletter']}" f"{collection_exercise['id']}{eq_id}{form_type}" }) logger.debug(payload) return payload
class EqPayload(object): def create_payload(self, case, party_id, business_party_id, survey): """ Creates the payload needed to communicate with EQ, built from the Case, Collection Exercise, Party, Survey and Collection Instrument services :case_id: The unique UUID references of a case :return Payload for EQ """ tx_id = str(uuid.uuid4()) logger.info('Creating payload for JWT', case_id=case['id'], tx_id=tx_id) # Collection Instrument ci_id = case['collectionInstrumentId'] ci = collection_instrument_controller.get_collection_instrument( ci_id, current_app.config['COLLECTION_INSTRUMENT_URL'], current_app.config['BASIC_AUTH']) if ci['type'] != 'EQ': raise InvalidEqPayLoad( f'Collection instrument {ci_id} type is not EQ') classifiers = ci['classifiers'] if not classifiers or not classifiers.get( 'eq_id') or not classifiers.get('form_type'): raise InvalidEqPayLoad( f'Collection instrument {ci_id} classifiers are incorrect or missing' ) eq_id = ci['classifiers']['eq_id'] form_type = ci['classifiers']['form_type'] # Collection Exercise collex_id = case["caseGroup"]["collectionExerciseId"] collex = collection_exercise_controller.get_collection_exercise( collex_id) collex_event_dates = self._get_collex_event_dates(collex_id) # Party party = party_controller.get_party_by_business_id( business_party_id, current_app.config['PARTY_URL'], current_app.config['BASIC_AUTH'], collection_exercise_id=collex_id) account_service_url = current_app.config['ACCOUNT_SERVICE_URL'] account_service_log_out_url = current_app.config[ 'ACCOUNT_SERVICE_LOG_OUT_URL'] iat = time.time() exp = time.time() + (5 * 60) payload = { 'jti': str(uuid.uuid4()), 'tx_id': tx_id, 'user_id': party_id, 'iat': int(iat), 'exp': int(exp), 'eq_id': eq_id, 'period_str': collex['userDescription'], 'period_id': collex['exerciseRef'], 'form_type': form_type, 'collection_exercise_sid': collex['id'], 'ru_ref': party['sampleUnitRef'] + party['checkletter'], 'ru_name': party['name'], 'survey_id': survey['surveyRef'], 'case_id': case['id'], 'case_ref': case['caseRef'], 'account_service_url': account_service_url, 'account_service_log_out_url': account_service_log_out_url, 'trad_as': f"{party['tradstyle1']} {party['tradstyle2']} {party['tradstyle3']}" } # Add any non null event dates that exist for this collection exercise payload.update([(key, value) for key, value in collex_event_dates.items() if value is not None]) logger.debug(payload) return payload