Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/foxbunny/acl.py
authentication framework for web.py
https://github.com/foxbunny/acl.py
Last synced: 28 days ago
JSON representation
authentication framework for web.py
- Host: GitHub
- URL: https://github.com/foxbunny/acl.py
- Owner: foxbunny
- License: gpl-3.0
- Created: 2009-12-24T21:51:24.000Z (almost 15 years ago)
- Default Branch: master
- Last Pushed: 2010-12-22T21:53:03.000Z (about 14 years ago)
- Last Synced: 2023-03-10T22:13:37.242Z (almost 2 years ago)
- Language: Python
- Homepage:
- Size: 283 KB
- Stars: 10
- Watchers: 2
- Forks: 4
- Open Issues: 7
-
Metadata Files:
- Readme: README
- License: LICENSE
Awesome Lists containing this project
README
# authentication.py: user authentication and management for web.py
The goal of this project is to provide a ready-to-use microframework for
creating and managing users, secure storage of authentication data, and
permission management for your [web.py](http://www.webpy.org/) site.## Dependencies
* [web.py](http://www.webpy.org/) (obviously)
* [nose](http://code.google.com/p/python-nose/) (for running tests only)
* [sqlite3](http://www.sqlite.org/) (for running tests only)## Project status
This project is currently under heavy development. Most facilities either don't
work, or are not even designed yet. We have scheduled the release of 0.1 with
fully functional user management during October 2010. Here is the brief roadmap:* v0.1 (Oct 2010): fully functional user management
* v0.2 (n/a): fully functional permissions management
* v0.3 (n/a): fully functional group managementKeep track of issues in the
[issue tracker](http://github.com/foxbunny/authentication.py/issues) to stay on
top of the changes that will end up in the releases.Each of the version will add one module to the project. User management is in
the ``auth`` module, which is curretly being worked on. Permissions management
will be pu in ``perm`` module, and groups will reside in ``group`` module.The project is definitely not dead. It was put on ice a year ago, but I've
started developing web apps again, so this project has become relevant again.Expect updates soon. The v0.1 release is expected in the following weeks. The
first release will _not_ include the example app, as I have no time to work on
it at this time. Therefore, I will not integrate the example into the master or
release branches. The README file, and the tests should be sufficient to cover
the usage.## Before using authentication.py
The first thing you need to do is tell authentication.py which database it will
be using. To do this, add ``authdb`` key to ``web.config``. Here's an example
using PostgreSQL:import web
somedb = web.database(dbn='postgres', db='my_app_db', user='postgres')
web.config.authdb = somedbYou can also have a separate database just for authentication (e.g, if you want
to use a common authentication database between different apps). Just assign
wahtever database you want to use to ``web.config.authdb``.If you want to take advantage of messaging facilities, you also need to define
a ``web.config.authmail`` key, and assign it a dictionary of options:import web
web.config.authmail = {'sender': '[email protected]',
'activation_subject': 'Activate your account',
'reset_subject': 'Your password has been reset',
'delete_subject': Your account was removed',
'suspend_subject': 'Your account is suspended'}Defaults for the subject messages are:
* ``activation_subject``: _Account activation_
* ``reset_subject``: _Password reset_
* ``delete_subject``: _Account removed_
* ``suspend_subject``: _Account suspended_If you are happy with these defaults, you don't have to include them in the
configuration dictionary. Sender is still required.## User object
``User`` object is the key component of the ``auth`` module. It has both
class methods and instance methods that facilitate its functionality.### Creating a new user
To create a user, you can use the ``User`` class from the
``authenticationpy.auth`` module. Before actually creating a user, you need to
specify the three required properties:>>> from authenticationpy.auth import User
>>> user = User(username='myuser'
... email='[email protected]')
>>> user.password = 'clear-text password'
>>> user.create()A user account is not atomatically activated after creation. The ``activate``
method must be called on the instance at some point to activate it.### Creating a user with activation e-mail
If you want to send out an activation e-mail, you can do so by specifying the
activation message:>>> from authenticationpy.auth import User
>>> user = User(username="myuser",
... email="[email protected]")
>>> user.password = 'clear-text password'
>>> user.create(message="""
Please activate your account at
http://mysite.com/activate/$url
""")The format of the activation message is arbitrary, and you can use any
template you like. The template variables available for customizing the
message dynamically are:* ``$url``: activation URL suffix that is generated automatically
* ``$username``: username
* ``$email``: the e-mail address used for creating the user
* ``$password``: the clear-text passwordNote that the clear-text password is only stored in memory, and cannot be
retrieved later. If you want to send activation e-mails more than once, do not
include the password in your template. If the clear-text password is lost, the
template variable will be replaced with an empty string.### Setting activation information and obtaining the action code
If you have your own system for notifying users about activation, and then
requesting activation action, you can use the ``set_activation`` method to set
the user account to an _activatable_ state. Here's an example:>>> from authenticationpy.auth import User
>>> user = User(username='myuser',
... email='[email protected]')
>>> user.password = 'clear-text password'
>>> code = user.set_activation()
>>> user.create()In the above example, the ``code`` variable is assigned an activation code that
is generated by the ``set_activation`` method. This code is the same one used
for the activation URL, and it's a SHA-256 hexdigest.### Finding a user account by activation code
This does not strictly apply to activation. It also applies to all cases where
you may be using the action code (such as account removal confirmation, or
password reset). To get a user account by action (activation) code, you can use
the ``get_user_by_act_code`` class method. Here is an example:>>> from authenticationpy.auth import User
>>> code = some_code # a SHA-256 hexdigest
>>> user = User.get_user_by_act_code(code)
# do something with the user account### Testing the timeliness of user action
Once a user clicks on the activation link (in fact, this applies to all cases
where you are using the action code for confirming user action), you know the
code, and you can also get the associated user account. If you don't impose any
deadlines for user action, you may proceed to activate the account, or any
other action that was confirmed. However, if you do impose deadlines, there is
a convenience method that you can use to test if user action was timely.To test the timeliness of user actions, you can call the
``is_interaction_timely`` method on any ``User`` instance.>>> import datetime
>>> from authenticationpy.auth import User
>>> code = some_code # a SHA-256 hexdigest
>>> user = User.get_user_by_act_code(code)
>>> deadline = 172800 # this is the deadline in seconds (48 hours)
>>> user.is_interaction_timely('a', deadline)
TrueThis method requires two arguments:
* ``type``: must be ``'a'`` (activation), ``'d'`` (delete), or ``'r'`` (reset password)
* ``deadline``: action deadline in secondsIt returns a boolean value of the success status.
If there are no actions to confirm (e.g., no pending activation or
confirmation), ``UserAccountError`` is raised.Clearing user action data
-------------------------Once user action was confirmed, it is no longer necessary to keep interaction
data in the database. To clear the data, you can use the ``clear_interaction``
instance method.>>> from authenticationpy.auth import User
>>> user = User.get_user(username='myuser')
>>> user.clear_interaction()
>>> user.store()After clearing the interaction data, the account must be stored to make the
changes permanent.Activating a user account
-------------------------Calling ``activate`` on User instance activates it. Although it is activated
in-memory, it is not saved as activated, so you need to store changes before a
user can log in.>>> from authenticationpy.auth import User
>>> user = User.get_user(username='myuser')
>>> user.activate()
>>> user.store()Creating a user with activation
-------------------------------You can both create and activate a user account at the same time. To do that,
you can pass the ``activated`` argument to the ``create`` method:>>> from authenticationpy.auth import User
>>> user = User(username='myuser',
... email='[email protected]')
>>> user.create(activated=True)
>>> same_user = User.get_user(username='myuser')
>>> same_user.active
TrueThis results in a single database transaction, which is more efficient than
calling ``create`` without ``activated`` argument, and then calling
``activate`` explicitly.Getting the user record
-----------------------To get the user record, you can call the ``get_user`` class method::
>>> from authenticationpy.auth import User
>>> user = User.get_user(email="[email protected]")You can use either the username or the e-mail address as an argument for the
``get_user`` method.### Authenticating the user
To check the user password (to authenticate it), you must call the
``authenticate`` method on the user object:>>> from authenticationpy.auth import User
>>> user = User.get_user(username='myuser')
>>> user.authenticate('clear-text password')
TrueThe method returns True or False depending on whether authentication was
successful. Note that due to web.py's session handling, authentication.py will
_not_ automatically assign users to a session. It is your responsibility to do
so.### Password length constraints
Default password minimum length is 4 characters. If you want your users to use
a longer minimum length password (or shorter), you can customize the minimum
length by setting ``web.config.min_pwd_length`` configuration variable. In case
the password you are trying to set is shorter than minimum length,
``ValueError`` is raised. The same exception is raised when password is
0-length. Even if you set ``web.config.min_pwd_length`` to 0, 0-length
passwords are not allowed. The absolute minimum allowed password length is 1.### Resetting the password
You can reset the user password in two ways. You can simply assign a new
clear-text password to the password property or you can call the
``reset_password`` method, which can optionally send out a notification or
confirmation e-mail.Here is an example using the property method::
>>> from authenticationpy.auth import User
>>> user = User.get_user(username='myuser')
>>> user.password = 'new password'
>>> user.store()And here is an example with the ``reset_password`` method::
>>> from authenticationpy.auth import User
>>> user = User.get_user(username='myuser')
>>> user.reset_password('new password',
message='Your password is now $password')The template for the ``message`` argument can contain the following variables:
* ``$url``: automatically generated confirmation url suffix
* ``$username``: username
* ``$email``: the user's e-mail address
* ``$password``: the new cleartext passwordIf you are not sending any confirmation e-mail, but you still use a different
confirmation method, you can use the ``confirmation`` argument. If you pass
this argument with the value of ``True``, ``reset_password`` will behave as if
you have passed it the ``message`` argument.You can also set the new password even if you send the e-mail. For example, if
you want to simply notify your user, rather than request an action, you can
pass the ``confirmation`` argument with the value of ``False`` and omit the URL
from URL from your message.### Confirming password resets
If you have decided to delay confirmation and send out a confirmation e-mail
when using ``password_reset`` method, you need to explicitly assign the new
password. The pending password (password that is still not confirmed) is stored
in encrypted form in the database. In order to assign that password as the new
password, you can call ``confirm_password``.>>> from authenticationpy.auth import User
>>> user = User.get_user(username='myuser')
>>> user.confirm_password()
>>> user.store()As you can see, you have to call ``store`` to make the changes permanent.
### Sending e-mails to a user
Arbitrary e-mail messages can be sent to users using the ``send_email`` method.
Here's a simple example:>>> from authenticationpy.auth import User
>>> user = User.get_user(username='myuser')
>>> user.send_email(message="Hi!")As will all other e-mail facilities, you can add template variables to the
e-mail message, but for regular e-mail, you can use any template variables you
like. Just pass any variable as a keyword argument:>>> from authenticationpy.auth import User
>>> user = User.get_user(username='myuser')
>>> user.send_email(message="$greeting, $username",
... greeting="Hello,",
... username=user.username)### Deleting a user
To delete a user (i.e, permanently remove its records), you can use the
``delete`` class method:>>> from authenticationpy.auth import User
>>> User.delete(username='myuser')You can also send out a notification or confirmation e-mail:
>>> from authenticationpy.auth import User
>>> User.delete(username='myuser',
... message="""
... Please confirm this by clicking on this link:
... http://mysite.com/confirm/$url
... """)If you decide to send a confirmation e-mail, the user account is not removed
until its removal is confirmed by ``confirm_delete`` class method.Available e-mail message template variables are::
* ``$url``: automatically generated confirmation url suffix
* ``$username``: username
* ``$email``: the user's e-mail address### Confirming user account removal
If you have used the confirmation e-mail functionality when deleting a user
account, you need to explcitly confirm account removal. You can do that by
using the ``confirm_delete`` class method::>>> from authenticationpy.auth import User
>>> User.confirm_delete(username='myuser')### Suspending an account
User account can be deleted, and it's gone forever. If you only want to
disable authentication for a particular account, you can suspend it instead of
deleting it. To do this, just use the ``suspend`` class method. It is an e-mail
method, like some of the other methods.>>> from authenticationpy.auth import User
>>> User.suspend(username='myuser',
... message="""
... Hi, $username,
... Your account has been suspended, can you believe it?
... """)Unlike other e-mail methods, ``suspend`` doesn't require any confirmation, so
the only available template variables are:* ``$username``: account username
* ``$email``: user's e-mail addressYou can also suspend an account by simply deactivating it::
>>> from authenticationpy.auth import User
>>> user = User.get_user(username='myuser')
>>> user.active = False
>>> user.store()Trying to authenticate using a suspended account will result in a
``UserAccountError`` exception.### Updating user details
Updating properties for a user is as simple as assigning new values to them.
Some validation occurs behind the scene (e.g, creating the encrypted version of
the password), but most of the time you don't need to worry about that. Once
you've assigned new properties for the user, you have to call the ``store``
method to write changes to the database.>>> from authenticationpy.auth import User
>>> user = User.get_user(username='myuser')
>>> user.username = 'mynewuser'
>>> user.store()You should note that even the e-mail address can be changed. It is your
responsibility to prevent that if you don't want your users to change the
e-mail address.