mirror of
https://github.com/wassname/flask-security.git
synced 2026-07-11 00:40:08 +08:00
No need to store remember_token in DB
This commit is contained in:
+2
-2
@@ -123,6 +123,7 @@ def create_sqlalchemy_app(auth_config=None, register_blueprint=True):
|
||||
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root@localhost/flask_security_test'
|
||||
|
||||
db = SQLAlchemy(app)
|
||||
app.db = db
|
||||
|
||||
roles_users = db.Table('roles_users',
|
||||
db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
|
||||
@@ -137,7 +138,6 @@ def create_sqlalchemy_app(auth_config=None, register_blueprint=True):
|
||||
id = db.Column(db.Integer, primary_key=True)
|
||||
email = db.Column(db.String(255), unique=True)
|
||||
password = db.Column(db.String(255))
|
||||
remember_token = db.Column(db.String(255))
|
||||
last_login_at = db.Column(db.DateTime())
|
||||
current_login_at = db.Column(db.DateTime())
|
||||
last_login_ip = db.Column(db.String(100))
|
||||
@@ -173,6 +173,7 @@ def create_mongoengine_app(auth_config=None):
|
||||
app.config['MONGODB_PORT'] = 27017
|
||||
|
||||
db = MongoEngine(app)
|
||||
app.db = db
|
||||
|
||||
class Role(db.Document, RoleMixin):
|
||||
name = db.StringField(required=True, unique=True, max_length=80)
|
||||
@@ -181,7 +182,6 @@ def create_mongoengine_app(auth_config=None):
|
||||
class User(db.Document, UserMixin):
|
||||
email = db.StringField(unique=True, max_length=255)
|
||||
password = db.StringField(required=True, max_length=255)
|
||||
remember_token = db.StringField(max_length=255)
|
||||
last_login_at = db.DateTimeField()
|
||||
current_login_at = db.DateTimeField()
|
||||
last_login_ip = db.StringField(max_length=100)
|
||||
|
||||
@@ -73,9 +73,6 @@ def confirm_by_token(token):
|
||||
data = serializer.loads(token, max_age=max_age)
|
||||
user = _datastore.find_user(id=data[0])
|
||||
|
||||
if md5(user.email) != data[1]:
|
||||
raise UserNotFoundError()
|
||||
|
||||
if user.confirmed_at:
|
||||
raise ConfirmationError(get_message('ALREADY_CONFIRMED'))
|
||||
|
||||
@@ -94,9 +91,6 @@ def confirm_by_token(token):
|
||||
except BadSignature:
|
||||
raise ConfirmationError(get_message('INVALID_CONFIRMATION_TOKEN'))
|
||||
|
||||
except UserNotFoundError:
|
||||
raise ConfirmationError(get_message('INVALID_CONFIRMATION_TOKEN'))
|
||||
|
||||
|
||||
def reset_confirmation_token(user):
|
||||
"""Resets the specified user's confirmation token and sends the user
|
||||
|
||||
+14
-15
@@ -21,7 +21,7 @@ from werkzeug.local import LocalProxy
|
||||
|
||||
from . import views, exceptions
|
||||
from .confirmable import requires_confirmation
|
||||
from .utils import config_value as cv, get_config, verify_password
|
||||
from .utils import config_value as cv, get_config, verify_password, md5
|
||||
|
||||
# Convenient references
|
||||
_security = LocalProxy(lambda: current_app.extensions['security'])
|
||||
@@ -62,6 +62,7 @@ _default_config = {
|
||||
'CONFIRM_SALT': 'confirm-salt',
|
||||
'RESET_SALT': 'reset-salt',
|
||||
'AUTH_SALT': 'auth-salt',
|
||||
'REMEMBER_SALT': 'remember-salt',
|
||||
'DEFAULT_HTTP_AUTH_REALM': 'Login Required'
|
||||
}
|
||||
|
||||
@@ -81,17 +82,16 @@ _default_flash_messages = {
|
||||
|
||||
def _user_loader(user_id):
|
||||
try:
|
||||
return _security.datastore.with_id(user_id)
|
||||
except Exception, e:
|
||||
current_app.logger.error('Error getting user: %s' % e)
|
||||
return _security.datastore.find_user(id=user_id)
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
def _token_loader(token):
|
||||
try:
|
||||
return _security.datastore.find_user(remember_token=token)
|
||||
except Exception, e:
|
||||
current_app.logger.error('Error getting user: %s' % e)
|
||||
data = _security.remember_token_serializer.loads(token)
|
||||
return _security.datastore.find_user(email=md5(data[0]))
|
||||
except:
|
||||
return None
|
||||
|
||||
|
||||
@@ -137,6 +137,10 @@ def _get_serializer(app, salt):
|
||||
return URLSafeTimedSerializer(secret_key=secret_key, salt=salt)
|
||||
|
||||
|
||||
def _get_remember_token_serializer(app):
|
||||
return _get_serializer(app, app.config['SECURITY_REMEMBER_SALT'])
|
||||
|
||||
|
||||
def _get_reset_serializer(app):
|
||||
return _get_serializer(app, app.config['SECURITY_RESET_SALT'])
|
||||
|
||||
@@ -157,9 +161,6 @@ class RoleMixin(object):
|
||||
def __ne__(self, other):
|
||||
return self.name != other and self.name != getattr(other, 'name', None)
|
||||
|
||||
def __str__(self):
|
||||
return '<Role name=%s>' % self.name
|
||||
|
||||
|
||||
class UserMixin(BaseUserMixin):
|
||||
"""Mixin for `User` model definitions"""
|
||||
@@ -170,7 +171,8 @@ class UserMixin(BaseUserMixin):
|
||||
|
||||
def get_auth_token(self):
|
||||
"""Returns the user's authentication token."""
|
||||
self.remember_token
|
||||
data = [md5(self.email), self.password]
|
||||
return _security.remember_token_serializer.dumps(data)
|
||||
|
||||
def has_role(self, role):
|
||||
"""Returns `True` if the user identifies with the specified role.
|
||||
@@ -178,10 +180,6 @@ class UserMixin(BaseUserMixin):
|
||||
:param role: A role name or `Role` instance"""
|
||||
return role in self.roles
|
||||
|
||||
def __str__(self):
|
||||
ctx = (str(self.id), self.email)
|
||||
return '<User id=%s, email=%s>' % ctx
|
||||
|
||||
|
||||
class AnonymousUser(AnonymousUserBase):
|
||||
"""AnonymousUser definition"""
|
||||
@@ -262,6 +260,7 @@ class Security(object):
|
||||
('login_manager', _get_login_manager(app)),
|
||||
('principal', _get_principal(app)),
|
||||
('pwd_context', _get_pwd_context(app)),
|
||||
('remember_token_serializer', _get_remember_token_serializer(app)),
|
||||
('token_auth_serializer', _get_token_auth_serializer(app))]:
|
||||
kwargs[key] = value
|
||||
|
||||
|
||||
@@ -37,6 +37,10 @@ class UserDatastore(object):
|
||||
raise NotImplementedError(
|
||||
"User datastore does not implement _save_model method")
|
||||
|
||||
def _delete_model(self, model):
|
||||
raise NotImplementedError(
|
||||
"User datastore does not implement _delete_model method")
|
||||
|
||||
def _do_with_id(self, id):
|
||||
raise NotImplementedError(
|
||||
"User datastore does not implement _do_with_id method")
|
||||
@@ -118,9 +122,6 @@ class UserDatastore(object):
|
||||
use_hmac=_security.password_hmac)
|
||||
kwargs['password'] = pwd_hash
|
||||
|
||||
kwargs['remember_token'] = utils.get_remember_token(kwargs['email'],
|
||||
kwargs['password'])
|
||||
|
||||
return kwargs
|
||||
|
||||
def with_id(self, id):
|
||||
@@ -170,6 +171,13 @@ class UserDatastore(object):
|
||||
user = self.user_model(**self._prepare_create_user_args(kwargs))
|
||||
return self._save_model(user)
|
||||
|
||||
def delete_user(self, user):
|
||||
"""Delete the specified user
|
||||
|
||||
:param user: The user to delete_user
|
||||
"""
|
||||
self._delete_model(user)
|
||||
|
||||
def add_role_to_user(self, user, role):
|
||||
"""Adds a role to a user if the user does not have it already. Returns
|
||||
the modified user.
|
||||
@@ -248,6 +256,10 @@ class SQLAlchemyUserDatastore(UserDatastore):
|
||||
self.db.session.commit()
|
||||
return model
|
||||
|
||||
def _delete_model(self, model):
|
||||
self.db.session.delete(model)
|
||||
self.db.session.commit()
|
||||
|
||||
def _do_with_id(self, id):
|
||||
return self.user_model.query.get(id)
|
||||
|
||||
@@ -292,6 +304,9 @@ class MongoEngineUserDatastore(UserDatastore):
|
||||
model.save()
|
||||
return model
|
||||
|
||||
def _delete_model(self, model):
|
||||
model.delete()
|
||||
|
||||
def _do_with_id(self, id):
|
||||
try:
|
||||
return self.user_model.objects.get(id=id)
|
||||
|
||||
@@ -44,9 +44,6 @@ def login_user(user, remember=True):
|
||||
if user.authentication_token is None:
|
||||
user.authentication_token = generate_authentication_token(user)
|
||||
|
||||
if remember:
|
||||
user.remember_token = get_remember_token(user.email, user.password)
|
||||
|
||||
if _security.trackable:
|
||||
old_current, new_current = user.current_login_at, datetime.utcnow()
|
||||
user.last_login_at = old_current or new_current
|
||||
@@ -110,12 +107,6 @@ def generate_token():
|
||||
return base64.urlsafe_b64encode(os.urandom(30))
|
||||
|
||||
|
||||
def get_remember_token(email, password):
|
||||
assert email is not None
|
||||
assert password is not None
|
||||
return make_secure_token(email, password)
|
||||
|
||||
|
||||
def do_flash(message, category=None):
|
||||
"""Flash a message depending on if the `FLASH_MESSAGES` configuration
|
||||
value is set.
|
||||
|
||||
Reference in New Issue
Block a user