Skip to content

Commit

Permalink
Switch to new Flask Extension naming scheme. Remove trailing white sp…
Browse files Browse the repository at this point in the history
…ace.
  • Loading branch information
Dan Sully committed Apr 21, 2012
1 parent f07abd0 commit 89865a1
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 65 deletions.
2 changes: 1 addition & 1 deletion docs/index.rst
@@ -1,7 +1,7 @@
=========== ===========
Flask-Login Flask-Login
=========== ===========
.. currentmodule:: flaskext.login .. currentmodule:: flask.ext.login


Flask-Login provides user session management for Flask. It handles the common Flask-Login provides user session management for Flask. It handles the common
tasks of logging in, logging out, and remembering your users' sessions over tasks of logging in, logging out, and remembering your users' sessions over
Expand Down
4 changes: 2 additions & 2 deletions example/login-example.py
Expand Up @@ -9,7 +9,7 @@
:license: MIT/X11, see LICENSE for more details. :license: MIT/X11, see LICENSE for more details.
""" """
from flask import Flask, request, render_template, redirect, url_for, flash from flask import Flask, request, render_template, redirect, url_for, flash
from flaskext.login import (LoginManager, current_user, login_required, from flask.ext.login import (LoginManager, current_user, login_required,
login_user, logout_user, UserMixin, AnonymousUser, login_user, logout_user, UserMixin, AnonymousUser,
confirm_login, fresh_login_required) confirm_login, fresh_login_required)


Expand All @@ -18,7 +18,7 @@ def __init__(self, name, id, active=True):
self.name = name self.name = name
self.id = id self.id = id
self.active = active self.active = active

def is_active(self): def is_active(self):
return self.active return self.active


Expand Down
94 changes: 47 additions & 47 deletions flaskext/login.py → flask_login.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
""" """
flaskext.login flask.ext.login
============== ==============
This module provides user session management for Flask. It lets you log your This module provides user session management for Flask. It lets you log your
Expand Down Expand Up @@ -39,7 +39,7 @@ def encode_cookie(payload):
""" """
This will encode a `unicode` value into a cookie, and sign that cookie This will encode a `unicode` value into a cookie, and sign that cookie
with the app's secret key. with the app's secret key.
:param payload: The value to encode, as `unicode`. :param payload: The value to encode, as `unicode`.
""" """
return u"%s|%s" % (payload, _cookie_digest(payload)) return u"%s|%s" % (payload, _cookie_digest(payload))
Expand All @@ -49,7 +49,7 @@ def decode_cookie(cookie):
""" """
This decodes a cookie given by `encode_cookie`. If verification of the This decodes a cookie given by `encode_cookie`. If verification of the
cookie fails, `None` will be returned. cookie fails, `None` will be returned.
:param cookie: An encoded cookie. :param cookie: An encoded cookie.
""" """
try: try:
Expand All @@ -67,7 +67,7 @@ def make_next_param(login, current):
""" """
Reduces the scheme and host from a given URL so it can be passed to Reduces the scheme and host from a given URL so it can be passed to
the given `login` URL more efficiently. the given `login` URL more efficiently.
:param login: The login URL being redirected to. :param login: The login URL being redirected to.
:param current: The URL to reduce. :param current: The URL to reduce.
""" """
Expand All @@ -86,7 +86,7 @@ def login_url(login_view, next_url=None, next_field="next"):
provided, this will just return the URL for it. If `next_url` is provided, provided, this will just return the URL for it. If `next_url` is provided,
however, this will append a ``next=URL`` parameter to the query string however, this will append a ``next=URL`` parameter to the query string
so that the login view can redirect back to that URL. so that the login view can redirect back to that URL.
:param login_view: The name of the login view. (Alternately, the actual :param login_view: The name of the login view. (Alternately, the actual
URL to the login view.) URL to the login view.)
:param next_url: The URL to give the login view for redirection. :param next_url: The URL to give the login view for redirection.
Expand All @@ -113,7 +113,7 @@ def make_secure_token(*args, **options):
from guessing the information. (To make it even more effective, if you from guessing the information. (To make it even more effective, if you
will never need to regenerate the token, you can pass some random data will never need to regenerate the token, you can pass some random data
as one of the arguments.) as one of the arguments.)
:param args: The data to include in the token. :param args: The data to include in the token.
:param options: To manually specify a secret key, pass ``key=THE_KEY``. :param options: To manually specify a secret key, pass ``key=THE_KEY``.
Otherwise, the current app's secret key will be used. Otherwise, the current app's secret key will be used.
Expand Down Expand Up @@ -179,34 +179,34 @@ def __init__(self):
self.user_callback = None self.user_callback = None
self.unauthorized_callback = None self.unauthorized_callback = None
self.needs_refresh_callback = None self.needs_refresh_callback = None

def user_loader(self, callback): def user_loader(self, callback):
""" """
This sets the callback for reloading a user from the session. The This sets the callback for reloading a user from the session. The
function you set should take a user ID (a `unicode`) and return a function you set should take a user ID (a `unicode`) and return a
user object, or `None` if the user does not exist. user object, or `None` if the user does not exist.
:param callback: The callback for retrieving a user object. :param callback: The callback for retrieving a user object.
""" """
self.user_callback = callback self.user_callback = callback

def token_loader(self, callback): def token_loader(self, callback):
""" """
This sets the callback for loading a user from an authentication This sets the callback for loading a user from an authentication
token. The function you set should take an authentication token token. The function you set should take an authentication token
(a `unicode, as returned by a user's `get_auth_token` method) and (a `unicode, as returned by a user's `get_auth_token` method) and
return a user object, or `None` if the user does not exist. return a user object, or `None` if the user does not exist.
:param callback: The callback for retrieving a user object. :param callback: The callback for retrieving a user object.
""" """
self.token_callback = callback self.token_callback = callback

def setup_app(self, app, add_context_processor=True): def setup_app(self, app, add_context_processor=True):
""" """
Configures an application. This registers a `before_request` and an Configures an application. This registers a `before_request` and an
`after_request` call, and attaches this `LoginManager` to it as `after_request` call, and attaches this `LoginManager` to it as
``app.login_manager``. ``app.login_manager``.
:param app: The `flask.Flask` object to configure. :param app: The `flask.Flask` object to configure.
:param add_context_processor: Whether to add a context processor to :param add_context_processor: Whether to add a context processor to
the app that adds a `current_user` the app that adds a `current_user`
Expand All @@ -217,32 +217,32 @@ def setup_app(self, app, add_context_processor=True):
app.after_request(self._update_remember_cookie) app.after_request(self._update_remember_cookie)
if add_context_processor: if add_context_processor:
app.context_processor(_user_context_processor) app.context_processor(_user_context_processor)

def unauthorized_handler(self, callback): def unauthorized_handler(self, callback):
""" """
This will set the callback for the `unauthorized` method, which among This will set the callback for the `unauthorized` method, which among
other things is used by `login_required`. It takes no arguments, and other things is used by `login_required`. It takes no arguments, and
should return a response to be sent to the user instead of their should return a response to be sent to the user instead of their
normal view. normal view.
:param callback: The callback for unauthorized users. :param callback: The callback for unauthorized users.
""" """
self.unauthorized_callback = callback self.unauthorized_callback = callback

def unauthorized(self): def unauthorized(self):
""" """
This is called when the user is required to log in. If you register a This is called when the user is required to log in. If you register a
callback with `unauthorized_handler`, then it will be called. callback with `unauthorized_handler`, then it will be called.
Otherwise, it will take the following actions: Otherwise, it will take the following actions:
- Flash `login_message` to the user. - Flash `login_message` to the user.
- Redirect the user to `login_view`. (The page they were attempting - Redirect the user to `login_view`. (The page they were attempting
to access will be passed in the `next` query string variable, so to access will be passed in the `next` query string variable, so
you can redirect there if present instead of the homepage.) you can redirect there if present instead of the homepage.)
If `login_view` is not defined, then it will simply raise a 401 If `login_view` is not defined, then it will simply raise a 401
(Unauthorized) error instead. (Unauthorized) error instead.
This should be returned from a view or before/after_request function, This should be returned from a view or before/after_request function,
otherwise the redirect will have no effect. otherwise the redirect will have no effect.
""" """
Expand All @@ -254,33 +254,33 @@ def unauthorized(self):
if self.login_message: if self.login_message:
flash(self.login_message) flash(self.login_message)
return redirect(login_url(self.login_view, request.url)) return redirect(login_url(self.login_view, request.url))

def needs_refresh_handler(self, callback): def needs_refresh_handler(self, callback):
""" """
This will set the callback for the `needs_refresh` method, which among This will set the callback for the `needs_refresh` method, which among
other things is used by `fresh_login_required`. It takes no arguments, other things is used by `fresh_login_required`. It takes no arguments,
and should return a response to be sent to the user instead of their and should return a response to be sent to the user instead of their
normal view. normal view.
:param callback: The callback for unauthorized users. :param callback: The callback for unauthorized users.
""" """
self.needs_refresh_callback = callback self.needs_refresh_callback = callback

def needs_refresh(self): def needs_refresh(self):
""" """
This is called when the user is logged in, but they need to be This is called when the user is logged in, but they need to be
reauthenticated because their session is stale. If you register a reauthenticated because their session is stale. If you register a
callback with `needs_refresh_handler`, then it will be called. callback with `needs_refresh_handler`, then it will be called.
Otherwise, it will take the following actions: Otherwise, it will take the following actions:
- Flash `needs_refresh_message` to the user. - Flash `needs_refresh_message` to the user.
- Redirect the user to `refresh_view`. (The page they were attempting - Redirect the user to `refresh_view`. (The page they were attempting
to access will be passed in the `next` query string variable, so to access will be passed in the `next` query string variable, so
you can redirect there if present instead of the homepage.) you can redirect there if present instead of the homepage.)
If `refresh_view` is not defined, then it will simply raise a 403 If `refresh_view` is not defined, then it will simply raise a 403
(Forbidden) error instead. (Forbidden) error instead.
This should be returned from a view or before/after_request function, This should be returned from a view or before/after_request function,
otherwise the redirect will have no effect. otherwise the redirect will have no effect.
""" """
Expand All @@ -291,7 +291,7 @@ def needs_refresh(self):
abort(403) abort(403)
flash(self.needs_refresh_message) flash(self.needs_refresh_message)
return redirect(login_url(self.refresh_view, request.url)) return redirect(login_url(self.refresh_view, request.url))

def _load_user(self): def _load_user(self):
config = current_app.config config = current_app.config
if config.get("SESSION_PROTECTION", self.session_protection): if config.get("SESSION_PROTECTION", self.session_protection):
Expand All @@ -306,7 +306,7 @@ def _load_user(self):
self._load_from_cookie(request.cookies[cookie_name]) self._load_from_cookie(request.cookies[cookie_name])
else: else:
self.reload_user() self.reload_user()

def _session_protection(self): def _session_protection(self):
sess = session._get_current_object() sess = session._get_current_object()
ident = _create_identifier() ident = _create_identifier()
Expand All @@ -326,8 +326,8 @@ def _session_protection(self):
session_protected.send(app) session_protected.send(app)
return True return True
return False return False


def reload_user(self): def reload_user(self):
ctx = _request_ctx_stack.top ctx = _request_ctx_stack.top
user_id = session.get("user_id", None) user_id = session.get("user_id", None)
Expand All @@ -339,7 +339,7 @@ def reload_user(self):
logout_user() logout_user()
else: else:
ctx.user = user ctx.user = user

def _load_from_cookie(self, cookie): def _load_from_cookie(self, cookie):
if self.token_callback: if self.token_callback:
user = self.token_callback(cookie) user = self.token_callback(cookie)
Expand All @@ -355,15 +355,15 @@ def _load_from_cookie(self, cookie):
session["user_id"] = user_id session["user_id"] = user_id
session["_fresh"] = False session["_fresh"] = False
self.reload_user() self.reload_user()

def _update_remember_cookie(self, response): def _update_remember_cookie(self, response):
operation = session.pop("remember", None) operation = session.pop("remember", None)
if operation == "set" and "user_id" in session: if operation == "set" and "user_id" in session:
self._set_cookie(response) self._set_cookie(response)
elif operation == "clear": elif operation == "clear":
self._clear_cookie(response) self._clear_cookie(response)
return response return response

def _set_cookie(self, response): def _set_cookie(self, response):
# cookie settings # cookie settings
config = current_app.config config = current_app.config
Expand All @@ -378,7 +378,7 @@ def _set_cookie(self, response):
expires = datetime.now() + duration expires = datetime.now() + duration
# actually set it # actually set it
response.set_cookie(cookie_name, data, expires=expires, domain=domain) response.set_cookie(cookie_name, data, expires=expires, domain=domain)

def _clear_cookie(self, response): def _clear_cookie(self, response):
config = current_app.config config = current_app.config
cookie_name = config.get("REMEMBER_COOKIE_NAME", COOKIE_NAME) cookie_name = config.get("REMEMBER_COOKIE_NAME", COOKIE_NAME)
Expand All @@ -405,10 +405,10 @@ def login_user(user, remember=False, force=False):
Logs a user in. You should pass the actual user object to this. If the Logs a user in. You should pass the actual user object to this. If the
user's `is_active` method returns `False`, they will not be logged in user's `is_active` method returns `False`, they will not be logged in
unless `force` is `True`. unless `force` is `True`.
This will return `True` if the log in attempt succeeds, and `False` if This will return `True` if the log in attempt succeeds, and `False` if
it fails (i.e. because the user is inactive). it fails (i.e. because the user is inactive).
:param user: The user object to log in. :param user: The user object to log in.
:param remember: Whether to remember the user after their session expires. :param remember: Whether to remember the user after their session expires.
:param force: If the user is inactive, setting this to `True` will log :param force: If the user is inactive, setting this to `True` will log
Expand Down Expand Up @@ -460,20 +460,20 @@ def login_required(fn):
If you decorate a view with this, it will ensure that the current user is If you decorate a view with this, it will ensure that the current user is
logged in and authenticated before calling the actual view. (If they are logged in and authenticated before calling the actual view. (If they are
not, it calls the `~LoginManager.unauthorized` callback.) For example:: not, it calls the `~LoginManager.unauthorized` callback.) For example::
@app.route("/post") @app.route("/post")
@login_required @login_required
def post(): def post():
pass pass
If there are only certain times you need to require that your user is If there are only certain times you need to require that your user is
logged in, you can do so with:: logged in, you can do so with::
if not current_user.is_authenticated(): if not current_user.is_authenticated():
return current_app.login_manager.unauthorized() return current_app.login_manager.unauthorized()
(which is essentially the code that this function adds to your views). (which is essentially the code that this function adds to your views).
:param fn: The view function to decorate. :param fn: The view function to decorate.
""" """
@wraps(fn) @wraps(fn)
Expand All @@ -490,12 +490,12 @@ def fresh_login_required(fn):
login is fresh - i.e. there session was not restored from a "remember me" login is fresh - i.e. there session was not restored from a "remember me"
cookie. Sensitive operations, like changing a password or e-mail, should cookie. Sensitive operations, like changing a password or e-mail, should
be protected with this, to impede the efforts of cookie thieves. be protected with this, to impede the efforts of cookie thieves.
If the user is not authenticated, `LoginManager.unauthorized` is called If the user is not authenticated, `LoginManager.unauthorized` is called
as normal. If they are authenticated, but their session is not fresh, as normal. If they are authenticated, but their session is not fresh,
it will call `LoginManager.needs_refresh` instead. (In that case, you it will call `LoginManager.needs_refresh` instead. (In that case, you
will need to provide a `~LoginManager.refresh_view`.) will need to provide a `~LoginManager.refresh_view`.)
:param fn: The view function to decorate. :param fn: The view function to decorate.
""" """
@wraps(fn) @wraps(fn)
Expand All @@ -518,19 +518,19 @@ def is_active(self):
Returns `True`. Returns `True`.
""" """
return True return True

def is_authenticated(self): def is_authenticated(self):
""" """
Returns `True`. Returns `True`.
""" """
return True return True

def is_anonymous(self): def is_anonymous(self):
""" """
Returns `False`. Returns `False`.
""" """
return False return False

def get_id(self): def get_id(self):
""" """
Assuming that the user object has an `id` attribute, this will take Assuming that the user object has an `id` attribute, this will take
Expand All @@ -548,13 +548,13 @@ class AnonymousUser(object):
""" """
def is_authenticated(self): def is_authenticated(self):
return False return False

def is_active(self): def is_active(self):
return False return False

def is_anonymous(self): def is_anonymous(self):
return True return True

def get_id(self): def get_id(self):
return None return None


Expand Down
1 change: 0 additions & 1 deletion flaskext/__init__.py

This file was deleted.

7 changes: 3 additions & 4 deletions setup.py
Expand Up @@ -23,15 +23,14 @@


setup( setup(
name='Flask-Login', name='Flask-Login',
version='0.1.1', version='0.1.2',
url='http://bitbucket.org/leafstorm/flask-login/', url='https://github.com/maxcountryman/flask-login',
license='MIT', license='MIT',
author='Matthew Frazier', author='Matthew Frazier',
author_email='leafstormrush@gmail.com', author_email='leafstormrush@gmail.com',
description='User session management for Flask', description='User session management for Flask',
long_description=__doc__, long_description=__doc__,
packages=['flaskext'], py_modules=['flask_login'],
namespace_packages=['flaskext'],
zip_safe=False, zip_safe=False,
platforms='any', platforms='any',
install_requires=[ install_requires=[
Expand Down

0 comments on commit 89865a1

Please sign in to comment.