def hexadecimal_token_validation( cls, user_id, auth_token: str, exchange_method: ExchangeMethods = None) -> bool: session = cls._Session() token = None if exchange_method: token = session.query(Token).filter_by( user_id=user_id, exchange_method=exchange_method.value).order_by( desc(Token.requested_time)).first() else: token = session.query(Token).filter_by(user_id=user_id).order_by( desc(Token.requested_time)).first() if not token: raise SecurityException('User has no token!') if token.deactivate: raise SecurityException('Token is Deactivated!') if datetime.utcnow() > token.time_limit: raise TimeoutException('Token is Expired!') if secrets.compare_digest(token.hex_token, auth_token): token.last_used_time = datetime.utcnow() session.commit() return token.exchange_method token.failed_attempts += 1 if token.failed_attempts > 3: token.deactivate = True session.commit() if token.deactivate: raise SecurityException('Token is Deactivated!') raise AuthenticationException('Token is not valid!')
def url_token_validation(cls, url_token: str) -> (): session = cls._Session() tk = session.query(Token).filter_by(url_token=url_token).first() if not tk: raise AuthenticationException('Url Token is not valid!') if tk.deactivate: raise SecurityException('Token is Deactivated!') if datetime.utcnow() > tk.time_limit: raise TimeoutException('Token is Expired!') tk.last_used_time = datetime.utcnow() return tk.user.uid, tk.exchange_method
def change_password_by_hex_token(cls, user_id, hex_token, new_password): if not passwordservice.password_validation(new_password): raise ValueException("Password is not valid!") if cls._hex_token_verification(user_id, hex_token): session = cls._Session() user = session.query(User).get(user_id) user.password = cls._password_service.hashing_password( new_password) session.commit() return True raise SecurityException("Token is not valid!")
def change_password(cls, user_id, old_password, new_password): session = cls._Session() user = session.query(User).get(user_id) if not user: raise SecurityException("User doesn't exist!") if not cls._password_service.password_verification( user.password, old_password): raise AuthenticationException("Wrong Password!") if not cls._password_service.password_validation(new_password): raise ValueException("Entered password is not valid!") pss = cls._password_service.hashing_password(new_password) user.password = pss session.commit() return True
def become_user(login_name, authenticator_key=None): """Changes current user to the user specified by `login_name` and returns the user object. If there are multiple results for a `login_name`, an authenticator_key must be given. Can only be called when the current user is admin. """ if not current_user.is_admin: raise SecurityException( "becoming other users not allowed for non-admin users") candidate_users = q(User).filter_by(login_name=login_name).all() if not candidate_users: raise ValueError("unknown user login name " + login_name) if len(candidate_users) == 1: user = candidate_users[0] else: # multiple candidates if not authenticator_key: raise ValueError( "no authenticator_key given, but multiple users found for login name" + login_name) parts = authenticator_key.split(":") if len(parts) != 2: raise ValueError("invalid authenticator key " + authenticator_key) authenticator_type, authenticator_name = parts authenticator_info = q(AuthenticatorInfo).filter_by( type=authenticator_type, name=authenticator_name).scalar() if authenticator_info is None: raise ValueError("cannot find authenticator key" + authenticator_key) user = filter_scalar( lambda u: u.authenticator_id == authenticator_info.id) if user is None: return request.session["user_id"] = user.id return user
def generate_token(cls, user_id: int, via: ExchangeMethods) -> bool: u = cls._get_user(user_id) if not u: raise SecurityException(f"User doesn't exist! user_id: {user_id}") if via == ExchangeMethods.PHONE and not u.phone: raise InnerException('User phone is not registered') if via == ExchangeMethods.EMAIL and not u.email: raise InnerException('User email is not registered') session = cls._Session() last_token = session.query(Token).filter_by(user_id=user_id).order_by( desc(Token.requested_time)).first() if last_token and not last_token.deactivate and last_token.exchange_method == via.value \ and datetime.utcnow() < last_token.time_limit: raise InnerException('A valid token already issued!') token = Token(user_id=u.uid, requested_time=datetime.utcnow()) token.hex_token = secrets.token_hex(2) token.url_token = secrets.token_urlsafe() token.exchange_method = via.value session.add(token) session.commit() # Todo: ******* send the token to the service provider (MailService|SMSService) ******** return True