class UserUpdateController(Resource): def __init__(self, *args, **kwargs): self.user_service = UserService() def get(self, id): users = self.user_service.retrieve(id) if not users: return {'data': [], 'message': 'No se encontrĂ³ el usuario'}, 404 return {'data': users, 'message': 'success'}, 200 def put(self, id): body = request.get_json() data = self.user_service.modify(id, **body) if not data: return { 'message': 'Ocurrio un error al modificar el usuario/Usuario no encontrado' }, 404 return {'data': data, 'message': 'Success'}, 200 def delete(self, id): data = self.user_service.delete(id) if not data: return { 'message': 'Ocurrio un error al eliminar el usuario/Usuario no encontrado' }, 404 return {'data': data, 'message': 'Success'}, 200
def login_route(): if request.method == 'POST': username = request.form.get('username') password = request.form.get('password') if not UserService.authenticate(username, password): flash('Invalid user key or password. Please try again.', 'danger') current_app.logger.warn( "Invalid credentials attempted for username '{0}'.".format( username)) return redirect(url_for('auth.login_route')) # Find or create user user = UserService.find_by(username=username, fetch_one=True) if user: UserService.update(user.id, authenticated=True) else: user = UserService.create(username=username, authenticated=True) # Log in user in Flask login_user(user) # Go to next page if defined next_page = session.pop('next') or request.args.get('next') if next_page: return redirect(next_page) return redirect(url_for('auth.login_route')) else: if current_user.is_authenticated: return redirect(url_for('user.me_route')) else: return render_template('pages/auth/authenticate.html')
def get(self): id = request.values.get('id', None) email = request.values.get('email', None) if email: response = UserService().get_user_by_email(email) else: response = UserService().get_user(id) return response, HTTPStatus.OK
def register(): body = validate( { 'email': field('email'), 'password': field('password'), 'repeat_password': field('password'), 'tos': field('tos') }, request.get_json(force=True, silent=True)) UserService.add_user(body) return 'Hi'
def facebook_login(self, facebook_access_token): # facebook login by using facebook access token, return user_name, user_id and boolean variable indicate if this user is new user try: # validate access_token facebook_app_id = get_system_config()["facebook_app"] verify_token_app_id = "https://graph.facebook.com/debug_token?input_token={}&access_token={}|{}".format( facebook_access_token, facebook_app_id["app_id"], facebook_app_id["app_secret"]) req = requests.get(url=verify_token_app_id) if req.status_code != 200: raise Exception(Message.FACEBOOK_ACCESS_TOKEN_INVALID) facebook_token_app_id_info = req.json() facebook_token_app_id = facebook_token_app_id_info["data"][ "app_id"] if facebook_token_app_id != facebook_app_id["app_id"]: raise Exception(Message.FACEBOOK_ACCESS_TOKEN_INVALID) verify_token_url = "https://graph.facebook.com/me?fields=id,name,email&access_token=" + facebook_access_token req = requests.get(url=verify_token_url) if req.status_code != 200: raise Exception(Message.FACEBOOK_ACCESS_TOKEN_INVALID) facebook_token_info = req.json() logger.info("Facebook login token spec:") logger.info(facebook_token_info) facebook_id = facebook_token_info["id"] facebook_email = facebook_token_info["email"] facebook_name = facebook_token_info["name"] # check account exits user = self.get_user_by_email(facebook_id) if user: user_info = UserService().get_user_by_id(user["id"]) return facebook_id, user[ "id"], user_info.password_verifier is None or user_info.password_verifier == "" else: # create new user new_user_id = KeyCloakUtils.create_user_without_password( facebook_email, facebook_id, "", facebook_name) new_user = UserService().create_user_social( id=new_user_id, email=facebook_email, display_name=facebook_name, auth_source='facebook') if new_user is None: self.delete_user(new_user_id) raise Exception(Message.REGISTER_USER_FAILED) return facebook_id, new_user_id, True except Exception as e: logger.info(e) raise Exception(Message.FACEBOOK_AUTH_FAILED)
async def register_srp(self, request, context): # check exist user try: email = request.email display_name = request.display_name password_verifier = request.password_verifier salt = request.salt iv_parameter = request.iv_parameter exists_user = self.service.get_user_by_email(email) if exists_user: raise Exception(Message.REGISTER_USER_ALREADY_EXISTS) # register new user new_user_id = self.service.register_srp_user( email, password_verifier, display_name) if new_user_id: # create new user in database UserService().create_new_user_srp(new_user_id, email, password_verifier, salt, iv_parameter, display_name, 'account') else: self.service.delete_user(new_user_id) raise Exception(Message.REGISTER_USER_FAILED) try: SignalService().peer_register_client_key( new_user_id, request.client_key_peer) except Exception: self.service.delete_user(new_user_id) UserService().delete_user(new_user_id) raise Exception(Message.REGISTER_USER_FAILED) return auth_messages.RegisterSRPRes() except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.REGISTER_USER_FAILED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL)
def office_login(self, office_access_token): # office login by using office access token, return user_name, user_id and boolean variable indicate if this user is new user try: verify_token_url = "https://graph.microsoft.com/v1.0/me" bearer = 'Bearer ' + office_access_token headers = {'Authorization': bearer} req = requests.get(url=verify_token_url, headers=headers) if req.status_code != 200: raise Exception(Message.OFFICE_ACCESS_TOKEN_INVALID) office_token_info = req.json() logger.info("Office login token spec:") logger.info(office_token_info) office_id = office_token_info["id"] # check account exits user = self.get_user_by_email(office_id) if user: user_info = UserService().get_user_by_id(user["id"]) return office_id, user[ "id"], user_info.password_verifier is None or user_info.password_verifier == "" else: display_name = office_token_info["displayName"] email = "" if not display_name: if office_token_info["userPrincipalName"]: user_principal_name = office_token_info[ "userPrincipalName"].split("@") if len(user_principal_name) > 0: display_name = user_principal_name[0] email = office_token_info["userPrincipalName"] # create new user new_user_id = KeyCloakUtils.create_user_without_password( email, office_id, "", display_name) new_user = UserService().create_user_social( id=new_user_id, email=office_token_info["mail"], display_name=display_name, auth_source='office') if new_user is None: self.delete_user(new_user_id) raise Exception(Message.REGISTER_USER_FAILED) return office_id, new_user_id, True except Exception as e: logger.info(e) raise Exception(Message.OFFICE_AUTH_FAILED)
class UserController(Resource): def __init__(self, *args, **kwargs): self.user_service = UserService() def get(self): users = self.user_service.fetch() if not users: return {'data': [], 'message': 'No se encontraron usuarios'}, 404 return {'data': users, 'message': 'success'}, 200 def post(self): body = request.get_json() data = self.user_service.create(**body) if not data: return {'message': 'Ocurrio un error al insertar'}, 404 return {'data': data, 'message': 'Success'}, 200
def google_login(self, google_id_token): # google login by using google id token, return user_name, user_id and boolean variable indicate if this user is new user try: verify_id_token_url = "https://oauth2.googleapis.com/tokeninfo?id_token=" + google_id_token req = requests.get(url=verify_id_token_url) if req.status_code != 200: raise Exception(Message.GOOGLE_AUTH_ID_TOKEN_INVALID) google_token_info = req.json() logger.info("Google login token spec:") logger.info(google_token_info) # check google_token_info["aud"] matching with google app id google_app_id = get_system_config()["google_app_id"] if google_token_info["aud"] != google_app_id[ "ios"] and google_token_info["aud"] != google_app_id[ "android"]: raise Exception(Message.GOOGLE_AUTH_FAILED) google_email = google_token_info["email"] # check account exits user = self.get_user_by_email(email=google_email) #active_user if user: if not user["emailVerified"]: KeyCloakUtils.active_user(user["id"]) user_info = UserService().get_user_by_id(user["id"]) return google_email, user[ "id"], user_info.password_verifier is None or user_info.password_verifier == "" else: # create new user new_user_id = KeyCloakUtils.create_user_without_password( google_email, google_email, "", google_token_info["name"]) new_user = UserService().create_user_social( id=new_user_id, email=google_email, display_name=google_token_info["name"], auth_source='google') if new_user is None: self.delete_user(new_user_id) raise Exception(Message.REGISTER_USER_FAILED) return google_email, new_user_id, True except Exception as e: logger.info(e) raise Exception(Message.GOOGLE_AUTH_FAILED)
def get(self): """ Get the dummy client for testing purposes. """ client = OAuth2ClientService.find_by( resource_owner_id=UserService.find_by(username='******', fetch_one=True).id, fetch_one=True) return client.client_info
def reset_user_words(user_telegram_id): """ Change all user word status to unused :param user_telegram_id: :return: """ user = UserService.filter(telegram_id=user_telegram_id) if user: user = user[0] else: return None user_words = UserWordService.filter(user_id=user.id) for word in user_words: UserWordService.update(user_word_id=word.id, status=True) return True
def add_user_word(user_telegram_id, word): """ add word to user word list :param user_telegram_id: :param word: :return: """ user = UserService.filter(telegram_id=user_telegram_id) if not user: # if no such word return None user = user[0] # if user already has this word if user_word := UserWordService.filter(user_id=user.id, word_id=word.id): return user_word[0]
def get_user_word(user_telegram_id): """ Return one of user`s unseen word :param user_telegram_id: :return: """ user = UserService.filter(telegram_id=user_telegram_id) if not user: return None user = user[0] user_word = UserWordService.pick_random_word(user.id) if not user_word: return None UserWordService.update(user_word.id, status=False) # mark word as used word = WordService.get_by_id(user_word.word_id) return word
def authenticate_user(self, credential): return UserService.get(credential.resource_owner.id)
def authenticate_user(self, username, password): user = UserService.find_by(username=username, fetch_one=True) if user and UserService.authenticate(username, password): return user
def authenticate_user(self, authorization_code): return UserService.get(authorization_code.resource_owner.id)
def post(self): payload = request.json saved_id = UserService().save(payload) return {"id": saved_id}, HTTPStatus.OK
async def register_pincode(self, request, context): try: exists_user = self.service.get_user_by_email(request.user_name) if not exists_user: raise Exception(Message.REGISTER_CLIENT_SIGNAL_KEY_FAILED) user_info = self.user_service.get_user_by_id(exists_user["id"]) if user_info.password_verifier is not None: raise Exception(Message.REGISTER_USER_ALREADY_EXISTS) salt = request.salt self.user_service.change_password(request, None, request.hash_pincode, exists_user['id']) # using hash_pincode as password for social user try: SignalService().peer_register_client_key( exists_user['id'], request.client_key_peer) except Exception as e: logger.error(e) try: UserService().update_hash_pin(exists_user['id'], request.hash_pincode, request.salt, request.iv_parameter) except Exception as e: logger.error(e) ## TODO: revert change_password SignalService().delete_client_peer_key(exists_user['id']) raise Message.get_error_object( Message.REGISTER_CLIENT_SIGNAL_KEY_FAILED) require_action = "" client_key_obj = request.client_key_peer client_key_peer = auth_messages.PeerGetClientKeyResponse( clientId=exists_user['id'], workspace_domain=get_owner_workspace_domain(), registrationId=client_key_obj.registrationId, deviceId=client_key_obj.deviceId, identityKeyPublic=client_key_obj.identityKeyPublic, preKeyId=client_key_obj.preKeyId, preKey=client_key_obj.preKey, signedPreKeyId=client_key_obj.signedPreKeyId, signedPreKey=client_key_obj.signedPreKey, signedPreKeySignature=client_key_obj.signedPreKeySignature, identityKeyEncrypted=client_key_obj.identityKeyEncrypted) token = self.service.token(request.user_name, request.hash_pincode) introspect_token = KeyCloakUtils.introspect_token( token['access_token']) self.user_service.update_last_login( user_id=introspect_token['sub']) return auth_messages.AuthRes( workspace_domain=get_owner_workspace_domain(), workspace_name=get_system_config()['server_name'], access_token=token["access_token"], expires_in=token['expires_in'], refresh_expires_in=token['refresh_expires_in'], refresh_token=token['refresh_token'], token_type=token['token_type'], session_state=token['session_state'], scope=token['scope'], salt=request.salt, client_key_peer=client_key_peer, iv_parameter=request.iv_parameter) except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object( Message.REGISTER_CLIENT_SIGNAL_KEY_FAILED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL)
def load_user(user_id): return UserService.get(user_id)
async def reset_pincode(self, request, context): try: success_status = self.service.verify_hash_pre_access_token( request.user_name, request.reset_pincode_token, "verify_pincode") exists_user = self.service.get_user_by_email(request.user_name) if not exists_user: raise Exception(Message.USER_NOT_FOUND) if not success_status: raise Exception(Message.REGISTER_CLIENT_SIGNAL_KEY_FAILED) self.user_service.change_password(request, None, request.hash_pincode, exists_user["id"]) old_client_key_peer = SignalService().peer_get_client_key( exists_user["id"]) SignalService().client_update_peer_key(exists_user["id"], request.client_key_peer) try: salt, iv_parameter = UserService().update_hash_pin( exists_user["id"], request.hash_pincode, request.salt, request.iv_parameter) except Exception as e: logger.error(e) SignalService().client_update_peer_key(exists_user["id"], old_client_key_peer) raise Message.get_error_object( Message.REGISTER_CLIENT_SIGNAL_KEY_FAILED) client_key_obj = request.client_key_peer client_key_peer = auth_messages.PeerGetClientKeyResponse( clientId=exists_user["id"], workspace_domain=get_owner_workspace_domain(), registrationId=client_key_obj.registrationId, deviceId=client_key_obj.deviceId, identityKeyPublic=client_key_obj.identityKeyPublic, preKeyId=client_key_obj.preKeyId, preKey=client_key_obj.preKey, signedPreKeyId=client_key_obj.signedPreKeyId, signedPreKey=client_key_obj.signedPreKey, signedPreKeySignature=client_key_obj.signedPreKeySignature, identityKeyEncrypted=client_key_obj.identityKeyEncrypted) # logout all device before get new token for user after updated new key user_sessions = KeyCloakUtils.get_sessions( user_id=exists_user["id"]) for user_session in user_sessions: KeyCloakUtils.remove_session(session_id=user_session['id']) token = self.service.token(request.user_name, request.hash_pincode) introspect_token = KeyCloakUtils.introspect_token( token['access_token']) return auth_messages.AuthRes( workspace_domain=get_owner_workspace_domain(), workspace_name=get_system_config()['server_name'], access_token=token["access_token"], expires_in=token['expires_in'], refresh_expires_in=token['refresh_expires_in'], refresh_token=token['refresh_token'], token_type=token['token_type'], session_state=token['session_state'], scope=token['scope'], salt=salt, client_key_peer=client_key_peer, iv_parameter=iv_parameter) except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object( Message.REGISTER_CLIENT_SIGNAL_KEY_FAILED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL)
def __init__(self, *args, **kwargs): self.user_service = UserService()
class UserController(BaseController, user_pb2_grpc.UserServicer): def __init__(self, *kwargs): self.service = UserService() @auth_required async def request_change_password(self, request, context): try: header_data = dict(context.invocation_metadata()) introspect_token = KeyCloakUtils.introspect_token( header_data['access_token']) user_name = introspect_token['preferred_username'] user_info = self.service.get_user_by_auth_source( user_name, "account") if not user_info: raise Exception(Message.AUTH_USER_NOT_FOUND) password_verifier = bytes.fromhex(user_info.password_verifier) salt = bytes.fromhex(user_info.salt) client_public = bytes.fromhex(request.client_public) srv = srp.Verifier(user_name, salt, password_verifier, client_public) s, B = srv.get_challenge() # need store private b of server server_private = srv.get_ephemeral_secret().hex() user_info.srp_server_private = server_private user_info.update() public_challenge_b = B.hex() auth_challenge_res = user_messages.RequestChangePasswordRes( salt=user_info.salt, public_challenge_b=public_challenge_b) return auth_challenge_res except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.CHANGE_PASSWORD_FAILED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @auth_required async def change_password(self, request, context): try: header_data = dict(context.invocation_metadata()) introspect_token = KeyCloakUtils.introspect_token( header_data['access_token']) user_name = introspect_token['preferred_username'] client_session_key_proof = request.client_session_key_proof user_info = self.service.get_user_by_auth_source( user_name, "account") if not user_info: raise Exception(Message.AUTH_USER_NOT_FOUND) password_verifier = bytes.fromhex(user_info.password_verifier) salt = bytes.fromhex(user_info.salt) client_session_key_proof_bytes = bytes.fromhex( client_session_key_proof) srv = srp.Verifier(username=user_name, bytes_s=salt, bytes_v=password_verifier, bytes_A=bytes.fromhex(request.client_public), bytes_b=bytes.fromhex( user_info.srp_server_private)) srv.verify_session(client_session_key_proof_bytes) authenticated = srv.authenticated() if not authenticated: raise Exception(Message.AUTHENTICATION_FAILED) self.service.change_password( request, user_info.password_verifier, request.hash_password, introspect_token['sub']) # update for keycloak try: old_identity_key_encrypted = SignalService( ).client_update_identity_key(introspect_token["sub"], request.identity_key_encrypted) except Exception as e: logger.error(e) self.service.change_password(request, request.hash_password, user_info.password_verifier, introspect_token['sub']) raise Exception(Message.REGISTER_CLIENT_SIGNAL_KEY_FAILED) try: salt, iv_parameter = self.service.update_hash_pass( introspect_token["sub"], request.hash_password, request.salt, request.iv_parameter) except Exception as e: logger.error(e) self.service.change_password(request, request.hash_password, request.password_verifier, introspect_token['sub']) SignalService().client_update_identity_key( introspect_token["sub"], old_identity_key_encrypted) raise Exception(Message.REGISTER_CLIENT_SIGNAL_KEY_FAILED) user_sessions = KeyCloakUtils.get_sessions( user_id=introspect_token["sub"]) for user_session in user_sessions: if user_session['id'] != introspect_token['session_state']: KeyCloakUtils.remove_session(session_id=user_session['id']) return user_messages.BaseResponse() except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.CHANGE_PASSWORD_FAILED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @auth_required async def get_mfa_state(self, request, context): try: header_data = dict(context.invocation_metadata()) introspect_token = KeyCloakUtils.introspect_token( header_data['access_token']) client_id = introspect_token['sub'] mfa_enable = self.service.get_mfa_state(client_id) return user_messages.MfaStateResponse(mfa_enable=mfa_enable, ) except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.GET_MFA_STATE_FALED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @auth_required async def disable_mfa(self, request, context): try: header_data = dict(context.invocation_metadata()) introspect_token = KeyCloakUtils.introspect_token( header_data['access_token']) if not introspect_token or 'sub' not in introspect_token: raise Exception(Message.AUTH_USER_NOT_FOUND) client_id = introspect_token['sub'] success, next_step = self.service.init_mfa_state_disabling( client_id) return user_messages.MfaBaseResponse(success=success, next_step=next_step) except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.GET_MFA_STATE_FALED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @request_logged @auth_required async def enable_mfa(self, request, context): try: header_data = dict(context.invocation_metadata()) introspect_token = KeyCloakUtils.introspect_token( header_data['access_token']) client_id = introspect_token['sub'] user_info = self.service.get_user_by_id(client_id) if user_info.phone_number is None: success = False next_step = 'mfa_update_phone_number' else: success, next_step = self.service.init_mfa_state_enabling( client_id) return user_messages.MfaBaseResponse(success=success, next_step=next_step) except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.GET_MFA_STATE_FALED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @request_logged @auth_required async def mfa_auth_challenge(self, request, context): try: header_data = dict(context.invocation_metadata()) introspect_token = KeyCloakUtils.introspect_token( header_data['access_token']) client_id = introspect_token['sub'] email = introspect_token['preferred_username'] self.service.mfa_validate_password_flow(client_id) user_info = self.service.get_user_by_id(client_id) password_verifier = bytes.fromhex(user_info.password_verifier) salt = bytes.fromhex(user_info.salt) client_public = bytes.fromhex(request.client_public) srv = srp.Verifier(email, salt, password_verifier, client_public) s, B = srv.get_challenge() server_private = srv.get_ephemeral_secret().hex() user_info.srp_server_private = server_private user_info.update() public_challenge_b = B.hex() auth_challenge_res = user_messages.MfaAuthChallengeResponse( salt=user_info.salt, public_challenge_b=public_challenge_b) return auth_challenge_res except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.GET_MFA_STATE_FALED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @request_logged @auth_required async def mfa_validate_password(self, request, context): try: header_data = dict(context.invocation_metadata()) introspect_token = KeyCloakUtils.introspect_token( header_data['access_token']) client_id = introspect_token['sub'] user_info = self.service.get_user_by_id(client_id) client_session_key_proof = request.client_session_key_proof user_name = introspect_token['preferred_username'] phone_number = user_info.phone_number password_verifier = bytes.fromhex(user_info.password_verifier) salt = bytes.fromhex(user_info.salt) client_session_key_proof_bytes = bytes.fromhex( client_session_key_proof) srv = srp.Verifier(username=user_name, bytes_s=salt, bytes_v=password_verifier, bytes_A=bytes.fromhex(request.client_public), bytes_b=bytes.fromhex( user_info.srp_server_private)) srv.verify_session(client_session_key_proof_bytes) authenticated = srv.authenticated() if not authenticated: raise Exception(Message.AUTHENTICATION_FAILED) success, next_step = self.service.mfa_request_otp( client_id, phone_number) return user_messages.MfaBaseResponse(success=success, next_step=next_step) except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.OTP_SERVER_NOT_RESPONDING) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @auth_required async def mfa_validate_otp(self, request, context): try: header_data = dict(context.invocation_metadata()) introspect_token = KeyCloakUtils.introspect_token( header_data['access_token']) client_id = introspect_token['sub'] success, next_step = self.service.validate_otp( client_id, request.otp) return user_messages.MfaBaseResponse(success=success, next_step=next_step) except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.GET_MFA_STATE_FALED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @auth_required async def mfa_resend_otp(self, request, context): try: header_data = dict(context.invocation_metadata()) introspect_token = KeyCloakUtils.introspect_token( header_data['access_token']) client_id = introspect_token['sub'] success, next_step = self.service.re_init_otp(client_id) return user_messages.MfaBaseResponse(success=success, next_step=next_step) except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.OTP_SERVER_NOT_RESPONDING) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @request_logged @auth_required async def get_profile(self, request, context): try: header_data = dict(context.invocation_metadata()) introspect_token = KeyCloakUtils.introspect_token( header_data['access_token']) client_id = introspect_token['sub'] user_info = self.service.get_profile(client_id) if user_info is not None: return user_info else: errors = [Message.get_error_object(Message.USER_NOT_FOUND)] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.NOT_FOUND) except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [Message.get_error_object(Message.GET_PROFILE_FAILED)] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @auth_required async def update_profile(self, request, context): logger.info("user update_profile api") try: display_name = request.display_name avatar = request.avatar phone_number = request.phone_number clear_phone_number = request.clear_phone_number header_data = dict(context.invocation_metadata()) introspect_token = KeyCloakUtils.introspect_token( header_data['access_token']) client_id = introspect_token['sub'] self.service.update_profile(client_id, display_name, phone_number, avatar, clear_phone_number) return user_messages.BaseResponse() except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.UPDATE_PROFILE_FAILED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) # @auth_required # @request_logged async def get_user_info(self, request, context): try: client_id = request.client_id client_workspace_domain = request.workspace_domain owner_workspace_domain = get_owner_workspace_domain() if client_workspace_domain == owner_workspace_domain: user_info = self.service.get_user_info(client_id, owner_workspace_domain) else: client = ClientUser(client_workspace_domain) user_info = client.get_user_info( client_id=client_id, workspace_domain=client_workspace_domain) if user_info is not None: return user_info else: errors = [Message.get_error_object(Message.USER_NOT_FOUND)] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.NOT_FOUND) except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.GET_USER_INFO_FAILED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @request_logged @auth_required async def search_user(self, request, context): logger.info("user search_user api") try: keyword = request.keyword header_data = dict(context.invocation_metadata()) introspect_token = KeyCloakUtils.introspect_token( header_data['access_token']) client_id = introspect_token['sub'] obj_res = self.service.search_user(keyword, client_id) return obj_res except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [Message.get_error_object(Message.SEARCH_USER_FAILED)] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @request_logged @auth_required async def get_users(self, request, context): try: header_data = dict(context.invocation_metadata()) introspect_token = KeyCloakUtils.introspect_token( header_data['access_token']) client_id = introspect_token['sub'] owner_workspace_domain = get_owner_workspace_domain() obj_res = self.service.get_users(client_id, owner_workspace_domain) return obj_res except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [Message.get_error_object(Message.SEARCH_USER_FAILED)] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @request_logged @auth_required async def get_user_domain(self, request, context): try: header_data = dict(context.invocation_metadata()) domain = "server.domain2" obj_res = self.service.get_users_domain(domain=domain) return obj_res except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [Message.get_error_object(Message.SEARCH_USER_FAILED)] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) # update status for user ("Active, Busy, Away, Do not disturb") @request_logged @auth_required async def update_status(self, request, context): logger.info("user update_status api") try: status = request.status header_data = dict(context.invocation_metadata()) introspect_token = KeyCloakUtils.introspect_token( header_data['access_token']) client_id = introspect_token['sub'] self.service.set_user_status(client_id, status) return user_messages.BaseResponse() except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.UPDATE_USER_STATUS_FAILED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @request_logged async def ping_request(self, request, context): logger.info("ping_request api") try: header_data = dict(context.invocation_metadata()) introspect_token = KeyCloakUtils.introspect_token( header_data['access_token']) client_id = introspect_token['sub'] self.service.update_client_record(client_id) return user_messages.BaseResponse() except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.PING_PONG_SERVER_FAILED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @request_logged async def get_clients_status(self, request, context): logger.info("get_client_status api") try: list_clients = request.lst_client should_get_profile = request.should_get_profile list_user_status = self.service.get_list_clients_status( list_clients, should_get_profile) return list_user_status except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.GET_USER_STATUS_FAILED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @request_logged async def upload_avatar(self, request, context): logger.info("upload_avatar api") try: file_name = request.file_name file_content = request.file_data file_content_type = request.file_content_type file_hash = request.file_hash # client_id from headers header_data = dict(context.invocation_metadata()) introspect_token = KeyCloakUtils.introspect_token( header_data['access_token']) client_id = introspect_token['sub'] obj_res = self.service.upload_avatar(client_id, file_name, file_content, file_content_type, file_hash) return obj_res except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.GET_USER_STATUS_FAILED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL)
def __init__(self, *kwargs): self.service = AuthService() self.user_service = UserService()
async def forgot_password_update(self, request, context): try: logger.info("from email {}".format(request.email)) user_info = self.user_service.get_user_by_auth_source( request.email, "account") old_user_id = user_info.id self.service.verify_hash_pre_access_token(old_user_id, request.pre_access_token, "forgot_password") new_user_id = self.service.forgot_user(request.email, request.password_verifier, user_info.display_name) try: await GroupService().forgot_peer_groups_for_client(user_info) except Exception as e: logger.error("cannot send notify to other group") logger.error(e) SignalService().delete_client_peer_key(old_user_id) if new_user_id: # create new user in database UserService().forgot_user(user_info, new_user_id, request.password_verifier, request.salt, request.iv_parameter) else: self.service.delete_user(new_user_id) raise Exception(Message.REGISTER_USER_FAILED) try: SignalService().peer_register_client_key( new_user_id, request.client_key_peer) except Exception: self.service.delete_user(new_user_id) UserService().delete_user(new_user_id) raise Exception(Message.REGISTER_USER_FAILED) token = self.service.token(request.email, request.password_verifier) if token: client_key_obj = request.client_key_peer client_key_peer = auth_messages.PeerGetClientKeyResponse( clientId=new_user_id, workspace_domain=get_owner_workspace_domain(), registrationId=client_key_obj.registrationId, deviceId=client_key_obj.deviceId, identityKeyPublic=client_key_obj.identityKeyPublic, preKeyId=client_key_obj.preKeyId, preKey=client_key_obj.preKey, signedPreKeyId=client_key_obj.signedPreKeyId, signedPreKey=client_key_obj.signedPreKey, signedPreKeySignature=client_key_obj.signedPreKeySignature, identityKeyEncrypted=client_key_obj.identityKeyEncrypted) self.user_service.update_last_login(user_id=new_user_id) auth_message = auth_messages.AuthRes( workspace_domain=get_owner_workspace_domain(), workspace_name=get_system_config()['server_name'], access_token=token['access_token'], expires_in=token['expires_in'], refresh_expires_in=token['refresh_expires_in'], refresh_token=token['refresh_token'], token_type=token['token_type'], session_state=token['session_state'], scope=token['scope'], salt=request.salt, client_key_peer=client_key_peer, iv_parameter=request.iv_parameter) else: raise Exception(Message.AUTH_USER_NOT_FOUND) return auth_message except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.CHANGE_PASSWORD_FAILED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL)
def __init__(self, *kwargs): self.service = UserService()
class AuthController(BaseController): def __init__(self, *kwargs): self.service = AuthService() self.user_service = UserService() @request_logged async def login_challenge(self, request, context): try: email = request.email user_info = self.user_service.get_user_by_auth_source( email, "account") if not user_info: raise Exception(Message.AUTH_USER_NOT_FOUND) password_verifier = bytes.fromhex(user_info.password_verifier) salt = bytes.fromhex(user_info.salt) client_public = bytes.fromhex(request.client_public) srv = srp.Verifier(email, salt, password_verifier, client_public) s, B = srv.get_challenge() server_private = srv.get_ephemeral_secret().hex() logger.info(server_private) user_info.srp_server_private = server_private user_info.update() public_challenge_b = B.hex() auth_challenge_res = auth_messages.AuthChallengeRes( salt=user_info.salt, public_challenge_b=public_challenge_b) return auth_challenge_res except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.AUTHENTICATION_FAILED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @request_logged async def login_authenticate(self, request, context): try: user_name = request.user_name exists_user = self.service.get_user_by_email(user_name) client_session_key_proof = request.client_session_key_proof user_info = self.user_service.get_user_by_id(exists_user["id"]) if not user_info: raise Exception(Message.AUTH_USER_NOT_FOUND) password_verifier = bytes.fromhex(user_info.password_verifier) salt = bytes.fromhex(user_info.salt) client_session_key_proof_bytes = bytes.fromhex( client_session_key_proof) srv = srp.Verifier(username=user_name, bytes_s=salt, bytes_v=password_verifier, bytes_A=bytes.fromhex(request.client_public), bytes_b=bytes.fromhex( user_info.srp_server_private)) srv.verify_session(client_session_key_proof_bytes) authenticated = srv.authenticated() if not authenticated: raise Exception(Message.AUTHENTICATION_FAILED) token = self.service.token(user_name, user_info.password_verifier) if token: user_id = user_info.id mfa_state = self.user_service.get_mfa_state(user_id=user_id) if not mfa_state: client_key_obj = SignalService().peer_get_client_key( user_id) client_key_peer = auth_messages.PeerGetClientKeyResponse( clientId=user_id, workspace_domain=get_owner_workspace_domain(), registrationId=client_key_obj.registration_id, deviceId=client_key_obj.device_id, identityKeyPublic=client_key_obj.identity_key_public, preKeyId=client_key_obj.prekey_id, preKey=client_key_obj.prekey, signedPreKeyId=client_key_obj.signed_prekey_id, signedPreKey=client_key_obj.signed_prekey, signedPreKeySignature=client_key_obj. signed_prekey_signature, identityKeyEncrypted=client_key_obj. identity_key_encrypted) self.user_service.update_last_login(user_id=user_id) auth_message = auth_messages.AuthRes( workspace_domain=get_owner_workspace_domain(), workspace_name=get_system_config()['server_name'], access_token=token['access_token'], expires_in=token['expires_in'], refresh_expires_in=token['refresh_expires_in'], refresh_token=token['refresh_token'], token_type=token['token_type'], session_state=token['session_state'], scope=token['scope'], salt=user_info.salt, client_key_peer=client_key_peer, iv_parameter=user_info.iv_parameter) else: pre_access_token = self.service.create_otp_service(user_id) auth_message = auth_messages.AuthRes( workspace_domain=get_owner_workspace_domain(), workspace_name=get_system_config()['server_name'], sub=user_id, pre_access_token=pre_access_token, require_action="mfa_validate_otp") return auth_message except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.AUTH_USER_NOT_FOUND) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @request_logged async def login_google(self, request, context): try: user_name, user_id, is_registered_pincode = self.service.google_login( request.id_token) user_info = self.user_service.get_user_by_id(user_id) require_action_mess = "verify_pincode" if not is_registered_pincode else "register_pincode" if require_action_mess == "verify_pincode": reset_pincode_token = self.service.hash_pre_access_token( user_name, "reset_pincode") else: reset_pincode_token = "" auth_challenge_res = auth_messages.SocialLoginRes( user_name=user_name, require_action=require_action_mess, reset_pincode_token=reset_pincode_token) return auth_challenge_res except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.AUTH_USER_NOT_FOUND) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @request_logged async def login_office(self, request, context): try: user_name, user_id, is_registered_pincode = self.service.office_login( request.access_token) user_info = self.user_service.get_user_by_id(user_id) require_action_mess = "verify_pincode" if not is_registered_pincode else "register_pincode" if require_action_mess == "verify_pincode": reset_pincode_token = self.service.hash_pre_access_token( user_name, "reset_pincode") else: reset_pincode_token = "" auth_challenge_res = auth_messages.SocialLoginRes( user_name=user_name, require_action=require_action_mess, reset_pincode_token=reset_pincode_token) return auth_challenge_res except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.AUTH_USER_NOT_FOUND) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @request_logged async def login_facebook(self, request, context): try: user_name, user_id, is_registered_pincode = self.service.facebook_login( request.access_token) user_info = self.user_service.get_user_by_id(user_id) require_action_mess = "verify_pincode" if not is_registered_pincode else "register_pincode" if require_action_mess == "verify_pincode": reset_pincode_token = self.service.hash_pre_access_token( user_name, "reset_pincode") else: reset_pincode_token = "" auth_challenge_res = auth_messages.SocialLoginRes( user_name=user_name, require_action=require_action_mess, reset_pincode_token=reset_pincode_token) return auth_challenge_res except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.AUTH_USER_NOT_FOUND) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @request_logged async def login_social_challange(self, request, context): try: user_name = request.user_name exists_user = self.service.get_user_by_email(user_name) user_info = self.user_service.get_user_by_id(exists_user["id"]) if not user_info: raise Exception(Message.AUTH_USER_NOT_FOUND) password_verifier = bytes.fromhex(user_info.password_verifier) salt = bytes.fromhex(user_info.salt) client_public = bytes.fromhex(request.client_public) srv = srp.Verifier(user_name, salt, password_verifier, client_public) s, B = srv.get_challenge() server_private = srv.get_ephemeral_secret().hex() logger.info(server_private) user_info.srp_server_private = server_private user_info.update() public_challenge_b = B.hex() auth_challenge_res = auth_messages.AuthChallengeRes( salt=user_info.salt, public_challenge_b=public_challenge_b) return auth_challenge_res except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.AUTHENTICATION_FAILED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @request_logged async def register_srp(self, request, context): # check exist user try: email = request.email display_name = request.display_name password_verifier = request.password_verifier salt = request.salt iv_parameter = request.iv_parameter exists_user = self.service.get_user_by_email(email) if exists_user: raise Exception(Message.REGISTER_USER_ALREADY_EXISTS) # register new user new_user_id = self.service.register_srp_user( email, password_verifier, display_name) if new_user_id: # create new user in database UserService().create_new_user_srp(new_user_id, email, password_verifier, salt, iv_parameter, display_name, 'account') else: self.service.delete_user(new_user_id) raise Exception(Message.REGISTER_USER_FAILED) try: SignalService().peer_register_client_key( new_user_id, request.client_key_peer) except Exception: self.service.delete_user(new_user_id) UserService().delete_user(new_user_id) raise Exception(Message.REGISTER_USER_FAILED) return auth_messages.RegisterSRPRes() except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.REGISTER_USER_FAILED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @request_logged async def forgot_password(self, request, context): try: self.service.send_forgot_password(request.email) return auth_messages.BaseResponse() except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.AUTH_USER_NOT_FOUND) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @request_logged async def forgot_password_update(self, request, context): try: logger.info("from email {}".format(request.email)) user_info = self.user_service.get_user_by_auth_source( request.email, "account") old_user_id = user_info.id self.service.verify_hash_pre_access_token(old_user_id, request.pre_access_token, "forgot_password") new_user_id = self.service.forgot_user(request.email, request.password_verifier, user_info.display_name) try: await GroupService().forgot_peer_groups_for_client(user_info) except Exception as e: logger.error("cannot send notify to other group") logger.error(e) SignalService().delete_client_peer_key(old_user_id) if new_user_id: # create new user in database UserService().forgot_user(user_info, new_user_id, request.password_verifier, request.salt, request.iv_parameter) else: self.service.delete_user(new_user_id) raise Exception(Message.REGISTER_USER_FAILED) try: SignalService().peer_register_client_key( new_user_id, request.client_key_peer) except Exception: self.service.delete_user(new_user_id) UserService().delete_user(new_user_id) raise Exception(Message.REGISTER_USER_FAILED) token = self.service.token(request.email, request.password_verifier) if token: client_key_obj = request.client_key_peer client_key_peer = auth_messages.PeerGetClientKeyResponse( clientId=new_user_id, workspace_domain=get_owner_workspace_domain(), registrationId=client_key_obj.registrationId, deviceId=client_key_obj.deviceId, identityKeyPublic=client_key_obj.identityKeyPublic, preKeyId=client_key_obj.preKeyId, preKey=client_key_obj.preKey, signedPreKeyId=client_key_obj.signedPreKeyId, signedPreKey=client_key_obj.signedPreKey, signedPreKeySignature=client_key_obj.signedPreKeySignature, identityKeyEncrypted=client_key_obj.identityKeyEncrypted) self.user_service.update_last_login(user_id=new_user_id) auth_message = auth_messages.AuthRes( workspace_domain=get_owner_workspace_domain(), workspace_name=get_system_config()['server_name'], access_token=token['access_token'], expires_in=token['expires_in'], refresh_expires_in=token['refresh_expires_in'], refresh_token=token['refresh_token'], token_type=token['token_type'], session_state=token['session_state'], scope=token['scope'], salt=request.salt, client_key_peer=client_key_peer, iv_parameter=request.iv_parameter) else: raise Exception(Message.AUTH_USER_NOT_FOUND) return auth_message except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.CHANGE_PASSWORD_FAILED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @auth_required @request_logged async def logout(self, request, context): try: header_data = dict(context.invocation_metadata()) introspect_token = KeyCloakUtils.introspect_token( header_data['access_token']) user_id = introspect_token['sub'] device_id = request.device_id refresh_token = request.refresh_token self.service.remove_token(client_id=user_id, device_id=device_id) MessageService().un_subscribe(user_id, device_id) NotifyInAppService().un_subscribe(user_id, device_id) self.service.logout(refresh_token) return auth_messages.BaseResponse() except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.AUTH_USER_NOT_FOUND) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) async def validate_otp(self, request, context): try: success_status = self.service.verify_otp(request.user_id, request.pre_access_token, request.otp_code) if not success_status: raise Exception(Message.AUTH_USER_NOT_FOUND) user_info = self.user_service.get_user_by_id(request.user_id) introspect_token = KeyCloakUtils.introspect_token( token['access_token']) require_action = "" client_key_obj = SignalService().peer_get_client_key( request.user_id) client_key_peer = auth_messages.PeerGetClientKeyResponse( clientId=request.user_id, workspace_domain=get_owner_workspace_domain(), registrationId=client_key_obj.registration_id, deviceId=client_key_obj.device_id, identityKeyPublic=client_key_obj.identity_key_public, preKeyId=client_key_obj.prekey_id, preKey=client_key_obj.prekey, signedPreKeyId=client_key_obj.signed_prekey_id, signedPreKey=client_key_obj.signed_prekey, signedPreKeySignature=client_key_obj.signed_prekey_signature, identityKeyEncrypted=client_key_obj.identity_key_encrypted) token = self.service.token(user_info.email, user_info.password_verifier) self.user_service.update_last_login(user_id=request.user_id) return auth_messages.AuthRes( workspace_domain=get_owner_workspace_domain(), workspace_name=get_system_config()['server_name'], access_token=token["access_token"], expires_in=token['expires_in'], refresh_expires_in=token['refresh_expires_in'], refresh_token=token['refresh_token'], token_type=token['token_type'], session_state=token['session_state'], scope=token['scope'], require_action=require_action, salt=user_info.salt, client_key_peer=client_key_peer, iv_parameter=user_info.iv_parameter) except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.GET_MFA_STATE_FALED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) async def resend_otp(self, request, context): try: pre_access_token = self.service.resend_otp( request.user_id, request.pre_access_token) return auth_messages.MfaResendOtpRes( success=True, pre_access_token=pre_access_token) except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.GET_MFA_STATE_FALED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) @request_logged async def register_pincode(self, request, context): try: exists_user = self.service.get_user_by_email(request.user_name) if not exists_user: raise Exception(Message.REGISTER_CLIENT_SIGNAL_KEY_FAILED) user_info = self.user_service.get_user_by_id(exists_user["id"]) if user_info.password_verifier is not None: raise Exception(Message.REGISTER_USER_ALREADY_EXISTS) salt = request.salt self.user_service.change_password(request, None, request.hash_pincode, exists_user['id']) # using hash_pincode as password for social user try: SignalService().peer_register_client_key( exists_user['id'], request.client_key_peer) except Exception as e: logger.error(e) try: UserService().update_hash_pin(exists_user['id'], request.hash_pincode, request.salt, request.iv_parameter) except Exception as e: logger.error(e) ## TODO: revert change_password SignalService().delete_client_peer_key(exists_user['id']) raise Message.get_error_object( Message.REGISTER_CLIENT_SIGNAL_KEY_FAILED) require_action = "" client_key_obj = request.client_key_peer client_key_peer = auth_messages.PeerGetClientKeyResponse( clientId=exists_user['id'], workspace_domain=get_owner_workspace_domain(), registrationId=client_key_obj.registrationId, deviceId=client_key_obj.deviceId, identityKeyPublic=client_key_obj.identityKeyPublic, preKeyId=client_key_obj.preKeyId, preKey=client_key_obj.preKey, signedPreKeyId=client_key_obj.signedPreKeyId, signedPreKey=client_key_obj.signedPreKey, signedPreKeySignature=client_key_obj.signedPreKeySignature, identityKeyEncrypted=client_key_obj.identityKeyEncrypted) token = self.service.token(request.user_name, request.hash_pincode) introspect_token = KeyCloakUtils.introspect_token( token['access_token']) self.user_service.update_last_login( user_id=introspect_token['sub']) return auth_messages.AuthRes( workspace_domain=get_owner_workspace_domain(), workspace_name=get_system_config()['server_name'], access_token=token["access_token"], expires_in=token['expires_in'], refresh_expires_in=token['refresh_expires_in'], refresh_token=token['refresh_token'], token_type=token['token_type'], session_state=token['session_state'], scope=token['scope'], salt=request.salt, client_key_peer=client_key_peer, iv_parameter=request.iv_parameter) except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object( Message.REGISTER_CLIENT_SIGNAL_KEY_FAILED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) async def reset_pincode(self, request, context): try: success_status = self.service.verify_hash_pre_access_token( request.user_name, request.reset_pincode_token, "verify_pincode") exists_user = self.service.get_user_by_email(request.user_name) if not exists_user: raise Exception(Message.USER_NOT_FOUND) if not success_status: raise Exception(Message.REGISTER_CLIENT_SIGNAL_KEY_FAILED) self.user_service.change_password(request, None, request.hash_pincode, exists_user["id"]) old_client_key_peer = SignalService().peer_get_client_key( exists_user["id"]) SignalService().client_update_peer_key(exists_user["id"], request.client_key_peer) try: salt, iv_parameter = UserService().update_hash_pin( exists_user["id"], request.hash_pincode, request.salt, request.iv_parameter) except Exception as e: logger.error(e) SignalService().client_update_peer_key(exists_user["id"], old_client_key_peer) raise Message.get_error_object( Message.REGISTER_CLIENT_SIGNAL_KEY_FAILED) client_key_obj = request.client_key_peer client_key_peer = auth_messages.PeerGetClientKeyResponse( clientId=exists_user["id"], workspace_domain=get_owner_workspace_domain(), registrationId=client_key_obj.registrationId, deviceId=client_key_obj.deviceId, identityKeyPublic=client_key_obj.identityKeyPublic, preKeyId=client_key_obj.preKeyId, preKey=client_key_obj.preKey, signedPreKeyId=client_key_obj.signedPreKeyId, signedPreKey=client_key_obj.signedPreKey, signedPreKeySignature=client_key_obj.signedPreKeySignature, identityKeyEncrypted=client_key_obj.identityKeyEncrypted) # logout all device before get new token for user after updated new key user_sessions = KeyCloakUtils.get_sessions( user_id=exists_user["id"]) for user_session in user_sessions: KeyCloakUtils.remove_session(session_id=user_session['id']) token = self.service.token(request.user_name, request.hash_pincode) introspect_token = KeyCloakUtils.introspect_token( token['access_token']) return auth_messages.AuthRes( workspace_domain=get_owner_workspace_domain(), workspace_name=get_system_config()['server_name'], access_token=token["access_token"], expires_in=token['expires_in'], refresh_expires_in=token['refresh_expires_in'], refresh_token=token['refresh_token'], token_type=token['token_type'], session_state=token['session_state'], scope=token['scope'], salt=salt, client_key_peer=client_key_peer, iv_parameter=iv_parameter) except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object( Message.REGISTER_CLIENT_SIGNAL_KEY_FAILED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL) async def verify_pincode(self, request, context): try: exists_user = self.service.get_user_by_email(request.user_name) user_info = self.user_service.get_user_by_id(exists_user["id"]) if not user_info: raise Exception(Message.AUTH_USER_NOT_FOUND) password_verifier = bytes.fromhex(user_info.password_verifier) salt = bytes.fromhex(user_info.salt) client_session_key_proof = request.client_session_key_proof client_session_key_proof_bytes = bytes.fromhex( client_session_key_proof) srv = srp.Verifier(username=request.user_name, bytes_s=salt, bytes_v=password_verifier, bytes_A=bytes.fromhex(request.client_public), bytes_b=bytes.fromhex( user_info.srp_server_private)) srv.verify_session(client_session_key_proof_bytes) authenticated = srv.authenticated() if not authenticated: raise Exception(Message.AUTHENTICATION_FAILED) token = self.service.token(request.user_name, user_info.password_verifier) introspect_token = KeyCloakUtils.introspect_token( token['access_token']) if not token: raise Exception(Message.VERIFY_PINCODE_FAILED) client_key_obj = SignalService().peer_get_client_key( introspect_token['sub']) client_key_peer = auth_messages.PeerGetClientKeyResponse( clientId=introspect_token['sub'], workspace_domain=get_owner_workspace_domain(), registrationId=client_key_obj.registration_id, deviceId=client_key_obj.device_id, identityKeyPublic=client_key_obj.identity_key_public, preKeyId=client_key_obj.prekey_id, preKey=client_key_obj.prekey, signedPreKeyId=client_key_obj.signed_prekey_id, signedPreKey=client_key_obj.signed_prekey, signedPreKeySignature=client_key_obj.signed_prekey_signature, identityKeyEncrypted=client_key_obj.identity_key_encrypted) self.user_service.update_last_login( user_id=introspect_token['sub']) return auth_messages.AuthRes( workspace_domain=get_owner_workspace_domain(), workspace_name=get_system_config()['server_name'], access_token=token["access_token"], expires_in=token['expires_in'], refresh_expires_in=token['refresh_expires_in'], refresh_token=token['refresh_token'], token_type=token['token_type'], session_state=token['session_state'], scope=token['scope'], salt=user_info.salt, client_key_peer=client_key_peer, iv_parameter=user_info.iv_parameter) except Exception as e: logger.error(e) if not e.args or e.args[0] not in Message.msg_dict: errors = [ Message.get_error_object(Message.VERIFY_PINCODE_FAILED) ] else: errors = [Message.get_error_object(e.args[0])] context.set_details( json.dumps(errors, default=lambda x: x.__dict__)) context.set_code(grpc.StatusCode.INTERNAL)