def authenticate(self, username, password): """ Verifies that a password matches the stored password for that username. If verification passes, the matching user instance is returned """ PraetorianError.require_condition( self.user_class is not None, "Praetorian must be initialized before this method is available", ) user = self.user_class.lookup(username) MissingUserError.require_condition( user is not None, 'Could not find the requested user', ) AuthenticationError.require_condition( self._verify_password(password, user.password), 'The password is incorrect', ) """ If we are set to PRAETORIAN_HASH_AUTOUPDATE then check our hash and if needed, update the user. The developer is responsible for using the returned user object and updating the data storage endpoint. Else, if we are set to PRAETORIAN_HASH_AUTOTEST then check out hash and return exception if our hash is using the wrong scheme, but don't modify the user. """ if self.hash_autoupdate: self.verify_and_update(user=user, password=password) elif self.hash_autotest: self.verify_and_update(user=user) return user
def authenticate(self, username, password): """ Verifies that a password matches the stored password for that username. If verification passes, the matching user instance is returned """ PraetorianError.require_condition( self.user_class is not None, "Praetorian must be initialized before this method is available", ) user = self.user_class.lookup(username) MissingUserError.require_condition( user is not None, 'Could not find the requested user', ) AuthenticationError.require_condition( self._verify_password(password, user.password), 'The password is incorrect', ) return user
def _check_user(self, user): """ Checks to make sure that a user is valid. First, checks that the user is not None. If this check fails, a MissingUserError is raised. Next, checks if the user has a validation method. If the method does not exist, the check passes. If the method exists, it is called. If the result of the call is not truthy, an InvalidUserError is raised """ MissingUserError.require_condition( user is not None, 'Could not find the requested user', ) user_validate_method = getattr(user, self.user_class_validation_method, None) if user_validate_method is None: return InvalidUserError.require_condition( user_validate_method(), "The user is not valid or has had access revoked", )
def send_reset_email(self, email, template=None, reset_sender=None, reset_uri=None, subject=None, override_access_lifespan=None): """ Sends a password reset email to a user, containing a time expiring token usable for validation. This requires your application is initialized with a `mail` extension, which supports Flask-Mail's `Message()` object and a `send()` method. Returns a dict containing the information sent, along with the `result` from mail send. :param: email: The email address to attempt to send to :param: template: HTML Template for reset email. If not provided, a stock entry is used :param: confirmation_sender: The sender that shoudl be attached to the reset email. Overrides the PRAETORIAN_RESET_SENDER config setting :param: confirmation_uri: The uri that should be visited to complete password reset. Should usually be a uri to a frontend or external service that calls the 'validate_reset_token()' method in the api to complete reset. Will override the PRAETORIAN_RESET_URI config setting :param: subject: The reset email subject. Will override the PRAETORIAN_RESET_SUBJECT config setting. :param: override_access_lifespan: Overrides the JWT_ACCESS_LIFESPAN to set an access lifespan for the registration token. """ if subject is None: subject = self.reset_subject if reset_uri is None: reset_uri = self.reset_uri sender = reset_sender or self.reset_sender user = self.user_class.lookup(email) MissingUserError.require_condition( user is not None, 'Could not find the requested user', ) flask.current_app.logger.debug( "Generating token with lifespan: {}".format( override_access_lifespan)) custom_token = self.encode_jwt_token( user, override_access_lifespan=override_access_lifespan, bypass_user_check=False, is_reset_token=True, ) return self.send_token_email(user.email, user, template, reset_sender, reset_uri, subject, custom_token=custom_token, sender=sender)