def login_callback(): client = Client(current_app.config['YOTI_CLIENT_SDK_ID'], current_app.config['YOTI_KEY_FILE_PATH']) token = request.args.get('token') if token: activity_details = client.get_activity_details(token) user_profile = activity_details.user_profile email_address = user_profile.get('email_address') user_details_res = requests.get( current_app.config['CASE_MANAGEMENT_API_URL'] + '/users', params={"email_address": email_address.lower()}, headers={'Accept': 'application/json'}) user_details = json.loads(user_details_res.text) if user_details: for user in user_details: session[ 'user_name'] = user['first_name'] + " " + user['last_name'] session['user_id'] = user['identity'] session['email'] = user['email_address'] return redirect(request.args.get('next')) else: redirect_url = request.args.get('next') return render_template('app/yoti_login.html', next=redirect_url, error_message="User not found") else: # in case of missing Yoti token, the previous redirect url is # lost so pass it back to the login form in a new variable redirect_url = request.args.get('next') return render_template('app/yoti_login.html', next=redirect_url, error_message="Token not found.")
def auth(): client = Client(YOTI_CLIENT_SDK_ID, YOTI_KEY_FILE_PATH) activity_details = client.get_activity_details(request.args["token"]) profile = activity_details.profile profile_dict = vars(profile) context = profile_dict.get("attributes") context["base64_selfie_uri"] = getattr(activity_details, "base64_selfie_uri") context["remember_me_id"] = getattr(activity_details, "remember_me_id") context["parent_remember_me_id"] = getattr( activity_details, "parent_remember_me_id" ) context["receipt_id"] = getattr(activity_details, "receipt_id") context["timestamp"] = getattr(activity_details, "timestamp") # change this number according to the age condition defined in Yoti Hub age_verified = profile.find_age_over_verification(18) # Age verification objects don't have the same properties as an attribute, # so for this example we had to mock an object with the same properties if age_verified is not None: context["age_verified"] = { "name": "age_verified", "value": age_verified, "sources": age_verified.attribute.sources, "verifiers": age_verified.attribute.verifiers, } selfie = context.get("selfie") if selfie is not None: save_image(selfie.value) return render_template("profile.html", **context)
def register_callback(): client = Client(current_app.config['YOTI_CLIENT_SDK_ID'], current_app.config['YOTI_KEY_FILE_PATH']) token = request.args.get('token') if token: try: activity_details = client.get_activity_details(token) user_profile = activity_details.user_profile user_request = { 'identity': activity_details.user_id, # if given_names or family_name are missing, get the first/last name in full_name respectively 'first_name': user_profile.get('given_names', user_profile.get('full_name').split()[0]), 'last_name': user_profile.get('family_name', user_profile.get('full_name').split()[-1]), 'email_address': user_profile.get('email_address'), 'phone_number': user_profile.get('phone_number'), 'address': { 'house_name_number': '', 'street': '', 'town_city': '', 'county': '', 'country': '', 'postcode': 'BS2 8EN' } } user_details_res = requests.post( current_app.config['CASE_MANAGEMENT_API_URL'] + '/users', data=json.dumps(user_request), headers={ 'Accept': 'application/json', 'Content-Type': 'application/json' }) user_details = user_details_res.json() if user_details: session['user_name'] = user_details[ 'first_name'] + " " + user_details['last_name'] session['user_id'] = user_details['identity'] session['email'] = user_details['email_address'] return redirect( url_for('conveyancer_user.registration_complete')) else: return redirect( url_for('auth.register_yoti', error_message="User not found")) except Exception as e: return redirect(url_for('auth.register_yoti', error_message=str(e))) else: # in case of missing Yoti token, the previous redirect url is # lost so pass it back to the login form in a new variable return render_template('app/register_yoti.html', error_message="Token not found.")
def auth(request): token = request.GET.get('token') if not token: return render(request, 'yoti_auth.html') client = Client(YOTI_CLIENT_SDK_ID, YOTI_KEY_FILE_PATH) activity_details = client.get_activity_details(token) request.session['activity_details'] = dict(activity_details) return redirect(reverse(YOTI_REDIRECT_TO))
def auth(): token = request.args.get('token') if not token: return render_template('yoti_auth.html') client_sdk_id = get_config_value('YOTI_CLIENT_SDK_ID') key_file_path = get_config_value('YOTI_KEY_FILE_PATH') client = Client(client_sdk_id, key_file_path) activity_details = client.get_activity_details(token) session['yoti_user_id'] = activity_details.user_id if not is_cookie_session(session): session['activity_details'] = dict(activity_details) else: activity_details_storage.save(activity_details) redirect_to = get_config_value('YOTI_REDIRECT_TO') return redirect(url_for(redirect_to))
def auth(): client = Client(YOTI_CLIENT_SDK_ID, YOTI_KEY_FILE_PATH) activity_details = client.get_activity_details(request.args['token']) user_profile = activity_details.user_profile user_profile['user_id'] = activity_details.user_id return render_template('profile.html', **user_profile)
def sign_callback(): yoti_client = Client(current_app.config['YOTI_CLIENT_SDK_ID'], current_app.config['YOTI_KEY_FILE_PATH']) token = request.args.get('token') if token: try: activity_details = yoti_client.get_activity_details(token) title_number = str(session['title_id']) # API to fetch seller's details url = current_app.config['CASE_MANAGEMENT_API_URL'] + '/cases' case_details_res = requests.get( url, params={ "title_number": title_number, "embed": "client" }, headers={'Accept': 'application/json'}) # Response case_details_obj = case_details_res.json() client = {} for case in case_details_obj: client = case['client'] client['type'] = "individual" # Check that the current user is authorised to sign the agreement if client['identity'] == activity_details.user_id: url = current_app.config['CONVEYANCER_API_URL'] + '/me' signatory_res = requests.get( url, headers={'Accept': 'application/json'}) signatory = signatory_res.json() agreement_approval_data = { "action": "sign", "signatory": signatory['me']['x500'], "signatory_individual": client } # Sign contract url = current_app.config[ 'CONVEYANCER_API_URL'] + '/titles/' + title_number + "/sales-agreement" response = requests.put( url, data=json.dumps(agreement_approval_data), headers={ 'Accept': 'Application/JSON', 'Content-Type': 'Application/JSON' }) # Output if response.status_code == 200: return redirect( url_for('conveyancer_user.agreement_signed')) else: return "Something went wrong:<br>" + response.text.replace( "\n", "<br/>") else: error_message = "User not authorised to sign" redirect_url = request.args.get('next') return redirect( url_for('conveyancer_user.agreement_signing', redirect_url=redirect_url, error_message=error_message)) except Exception as e: error_message = str(e) redirect_url = request.args.get('next') return redirect( url_for('conveyancer_user.agreement_signing', redirect_url=redirect_url, error_message=error_message)) else: return 'Yoti token missing'
def get(self, request, *args, **kwargs): client = Client(YOTI_CLIENT_SDK_ID, YOTI_FULL_KEY_FILE_PATH) activity_details = client.get_activity_details(request.GET['token']) context = activity_details.user_profile self.save_image(context.get('selfie')) return self.render_to_response(context)
class YotiConnection(BaseSyncConnection): """Proxy to the functionality of the SDK or API.""" MAX_WORKER_THREADS = 5 connection_id = PublicId.from_str("fetchai/yoti:0.1.0") def __init__(self, **kwargs: Any) -> None: """ Initialize a connection to an SDK or API. :param configuration: the connection configuration. :param crypto_store: object to access the connection crypto objects. :param identity: the identity object. """ super().__init__(**kwargs) yoti_client_sdk_id = cast( Optional[str], self.configuration.config.get("yoti_client_sdk_id") ) yoti_key_file_path = cast( Optional[str], self.configuration.config.get("yoti_key_file_path") ) if yoti_client_sdk_id is None or yoti_key_file_path is None: raise ValueError("Missing configuration.") self._client = YotiClient(yoti_client_sdk_id, yoti_key_file_path) self.dialogues = YotiDialogues() def on_connect(self) -> None: """Run on connect.""" def on_disconnect(self) -> None: """Run on disconnect.""" def on_send(self, envelope: Envelope) -> None: """ Send an envelope. :param envelope: the envelope to send. :return: None """ self.dispatch(envelope) def dispatch(self, envelope: Envelope) -> None: """ Dispatch the request to the right sender handler. :param envelope: the envelope. :return: an awaitable. """ if not isinstance(envelope.message, Message): # pragma: nocover raise ValueError("Yoti connection expects non-serialized messages.") message = cast(YotiMessage, envelope.message) dialogue = cast(Optional[YotiDialogue], self.dialogues.update(message)) if dialogue is None: raise ValueError( # pragma: nocover "No dialogue created. Message={} not valid.".format(message) ) performative = message.performative handler = self.get_handler(performative.value) response_message = handler(message, dialogue) if not response_message: self.logger.warning(f"Construct no response messge for {envelope}") return response_envelope = Envelope( to=envelope.sender, sender=envelope.to, message=response_message, context=envelope.context, ) self.put_envelope(response_envelope) def get_handler(self, performative: str) -> Callable[[Message, Dialogue], Message]: """ Get the handler method, given the message performative. :param performative_name: the message performative. :return: the method that will send the request. """ handler = getattr(self, performative, None) if handler is None: raise Exception("Performative not recognized.") return handler def get_profile(self, message: YotiMessage, dialogue: YotiDialogue) -> YotiMessage: """ Send the request 'get_request'. :param message: the Yoti message :param dialogue: the Yoti dialogue :return: None """ activity_details = self._client.get_activity_details(message.token) if activity_details is None: response = self.get_error_message( ValueError("No activity_details returned"), message, dialogue ) return response try: remember_me_id = activity_details.user_id profile = activity_details.profile if message.dotted_path == "": attributes = { key: value.value if isinstance(value.value, str) else json.dumps(value.value) for key, value in profile.attributes.items() } result = {"remember_me_id": remember_me_id, **attributes} else: callable_ = rgetattr(profile, message.dotted_path, *message.args) if len(message.args) != 0: intermediate = callable_(*message.args) else: intermediate = callable_ result = { "remember_me_id": remember_me_id, "name": intermediate.name, "value": intermediate.value, "sources": ",".join( [source.value for source in intermediate.sources] ), "verifiers": ",".join( [verifier.value for verifier in intermediate.verifiers] ), } response = cast( YotiMessage, dialogue.reply( performative=YotiMessage.Performative.PROFILE, target_message=message, info=result, ), ) except Exception as e: # pylint: disable=broad-except response = self.get_error_message(e, message, dialogue) if self._logger: self._logger.exception("Error during envelope handling") return response @staticmethod def get_error_message( e: Exception, message: YotiMessage, dialogue: YotiDialogue, ) -> YotiMessage: """ Build an error message. :param e: the exception :param message: the received message. :param dialogue: the dialogue. :return: an error message response. """ response = cast( YotiMessage, dialogue.reply( performative=YotiMessage.Performative.ERROR, target_message=message, error_code=500, error_msg=str(e), ), ) return response