From deaf64d3621285382621f4579db30e79f43651cb Mon Sep 17 00:00:00 2001 From: Pjotr Prins Date: Mon, 26 Mar 2018 10:14:41 +0000 Subject: Remove flask_security module - not used --- wqflask/flask_security/__init__.py | 25 -- wqflask/flask_security/changeable.py | 45 --- wqflask/flask_security/confirmable.py | 83 ----- wqflask/flask_security/core.py | 382 --------------------- wqflask/flask_security/datastore.py | 261 -------------- wqflask/flask_security/decorators.py | 207 ----------- wqflask/flask_security/forms.py | 286 --------------- wqflask/flask_security/passwordless.py | 59 ---- wqflask/flask_security/recoverable.py | 80 ----- wqflask/flask_security/registerable.py | 44 --- wqflask/flask_security/script.py | 130 ------- wqflask/flask_security/signals.py | 29 -- wqflask/flask_security/templates/.DS_Store | Bin 6148 -> 0 bytes .../flask_security/templates/security/.DS_Store | Bin 6148 -> 0 bytes .../flask_security/templates/security/_macros.html | 16 - .../flask_security/templates/security/_menu.html | 15 - .../templates/security/_messages.html | 9 - .../templates/security/change_password.html | 11 - .../templates/security/email/change_notice.html | 4 - .../templates/security/email/change_notice.txt | 5 - .../security/email/confirmation_instructions.html | 3 - .../security/email/confirmation_instructions.txt | 3 - .../security/email/login_instructions.html | 5 - .../security/email/login_instructions.txt | 5 - .../security/email/reset_instructions.html | 1 - .../security/email/reset_instructions.txt | 3 - .../templates/security/email/reset_notice.html | 1 - .../templates/security/email/reset_notice.txt | 1 - .../templates/security/email/welcome.html | 7 - .../templates/security/email/welcome.txt | 7 - .../templates/security/forgot_password.html | 9 - .../templates/security/login_user.html | 12 - .../templates/security/register_user.html | 13 - .../templates/security/reset_password.html | 10 - .../templates/security/send_confirmation.html | 9 - .../templates/security/send_login.html | 9 - wqflask/flask_security/utils.py | 379 -------------------- wqflask/flask_security/views.py | 359 ------------------- 38 files changed, 2527 deletions(-) delete mode 100644 wqflask/flask_security/__init__.py delete mode 100644 wqflask/flask_security/changeable.py delete mode 100644 wqflask/flask_security/confirmable.py delete mode 100644 wqflask/flask_security/core.py delete mode 100644 wqflask/flask_security/datastore.py delete mode 100644 wqflask/flask_security/decorators.py delete mode 100644 wqflask/flask_security/forms.py delete mode 100644 wqflask/flask_security/passwordless.py delete mode 100644 wqflask/flask_security/recoverable.py delete mode 100644 wqflask/flask_security/registerable.py delete mode 100644 wqflask/flask_security/script.py delete mode 100644 wqflask/flask_security/signals.py delete mode 100644 wqflask/flask_security/templates/.DS_Store delete mode 100644 wqflask/flask_security/templates/security/.DS_Store delete mode 100644 wqflask/flask_security/templates/security/_macros.html delete mode 100644 wqflask/flask_security/templates/security/_menu.html delete mode 100644 wqflask/flask_security/templates/security/_messages.html delete mode 100644 wqflask/flask_security/templates/security/change_password.html delete mode 100644 wqflask/flask_security/templates/security/email/change_notice.html delete mode 100644 wqflask/flask_security/templates/security/email/change_notice.txt delete mode 100644 wqflask/flask_security/templates/security/email/confirmation_instructions.html delete mode 100644 wqflask/flask_security/templates/security/email/confirmation_instructions.txt delete mode 100644 wqflask/flask_security/templates/security/email/login_instructions.html delete mode 100644 wqflask/flask_security/templates/security/email/login_instructions.txt delete mode 100644 wqflask/flask_security/templates/security/email/reset_instructions.html delete mode 100644 wqflask/flask_security/templates/security/email/reset_instructions.txt delete mode 100644 wqflask/flask_security/templates/security/email/reset_notice.html delete mode 100644 wqflask/flask_security/templates/security/email/reset_notice.txt delete mode 100644 wqflask/flask_security/templates/security/email/welcome.html delete mode 100644 wqflask/flask_security/templates/security/email/welcome.txt delete mode 100644 wqflask/flask_security/templates/security/forgot_password.html delete mode 100644 wqflask/flask_security/templates/security/login_user.html delete mode 100644 wqflask/flask_security/templates/security/register_user.html delete mode 100644 wqflask/flask_security/templates/security/reset_password.html delete mode 100644 wqflask/flask_security/templates/security/send_confirmation.html delete mode 100644 wqflask/flask_security/templates/security/send_login.html delete mode 100644 wqflask/flask_security/utils.py delete mode 100644 wqflask/flask_security/views.py diff --git a/wqflask/flask_security/__init__.py b/wqflask/flask_security/__init__.py deleted file mode 100644 index 81e6c89e..00000000 --- a/wqflask/flask_security/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask.ext.security - ~~~~~~~~~~~~~~~~~~ - - Flask-Security is a Flask extension that aims to add quick and simple - security via Flask-Login, Flask-Principal, Flask-WTF, and passlib. - - :copyright: (c) 2012 by Matt Wright. - :license: MIT, see LICENSE for more details. -""" - -__version__ = '1.6.0' - -from .core import Security, RoleMixin, UserMixin, AnonymousUser, current_user -from .datastore import SQLAlchemyUserDatastore, MongoEngineUserDatastore, PeeweeUserDatastore -from .decorators import auth_token_required, http_auth_required, \ - login_required, roles_accepted, roles_required -from .forms import ForgotPasswordForm, LoginForm, RegisterForm, \ - ResetPasswordForm, PasswordlessLoginForm, ConfirmRegisterForm -from .signals import confirm_instructions_sent, password_reset, \ - reset_password_instructions_sent, user_confirmed, user_registered -from .utils import login_user, logout_user, url_for_security - -print "Using our own flask.ext.security" \ No newline at end of file diff --git a/wqflask/flask_security/changeable.py b/wqflask/flask_security/changeable.py deleted file mode 100644 index 4447b655..00000000 --- a/wqflask/flask_security/changeable.py +++ /dev/null @@ -1,45 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask.ext.security.changeable - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Flask-Security recoverable module - - :copyright: (c) 2012 by Matt Wright. - :author: Eskil Heyn Olsen - :license: MIT, see LICENSE for more details. -""" - -from flask import current_app as app, request -from werkzeug.local import LocalProxy - -from .signals import password_changed -from .utils import send_mail, encrypt_password, url_for_security, \ - config_value - - -# Convenient references -_security = LocalProxy(lambda: app.extensions['security']) - -_datastore = LocalProxy(lambda: _security.datastore) - - -def send_password_changed_notice(user): - """Sends the password changed notice email for the specified user. - - :param user: The user to send the notice to - """ - send_mail(config_value('EMAIL_SUBJECT_PASSWORD_CHANGE_NOTICE'), user.email, - 'change_notice', user=user) - - -def change_user_password(user, password): - """Change the specified user's password - - :param user: The user to change_password - :param password: The unencrypted new password - """ - user.password = encrypt_password(password) - _datastore.put(user) - send_password_changed_notice(user) - password_changed.send(user, app=app._get_current_object()) diff --git a/wqflask/flask_security/confirmable.py b/wqflask/flask_security/confirmable.py deleted file mode 100644 index a7caf6cd..00000000 --- a/wqflask/flask_security/confirmable.py +++ /dev/null @@ -1,83 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask.ext.security.confirmable - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Flask-Security confirmable module - - :copyright: (c) 2012 by Matt Wright. - :license: MIT, see LICENSE for more details. -""" - -from datetime import datetime - -from flask import current_app as app, request -from werkzeug.local import LocalProxy - -from .utils import send_mail, md5, url_for_security, get_token_status,\ - config_value -from .signals import user_confirmed, confirm_instructions_sent - - -# Convenient references -_security = LocalProxy(lambda: app.extensions['security']) - -_datastore = LocalProxy(lambda: _security.datastore) - - -def generate_confirmation_link(user): - token = generate_confirmation_token(user) - url = url_for_security('confirm_email', token=token) - return request.url_root[:-1] + url, token - - -def send_confirmation_instructions(user): - """Sends the confirmation instructions email for the specified user. - - :param user: The user to send the instructions to - :param token: The confirmation token - """ - - confirmation_link, token = generate_confirmation_link(user) - - send_mail(config_value('EMAIL_SUBJECT_CONFIRM'), user.email, - 'confirmation_instructions', user=user, - confirmation_link=confirmation_link) - - confirm_instructions_sent.send(user, app=app._get_current_object()) - return token - - -def generate_confirmation_token(user): - """Generates a unique confirmation token for the specified user. - - :param user: The user to work with - """ - data = [str(user.id), md5(user.email)] - return _security.confirm_serializer.dumps(data) - - -def requires_confirmation(user): - """Returns `True` if the user requires confirmation.""" - return _security.confirmable and user.confirmed_at == None - - -def confirm_email_token_status(token): - """Returns the expired status, invalid status, and user of a confirmation - token. For example:: - - expired, invalid, user = confirm_email_token_status('...') - - :param token: The confirmation token - """ - return get_token_status(token, 'confirm', 'CONFIRM_EMAIL') - - -def confirm_user(user): - """Confirms the specified user - - :param user: The user to confirm - """ - user.confirmed_at = datetime.utcnow() - _datastore.put(user) - user_confirmed.send(user, app=app._get_current_object()) diff --git a/wqflask/flask_security/core.py b/wqflask/flask_security/core.py deleted file mode 100644 index 0f3a231f..00000000 --- a/wqflask/flask_security/core.py +++ /dev/null @@ -1,382 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask.ext.security.core - ~~~~~~~~~~~~~~~~~~~~~~~ - - Flask-Security core module - - :copyright: (c) 2012 by Matt Wright. - :license: MIT, see LICENSE for more details. -""" - -from flask import current_app -from flask.ext.login import AnonymousUser as AnonymousUserBase, \ - UserMixin as BaseUserMixin, LoginManager, current_user -from flask.ext.principal import Principal, RoleNeed, UserNeed, Identity, \ - identity_loaded -from itsdangerous import URLSafeTimedSerializer -from passlib.context import CryptContext -from werkzeug.datastructures import ImmutableList -from werkzeug.local import LocalProxy - -from .utils import config_value as cv, get_config, md5, url_for_security -from .views import create_blueprint -from .forms import LoginForm, ConfirmRegisterForm, RegisterForm, \ - ForgotPasswordForm, ChangePasswordForm, ResetPasswordForm, \ - SendConfirmationForm, PasswordlessLoginForm - -# Convenient references -_security = LocalProxy(lambda: current_app.extensions['security']) - - -#: Default Flask-Security configuration -_default_config = { - 'BLUEPRINT_NAME': 'security', - 'URL_PREFIX': None, - 'SUBDOMAIN': None, - 'FLASH_MESSAGES': True, - 'PASSWORD_HASH': 'plaintext', - 'PASSWORD_SALT': None, - 'LOGIN_URL': '/login', - 'LOGOUT_URL': '/logout', - 'REGISTER_URL': '/register', - 'RESET_URL': '/reset', - 'CHANGE_URL': '/change', - 'CONFIRM_URL': '/confirm', - 'POST_LOGIN_VIEW': '/', - 'POST_LOGOUT_VIEW': '/', - 'CONFIRM_ERROR_VIEW': None, - 'POST_REGISTER_VIEW': None, - 'POST_CONFIRM_VIEW': None, - 'POST_RESET_VIEW': None, - 'POST_CHANGE_VIEW': None, - 'UNAUTHORIZED_VIEW': None, - 'FORGOT_PASSWORD_TEMPLATE': 'security/forgot_password.html', - 'LOGIN_USER_TEMPLATE': 'security/login_user.html', - 'REGISTER_USER_TEMPLATE': 'security/register_user.html', - 'RESET_PASSWORD_TEMPLATE': 'security/reset_password.html', - 'SEND_CONFIRMATION_TEMPLATE': 'security/send_confirmation.html', - 'SEND_LOGIN_TEMPLATE': 'security/send_login.html', - 'CONFIRMABLE': False, - 'REGISTERABLE': False, - 'RECOVERABLE': False, - 'TRACKABLE': False, - 'PASSWORDLESS': False, - 'CHANGEABLE': False, - 'SEND_REGISTER_EMAIL': True, - 'LOGIN_WITHIN': '1 days', - 'CONFIRM_EMAIL_WITHIN': '5 days', - 'RESET_PASSWORD_WITHIN': '5 days', - 'LOGIN_WITHOUT_CONFIRMATION': False, - 'EMAIL_SENDER': 'no-reply@localhost', - 'TOKEN_AUTHENTICATION_KEY': 'auth_token', - 'TOKEN_AUTHENTICATION_HEADER': 'Authentication-Token', - 'CONFIRM_SALT': 'confirm-salt', - 'RESET_SALT': 'reset-salt', - 'LOGIN_SALT': 'login-salt', - 'CHANGE_SALT': 'change-salt', - 'REMEMBER_SALT': 'remember-salt', - 'DEFAULT_HTTP_AUTH_REALM': 'Login Required', - 'EMAIL_SUBJECT_REGISTER': 'Welcome', - 'EMAIL_SUBJECT_CONFIRM': 'Please confirm your email', - 'EMAIL_SUBJECT_PASSWORDLESS': 'Login instructions', - 'EMAIL_SUBJECT_PASSWORD_NOTICE': 'Your password has been reset', - 'EMAIL_SUBJECT_PASSWORD_CHANGE_NOTICE': 'Your password has been changed', - 'EMAIL_SUBJECT_PASSWORD_RESET': 'Password reset instructions' -} - -#: Default Flask-Security messages -_default_messages = { - 'UNAUTHORIZED': ('You do not have permission to view this resource.', 'error'), - 'CONFIRM_REGISTRATION': ('Thank you. Confirmation instructions have been sent to %(email)s.', 'success'), - 'EMAIL_CONFIRMED': ('Thank you. Your email has been confirmed.', 'success'), - 'ALREADY_CONFIRMED': ('Your email has already been confirmed.', 'info'), - 'INVALID_CONFIRMATION_TOKEN': ('Invalid confirmation token.', 'error'), - 'EMAIL_ALREADY_ASSOCIATED': ('%(email)s is already associated with an account.', 'error'), - 'PASSWORD_MISMATCH': ('Password does not match', 'error'), - 'RETYPE_PASSWORD_MISMATCH': ('Passwords do not match', 'error'), - 'INVALID_REDIRECT': ('Redirections outside the domain are forbidden', 'error'), - 'PASSWORD_RESET_REQUEST': ('Instructions to reset your password have been sent to %(email)s.', 'info'), - 'PASSWORD_RESET_EXPIRED': ('You did not reset your password within %(within)s. New instructions have been sent to %(email)s.', 'error'), - 'INVALID_RESET_PASSWORD_TOKEN': ('Invalid reset password token.', 'error'), - 'CONFIRMATION_REQUIRED': ('Email requires confirmation.', 'error'), - 'CONFIRMATION_REQUEST': ('Confirmation instructions have been sent to %(email)s.', 'info'), - 'CONFIRMATION_EXPIRED': ('You did not confirm your email within %(within)s. New instructions to confirm your email have been sent to %(email)s.', 'error'), - 'LOGIN_EXPIRED': ('You did not login within %(within)s. New instructions to login have been sent to %(email)s.', 'error'), - 'LOGIN_EMAIL_SENT': ('Instructions to login have been sent to %(email)s.', 'success'), - 'INVALID_LOGIN_TOKEN': ('Invalid login token.', 'error'), - 'DISABLED_ACCOUNT': ('Account is disabled.', 'error'), - 'EMAIL_NOT_PROVIDED': ('Email not provided', 'error'), - 'INVALID_EMAIL_ADDRESS': ('Invalid email address', 'error'), - 'PASSWORD_NOT_PROVIDED': ('Password not provided', 'error'), - 'USER_DOES_NOT_EXIST': ('Specified user does not exist', 'error'), - 'INVALID_PASSWORD': ('Invalid password', 'error'), - 'PASSWORDLESS_LOGIN_SUCCESSFUL': ('You have successfuly logged in.', 'success'), - 'PASSWORD_RESET': ('You successfully reset your password and you have been logged in automatically.', 'success'), - 'PASSWORD_CHANGE': ('You successfully changed your password.', 'success'), - 'LOGIN': ('Please log in to access this page.', 'info'), - 'REFRESH': ('Please reauthenticate to access this page.', 'info'), -} - -_allowed_password_hash_schemes = [ - 'bcrypt', - 'des_crypt', - 'pbkdf2_sha256', - 'pbkdf2_sha512', - 'sha256_crypt', - 'sha512_crypt', - # And always last one... - 'plaintext' -] - -_default_forms = { - 'login_form': LoginForm, - 'confirm_register_form': ConfirmRegisterForm, - 'register_form': RegisterForm, - 'forgot_password_form': ForgotPasswordForm, - 'reset_password_form': ResetPasswordForm, - 'change_password_form': ChangePasswordForm, - 'send_confirmation_form': SendConfirmationForm, - 'passwordless_login_form': PasswordlessLoginForm, -} - - -def _user_loader(user_id): - return _security.datastore.find_user(id=user_id) - - -def _token_loader(token): - try: - data = _security.remember_token_serializer.loads(token) - user = _security.datastore.find_user(id=data[0]) - if user and md5(user.password) == data[1]: - return user - except: - pass - - return None - - -def _identity_loader(): - if not isinstance(current_user._get_current_object(), AnonymousUser): - identity = Identity(current_user.id) - return identity - - -def _on_identity_loaded(sender, identity): - if hasattr(current_user, 'id'): - identity.provides.add(UserNeed(current_user.id)) - - for role in current_user.roles: - identity.provides.add(RoleNeed(role.name)) - - identity.user = current_user - - -def _get_login_manager(app): - lm = LoginManager() - lm.anonymous_user = AnonymousUser - lm.login_view = '%s.login' % cv('BLUEPRINT_NAME', app=app) - lm.user_loader(_user_loader) - lm.token_loader(_token_loader) - lm.login_message, lm.login_message_category = cv('MSG_LOGIN', app=app) - lm.needs_refresh_message, lm.needs_refresh_message_category = cv('MSG_REFRESH', app=app) - lm.init_app(app) - return lm - - -def _get_principal(app): - p = Principal(app, use_sessions=False) - p.identity_loader(_identity_loader) - return p - - -def _get_pwd_context(app): - pw_hash = cv('PASSWORD_HASH', app=app) - if pw_hash not in _allowed_password_hash_schemes: - allowed = ', '.join(_allowed_password_hash_schemes[:-1]) + ' and ' + _allowed_password_hash_schemes[-1] - raise ValueError("Invalid hash scheme %r. Allowed values are %s" % (pw_hash, allowed)) - return CryptContext(schemes=_allowed_password_hash_schemes, default=pw_hash) - - -def _get_serializer(app, name): - secret_key = app.config.get('SECRET_KEY') - salt = app.config.get('SECURITY_%s_SALT' % name.upper()) - return URLSafeTimedSerializer(secret_key=secret_key, salt=salt) - - -def _get_state(app, datastore, **kwargs): - for key, value in get_config(app).items(): - print "in _get_state [{}]: {}".format(key, value) - kwargs[key.lower()] = value - - kwargs.update(dict( - app=app, - datastore=datastore, - login_manager=_get_login_manager(app), - principal=_get_principal(app), - pwd_context=_get_pwd_context(app), - remember_token_serializer=_get_serializer(app, 'remember'), - login_serializer=_get_serializer(app, 'login'), - reset_serializer=_get_serializer(app, 'reset'), - confirm_serializer=_get_serializer(app, 'confirm'), - _context_processors={}, - _send_mail_task=None - )) - - for key, value in _default_forms.items(): - if key not in kwargs or not kwargs[key]: - kwargs[key] = value - - return _SecurityState(**kwargs) - - -def _context_processor(): - return dict(url_for_security=url_for_security, security=_security) - - -class RoleMixin(object): - """Mixin for `Role` model definitions""" - def __eq__(self, other): - return (self.name == other or \ - self.name == getattr(other, 'name', None)) - - def __ne__(self, other): - return (self.name != other and - self.name != getattr(other, 'name', None)) - - -class UserMixin(BaseUserMixin): - """Mixin for `User` model definitions""" - - def is_active(self): - """Returns `True` if the user is active.""" - return self.active - - def get_auth_token(self): - """Returns the user's authentication token.""" - data = [str(self.id), md5(self.password)] - return _security.remember_token_serializer.dumps(data) - - def has_role(self, role): - """Returns `True` if the user identifies with the specified role. - - :param role: A role name or `Role` instance""" - return role in self.roles - - -class AnonymousUser(AnonymousUserBase): - """AnonymousUser definition""" - - def __init__(self): - super(AnonymousUser, self).__init__() - self.roles = ImmutableList() - - def has_role(self, *args): - """Returns `False`""" - return False - - -class _SecurityState(object): - - def __init__(self, **kwargs): - for key, value in kwargs.items(): - setattr(self, key.lower(), value) - - def _add_ctx_processor(self, endpoint, fn): - group = self._context_processors.setdefault(endpoint, []) - fn not in group and group.append(fn) - - def _run_ctx_processor(self, endpoint): - rv, fns = {}, [] - for g in [None, endpoint]: - for fn in self._context_processors.setdefault(g, []): - rv.update(fn()) - return rv - - def context_processor(self, fn): - self._add_ctx_processor(None, fn) - - def forgot_password_context_processor(self, fn): - self._add_ctx_processor('forgot_password', fn) - - def login_context_processor(self, fn): - self._add_ctx_processor('login', fn) - - def register_context_processor(self, fn): - self._add_ctx_processor('register', fn) - - def reset_password_context_processor(self, fn): - self._add_ctx_processor('reset_password', fn) - - def change_password_context_processor(self, fn): - self._add_ctx_processor('change_password', fn) - - def send_confirmation_context_processor(self, fn): - self._add_ctx_processor('send_confirmation', fn) - - def send_login_context_processor(self, fn): - self._add_ctx_processor('send_login', fn) - - def mail_context_processor(self, fn): - self._add_ctx_processor('mail', fn) - - def send_mail_task(self, fn): - self._send_mail_task = fn - - -class Security(object): - """The :class:`Security` class initializes the Flask-Security extension. - - :param app: The application. - :param datastore: An instance of a user datastore. - """ - def __init__(self, app=None, datastore=None, **kwargs): - self.app = app - self.datastore = datastore - - if app is not None and datastore is not None: - self._state = self.init_app(app, datastore, **kwargs) - - def init_app(self, app, datastore=None, register_blueprint=True, - login_form=None, confirm_register_form=None, - register_form=None, forgot_password_form=None, - reset_password_form=None, change_password_form=None, - send_confirmation_form=None, passwordless_login_form=None): - """Initializes the Flask-Security extension for the specified - application and datastore implentation. - - :param app: The application. - :param datastore: An instance of a user datastore. - :param register_blueprint: to register the Security blueprint or not. - """ - datastore = datastore or self.datastore - - for key, value in _default_config.items(): - app.config.setdefault('SECURITY_' + key, value) - - for key, value in _default_messages.items(): - app.config.setdefault('SECURITY_MSG_' + key, value) - - identity_loaded.connect_via(app)(_on_identity_loaded) - - state = _get_state(app, datastore, - login_form=login_form, - confirm_register_form=confirm_register_form, - register_form=register_form, - forgot_password_form=forgot_password_form, - reset_password_form=reset_password_form, - change_password_form=change_password_form, - send_confirmation_form=send_confirmation_form, - passwordless_login_form=passwordless_login_form) - - if register_blueprint: - app.register_blueprint(create_blueprint(state, __name__)) - app.context_processor(_context_processor) - - app.extensions['security'] = state - - return state - - def __getattr__(self, name): - return getattr(self._state, name, None) diff --git a/wqflask/flask_security/datastore.py b/wqflask/flask_security/datastore.py deleted file mode 100644 index 634399d9..00000000 --- a/wqflask/flask_security/datastore.py +++ /dev/null @@ -1,261 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask.ext.security.datastore - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - This module contains an user datastore classes. - - :copyright: (c) 2012 by Matt Wright. - :license: MIT, see LICENSE for more details. -""" - -class Datastore(object): - def __init__(self, db): - self.db = db - - def commit(self): - pass - - def put(self, model): - raise NotImplementedError - - def delete(self, model): - raise NotImplementedError - - -class SQLAlchemyDatastore(Datastore): - def commit(self): - self.db.session.commit() - - def put(self, model): - self.db.session.add(model) - return model - - def delete(self, model): - self.db.session.delete(model) - - -class MongoEngineDatastore(Datastore): - def put(self, model): - model.save() - return model - - def delete(self, model): - model.delete() - - -class PeeweeDatastore(Datastore): - def put(self, model): - model.save() - return model - - def delete(self, model): - model.delete_instance() - - -class UserDatastore(object): - """Abstracted user datastore. - - :param user_model: A user model class definition - :param role_model: A role model class definition - """ - - def __init__(self, user_model, role_model): - self.user_model = user_model - self.role_model = role_model - - def _prepare_role_modify_args(self, user, role): - if isinstance(user, basestring): - user = self.find_user(email=user) - if isinstance(role, basestring): - role = self.find_role(role) - return user, role - - def _prepare_create_user_args(self, **kwargs): - kwargs.setdefault('active', True) - roles = kwargs.get('roles', []) - for i, role in enumerate(roles): - rn = role.name if isinstance(role, self.role_model) else role - # see if the role exists - roles[i] = self.find_role(rn) - kwargs['roles'] = roles - return kwargs - - def find_user(self, *args, **kwargs): - """Returns a user matching the provided parameters.""" - raise NotImplementedError - - def find_role(self, *args, **kwargs): - """Returns a role matching the provided name.""" - raise NotImplementedError - - def add_role_to_user(self, user, role): - """Adds a role tp a user - - :param user: The user to manipulate - :param role: The role to add to the user - """ - rv = False - user, role = self._prepare_role_modify_args(user, role) - if role not in user.roles: - rv = True - user.roles.append(role) - return rv - - def remove_role_from_user(self, user, role): - """Removes a role from a user - - :param user: The user to manipulate - :param role: The role to remove from the user - """ - rv = False - user, role = self._prepare_role_modify_args(user, role) - if role in user.roles: - rv = True - user.roles.remove(role) - return rv - - def toggle_active(self, user): - """Toggles a user's active status. Always returns True.""" - user.active = not user.active - return True - - def deactivate_user(self, user): - """Deactivates a specified user. Returns `True` if a change was made. - - :param user: The user to deactivate - """ - if user.active: - user.active = False - return True - return False - - def activate_user(self, user): - """Activates a specified user. Returns `True` if a change was made. - - :param user: The user to activate - """ - if not user.active: - user.active = True - return True - return False - - def create_role(self, **kwargs): - """Creates and returns a new role from the given parameters.""" - - role = self.role_model(**kwargs) - return self.put(role) - - def find_or_create_role(self, name, **kwargs): - """Returns a role matching the given name or creates it with any - additionally provided parameters - """ - kwargs["name"] = name - return self.find_role(name) or self.create_role(**kwargs) - - def create_user(self, **kwargs): - """Creates and returns a new user from the given parameters.""" - - user = self.user_model(**self._prepare_create_user_args(**kwargs)) - print "in abstraced create_user, user is:", user - return self.put(user) - - def delete_user(self, user): - """Delete the specified user - - :param user: The user to delete - """ - self.delete(user) - - -class SQLAlchemyUserDatastore(SQLAlchemyDatastore, UserDatastore): - """A SQLAlchemy datastore implementation for Flask-Security that assumes the - use of the Flask-SQLAlchemy extension. - """ - def __init__(self, db, user_model, role_model): - SQLAlchemyDatastore.__init__(self, db) - UserDatastore.__init__(self, user_model, role_model) - - def find_user(self, **kwargs): - return self.user_model.query.filter_by(**kwargs).first() - - def find_role(self, role): - return self.role_model.query.filter_by(name=role).first() - - -class MongoEngineUserDatastore(MongoEngineDatastore, UserDatastore): - """A MongoEngine datastore implementation for Flask-Security that assumes - the use of the Flask-MongoEngine extension. - """ - def __init__(self, db, user_model, role_model): - MongoEngineDatastore.__init__(self, db) - UserDatastore.__init__(self, user_model, role_model) - - def find_user(self, **kwargs): - return self.user_model.objects(**kwargs).first() - - def find_role(self, role): - return self.role_model.objects(name=role).first() - - -class PeeweeUserDatastore(PeeweeDatastore, UserDatastore): - """A PeeweeD datastore implementation for Flask-Security that assumes - the use of the Flask-Peewee extension. - - :param user_model: A user model class definition - :param role_model: A role model class definition - :param role_link: A model implementing the many-to-many user-role relation - """ - def __init__(self, db, user_model, role_model, role_link): - PeeweeDatastore.__init__(self, db) - UserDatastore.__init__(self, user_model, role_model) - self.UserRole = role_link - - def find_user(self, **kwargs): - try: - return self.user_model.filter(**kwargs).get() - except self.user_model.DoesNotExist: - return None - - def find_role(self, role): - try: - return self.role_model.filter(name=role).get() - except self.role_model.DoesNotExist: - return None - - def create_user(self, **kwargs): - """Creates and returns a new user from the given parameters.""" - roles = kwargs.pop('roles', []) - user = self.user_model(**self._prepare_create_user_args(**kwargs)) - user = self.put(user) - for role in roles: - self.add_role_to_user(user, role) - return user - - - def add_role_to_user(self, user, role): - """Adds a role tp a user - - :param user: The user to manipulate - :param role: The role to add to the user - """ - user, role = self._prepare_role_modify_args(user, role) - if self.UserRole.select().where(self.UserRole.user==user, self.UserRole.role==role).count(): - return False - else: - self.UserRole.create(user=user, role=role) - return True - - def remove_role_from_user(self, user, role): - """Removes a role from a user - - :param user: The user to manipulate - :param role: The role to remove from the user - """ - user, role = self._prepare_role_modify_args(user, role) - if self.UserRole.select().where(self.UserRole.user==user, self.UserRole.role==role).count(): - self.UserRole.delete().where(self.UserRole.user==user, self.UserRole.role==role) - return True - else: - return False - diff --git a/wqflask/flask_security/decorators.py b/wqflask/flask_security/decorators.py deleted file mode 100644 index 0ea1105c..00000000 --- a/wqflask/flask_security/decorators.py +++ /dev/null @@ -1,207 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask.ext.security.decorators - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Flask-Security decorators module - - :copyright: (c) 2012 by Matt Wright. - :license: MIT, see LICENSE for more details. -""" - -from functools import wraps - -from flask import current_app, Response, request, redirect, _request_ctx_stack -from flask.ext.login import current_user, login_required -from flask.ext.principal import RoleNeed, Permission, Identity, identity_changed -from werkzeug.local import LocalProxy - -from . import utils - - -# Convenient references -_security = LocalProxy(lambda: current_app.extensions['security']) - - -_default_unauthorized_html = """ -
The server could not verify that you are authorized to access the URL - requested. You either supplied the wrong credentials (e.g. a bad password), - or your browser doesn't understand how to supply the credentials required.
- """ - - -def _get_unauthorized_response(text=None, headers=None): - text = text or _default_unauthorized_html - headers = headers or {} - return Response(text, 401, headers) - - -def _get_unauthorized_view(): - cv = utils.get_url(utils.config_value('UNAUTHORIZED_VIEW')) - utils.do_flash(*utils.get_message('UNAUTHORIZED')) - return redirect(cv or request.referrer or '/') - - -def _check_token(): - header_key = _security.token_authentication_header - args_key = _security.token_authentication_key - header_token = request.headers.get(header_key, None) - token = request.args.get(args_key, header_token) - if request.json: - token = request.json.get(args_key, token) - serializer = _security.remember_token_serializer - - try: - data = serializer.loads(token) - except: - return False - - user = _security.datastore.find_user(id=data[0]) - - if utils.md5(user.password) == data[1]: - app = current_app._get_current_object() - _request_ctx_stack.top.user = user - identity_changed.send(app, identity=Identity(user.id)) - return True - - -def _check_http_auth(): - auth = request.authorization or dict(username=None, password=None) - user = _security.datastore.find_user(email=auth.username) - - if user and utils.verify_and_update_password(auth.password, user): - _security.datastore.commit() - app = current_app._get_current_object() - _request_ctx_stack.top.user = user - identity_changed.send(app, identity=Identity(user.id)) - return True - - return False - - -def http_auth_required(realm): - """Decorator that protects endpoints using Basic HTTP authentication. - The username should be set to the user's email address. - - :param realm: optional realm name""" - - def decorator(fn): - @wraps(fn) - def wrapper(*args, **kwargs): - if _check_http_auth(): - return fn(*args, **kwargs) - r = _security.default_http_auth_realm if callable(realm) else realm - h = {'WWW-Authenticate': 'Basic realm="%s"' % r} - return _get_unauthorized_response(headers=h) - return wrapper - - if callable(realm): - return decorator(realm) - return decorator - - -def auth_token_required(fn): - """Decorator that protects endpoints using token authentication. The token - should be added to the request by the client by using a query string - variable with a name equal to the configuration value of - `SECURITY_TOKEN_AUTHENTICATION_KEY` or in a request header named that of - the configuration value of `SECURITY_TOKEN_AUTHENTICATION_HEADER` - """ - - @wraps(fn) - def decorated(*args, **kwargs): - if _check_token(): - return fn(*args, **kwargs) - return _get_unauthorized_response() - return decorated - - -def auth_required(*auth_methods): - """ - Decorator that protects enpoints through multiple mechanisms - Example:: - - @app.route('/dashboard') - @auth_required('token', 'session') - def dashboard(): - return 'Dashboard' - - :param auth_methods: Specified mechanisms. - """ - login_mechanisms = { - 'token': lambda: _check_token(), - 'basic': lambda: _check_http_auth(), - 'session': lambda: current_user.is_authenticated() - } - - def wrapper(fn): - @wraps(fn) - def decorated_view(*args, **kwargs): - mechanisms = [login_mechanisms.get(method) for method in auth_methods] - for mechanism in mechanisms: - if mechanism and mechanism(): - return fn(*args, **kwargs) - return _get_unauthorized_response() - return decorated_view - return wrapper - - -def roles_required(*roles): - """Decorator which specifies that a user must have all the specified roles. - Example:: - - @app.route('/dashboard') - @roles_required('admin', 'editor') - def dashboard(): - return 'Dashboard' - - The current user must have both the `admin` role and `editor` role in order - to view the page. - - :param args: The required roles. - """ - def wrapper(fn): - @wraps(fn) - def decorated_view(*args, **kwargs): - perms = [Permission(RoleNeed(role)) for role in roles] - for perm in perms: - if not perm.can(): - return _get_unauthorized_view() - return fn(*args, **kwargs) - return decorated_view - return wrapper - - -def roles_accepted(*roles): - """Decorator which specifies that a user must have at least one of the - specified roles. Example:: - - @app.route('/create_post') - @roles_accepted('editor', 'author') - def create_post(): - return 'Create Post' - - The current user must have either the `editor` role or `author` role in - order to view the page. - - :param args: The possible roles. - """ - def wrapper(fn): - @wraps(fn) - def decorated_view(*args, **kwargs): - perm = Permission(*[RoleNeed(role) for role in roles]) - if perm.can(): - return fn(*args, **kwargs) - return _get_unauthorized_view() - return decorated_view - return wrapper - - -def anonymous_user_required(f): - @wraps(f) - def wrapper(*args, **kwargs): - if current_user.is_authenticated(): - return redirect(utils.get_url(_security.post_login_view)) - return f(*args, **kwargs) - return wrapper diff --git a/wqflask/flask_security/forms.py b/wqflask/flask_security/forms.py deleted file mode 100644 index 54677e77..00000000 --- a/wqflask/flask_security/forms.py +++ /dev/null @@ -1,286 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask.ext.security.forms - ~~~~~~~~~~~~~~~~~~~~~~~~ - - Flask-Security forms module - - :copyright: (c) 2012 by Matt Wright. - :license: MIT, see LICENSE for more details. -""" - -import inspect -import urlparse - -import flask_wtf as wtf - -from flask import request, current_app -from flask_wtf import Form as BaseForm, TextField, PasswordField, \ - SubmitField, HiddenField, BooleanField, ValidationError, Field -from flask_login import current_user -from werkzeug.local import LocalProxy - -from .confirmable import requires_confirmation -from .utils import verify_and_update_password, get_message - -# Convenient reference -_datastore = LocalProxy(lambda: current_app.extensions['security'].datastore) - -_default_field_labels = { - 'email': 'Email Address', - 'password': 'Password', - 'remember_me': 'Remember Me', - 'login': 'Login', - 'retype_password': 'Retype Password', - 'register': 'Register', - 'send_confirmation': 'Resend Confirmation Instructions', - 'recover_password': 'Recover Password', - 'reset_password': 'Reset Password', - 'retype_password': 'Retype Password', - 'new_password': 'New Password', - 'change_password': 'Change Password', - 'send_login_link': 'Send Login Link' -} - - -class ValidatorMixin(object): - def __call__(self, form, field): - if self.message and self.message.isupper(): - self.message = get_message(self.message)[0] - return super(ValidatorMixin, self).__call__(form, field) - - -class EqualTo(ValidatorMixin, wtf.EqualTo): - pass - - -class Required(ValidatorMixin, wtf.Required): - pass - - -class Email(ValidatorMixin, wtf.Email): - pass - - -class Length(ValidatorMixin, wtf.Length): - pass - - -email_required = Required(message='EMAIL_NOT_PROVIDED') -email_validator = Email(message='INVALID_EMAIL_ADDRESS') -password_required = Required(message='PASSWORD_NOT_PROVIDED') - - -def get_form_field_label(key): - return _default_field_labels.get(key, '') - - -def unique_user_email(form, field): - if _datastore.find_user(email=field.data) is not None: - msg = get_message('EMAIL_ALREADY_ASSOCIATED', email=field.data)[0] - raise ValidationError(msg) - - -def valid_user_email(form, field): - form.user = _datastore.find_user(email=field.data) - if form.user is None: - raise ValidationError(get_message('USER_DOES_NOT_EXIST')[0]) - - -class Form(BaseForm): - def __init__(self, *args, **kwargs): - #print "importing tracer" - #from wqflask import tracer - #tracer.turn_on() - #print "imported tracer" - print "in Form, args:", args - print "in Form, kwargs:", kwargs - if current_app.testing: - self.TIME_LIMIT = None - super(Form, self).__init__(*args, **kwargs) - - -class EmailFormMixin(): - email = TextField(get_form_field_label('email'), - validators=[email_required, - email_validator]) - - -class UserEmailFormMixin(): - user = None - email = TextField(get_form_field_label('email'), - validators=[email_required, - email_validator, - valid_user_email]) - - -class UniqueEmailFormMixin(): - email = TextField(get_form_field_label('email'), - validators=[email_required, - email_validator, - unique_user_email]) - - -class PasswordFormMixin(): - password = PasswordField(get_form_field_label('password'), - validators=[password_required]) - - -class NewPasswordFormMixin(): - password = PasswordField(get_form_field_label('password'), - validators=[password_required, - Length(min=6, max=128)]) - - -class PasswordConfirmFormMixin(): - password_confirm = PasswordField( - get_form_field_label('retype_password'), - validators=[EqualTo('password', message='RETYPE_PASSWORD_MISMATCH')]) - - -class NextFormMixin(): - next = HiddenField() - - def validate_next(self, field): - url_next = urlparse.urlsplit(field.data) - url_base = urlparse.urlsplit(request.host_url) - if url_next.netloc and url_next.netloc != url_base.netloc: - field.data = '' - raise ValidationError(get_message('INVALID_REDIRECT')[0]) - - -class RegisterFormMixin(): - submit = SubmitField(get_form_field_label('register')) - - def to_dict(form): - def is_field_and_user_attr(member): - print "in ifaua:", member - return isinstance(member, Field) and \ - hasattr(_datastore.user_model, member.name) - - print("green:", vars(form)) - fields = inspect.getmembers(form, is_field_and_user_attr) - print("fields:" ,vars(form)) - return dict((key, value.data) for key, value in fields) - - -class SendConfirmationForm(Form, UserEmailFormMixin): - """The default forgot password form""" - - submit = SubmitField(get_form_field_label('send_confirmation')) - - def __init__(self, *args, **kwargs): - super(SendConfirmationForm, self).__init__(*args, **kwargs) - if request.method == 'GET': - self.email.data = request.args.get('email', None) - - def validate(self): - if not super(SendConfirmationForm, self).validate(): - return False - if self.user.confirmed_at is not None: - self.email.errors.append(get_message('ALREADY_CONFIRMED')[0]) - return False - return True - - -class ForgotPasswordForm(Form, UserEmailFormMixin): - """The default forgot password form""" - - submit = SubmitField(get_form_field_label('recover_password')) - - -class PasswordlessLoginForm(Form, UserEmailFormMixin): - """The passwordless login form""" - - submit = SubmitField(get_form_field_label('send_login_link')) - - def __init__(self, *args, **kwargs): - super(PasswordlessLoginForm, self).__init__(*args, **kwargs) - - def validate(self): - if not super(PasswordlessLoginForm, self).validate(): - return False - if not self.user.is_active(): - self.email.errors.append(get_message('DISABLED_ACCOUNT')[0]) - return False - return True - - -class LoginForm(Form, NextFormMixin): - """The default login form""" - - email = TextField(get_form_field_label('email')) - password = PasswordField(get_form_field_label('password')) - remember = BooleanField(get_form_field_label('remember_me')) - submit = SubmitField(get_form_field_label('login')) - - def __init__(self, *args, **kwargs): - super(LoginForm, self).__init__(*args, **kwargs) - - def validate(self): - if not super(LoginForm, self).validate(): - return False - - if self.email.data.strip() == '': - self.email.errors.append(get_message('EMAIL_NOT_PROVIDED')[0]) - return False - - if self.password.data.strip() == '': - self.password.errors.append(get_message('PASSWORD_NOT_PROVIDED')[0]) - return False - - self.user = _datastore.find_user(email=self.email.data) - - if self.user is None: - self.email.errors.append(get_message('USER_DOES_NOT_EXIST')[0]) - return False - if not verify_and_update_password(self.password.data, self.user): - self.password.errors.append(get_message('INVALID_PASSWORD')[0]) - return False - if requires_confirmation(self.user): - self.email.errors.append(get_message('CONFIRMATION_REQUIRED')[0]) - return False - if not self.user.is_active(): - self.email.errors.append(get_message('DISABLED_ACCOUNT')[0]) - return False - return True - - -class ConfirmRegisterForm(Form, RegisterFormMixin, - UniqueEmailFormMixin, NewPasswordFormMixin): - pass - - -class RegisterForm(ConfirmRegisterForm, PasswordConfirmFormMixin): - pass - - -class ResetPasswordForm(Form, NewPasswordFormMixin, PasswordConfirmFormMixin): - """The default reset password form""" - - submit = SubmitField(get_form_field_label('reset_password')) - - -class ChangePasswordForm(Form, PasswordFormMixin): - """The default change password form""" - - new_password = PasswordField(get_form_field_label('new_password'), - validators=[password_required, - Length(min=6, max=128)]) - - new_password_confirm = PasswordField(get_form_field_label('retype_password'), - validators=[EqualTo('new_password', message='RETYPE_PASSWORD_MISMATCH')]) - - submit = SubmitField(get_form_field_label('change_password')) - - def validate(self): - if not super(ChangePasswordForm, self).validate(): - return False - - if self.password.data.strip() == '': - self.password.errors.append(get_message('PASSWORD_NOT_PROVIDED')[0]) - return False - if not verify_and_update_password(self.password.data, current_user): - self.password.errors.append(get_message('INVALID_PASSWORD')[0]) - return False - return True diff --git a/wqflask/flask_security/passwordless.py b/wqflask/flask_security/passwordless.py deleted file mode 100644 index b0accb2c..00000000 --- a/wqflask/flask_security/passwordless.py +++ /dev/null @@ -1,59 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask.ext.security.passwordless - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Flask-Security passwordless module - - :copyright: (c) 2012 by Matt Wright. - :license: MIT, see LICENSE for more details. -""" - -from flask import request, current_app as app -from werkzeug.local import LocalProxy - -from .signals import login_instructions_sent -from .utils import send_mail, url_for_security, get_token_status, \ - config_value - - -# Convenient references -_security = LocalProxy(lambda: app.extensions['security']) - -_datastore = LocalProxy(lambda: _security.datastore) - - -def send_login_instructions(user): - """Sends the login instructions email for the specified user. - - :param user: The user to send the instructions to - :param token: The login token - """ - token = generate_login_token(user) - url = url_for_security('token_login', token=token) - login_link = request.url_root[:-1] + url - - send_mail(config_value('EMAIL_SUBJECT_PASSWORDLESS'), user.email, - 'login_instructions', user=user, login_link=login_link) - - login_instructions_sent.send(dict(user=user, login_token=token), - app=app._get_current_object()) - - -def generate_login_token(user): - """Generates a unique login token for the specified user. - - :param user: The user the token belongs to - """ - return _security.login_serializer.dumps([str(user.id)]) - - -def login_token_status(token): - """Returns the expired status, invalid status, and user of a login token. - For example:: - - expired, invalid, user = login_token_status('...') - - :param token: The login token - """ - return get_token_status(token, 'login', 'LOGIN') diff --git a/wqflask/flask_security/recoverable.py b/wqflask/flask_security/recoverable.py deleted file mode 100644 index 6aafc111..00000000 --- a/wqflask/flask_security/recoverable.py +++ /dev/null @@ -1,80 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask.ext.security.recoverable - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Flask-Security recoverable module - - :copyright: (c) 2012 by Matt Wright. - :license: MIT, see LICENSE for more details. -""" - -from flask import current_app as app, request -from werkzeug.local import LocalProxy - -from .signals import password_reset, reset_password_instructions_sent -from .utils import send_mail, md5, encrypt_password, url_for_security, \ - get_token_status, config_value - - -# Convenient references -_security = LocalProxy(lambda: app.extensions['security']) - -_datastore = LocalProxy(lambda: _security.datastore) - - -def send_reset_password_instructions(user): - """Sends the reset password instructions email for the specified user. - - :param user: The user to send the instructions to - """ - token = generate_reset_password_token(user) - url = url_for_security('reset_password', token=token) - reset_link = request.url_root[:-1] + url - - send_mail(config_value('EMAIL_SUBJECT_PASSWORD_RESET'), user.email, - 'reset_instructions', - user=user, reset_link=reset_link) - - reset_password_instructions_sent.send(dict(user=user, token=token), - app=app._get_current_object()) - - -def send_password_reset_notice(user): - """Sends the password reset notice email for the specified user. - - :param user: The user to send the notice to - """ - send_mail(config_value('EMAIL_SUBJECT_PASSWORD_NOTICE'), user.email, - 'reset_notice', user=user) - - -def generate_reset_password_token(user): - """Generates a unique reset password token for the specified user. - - :param user: The user to work with - """ - data = [str(user.id), md5(user.password)] - return _security.reset_serializer.dumps(data) - - -def reset_password_token_status(token): - """Returns the expired status, invalid status, and user of a password reset - token. For example:: - - expired, invalid, user = reset_password_token_status('...') - - :param token: The password reset token - """ - return get_token_status(token, 'reset', 'RESET_PASSWORD') - -def update_password(user, password): - """Update the specified user's password - - :param user: The user to update_password - :param password: The unencrypted new password - """ - user.password = encrypt_password(password) - _datastore.put(user) - send_password_reset_notice(user) - password_reset.send(user, app=app._get_current_object()) diff --git a/wqflask/flask_security/registerable.py b/wqflask/flask_security/registerable.py deleted file mode 100644 index 4606c7c6..00000000 --- a/wqflask/flask_security/registerable.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask.ext.security.registerable - ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Flask-Security registerable module - - :copyright: (c) 2012 by Matt Wright. - :license: MIT, see LICENSE for more details. -""" - -from flask import current_app as app -from werkzeug.local import LocalProxy - -from .confirmable import generate_confirmation_link -from .signals import user_registered -from .utils import do_flash, get_message, send_mail, encrypt_password, \ - config_value - -# Convenient references -_security = LocalProxy(lambda: app.extensions['security']) - -_datastore = LocalProxy(lambda: _security.datastore) - - -def register_user(**kwargs): - print "in register_user kwargs:", kwargs - confirmation_link, token = None, None - kwargs['password'] = encrypt_password(kwargs['password']) - user = _datastore.create_user(**kwargs) - _datastore.commit() - - if _security.confirmable: - confirmation_link, token = generate_confirmation_link(user) - do_flash(*get_message('CONFIRM_REGISTRATION', email=user.email)) - - user_registered.send(dict(user=user, confirm_token=token), - app=app._get_current_object()) - - if config_value('SEND_REGISTER_EMAIL'): - send_mail(config_value('EMAIL_SUBJECT_REGISTER'), user.email, 'welcome', - user=user, confirmation_link=confirmation_link) - - return user diff --git a/wqflask/flask_security/script.py b/wqflask/flask_security/script.py deleted file mode 100644 index 9c9a2469..00000000 --- a/wqflask/flask_security/script.py +++ /dev/null @@ -1,130 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask.ext.security.script - ~~~~~~~~~~~~~~~~~~~~~~~~~ - - Flask-Security script module - - :copyright: (c) 2012 by Matt Wright. - :license: MIT, see LICENSE for more details. -""" -try: - import simplejson as json -except ImportError: - import json - -import re - -from flask import current_app -from flask.ext.script import Command, Option -from werkzeug.local import LocalProxy - -from .utils import encrypt_password - - -_datastore = LocalProxy(lambda: current_app.extensions['security'].datastore) - - -def pprint(obj): - print json.dumps(obj, sort_keys=True, indent=4) - - -def commit(fn): - def wrapper(*args, **kwargs): - fn(*args, **kwargs) - _datastore.commit() - return wrapper - - -class CreateUserCommand(Command): - """Create a user""" - - option_list = ( - Option('-e', '--email', dest='email', default=None), - Option('-p', '--password', dest='password', default=None), - Option('-a', '--active', dest='active', default=''), - ) - - @commit - def run(self, **kwargs): - # sanitize active input - ai = re.sub(r'\s', '', str(kwargs['active'])) - kwargs['active'] = ai.lower() in ['', 'y', 'yes', '1', 'active'] - - from flask_security.forms import ConfirmRegisterForm - from werkzeug.datastructures import MultiDict - - form = ConfirmRegisterForm(MultiDict(kwargs), csrf_enabled=False) - - if form.validate(): - kwargs['password'] = encrypt_password(kwargs['password']) - _datastore.create_user(**kwargs) - print 'User created successfully.' - kwargs['password'] = '****' - pprint(kwargs) - else: - print 'Error creating user' - pprint(form.errors) - - -class CreateRoleCommand(Command): - """Create a role""" - - option_list = ( - Option('-n', '--name', dest='name', default=None), - Option('-d', '--desc', dest='description', default=None), - ) - - @commit - def run(self, **kwargs): - _datastore.create_role(**kwargs) - print 'Role "%(name)s" created successfully.' % kwargs - - -class _RoleCommand(Command): - option_list = ( - Option('-u', '--user', dest='user_identifier'), - Option('-r', '--role', dest='role_name'), - ) - - -class AddRoleCommand(_RoleCommand): - """Add a role to a user""" - - @commit - def run(self, user_identifier, role_name): - _datastore.add_role_to_user(user_identifier, role_name) - print "Role '%s' added to user '%s' successfully" % (role_name, user_identifier) - - -class RemoveRoleCommand(_RoleCommand): - """Add a role to a user""" - - @commit - def run(self, user_identifier, role_name): - _datastore.remove_role_from_user(user_identifier, role_name) - print "Role '%s' removed from user '%s' successfully" % (role_name, user_identifier) - - -class _ToggleActiveCommand(Command): - option_list = ( - Option('-u', '--user', dest='user_identifier'), - ) - - -class DeactivateUserCommand(_ToggleActiveCommand): - """Deactive a user""" - - @commit - def run(self, user_identifier): - _datastore.deactivate_user(user_identifier) - print "User '%s' has been deactivated" % user_identifier - - -class ActivateUserCommand(_ToggleActiveCommand): - """Deactive a user""" - - @commit - def run(self, user_identifier): - _datastore.activate_user(user_identifier) - print "User '%s' has been activated" % user_identifier diff --git a/wqflask/flask_security/signals.py b/wqflask/flask_security/signals.py deleted file mode 100644 index e1c29548..00000000 --- a/wqflask/flask_security/signals.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -""" - flask.ext.security.signals - ~~~~~~~~~~~~~~~~~~~~~~~~~~ - - Flask-Security signals module - - :copyright: (c) 2012 by Matt Wright. - :license: MIT, see LICENSE for more details. -""" - -import blinker - - -signals = blinker.Namespace() - -user_registered = signals.signal("user-registered") - -user_confirmed = signals.signal("user-confirmed") - -confirm_instructions_sent = signals.signal("confirm-instructions-sent") - -login_instructions_sent = signals.signal("login-instructions-sent") - -password_reset = signals.signal("password-reset") - -password_changed = signals.signal("password-changed") - -reset_password_instructions_sent = signals.signal("password-reset-instructions-sent") diff --git a/wqflask/flask_security/templates/.DS_Store b/wqflask/flask_security/templates/.DS_Store deleted file mode 100644 index b72f1d98..00000000 Binary files a/wqflask/flask_security/templates/.DS_Store and /dev/null differ diff --git a/wqflask/flask_security/templates/security/.DS_Store b/wqflask/flask_security/templates/security/.DS_Store deleted file mode 100644 index 5008ddfc..00000000 Binary files a/wqflask/flask_security/templates/security/.DS_Store and /dev/null differ diff --git a/wqflask/flask_security/templates/security/_macros.html b/wqflask/flask_security/templates/security/_macros.html deleted file mode 100644 index 8575f3db..00000000 --- a/wqflask/flask_security/templates/security/_macros.html +++ /dev/null @@ -1,16 +0,0 @@ -{% macro render_field_with_errors(field) %} -- {{ field.label }} {{ field(**kwargs)|safe }} - {% if field.errors %} -
{{ field(**kwargs)|safe }}
-{% endmacro %} \ No newline at end of file diff --git a/wqflask/flask_security/templates/security/_menu.html b/wqflask/flask_security/templates/security/_menu.html deleted file mode 100644 index 5291f809..00000000 --- a/wqflask/flask_security/templates/security/_menu.html +++ /dev/null @@ -1,15 +0,0 @@ -{% if security.registerable or security.recoverable or security.confirmabled %} -Your password has been changed.
-{% if security.recoverable %} -If you did not change your password, click here to reset it.
-{% endif %} diff --git a/wqflask/flask_security/templates/security/email/change_notice.txt b/wqflask/flask_security/templates/security/email/change_notice.txt deleted file mode 100644 index e74bd80d..00000000 --- a/wqflask/flask_security/templates/security/email/change_notice.txt +++ /dev/null @@ -1,5 +0,0 @@ -Your password has been changed -{% if security.recoverable %} -If you did not change your password, click the link below to reset it. -{{ url_for_security('forgot_password', _external=True) }} -{% endif %} diff --git a/wqflask/flask_security/templates/security/email/confirmation_instructions.html b/wqflask/flask_security/templates/security/email/confirmation_instructions.html deleted file mode 100644 index 5082a9a8..00000000 --- a/wqflask/flask_security/templates/security/email/confirmation_instructions.html +++ /dev/null @@ -1,3 +0,0 @@ -Please confirm your email through the link below:
- - \ No newline at end of file diff --git a/wqflask/flask_security/templates/security/email/confirmation_instructions.txt b/wqflask/flask_security/templates/security/email/confirmation_instructions.txt deleted file mode 100644 index fb435b55..00000000 --- a/wqflask/flask_security/templates/security/email/confirmation_instructions.txt +++ /dev/null @@ -1,3 +0,0 @@ -Please confirm your email through the link below: - -{{ confirmation_link }} \ No newline at end of file diff --git a/wqflask/flask_security/templates/security/email/login_instructions.html b/wqflask/flask_security/templates/security/email/login_instructions.html deleted file mode 100644 index 45a7cb57..00000000 --- a/wqflask/flask_security/templates/security/email/login_instructions.html +++ /dev/null @@ -1,5 +0,0 @@ -Welcome {{ user.email }}!
- -You can log into your through the link below:
- - \ No newline at end of file diff --git a/wqflask/flask_security/templates/security/email/login_instructions.txt b/wqflask/flask_security/templates/security/email/login_instructions.txt deleted file mode 100644 index 1364ed65..00000000 --- a/wqflask/flask_security/templates/security/email/login_instructions.txt +++ /dev/null @@ -1,5 +0,0 @@ -Welcome {{ user.email }}! - -You can log into your through the link below: - -{{ login_link }} \ No newline at end of file diff --git a/wqflask/flask_security/templates/security/email/reset_instructions.html b/wqflask/flask_security/templates/security/email/reset_instructions.html deleted file mode 100644 index fd0b48d8..00000000 --- a/wqflask/flask_security/templates/security/email/reset_instructions.html +++ /dev/null @@ -1 +0,0 @@ -Click here to reset your password
\ No newline at end of file diff --git a/wqflask/flask_security/templates/security/email/reset_instructions.txt b/wqflask/flask_security/templates/security/email/reset_instructions.txt deleted file mode 100644 index 91ac288e..00000000 --- a/wqflask/flask_security/templates/security/email/reset_instructions.txt +++ /dev/null @@ -1,3 +0,0 @@ -Click the link below to reset your password: - -{{ reset_link }} \ No newline at end of file diff --git a/wqflask/flask_security/templates/security/email/reset_notice.html b/wqflask/flask_security/templates/security/email/reset_notice.html deleted file mode 100644 index 536e2961..00000000 --- a/wqflask/flask_security/templates/security/email/reset_notice.html +++ /dev/null @@ -1 +0,0 @@ -Your password has been reset
\ No newline at end of file diff --git a/wqflask/flask_security/templates/security/email/reset_notice.txt b/wqflask/flask_security/templates/security/email/reset_notice.txt deleted file mode 100644 index a3fa0b4b..00000000 --- a/wqflask/flask_security/templates/security/email/reset_notice.txt +++ /dev/null @@ -1 +0,0 @@ -Your password has been reset \ No newline at end of file diff --git a/wqflask/flask_security/templates/security/email/welcome.html b/wqflask/flask_security/templates/security/email/welcome.html deleted file mode 100644 index 55eaed61..00000000 --- a/wqflask/flask_security/templates/security/email/welcome.html +++ /dev/null @@ -1,7 +0,0 @@ -Welcome {{ user.email }}!
- -{% if security.confirmable %} -You can confirm your email through the link below:
- - -{% endif %} \ No newline at end of file diff --git a/wqflask/flask_security/templates/security/email/welcome.txt b/wqflask/flask_security/templates/security/email/welcome.txt deleted file mode 100644 index fb6ee5b5..00000000 --- a/wqflask/flask_security/templates/security/email/welcome.txt +++ /dev/null @@ -1,7 +0,0 @@ -Welcome {{ user.email }}! - -{% if security.confirmable %} -You can confirm your email through the link below: - -{{ confirmation_link }} -{% endif %} \ No newline at end of file diff --git a/wqflask/flask_security/templates/security/forgot_password.html b/wqflask/flask_security/templates/security/forgot_password.html deleted file mode 100644 index 90fcaf66..00000000 --- a/wqflask/flask_security/templates/security/forgot_password.html +++ /dev/null @@ -1,9 +0,0 @@ -{% from "security/_macros.html" import render_field_with_errors, render_field %} -{% include "security/_messages.html" %} -