add initial auth framework
This commit is contained in:
parent
4808857f40
commit
df9524a6ac
12 changed files with 280 additions and 202 deletions
|
@ -74,7 +74,7 @@ def init(config):
|
||||||
from edbob.db import enum
|
from edbob.db import enum
|
||||||
# from edbob.db.model import get_metadata
|
# from edbob.db.model import get_metadata
|
||||||
# from edbob.db.mappers import make_mappers
|
# from edbob.db.mappers import make_mappers
|
||||||
# from edbob.db.extensions import extend_framework
|
from edbob.db.extensions import extend_framework
|
||||||
|
|
||||||
# global inited, engines, engine, metadata
|
# global inited, engines, engine, metadata
|
||||||
global inited, engines, engine
|
global inited, engines, engine
|
||||||
|
@ -103,7 +103,7 @@ def init(config):
|
||||||
|
|
||||||
# metadata = get_metadata(bind=engine)
|
# metadata = get_metadata(bind=engine)
|
||||||
# make_mappers(metadata)
|
# make_mappers(metadata)
|
||||||
# extend_framework()
|
extend_framework()
|
||||||
|
|
||||||
edbob.graft(edbob, edbob.db)
|
edbob.graft(edbob, edbob.db)
|
||||||
# edbob.graft(edbob, classes)
|
# edbob.graft(edbob, classes)
|
||||||
|
|
|
@ -32,7 +32,6 @@ from sqlalchemy.orm import object_session
|
||||||
|
|
||||||
import edbob
|
import edbob
|
||||||
from edbob.db import needs_session
|
from edbob.db import needs_session
|
||||||
from edbob.db.classes import Permission, Role, User
|
|
||||||
|
|
||||||
|
|
||||||
class BcryptAuthenticator(edbob.Object):
|
class BcryptAuthenticator(edbob.Object):
|
||||||
|
@ -55,13 +54,13 @@ def authenticate_user(session, username, password):
|
||||||
returns the :class:`edbob.User` instance; otherwise returns ``None``.
|
returns the :class:`edbob.User` instance; otherwise returns ``None``.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
user = session.query(User).filter_by(username=username).first()
|
q = session.query(edbob.User)
|
||||||
if not user:
|
q = q.filter(edbob.User.username == username)
|
||||||
return None
|
user = q.first()
|
||||||
auth = BcryptAuthenticator()
|
if user:
|
||||||
if not auth.authenticate_user(user, password):
|
auth = BcryptAuthenticator()
|
||||||
return None
|
if auth.authenticate_user(user, password):
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
def administrator_role(session):
|
def administrator_role(session):
|
||||||
|
@ -103,3 +102,26 @@ def has_permission(obj, perm):
|
||||||
if permission == perm:
|
if permission == perm:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def init_database(engine, session):
|
||||||
|
"""
|
||||||
|
Initialize the auth system within an ``edbob`` database.
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Create 'admin' user with full rights.
|
||||||
|
admin = edbob.User()
|
||||||
|
admin.username = 'admin'
|
||||||
|
set_user_password(admin, 'admin')
|
||||||
|
# admin.roles.append(administrator_role(session))
|
||||||
|
session.add(admin)
|
||||||
|
session.flush()
|
||||||
|
|
||||||
|
|
||||||
|
def set_user_password(user, password):
|
||||||
|
"""
|
||||||
|
Sets the password for the given :class:`edbob.User` instance.
|
||||||
|
"""
|
||||||
|
|
||||||
|
auth = BcryptAuthenticator()
|
||||||
|
auth.populate_user(user, password)
|
||||||
|
|
|
@ -93,36 +93,43 @@ class Extension(edbob.Object):
|
||||||
# """
|
# """
|
||||||
# pass
|
# pass
|
||||||
|
|
||||||
def add_class(self, cls):
|
# def add_class(self, cls):
|
||||||
|
# """
|
||||||
|
# Convenience method for use in :meth:`extend_classes()`.
|
||||||
|
# """
|
||||||
|
|
||||||
|
# from edbob.db import classes
|
||||||
|
|
||||||
|
# name = cls.__name__
|
||||||
|
# edbob.graft(classes, {name:cls}, name)
|
||||||
|
|
||||||
|
# def extend_classes(self):
|
||||||
|
# """
|
||||||
|
# Any extra classes provided by the extension should be added to the ORM
|
||||||
|
# whenever this method is called.
|
||||||
|
|
||||||
|
# Note that the :meth:`add_class()` convenience method is designed to be
|
||||||
|
# used when adding classes.
|
||||||
|
# """
|
||||||
|
# pass
|
||||||
|
|
||||||
|
def extend_framework(self):
|
||||||
"""
|
"""
|
||||||
Convenience method for use in :meth:`extend_classes()`.
|
Extends the framework...
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from edbob.db import classes
|
edbob.graft(edbob, self.get_model_module())
|
||||||
|
|
||||||
name = cls.__name__
|
# def extend_mappers(self, metadata):
|
||||||
edbob.graft(classes, {name:cls}, name)
|
# """
|
||||||
|
# All SQLAlchemy mapping to be done by the extension should be done
|
||||||
|
# within this method.
|
||||||
|
|
||||||
def extend_classes(self):
|
# Any extra classes the extension provides will typically be mapped here.
|
||||||
"""
|
# Any manipulation the extension needs to perform on the ``edbob`` core
|
||||||
Any extra classes provided by the extension should be added to the ORM
|
# ORM should be done here as well.
|
||||||
whenever this method is called.
|
# """
|
||||||
|
# pass
|
||||||
Note that the :meth:`add_class()` convenience method is designed to be
|
|
||||||
used when adding classes.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def extend_mappers(self, metadata):
|
|
||||||
"""
|
|
||||||
All SQLAlchemy mapping to be done by the extension should be done
|
|
||||||
within this method.
|
|
||||||
|
|
||||||
Any extra classes the extension provides will typically be mapped here.
|
|
||||||
Any manipulation the extension needs to perform on the ``edbob`` core
|
|
||||||
ORM should be done here as well.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
def get_metadata(self, recurse=False):
|
def get_metadata(self, recurse=False):
|
||||||
"""
|
"""
|
||||||
|
@ -173,25 +180,25 @@ class Extension(edbob.Object):
|
||||||
if isinstance(obj, type) and issubclass(obj, model.Base):
|
if isinstance(obj, type) and issubclass(obj, model.Base):
|
||||||
obj.__table__.tometadata(metadata)
|
obj.__table__.tometadata(metadata)
|
||||||
|
|
||||||
def remove_class(self, name):
|
# def remove_class(self, name):
|
||||||
"""
|
# """
|
||||||
Convenience method for use in :meth:`restore_classes()`.
|
# Convenience method for use in :meth:`restore_classes()`.
|
||||||
"""
|
# """
|
||||||
|
|
||||||
from edbob.db import classes
|
# from edbob.db import classes
|
||||||
|
|
||||||
if name in classes.__all__:
|
# if name in classes.__all__:
|
||||||
classes.__all__.remove(name)
|
# classes.__all__.remove(name)
|
||||||
if hasattr(classes, name):
|
# if hasattr(classes, name):
|
||||||
del classes.__dict__[name]
|
# del classes.__dict__[name]
|
||||||
|
|
||||||
def restore_classes(self):
|
# def restore_classes(self):
|
||||||
"""
|
# """
|
||||||
This method should remove any extra classes which were added within
|
# This method should remove any extra classes which were added within
|
||||||
:meth:`extend_classes()`. Note that there is a :meth:`remove_class()`
|
# :meth:`extend_classes()`. Note that there is a :meth:`remove_class()`
|
||||||
method for convenience in doing so.
|
# method for convenience in doing so.
|
||||||
"""
|
# """
|
||||||
pass
|
# pass
|
||||||
|
|
||||||
|
|
||||||
def activate_extension(extension, engine=None):
|
def activate_extension(extension, engine=None):
|
||||||
|
@ -233,6 +240,7 @@ def activate_extension(extension, engine=None):
|
||||||
# merge_extension_metadata(extension)
|
# merge_extension_metadata(extension)
|
||||||
# extension.extend_classes()
|
# extension.extend_classes()
|
||||||
# extension.extend_mappers(Base.metadata)
|
# extension.extend_mappers(Base.metadata)
|
||||||
|
extension.extend_framework()
|
||||||
|
|
||||||
# Add extension to in-memory active extensions tracker.
|
# Add extension to in-memory active extensions tracker.
|
||||||
active_extensions(engine).append(extension.name)
|
active_extensions(engine).append(extension.name)
|
||||||
|
@ -318,23 +326,24 @@ def extend_framework():
|
||||||
|
|
||||||
session = Session()
|
session = Session()
|
||||||
try:
|
try:
|
||||||
active_extensions = session.query(ActiveExtension).all()
|
active = session.query(ActiveExtension).all()
|
||||||
except sqlalchemy.exc.ProgrammingError:
|
except sqlalchemy.exc.ProgrammingError:
|
||||||
session.close()
|
session.close()
|
||||||
return
|
return
|
||||||
|
|
||||||
extensions = {}
|
extensions = {}
|
||||||
for ext in active_extensions:
|
for ext in active:
|
||||||
extensions[ext.name] = get_extension(ext.name)
|
extensions[ext.name] = get_extension(ext.name)
|
||||||
session.close()
|
session.close()
|
||||||
|
|
||||||
for name in sorted(extensions, extension_sorter(extensions)):
|
for name in sorted(extensions, extension_sorter(extensions)):
|
||||||
ext = extensions[name]
|
|
||||||
log.info("Applying active extension: %s" % name)
|
log.info("Applying active extension: %s" % name)
|
||||||
merge_extension_metadata(ext)
|
ext = extensions[name]
|
||||||
ext.extend_classes()
|
# merge_extension_metadata(ext)
|
||||||
ext.extend_mappers(rattail.metadata)
|
# ext.extend_classes()
|
||||||
active_extensions[name] = ext
|
# ext.extend_mappers(rattail.metadata)
|
||||||
|
ext.extend_framework()
|
||||||
|
_active_extensions[name] = ext
|
||||||
|
|
||||||
|
|
||||||
def extension_active(extension, engine=None):
|
def extension_active(extension, engine=None):
|
||||||
|
|
|
@ -26,10 +26,11 @@
|
||||||
``edbob.db.extensions.auth`` -- 'auth' Extension
|
``edbob.db.extensions.auth`` -- 'auth' Extension
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from sqlalchemy import MetaData
|
|
||||||
|
|
||||||
from edbob.db.extensions import Extension
|
from edbob.db.extensions import Extension
|
||||||
|
|
||||||
|
from edbob.db.extensions.auth.model import *
|
||||||
|
from edbob.db.extensions.auth.model import __all__
|
||||||
|
|
||||||
|
|
||||||
class AuthExtension(Extension):
|
class AuthExtension(Extension):
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,10 @@
|
||||||
|
|
||||||
from sqlalchemy import *
|
from sqlalchemy import *
|
||||||
from sqlalchemy.orm import relationship
|
from sqlalchemy.orm import relationship
|
||||||
|
from sqlalchemy.ext.associationproxy import association_proxy
|
||||||
|
|
||||||
import edbob
|
import edbob
|
||||||
from edbob.db.model import Base
|
from edbob.db.model import Base, uuid_column
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['Person', 'User']
|
__all__ = ['Person', 'User']
|
||||||
|
@ -52,7 +53,7 @@ class Person(Base):
|
||||||
|
|
||||||
__tablename__ = 'people'
|
__tablename__ = 'people'
|
||||||
|
|
||||||
uuid = Column(String(32), primary_key=True, default=edbob.get_uuid)
|
uuid = uuid_column()
|
||||||
first_name = Column(String(50))
|
first_name = Column(String(50))
|
||||||
last_name = Column(String(50))
|
last_name = Column(String(50))
|
||||||
display_name = Column(String(100), default=get_person_display_name)
|
display_name = Column(String(100), default=get_person_display_name)
|
||||||
|
@ -72,11 +73,14 @@ class User(Base):
|
||||||
|
|
||||||
__tablename__ = 'users'
|
__tablename__ = 'users'
|
||||||
|
|
||||||
uuid = Column(String(32), primary_key=True, default=edbob.get_uuid)
|
uuid = uuid_column()
|
||||||
username = Column(String(25), nullable=False, unique=True)
|
username = Column(String(25), nullable=False, unique=True)
|
||||||
|
password = Column(String(60))
|
||||||
|
salt = Column(String(29))
|
||||||
person_uuid = Column(String(32), ForeignKey('people.uuid'))
|
person_uuid = Column(String(32), ForeignKey('people.uuid'))
|
||||||
|
|
||||||
person = relationship(Person, backref='user')
|
person = relationship(Person, backref='user')
|
||||||
|
# display_name = association_proxy('person', 'display_name')
|
||||||
|
|
||||||
# roles = association_proxy('_roles', 'role',
|
# roles = association_proxy('_roles', 'role',
|
||||||
# creator=lambda x: UserRole(role=x),
|
# creator=lambda x: UserRole(role=x),
|
||||||
|
@ -87,3 +91,13 @@ class User(Base):
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return str(self.username or '')
|
return str(self.username or '')
|
||||||
|
|
||||||
|
@property
|
||||||
|
def display_name(self):
|
||||||
|
"""
|
||||||
|
Returns the user's ``person.display_name``, if present, otherwise the
|
||||||
|
``username``.
|
||||||
|
"""
|
||||||
|
if self.person and self.person.display_name:
|
||||||
|
return self.person.display_name
|
||||||
|
return self.username
|
||||||
|
|
|
@ -77,7 +77,7 @@ table.wrapper td.right {
|
||||||
}
|
}
|
||||||
|
|
||||||
#login {
|
#login {
|
||||||
margin: 8px auto auto 20px;
|
margin: 8px 20px auto auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#user-menu {
|
#user-menu {
|
||||||
|
|
|
@ -32,6 +32,7 @@ from pyramid.security import authenticated_userid
|
||||||
import edbob
|
import edbob
|
||||||
from edbob.db.auth import has_permission
|
from edbob.db.auth import has_permission
|
||||||
from edbob.pyramid import helpers
|
from edbob.pyramid import helpers
|
||||||
|
from edbob.pyramid import Session
|
||||||
|
|
||||||
|
|
||||||
def before_render(event):
|
def before_render(event):
|
||||||
|
@ -62,9 +63,9 @@ def context_found(event):
|
||||||
|
|
||||||
def has_perm_func(request):
|
def has_perm_func(request):
|
||||||
def has_perm(perm):
|
def has_perm(perm):
|
||||||
if not request.current_user:
|
if not request.user:
|
||||||
return False
|
return False
|
||||||
return has_permission(request.current_user, perm)
|
return has_permission(request.user, perm)
|
||||||
return has_perm
|
return has_perm
|
||||||
|
|
||||||
request = event.request
|
request = event.request
|
||||||
|
@ -73,7 +74,7 @@ def context_found(event):
|
||||||
|
|
||||||
uuid = authenticated_userid(request)
|
uuid = authenticated_userid(request)
|
||||||
if uuid:
|
if uuid:
|
||||||
request.user = get_session().query(rattail.User).get(uuid)
|
request.user = Session.query(edbob.User).get(uuid)
|
||||||
|
|
||||||
|
|
||||||
def includeme(config):
|
def includeme(config):
|
||||||
|
|
|
@ -30,13 +30,12 @@
|
||||||
<div id="header">
|
<div id="header">
|
||||||
${self.home_link()}
|
${self.home_link()}
|
||||||
<h1 class="left">${self.title()}</h1>
|
<h1 class="left">${self.title()}</h1>
|
||||||
<div id="login" class="left">
|
<div id="login" class="right">
|
||||||
## <% user = request.current_user %>
|
% if request.user:
|
||||||
% if user:
|
logged in as <strong>${request.user.display_name}</strong>
|
||||||
logged in as <strong>${user.display_name}</strong>
|
|
||||||
(${h.link_to("logout", url('logout'))})
|
(${h.link_to("logout", url('logout'))})
|
||||||
% else:
|
% else:
|
||||||
## ${h.link_to("login", url('login'))}
|
${h.link_to("login", url('login'))}
|
||||||
% endif
|
% endif
|
||||||
</div>
|
</div>
|
||||||
</div><!-- header -->
|
</div><!-- header -->
|
||||||
|
|
64
edbob/pyramid/templates/edbob/login.mako
Normal file
64
edbob/pyramid/templates/edbob/login.mako
Normal file
|
@ -0,0 +1,64 @@
|
||||||
|
<%inherit file="/base.mako" />
|
||||||
|
|
||||||
|
<%def name="title()">Login</%def>
|
||||||
|
|
||||||
|
<%def name="head_tags()">
|
||||||
|
${h.stylesheet_link(request.static_url('edbob.pyramid:static/css/login.css'))}
|
||||||
|
</%def>
|
||||||
|
|
||||||
|
${h.image(request.static_url('edbob.pyramid:static/img/logo.jpg'), "edbob logo")}
|
||||||
|
|
||||||
|
<div class="fieldset">
|
||||||
|
${h.form('')}
|
||||||
|
## <input type="hidden" name="login" value="True" />
|
||||||
|
<input type="hidden" name="referer" value="${referer}" />
|
||||||
|
|
||||||
|
% if error:
|
||||||
|
<div class="error">${error}</div>
|
||||||
|
% endif
|
||||||
|
|
||||||
|
<div class="field-couple">
|
||||||
|
<label for="username">Username:</label>
|
||||||
|
<input type="text" name="username" id="username" value="" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field-couple">
|
||||||
|
<label for="password">Password:</label>
|
||||||
|
<input type="password" name="password" id="password" value="" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="buttons">
|
||||||
|
${h.submit('submit', "Login")}
|
||||||
|
<input type="reset" value="Reset" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
${h.end_form()}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script language="javascript" type="text/javascript">
|
||||||
|
|
||||||
|
$(function() {
|
||||||
|
|
||||||
|
$('form').submit(function() {
|
||||||
|
if (! $('#username').val()) {
|
||||||
|
with ($('#username').get(0)) {
|
||||||
|
select();
|
||||||
|
focus();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (! $('#password').val()) {
|
||||||
|
with ($('#password').get(0)) {
|
||||||
|
select();
|
||||||
|
focus();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#username').focus();
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
|
@ -1,64 +1,2 @@
|
||||||
<%inherit file="base.mako" />
|
<%inherit file="/edbob/login.mako" />
|
||||||
|
${parent.body()}
|
||||||
<%def name="title()">Login</%def>
|
|
||||||
|
|
||||||
<%def name="head_tags()">
|
|
||||||
${h.stylesheet_link('edbob/css/login.css')}
|
|
||||||
</%def>
|
|
||||||
|
|
||||||
${h.image('edbob/img/logo.jpg', "edbob logo")}
|
|
||||||
|
|
||||||
<div class="fieldset">
|
|
||||||
${h.form('')}
|
|
||||||
## <input type="hidden" name="login" value="True" />
|
|
||||||
## <input type="hidden" name="referrer" value="${referrer}" />
|
|
||||||
|
|
||||||
% if error:
|
|
||||||
<div class="error">${error}</div>
|
|
||||||
% endif
|
|
||||||
|
|
||||||
<div class="field-couple">
|
|
||||||
<label for="username">Username:</label>
|
|
||||||
<input type="text" name="username" id="username" value="" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="field-couple">
|
|
||||||
<label for="password">Password:</label>
|
|
||||||
<input type="password" name="password" id="password" value="" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="buttons">
|
|
||||||
${h.submit('submit', "Login")}
|
|
||||||
<input type="reset" value="Reset" />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
${h.end_form()}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script language="javascript" type="text/javascript">
|
|
||||||
|
|
||||||
$(function() {
|
|
||||||
|
|
||||||
$('form').submit(function() {
|
|
||||||
if (! $('#username').val()) {
|
|
||||||
with ($('#username').get(0)) {
|
|
||||||
select();
|
|
||||||
focus();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (! $('#password').val()) {
|
|
||||||
with ($('#password').get(0)) {
|
|
||||||
select();
|
|
||||||
focus();
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
|
|
||||||
$('#username').focus();
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
|
@ -26,71 +26,6 @@
|
||||||
``edbob.pyramid.views`` -- Views
|
``edbob.pyramid.views`` -- Views
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
|
||||||
import os.path
|
|
||||||
|
|
||||||
from pyramid.response import Response
|
|
||||||
from pyramid.view import view_config
|
|
||||||
from pyramid.httpexceptions import HTTPFound
|
|
||||||
|
|
||||||
from edbob.db.auth import authenticate_user
|
|
||||||
|
|
||||||
|
|
||||||
_here = os.path.join(os.path.dirname(__file__), os.pardir)
|
|
||||||
|
|
||||||
|
|
||||||
# _favicon = open(os.path.join(_here, 'static', 'favicon.ico'), 'rb').read()
|
|
||||||
# _favicon_response = Response(content_type='image/x-icon', body=_favicon)
|
|
||||||
|
|
||||||
# @view_config(route_name='favicon.ico')
|
|
||||||
# def favicon_ico(context, request):
|
|
||||||
# return _favicon_response
|
|
||||||
|
|
||||||
|
|
||||||
# @view_config(route_name='home', renderer='/home.mako')
|
|
||||||
# def home(context, request):
|
|
||||||
# return {}
|
|
||||||
|
|
||||||
|
|
||||||
@view_config(route_name='login', renderer='login.mako')
|
|
||||||
def login(context, request):
|
|
||||||
"""
|
|
||||||
The login view, responsible for displaying and handling the login form.
|
|
||||||
"""
|
|
||||||
|
|
||||||
if request.params.get('referer'):
|
|
||||||
referer = request.params['referer']
|
|
||||||
elif request.session.get('referer'):
|
|
||||||
referer = request.session.pop('referer')
|
|
||||||
else:
|
|
||||||
referer = request.referer or request.route_url('home')
|
|
||||||
# if request.current_user:
|
|
||||||
# return HTTPFound(location=referer)
|
|
||||||
# form = Form(self.request, schema=UserLogin)
|
|
||||||
# if form.validate():
|
|
||||||
# user = authenticate_user(self.Session(), form.data['username'], form.data['password'])
|
|
||||||
# if user:
|
|
||||||
# self.request.session.flash("%s logged in at %s" % (
|
|
||||||
# user.display_name,
|
|
||||||
# datetime.datetime.now().strftime("%I:%M %p")))
|
|
||||||
# headers = remember(self.request, user.uuid)
|
|
||||||
# return HTTPFound(location=referer, headers=headers)
|
|
||||||
# self.request.session.flash("Invalid username or password.")
|
|
||||||
# return {'form':FormRenderer(form), 'referer':referer}
|
|
||||||
return {}
|
|
||||||
|
|
||||||
|
|
||||||
# _robots = open(os.path.join(_here, 'static', 'robots.txt')).read()
|
|
||||||
# _robots_response = Response(content_type='text/plain', body=_robots)
|
|
||||||
|
|
||||||
# @view_config(route_name='robots.txt')
|
|
||||||
# def robots_txt(context, request):
|
|
||||||
# return _robots_response
|
|
||||||
|
|
||||||
|
|
||||||
def includeme(config):
|
def includeme(config):
|
||||||
# config.add_route('home', '/')
|
config.include('edbob.pyramid.views.auth')
|
||||||
# config.add_route('favicon.ico', '/favicon.ico')
|
|
||||||
# config.add_route('robots.txt', '/robots.txt')
|
|
||||||
config.add_route('login', '/login')
|
|
||||||
config.scan()
|
|
||||||
|
|
95
edbob/pyramid/views/auth.py
Normal file
95
edbob/pyramid/views/auth.py
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
################################################################################
|
||||||
|
#
|
||||||
|
# edbob -- Pythonic Software Framework
|
||||||
|
# Copyright © 2010-2012 Lance Edgar
|
||||||
|
#
|
||||||
|
# This file is part of edbob.
|
||||||
|
#
|
||||||
|
# edbob is free software: you can redistribute it and/or modify it under the
|
||||||
|
# terms of the GNU Affero General Public License as published by the Free
|
||||||
|
# Software Foundation, either version 3 of the License, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# edbob is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||||
|
# FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for
|
||||||
|
# more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Affero General Public License
|
||||||
|
# along with edbob. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
#
|
||||||
|
################################################################################
|
||||||
|
|
||||||
|
"""
|
||||||
|
``edbob.pyramid.views.auth`` -- Auth Views
|
||||||
|
"""
|
||||||
|
|
||||||
|
import formencode
|
||||||
|
from pyramid.view import view_config
|
||||||
|
from pyramid.httpexceptions import HTTPFound
|
||||||
|
from pyramid.security import remember, forget
|
||||||
|
from pyramid_simpleform import Form
|
||||||
|
from pyramid_simpleform.renderers import FormRenderer
|
||||||
|
|
||||||
|
import edbob
|
||||||
|
from edbob.db.auth import authenticate_user
|
||||||
|
from edbob.pyramid import Session
|
||||||
|
|
||||||
|
|
||||||
|
class UserLogin(formencode.Schema):
|
||||||
|
allow_extra_fields = True
|
||||||
|
filter_extra_fields = True
|
||||||
|
username = formencode.validators.NotEmpty()
|
||||||
|
password = formencode.validators.NotEmpty()
|
||||||
|
|
||||||
|
|
||||||
|
@view_config(route_name='login', renderer='/login.mako')
|
||||||
|
def login(context, request):
|
||||||
|
"""
|
||||||
|
The login view, responsible for displaying and handling the login form.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if request.params.get('referer'):
|
||||||
|
referer = request.params['referer']
|
||||||
|
elif request.session.get('referer'):
|
||||||
|
referer = request.session.pop('referer')
|
||||||
|
else:
|
||||||
|
referer = request.referer or request.route_url('home')
|
||||||
|
if referer == request.route_url('login'):
|
||||||
|
referer = request.route_url('home')
|
||||||
|
|
||||||
|
# Redirect if already logged in.
|
||||||
|
if request.user:
|
||||||
|
return HTTPFound(location=referer)
|
||||||
|
|
||||||
|
form = Form(request, schema=UserLogin)
|
||||||
|
if form.validate():
|
||||||
|
user = authenticate_user(form.data['username'],
|
||||||
|
form.data['password'],
|
||||||
|
session=Session())
|
||||||
|
if user:
|
||||||
|
request.session.flash("%s logged in at %s" % (
|
||||||
|
user.display_name,
|
||||||
|
edbob.local_time().strftime('%I:%M %p')))
|
||||||
|
headers = remember(request, user.uuid)
|
||||||
|
return HTTPFound(location=referer, headers=headers)
|
||||||
|
request.session.flash("Invalid username or password")
|
||||||
|
return {'form': FormRenderer(form), 'referer': referer}
|
||||||
|
|
||||||
|
|
||||||
|
@view_config(route_name='logout')
|
||||||
|
def logout(context, request):
|
||||||
|
request.session.delete()
|
||||||
|
request.session.flash("%s logged out at %s" % (
|
||||||
|
request.user.display_name,
|
||||||
|
edbob.local_time().strftime("%I:%M %p")))
|
||||||
|
headers = forget(request)
|
||||||
|
return HTTPFound(location=request.route_url('login'), headers=headers)
|
||||||
|
|
||||||
|
|
||||||
|
def includeme(config):
|
||||||
|
config.add_route('login', '/login')
|
||||||
|
config.add_route('logout', '/logout')
|
||||||
|
config.scan()
|
Loading…
Add table
Add a link
Reference in a new issue