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.model import get_metadata
 | 
			
		||||
    # 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
 | 
			
		||||
| 
						 | 
				
			
			@ -103,7 +103,7 @@ def init(config):
 | 
			
		|||
    
 | 
			
		||||
    # metadata = get_metadata(bind=engine)
 | 
			
		||||
    # make_mappers(metadata)
 | 
			
		||||
    # extend_framework()
 | 
			
		||||
    extend_framework()
 | 
			
		||||
 | 
			
		||||
    edbob.graft(edbob, edbob.db)
 | 
			
		||||
    # edbob.graft(edbob, classes)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,7 +32,6 @@ from sqlalchemy.orm import object_session
 | 
			
		|||
 | 
			
		||||
import edbob
 | 
			
		||||
from edbob.db import needs_session
 | 
			
		||||
from edbob.db.classes import Permission, Role, User
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class BcryptAuthenticator(edbob.Object):
 | 
			
		||||
| 
						 | 
				
			
			@ -55,13 +54,13 @@ def authenticate_user(session, username, password):
 | 
			
		|||
    returns the :class:`edbob.User` instance; otherwise returns ``None``.
 | 
			
		||||
    """
 | 
			
		||||
 | 
			
		||||
    user = session.query(User).filter_by(username=username).first()
 | 
			
		||||
    if not user:
 | 
			
		||||
        return None
 | 
			
		||||
    auth = BcryptAuthenticator()
 | 
			
		||||
    if not auth.authenticate_user(user, password):
 | 
			
		||||
        return None
 | 
			
		||||
    return user
 | 
			
		||||
    q = session.query(edbob.User)
 | 
			
		||||
    q = q.filter(edbob.User.username == username)
 | 
			
		||||
    user = q.first()
 | 
			
		||||
    if user:
 | 
			
		||||
        auth = BcryptAuthenticator()
 | 
			
		||||
        if auth.authenticate_user(user, password):
 | 
			
		||||
            return user
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def administrator_role(session):
 | 
			
		||||
| 
						 | 
				
			
			@ -103,3 +102,26 @@ def has_permission(obj, perm):
 | 
			
		|||
            if permission == perm:
 | 
			
		||||
                return True
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
    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__
 | 
			
		||||
        edbob.graft(classes, {name:cls}, name)
 | 
			
		||||
    # def extend_mappers(self, metadata):
 | 
			
		||||
    #     """
 | 
			
		||||
    #     All SQLAlchemy mapping to be done by the extension should be done
 | 
			
		||||
    #     within this method.
 | 
			
		||||
 | 
			
		||||
    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_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
 | 
			
		||||
    #     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):
 | 
			
		||||
        """
 | 
			
		||||
| 
						 | 
				
			
			@ -173,25 +180,25 @@ class Extension(edbob.Object):
 | 
			
		|||
            if isinstance(obj, type) and issubclass(obj, model.Base):
 | 
			
		||||
                obj.__table__.tometadata(metadata)
 | 
			
		||||
 | 
			
		||||
    def remove_class(self, name):
 | 
			
		||||
        """
 | 
			
		||||
        Convenience method for use in :meth:`restore_classes()`.
 | 
			
		||||
        """
 | 
			
		||||
    # def remove_class(self, name):
 | 
			
		||||
    #     """
 | 
			
		||||
    #     Convenience method for use in :meth:`restore_classes()`.
 | 
			
		||||
    #     """
 | 
			
		||||
 | 
			
		||||
        from edbob.db import classes
 | 
			
		||||
    #     from edbob.db import classes
 | 
			
		||||
 | 
			
		||||
        if name in classes.__all__:
 | 
			
		||||
            classes.__all__.remove(name)
 | 
			
		||||
        if hasattr(classes, name):
 | 
			
		||||
            del classes.__dict__[name]
 | 
			
		||||
    #     if name in classes.__all__:
 | 
			
		||||
    #         classes.__all__.remove(name)
 | 
			
		||||
    #     if hasattr(classes, name):
 | 
			
		||||
    #         del classes.__dict__[name]
 | 
			
		||||
 | 
			
		||||
    def restore_classes(self):
 | 
			
		||||
        """
 | 
			
		||||
        This method should remove any extra classes which were added within
 | 
			
		||||
        :meth:`extend_classes()`.  Note that there is a :meth:`remove_class()`
 | 
			
		||||
        method for convenience in doing so.
 | 
			
		||||
        """
 | 
			
		||||
        pass
 | 
			
		||||
    # def restore_classes(self):
 | 
			
		||||
    #     """
 | 
			
		||||
    #     This method should remove any extra classes which were added within
 | 
			
		||||
    #     :meth:`extend_classes()`.  Note that there is a :meth:`remove_class()`
 | 
			
		||||
    #     method for convenience in doing so.
 | 
			
		||||
    #     """
 | 
			
		||||
    #     pass
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def activate_extension(extension, engine=None):
 | 
			
		||||
| 
						 | 
				
			
			@ -233,6 +240,7 @@ def activate_extension(extension, engine=None):
 | 
			
		|||
    # merge_extension_metadata(extension)
 | 
			
		||||
    # extension.extend_classes()
 | 
			
		||||
    # extension.extend_mappers(Base.metadata)
 | 
			
		||||
    extension.extend_framework()
 | 
			
		||||
 | 
			
		||||
    # Add extension to in-memory active extensions tracker.
 | 
			
		||||
    active_extensions(engine).append(extension.name)
 | 
			
		||||
| 
						 | 
				
			
			@ -318,23 +326,24 @@ def extend_framework():
 | 
			
		|||
 | 
			
		||||
    session = Session()
 | 
			
		||||
    try:
 | 
			
		||||
        active_extensions = session.query(ActiveExtension).all()
 | 
			
		||||
        active = session.query(ActiveExtension).all()
 | 
			
		||||
    except sqlalchemy.exc.ProgrammingError:
 | 
			
		||||
        session.close()
 | 
			
		||||
        return
 | 
			
		||||
 | 
			
		||||
    extensions = {}
 | 
			
		||||
    for ext in active_extensions:
 | 
			
		||||
    for ext in active:
 | 
			
		||||
        extensions[ext.name] = get_extension(ext.name)
 | 
			
		||||
    session.close()
 | 
			
		||||
 | 
			
		||||
    for name in sorted(extensions, extension_sorter(extensions)):
 | 
			
		||||
        ext = extensions[name]
 | 
			
		||||
        log.info("Applying active extension: %s" % name)
 | 
			
		||||
        merge_extension_metadata(ext)
 | 
			
		||||
        ext.extend_classes()
 | 
			
		||||
        ext.extend_mappers(rattail.metadata)
 | 
			
		||||
        active_extensions[name] = ext
 | 
			
		||||
        ext = extensions[name]
 | 
			
		||||
        # merge_extension_metadata(ext)
 | 
			
		||||
        # ext.extend_classes()
 | 
			
		||||
        # ext.extend_mappers(rattail.metadata)
 | 
			
		||||
        ext.extend_framework()
 | 
			
		||||
        _active_extensions[name] = ext
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def extension_active(extension, engine=None):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,10 +26,11 @@
 | 
			
		|||
``edbob.db.extensions.auth`` -- 'auth' Extension
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
from sqlalchemy import MetaData
 | 
			
		||||
 | 
			
		||||
from edbob.db.extensions import Extension
 | 
			
		||||
 | 
			
		||||
from edbob.db.extensions.auth.model import *
 | 
			
		||||
from edbob.db.extensions.auth.model import __all__
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class AuthExtension(Extension):
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -28,9 +28,10 @@
 | 
			
		|||
 | 
			
		||||
from sqlalchemy import *
 | 
			
		||||
from sqlalchemy.orm import relationship
 | 
			
		||||
from sqlalchemy.ext.associationproxy import association_proxy
 | 
			
		||||
 | 
			
		||||
import edbob
 | 
			
		||||
from edbob.db.model import Base
 | 
			
		||||
from edbob.db.model import Base, uuid_column
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
__all__ = ['Person', 'User']
 | 
			
		||||
| 
						 | 
				
			
			@ -52,7 +53,7 @@ class Person(Base):
 | 
			
		|||
 | 
			
		||||
    __tablename__ = 'people'
 | 
			
		||||
 | 
			
		||||
    uuid = Column(String(32), primary_key=True, default=edbob.get_uuid)
 | 
			
		||||
    uuid = uuid_column()
 | 
			
		||||
    first_name = Column(String(50))
 | 
			
		||||
    last_name = Column(String(50))
 | 
			
		||||
    display_name = Column(String(100), default=get_person_display_name)
 | 
			
		||||
| 
						 | 
				
			
			@ -72,11 +73,14 @@ class User(Base):
 | 
			
		|||
 | 
			
		||||
    __tablename__ = 'users'
 | 
			
		||||
 | 
			
		||||
    uuid = Column(String(32), primary_key=True, default=edbob.get_uuid)
 | 
			
		||||
    uuid = uuid_column()
 | 
			
		||||
    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 = relationship(Person, backref='user')
 | 
			
		||||
    # display_name = association_proxy('person', 'display_name')
 | 
			
		||||
 | 
			
		||||
    # roles = association_proxy('_roles', 'role',
 | 
			
		||||
    #                           creator=lambda x: UserRole(role=x),
 | 
			
		||||
| 
						 | 
				
			
			@ -87,3 +91,13 @@ class User(Base):
 | 
			
		|||
 | 
			
		||||
    def __str__(self):
 | 
			
		||||
        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 {
 | 
			
		||||
    margin: 8px auto auto 20px;
 | 
			
		||||
    margin: 8px 20px auto auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#user-menu {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -32,6 +32,7 @@ from pyramid.security import authenticated_userid
 | 
			
		|||
import edbob
 | 
			
		||||
from edbob.db.auth import has_permission
 | 
			
		||||
from edbob.pyramid import helpers
 | 
			
		||||
from edbob.pyramid import Session
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def before_render(event):
 | 
			
		||||
| 
						 | 
				
			
			@ -62,9 +63,9 @@ def context_found(event):
 | 
			
		|||
 | 
			
		||||
    def has_perm_func(request):
 | 
			
		||||
        def has_perm(perm):
 | 
			
		||||
            if not request.current_user:
 | 
			
		||||
            if not request.user:
 | 
			
		||||
                return False
 | 
			
		||||
            return has_permission(request.current_user, perm)
 | 
			
		||||
            return has_permission(request.user, perm)
 | 
			
		||||
        return has_perm
 | 
			
		||||
 | 
			
		||||
    request = event.request
 | 
			
		||||
| 
						 | 
				
			
			@ -73,7 +74,7 @@ def context_found(event):
 | 
			
		|||
 | 
			
		||||
    uuid = authenticated_userid(request)
 | 
			
		||||
    if uuid:
 | 
			
		||||
        request.user = get_session().query(rattail.User).get(uuid)
 | 
			
		||||
        request.user = Session.query(edbob.User).get(uuid)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def includeme(config):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,13 +30,12 @@
 | 
			
		|||
	<div id="header">
 | 
			
		||||
	  ${self.home_link()}
 | 
			
		||||
	  <h1 class="left">${self.title()}</h1>
 | 
			
		||||
	  <div id="login" class="left">
 | 
			
		||||
##	    <% user = request.current_user %>
 | 
			
		||||
	    % if user:
 | 
			
		||||
		logged in as <strong>${user.display_name}</strong>
 | 
			
		||||
	  <div id="login" class="right">
 | 
			
		||||
	    % if request.user:
 | 
			
		||||
		logged in as <strong>${request.user.display_name}</strong>
 | 
			
		||||
		(${h.link_to("logout", url('logout'))})
 | 
			
		||||
	    % else:
 | 
			
		||||
##		${h.link_to("login", url('login'))}
 | 
			
		||||
		${h.link_to("login", url('login'))}
 | 
			
		||||
	    % endif
 | 
			
		||||
	  </div>
 | 
			
		||||
	</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" />
 | 
			
		||||
 | 
			
		||||
<%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>
 | 
			
		||||
<%inherit file="/edbob/login.mako" />
 | 
			
		||||
${parent.body()}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -26,71 +26,6 @@
 | 
			
		|||
``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):
 | 
			
		||||
    # config.add_route('home', '/')
 | 
			
		||||
    # config.add_route('favicon.ico', '/favicon.ico')
 | 
			
		||||
    # config.add_route('robots.txt', '/robots.txt')
 | 
			
		||||
    config.add_route('login', '/login')
 | 
			
		||||
    config.scan()
 | 
			
		||||
    config.include('edbob.pyramid.views.auth')
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										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