def post(self): args = self.get_arguments() token = uuid.uuid4() try: user = persons_service.get_person_by_email(args["email"]) except PersonNotFoundException: return { "error": True, "message": "Email not listed in database." }, 400 auth_tokens_store.add("reset-%s" % token, args["email"], ttl=3600 * 2) message_text = """Hello %s, You have requested for a password reset. You can connect here to change your password: https://%s/reset-change-password/%s Regards, CGWire Team """ % (user["first_name"], current_app.config["DOMAIN_NAME"], token) if current_app.config["MAIL_DEBUG"]: print(message_text) else: message = Message(body=message_text, subject="CGWire password recovery", recipients=[args["email"]]) mail.send(message) return {"success": "Reset token sent"}
def register_tokens(app, access_token, refresh_token=None): access_jti = get_jti(encoded_token=access_token) auth_tokens_store.add(access_jti, 'false', app.config["JWT_ACCESS_TOKEN_EXPIRES"]) if refresh_token is not None: refresh_jti = get_jti(encoded_token=refresh_token) auth_tokens_store.add(refresh_jti, 'false', app.config["JWT_REFRESH_TOKEN_EXPIRES"])
def register_tokens(app, access_token, refresh_token=None): """ Register access and refresh tokens to auth token store. That way they can be used like a session. """ access_jti = get_jti(encoded_token=access_token) auth_tokens_store.add(access_jti, 'false', app.config["JWT_ACCESS_TOKEN_EXPIRES"]) if refresh_token is not None: refresh_jti = get_jti(encoded_token=refresh_token) auth_tokens_store.add(refresh_jti, 'false', app.config["JWT_REFRESH_TOKEN_EXPIRES"])
def test_reset_password(self): email = self.user["email"] self.assertIsNotAuthenticated({}, code=422) data = {"email": "*****@*****.**"} self.post("auth/reset-password", data, 400) data = {"email": email} response = self.post("auth/reset-password", data, 200) self.assertTrue(response["success"]) token = "token-test" new_password = "******" auth_tokens_store.add("reset-%s" % token, email) data = { "token": token, "password": new_password, "password2": new_password, } response = self.put("auth/reset-password", data, 200) self.assertTrue(response["success"]) self.post("auth/login", {"email": email, "password": new_password}, 200)
def post(self): (email, password) = self.get_arguments() try: user = auth_service.check_auth(app, email, password) del user["password"] if auth_service.is_default_password(app, password): token = uuid.uuid4() auth_tokens_store.add("reset-%s" % token, email, ttl=3600 * 2) current_app.logger.info("User must change his password.") return ( { "login": False, "default_password": True, "token": str(token), }, 400, ) access_token = create_access_token(identity=user["email"]) refresh_token = create_refresh_token(identity=user["email"]) auth_service.register_tokens(app, access_token, refresh_token) identity_changed.send(current_app._get_current_object(), identity=Identity(user["id"])) ip_address = request.environ.get("HTTP_X_REAL_IP", request.remote_addr) if is_from_browser(request.user_agent): organisation = persons_service.get_organisation() response = jsonify({ "user": user, "organisation": organisation, "ldap": app.config["AUTH_STRATEGY"] == "auth_remote_ldap", "login": True, }) set_access_cookies(response, access_token) set_refresh_cookies(response, refresh_token) events_service.create_login_log(user["id"], ip_address, "web") else: events_service.create_login_log(user["id"], ip_address, "script") response = { "login": True, "user": user, "ldap": app.config["AUTH_STRATEGY"] == "auth_remote_ldap", "access_token": access_token, "refresh_token": refresh_token, } return response except PersonNotFoundException: current_app.logger.info("User is not registered.") return {"login": False}, 400 except WrongUserException: current_app.logger.info("User is not registered.") return {"login": False}, 400 except WrongPasswordException: current_app.logger.info("User gave a wrong password.") return {"login": False}, 400 except NoAuthStrategyConfigured: current_app.logger.info( "Authentication strategy is not properly configured.") return {"login": False}, 400 except TimeoutError: current_app.logger.info("Timeout occurs while logging in.") return {"login": False}, 400 except UnactiveUserException: return ( { "error": True, "login": False, "message": "User is unactive, he cannot log in.", }, 400, ) except OperationalError as exception: current_app.logger.error(exception, exc_info=1) return ( { "error": True, "login": False, "message": "Database doesn't seem reachable.", }, 500, ) except Exception as exception: current_app.logger.error(exception, exc_info=1) if hasattr(exception, "message"): message = exception.message else: message = str(exception) return {"error": True, "login": False, "message": message}, 500
def revoke_tokens(app, jti): """ Remove access and refresh tokens from auth token store. """ auth_tokens_store.add(jti, 'true', app.config["JWT_ACCESS_TOKEN_EXPIRES"])
def post(self): """ Ressource to allow a user to change his password when he forgets it. --- description: "It uses a classic scheme: a token is sent by email to the user. Then he can change his password." tags: - Authentification parameters: - in: body name: Email description: The email of the user schema: type: object required: - email properties: email: type: string responses: 200: description: Reset token sent 400: description: Email not listed in database """ args = self.get_arguments() try: user = persons_service.get_person_by_email(args["email"]) except PersonNotFoundException: return ( { "error": True, "message": "Email not listed in database." }, 400, ) token = uuid.uuid4() auth_tokens_store.add("reset-%s" % token, args["email"], ttl=3600 * 2) message_text = """Hello %s, You have requested for a password reset. You can connect here to change your password: %s://%s/reset-change-password/%s Regards, CGWire Team """ % ( user["first_name"], current_app.config["DOMAIN_PROTOCOL"], current_app.config["DOMAIN_NAME"], token, ) if current_app.config["MAIL_DEBUG"]: print(message_text) else: message = Message( body=message_text, subject="CGWire password recovery", recipients=[args["email"]], ) mail.send(message) return {"success": "Reset token sent"}
def post(self): """ Log in user by creating and registering auth tokens. --- description: Login is based on email and password. If no user match given email and a destkop ID, it looks in matching the desktop ID with the one stored in database. It is useful for clients that run on desktop tools and that don't know user email. tags: - Authentification parameters: - in: body name: Credentials description: The email and password of the user schema: type: object required: - email - password properties: email: type: string password: type: string responses: 200: description: Login successful 400: description: Login failed 500: description: Database not reachable """ (email, password) = self.get_arguments() try: user = auth_service.check_auth(app, email, password) if "password" in user: del user["password"] if auth_service.is_default_password(app, password): token = uuid.uuid4() auth_tokens_store.add("reset-%s" % token, email, ttl=3600 * 2) current_app.logger.info("User must change his password.") return ( { "login": False, "default_password": True, "token": str(token), }, 400, ) access_token = create_access_token(identity=user["email"]) refresh_token = create_refresh_token(identity=user["email"]) auth_service.register_tokens(app, access_token, refresh_token) identity_changed.send( current_app._get_current_object(), identity=Identity(user["id"]), ) ip_address = request.environ.get("HTTP_X_REAL_IP", request.remote_addr) if is_from_browser(request.user_agent): organisation = persons_service.get_organisation() response = jsonify({ "user": user, "organisation": organisation, "ldap": app.config["AUTH_STRATEGY"] == "auth_remote_ldap", "login": True, }) set_access_cookies(response, access_token) set_refresh_cookies(response, refresh_token) events_service.create_login_log(user["id"], ip_address, "web") else: events_service.create_login_log(user["id"], ip_address, "script") response = { "login": True, "user": user, "ldap": app.config["AUTH_STRATEGY"] == "auth_remote_ldap", "access_token": access_token, "refresh_token": refresh_token, } return response except PersonNotFoundException: current_app.logger.info("User is not registered.") return {"login": False}, 400 except WrongUserException: current_app.logger.info("User is not registered.") return {"login": False}, 400 except WrongPasswordException: current_app.logger.info("User gave a wrong password.") return {"login": False}, 400 except NoAuthStrategyConfigured: current_app.logger.info( "Authentication strategy is not properly configured.") return {"login": False}, 400 except TimeoutError: current_app.logger.info("Timeout occurs while logging in.") return {"login": False}, 400 except UnactiveUserException: return ( { "error": True, "login": False, "message": "User is inactive, he cannot log in.", }, 400, ) except OperationalError as exception: current_app.logger.error(exception, exc_info=1) return ( { "error": True, "login": False, "message": "Database doesn't seem reachable.", }, 500, ) except Exception as exception: current_app.logger.error(exception, exc_info=1) if hasattr(exception, "message"): message = exception.message else: message = str(exception) return {"error": True, "login": False, "message": message}, 500
def revoke_tokens(app, jti): auth_tokens_store.add(jti, 'true', app.config["JWT_ACCESS_TOKEN_EXPIRES"])