Skip to content

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

License

Notifications You must be signed in to change notification settings

AmbiLabs/web.py-auth

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

50 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Python 79.4%
  • HTML 20.6%