paulsykes / web.py-auth

An authentication module for web.py 0.3, code originally by jpscaletti.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Authentication module for web.py 0.3

This is an authentication module for web.py, code originally by jpscaletti.

The module allows you to:

  • Limit access to pages based on if the user is logged in, if is authorized (by checking against a table of permissions) or meet certain conditions.

  • Generate and manage password hashes. Sha1, sha512 and bcrypt are supported.

  • Authenticate a user by checking a login and password against a database of users.

  • Generate and validate tokens for passwords resets.

  • CAPTCHA validation(Only visual CAPTCHAs) (New)

It also includes default pages to login, generate a password-reset token, email the token and set a new password after the token is validated.

Installation

  1. Put the auth package in the web/contrib/ folder.

  2. Create the following tables:

    CREATE TABLE user (
        user_id             int NOT NULL AUTO_INCREMENT PRIMARY KEY,
        user_login          varchar(64) NOT NULL,
        user_password       varchar(255) NOT NULL,
        user_email          varchar(64),  # Optional, see settings
        user_status         varchar(16) NOT NULL DEFAULT 'active',
        user_last_login     datetime NOT NULL
    )
    
    CREATE TABLE permission (
        permission_id           int NOT NULL AUTO_INCREMENT PRIMARY KEY,
        permission_codename     varchar(50),  # Example: 'can_vote'
        permission_desc         varchar(50)   # Example: 'Can vote in elections'
    )
    
    CREATE TABLE user_permission (
        up_user_id          int REFERENCES user (user_id),
        up_permission_id    int REFERENCES permission (permission_id),
        PRIMARY KEY (up_user_id, up_permission_id)
    )
  3. Generally use in your code:

    import web
    from web.contrib.auth import auth
    
    urls = (
        '/', 'index',
    )
    app = web.application(urls, locals())
    db = web.database(dbn='mysql', db='webpy', user='scott', pw='tiger')
    settings = {}
    
    auth.init_app(app, db, **settings)

    The system will create and use a DiskStore session. If you want to use an existing one or another type of session, you pass it as an argument.

    mysession = web.session.Session(app, web.session.DiskStore('sessions'))
    auth.init_app(app, db, mysession, **settings)
  4. Enable CAPTCHA validation

    To enable the CAPTCHA validation, you need an extra CAPTCHA module which could generate the CAPTCHAs(visual CAPTCHAs) and the text-based check-code(can be input by user on the authentication page). You should use a wrapper function, which has No parameters and exact TWO return values. One is the CAPTCHA image, an str instance, the value or content of a cStringIO.StringO or StringIO.StringO object(see here for details), whose file type determines the value of captcha_image_type. The other one is the CAPTCHA check-code string. Then, pass the wrapper function and the image type as arguments.

    from Captcha import captcha_func
    
    settings = dict({
        'captcha_func': captcha_func,
        'captcha_image_type': 'png',
    })
    
    auth.init_app(app, db, **settings)

Usage

Once you initiated the auth application a number of methods are available:

@auth.protected(**pars)
Decorator for limiting the access to pages.
Examples:

Limiting access to authenticated users

class SomePage:
    @auth.protected()
    def GET(self):
        ...

Limiting access to users with a specific permission

class SomePage:
    @auth.protected(perm='can_edit')
    def GET(self):
        ...

Limiting access to users who pass a test


def over18(user):
    return user.age > 18

class SomePage:
    @auth.protected(test=over18)
    def GET(self):
        ...

Limiting access to users who need to pass the CAPTCHA validation

class SomePage:
    @auth.protected(captcha_on=True)
    def GET(self):
        ...

If the CAPTCHA validation is failed or the user isn't authorized it'll be redirected to settings.url_login ('/login' by default).

auth.authenticate(login, password)
Validates the user's credentials. If they are valid returns a user object (minus the password hash) or None if not.
user = auth.authenticate(login='john', password='secret')
if not user:
    return 'That's correct'
else:
    return 'Wrong!'

This function does not log in the user. Use auth.login() for that.

auth.login(user)
Set the user as logged in.
auth.check_password(password, stored_passw)
Returns a boolean of whether the password was correct.
auth.logout()
Flush the authenticated user session
auth.user_exist(login)
Return True if a user with that login already exist.
auth.create_user(login, password=None, perms=[], **data)
Create a new user and returns the user_id.

If password is None, it will marks the user as having no password (check_password() for this user will never return True).

auth.set_password(login, password=None)
Sets the password of an already existing user to the given raw string, taking care of the password hashing.
auth.update_user(login, **data)
Update the user's data taking care of the password hashing if one is provided.
auth.get_user(login=None)
Returns a user object (minus the password hash).

If login is None returns the currently authenticated user object or None if there isn't one

auth.pass_test(user=None)
Return True if the user pass the test.

test must be a function that takes a user object and returns True or False.

auth.has_perm(perm, user=None)
Return True if the user has the permission.

Perm can be either a single permission (string) or a sequence of them.

auth.get_permissions(user=None)
Returns a list of permission strings that the user has.
auth.create_permission(codename, desc)
Creates a new permission. If the permission already exists it update the description.

Example: create_permission('new_posts', 'Can write new posts')

auth.delete_permission(codename)
Deletes a permission
auth.add_permission(perm, user_id)
Assign an existing permission to a user.
auth.remove_permission(perm, user_id)
Removes the permission.
auth.login_form(auth)
A login form to be used inside other pages (like the home page).

Automatic views

By default the system will map a login, logout and password-reset pages. This can be disabled in the settings.

Settings

hash_type = 'sha512'
Either sha1, sha512 (default) or bcrypt — the algorithm used to perform a one-way hash of the password. Note that bcrypt is only supported on platforms that have the Python py-bcrypt module available.
hash_depth = 12
How many time the password is recursively hashed.
db_email_field = 'user_email'
Field of the user table that contains the email address. For instance, if you want to use the email as the username, you can change this to 'user_login'.
password_minlen = 6
Minimum password length. set_password() and create_user will raise an "AuthError, 'bad password'" if the password is shorter than this.
forced_delay = 0.5
Artificial delay (in seconds) to slow down brute-force attacks
auto_map = True
Disable the auto-magically generated pages for login, logout and password reset. If it is True, it will use the url_* and template_* settings.
captcha_enabled = False
CAPTCHA validation is disabled by default. You could enable it automatically by define an extra CAPTCHA generation module as described above.
captcha_image_type = 'png'
The default file type of the CAPTCHA image, which is decided by the module which generates the CAPTCHA image. You could set the value here without passing a dict argument settings that contains it.
url_captcha = '/captcha'
The URL for the CAPTCHA image.
url_login = '/login'
The URL for the log in page.
url_logout = '/logout'
The URL for the log out.
url_after_login = '/'
Go there after a successful login
template_login = None
A template function:
render = web.template.render('/templates')
settings = dict(
    template_login = render.mylogin,
)
auth = DBAuth(app, db, **settings)

If None, the default template will be used. See web/contrib/auth/templates/login.html

url_reset_token = '/password_reset'
The URL of the password-reset token generation page.
url_reset_change = '/password_reset'
The URL for the password change page.
template_reset_token = None
A template function. If None, the default template will be used. See web/contrib/auth/templates/reset_token.html
template_reset_email = None
A template function. If None, the default template will be used. See web/contrib/auth/templates/reset_email.html
template_reset_change = None
A template function. If None, the default template will be used. See web/contrib/auth/templates/reset_change.html
reset_expire_after = 2
Number of hours than the password-reset token will be valid.
email_from = ''
The password-reset email “From:” header.

License (MIT)

This module is released under the MIT license (MIT), anyone is welcome to contribute.

About

An authentication module for web.py 0.3, code originally by jpscaletti.

License:Other


Languages

Language:Python 79.4%Language:HTML 20.6%