* use sha512 passwords
* more robust SQLAlchemy session handling code * implemented password change mechanism
This commit is contained in:
parent
ade660419c
commit
949e699e25
7 changed files with 99 additions and 28 deletions
|
@ -38,7 +38,7 @@ sqlalchemy.url = sqlite:///%(here)s/gvaweb.sqlite
|
||||||
authkit.setup.method = form, cookie
|
authkit.setup.method = form, cookie
|
||||||
authkit.form.authenticate.user.type = gnuviechadminweb.model:GVAUsers
|
authkit.form.authenticate.user.type = gnuviechadminweb.model:GVAUsers
|
||||||
authkit.form.authenticate.user.data = gnuviechadminweb.model.meta
|
authkit.form.authenticate.user.data = gnuviechadminweb.model.meta
|
||||||
authkit.form.authenticate.user.encrypt = authkit.users:md5
|
authkit.form.authenticate.user.encrypt = gnuviechadminweb.model:sha512
|
||||||
authkit.cookie.secret = really secret data
|
authkit.cookie.secret = really secret data
|
||||||
authkit.cookie.signoutpath = /login/logout
|
authkit.cookie.signoutpath = /login/logout
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from gnuviechadminweb.lib.base import *
|
from gnuviechadminweb.lib.base import *
|
||||||
|
from authkit.permissions import ValidAuthKitUser
|
||||||
|
from authkit.authorize.pylons_adaptors import authorize
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -9,3 +11,26 @@ class GvaController(BaseController):
|
||||||
def index(self):
|
def index(self):
|
||||||
# Return a rendered template
|
# Return a rendered template
|
||||||
return render('/main.mako')
|
return render('/main.mako')
|
||||||
|
|
||||||
|
@authorize(ValidAuthKitUser())
|
||||||
|
def password(self):
|
||||||
|
return render('/chpassword.mako')
|
||||||
|
|
||||||
|
@authorize(ValidAuthKitUser())
|
||||||
|
def updatepassword(self):
|
||||||
|
users = request.environ['authkit.users']
|
||||||
|
if users.user_has_password(request.environ['REMOTE_USER'],
|
||||||
|
request.params['oldpassword']):
|
||||||
|
if request.params['password'] != request.params['confirm']:
|
||||||
|
c.messages['errors'].append("New password and confirmation don't match")
|
||||||
|
elif len(request.params['password']) < 8:
|
||||||
|
c.messages['errors'].append("Your new password is too short. It must consist of at least 8 characters")
|
||||||
|
else:
|
||||||
|
users.user_set_password(request.environ['REMOTE_USER'],
|
||||||
|
request.params['password'])
|
||||||
|
c.messages['messages'].append("Your password has been changed.")
|
||||||
|
else:
|
||||||
|
c.messages['errors'].append("Your old password is not correct.")
|
||||||
|
if c.messages['errors']:
|
||||||
|
return render('/chpassword.mako')
|
||||||
|
return render('/main.mako')
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from authkit.users import Users
|
from authkit.users import Users
|
||||||
from gnuviechadminweb.model.user import Group, Role, User
|
from gnuviechadminweb.model.user import Group, Role, User
|
||||||
|
@ -6,33 +7,33 @@ import logging
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
def needsConnection(func):
|
def initializedSession(func):
|
||||||
def wrapper(*__args, **__kw):
|
def wrapper(*__args, **__kwargs):
|
||||||
from sqlalchemy.orm import create_session
|
meta = __args[0].meta
|
||||||
engine = __args[0].meta.engine
|
conn = meta.engine.connect()
|
||||||
conn = engine.contextual_connect()
|
meta.Session.configure(bind=conn)
|
||||||
if conn.closed:
|
try:
|
||||||
conn = engine.connect()
|
return func(*__args, **__kwargs)
|
||||||
__args[0].session = create_session(bind=conn)
|
finally:
|
||||||
try:
|
meta.Session.remove()
|
||||||
return func(*__args, **__kw)
|
conn.close()
|
||||||
finally:
|
|
||||||
conn.close()
|
|
||||||
else:
|
|
||||||
__args[0].session = create_session(bind=conn)
|
|
||||||
return func(*__args, **__kw)
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
|
def sha512(password, secret = ''):
|
||||||
|
import hashlib
|
||||||
|
m = hashlib.sha512()
|
||||||
|
m.update(password)
|
||||||
|
m.update(secret)
|
||||||
|
return m.hexdigest()
|
||||||
|
|
||||||
class GVAUsers(Users):
|
class GVAUsers(Users):
|
||||||
def __init__(self, data, encrypt = None):
|
def __init__(self, data, encrypt = None):
|
||||||
Users.__init__(self, data, encrypt)
|
Users.__init__(self, data, encrypt)
|
||||||
log.debug("in __init__")
|
log.debug("in __init__")
|
||||||
self.meta = eval_import(self.data)
|
self.meta = eval_import(self.data)
|
||||||
self.session = self.meta.Session
|
|
||||||
|
|
||||||
@needsConnection
|
|
||||||
def _getSession(self):
|
def _getSession(self):
|
||||||
return self.session
|
return self.meta.Session
|
||||||
|
|
||||||
def _get_group(self, groupname):
|
def _get_group(self, groupname):
|
||||||
return self._getSession().query(Group).filter_by(name=groupname).one()
|
return self._getSession().query(Group).filter_by(name=groupname).one()
|
||||||
|
@ -44,6 +45,7 @@ class GVAUsers(Users):
|
||||||
return self._getSession().query(Role).filter_by(name=rolename).one()
|
return self._getSession().query(Role).filter_by(name=rolename).one()
|
||||||
|
|
||||||
# Create Methods
|
# Create Methods
|
||||||
|
@initializedSession
|
||||||
def user_create(self, username, password, group=None):
|
def user_create(self, username, password, group=None):
|
||||||
n_user = User()
|
n_user = User()
|
||||||
n_user.name = username
|
n_user.name = username
|
||||||
|
@ -53,12 +55,14 @@ class GVAUsers(Users):
|
||||||
self._getSession().save(n_user)
|
self._getSession().save(n_user)
|
||||||
self._getSession().commit()
|
self._getSession().commit()
|
||||||
|
|
||||||
|
@initializedSession
|
||||||
def role_create(self, role):
|
def role_create(self, role):
|
||||||
n_role = Role()
|
n_role = Role()
|
||||||
n_role.name = role
|
n_role.name = role
|
||||||
self._getSession().save(n_role)
|
self._getSession().save(n_role)
|
||||||
self._getSession().commit()
|
self._getSession().commit()
|
||||||
|
|
||||||
|
@initializedSession
|
||||||
def group_create(self, group):
|
def group_create(self, group):
|
||||||
n_group = Group()
|
n_group = Group()
|
||||||
n_group.name = group
|
n_group.name = group
|
||||||
|
@ -66,19 +70,23 @@ class GVAUsers(Users):
|
||||||
self._getSession().commit()
|
self._getSession().commit()
|
||||||
|
|
||||||
# Delete Methods
|
# Delete Methods
|
||||||
|
@initializedSession
|
||||||
def user_delete(self, username):
|
def user_delete(self, username):
|
||||||
self._getSession().delete(self._get_user(username))
|
self._getSession().delete(self._get_user(username))
|
||||||
self._getSession().commit()
|
self._getSession().commit()
|
||||||
|
|
||||||
|
@initializedSession
|
||||||
def role_delete(self, role):
|
def role_delete(self, role):
|
||||||
self._getSession().delete(self._get_role(role))
|
self._getSession().delete(self._get_role(role))
|
||||||
self._getSession().commit()
|
self._getSession().commit()
|
||||||
|
|
||||||
|
@initializedSession
|
||||||
def group_delete(self, group):
|
def group_delete(self, group):
|
||||||
self._getSession().delete(self._get_group())
|
self._getSession().delete(self._get_group())
|
||||||
self._getSession().commit()
|
self._getSession().commit()
|
||||||
|
|
||||||
# Delete Cascade Methods
|
# Delete Cascade Methods
|
||||||
|
@initializedSession
|
||||||
def role_delete_cascade(self, role):
|
def role_delete_cascade(self, role):
|
||||||
n_role = self._get_role(role)
|
n_role = self._get_role(role)
|
||||||
for user in self._getSession().query(User).roles.any(name=role).all():
|
for user in self._getSession().query(User).roles.any(name=role).all():
|
||||||
|
@ -86,6 +94,7 @@ class GVAUsers(Users):
|
||||||
self._getSession().delete(n_role)
|
self._getSession().delete(n_role)
|
||||||
self._getSession().commit()
|
self._getSession().commit()
|
||||||
|
|
||||||
|
@initializedSession
|
||||||
def group_delete_cascade(self, group):
|
def group_delete_cascade(self, group):
|
||||||
n_group = self._get_group(group)
|
n_group = self._get_group(group)
|
||||||
self._getSession().delete(self._getSession().query(User).filter_by(
|
self._getSession().delete(self._getSession().query(User).filter_by(
|
||||||
|
@ -94,32 +103,39 @@ class GVAUsers(Users):
|
||||||
self._getSession().commit()
|
self._getSession().commit()
|
||||||
|
|
||||||
# Existence Methods
|
# Existence Methods
|
||||||
|
@initializedSession
|
||||||
def user_exists(self, username):
|
def user_exists(self, username):
|
||||||
return self._getSession().query(User).filter_by(
|
return self._getSession().query(User).filter_by(
|
||||||
name=username).count() == 1
|
name=username).count() == 1
|
||||||
|
|
||||||
|
@initializedSession
|
||||||
def role_exists(self, role):
|
def role_exists(self, role):
|
||||||
return self._getSession().query(Role).filter_by(
|
return self._getSession().query(Role).filter_by(
|
||||||
name=role).count() == 1
|
name=role).count() == 1
|
||||||
|
|
||||||
|
@initializedSession
|
||||||
def group_exists(self, group):
|
def group_exists(self, group):
|
||||||
return self._getSession().query(Group).filter_by(
|
return self._getSession().query(Group).filter_by(
|
||||||
name=group).count() == 1
|
name=group).count() == 1
|
||||||
|
|
||||||
# List Methods
|
# List Methods
|
||||||
|
@initializedSession
|
||||||
def list_roles(self):
|
def list_roles(self):
|
||||||
return [role.name.lower() for role in self._getSession().query(
|
return [role.name.lower() for role in self._getSession().query(
|
||||||
Role).all()]
|
Role).all()]
|
||||||
|
|
||||||
|
@initializedSession
|
||||||
def list_users(self):
|
def list_users(self):
|
||||||
return [user.name.lower() for user in self._getSession().query(
|
return [user.name.lower() for user in self._getSession().query(
|
||||||
User).all()]
|
User).all()]
|
||||||
|
|
||||||
|
@initializedSession
|
||||||
def list_groups(self):
|
def list_groups(self):
|
||||||
return [group.name.lower() for group in self._getSession().query(
|
return [group.name.lower() for group in self._getSession().query(
|
||||||
Group).all()]
|
Group).all()]
|
||||||
|
|
||||||
# User Methods
|
# User Methods
|
||||||
|
@initializedSession
|
||||||
def user(self, username):
|
def user(self, username):
|
||||||
user = self._get_user(username)
|
user = self._get_user(username)
|
||||||
roles = [role.name.lower() for role in user.roles]
|
roles = [role.name.lower() for role in user.roles]
|
||||||
|
@ -131,40 +147,48 @@ class GVAUsers(Users):
|
||||||
'roles' : roles
|
'roles' : roles
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@initializedSession
|
||||||
def user_roles(self, username):
|
def user_roles(self, username):
|
||||||
user = self._get_user(username)
|
user = self._get_user(username)
|
||||||
roles = [role.name.lower() for role in user.roles]
|
roles = [role.name.lower() for role in user.roles]
|
||||||
roles.sort()
|
roles.sort()
|
||||||
return roles
|
return roles
|
||||||
|
|
||||||
|
@initializedSession
|
||||||
def user_group(self, username):
|
def user_group(self, username):
|
||||||
user = self._get_user(username)
|
user = self._get_user(username)
|
||||||
return None if user.group is None else user.group.name
|
return None if user.group is None else user.group.name
|
||||||
|
|
||||||
|
@initializedSession
|
||||||
def user_password(self, username):
|
def user_password(self, username):
|
||||||
user = self._get_user(username)
|
user = self._get_user(username)
|
||||||
return user.password
|
return user.password
|
||||||
|
|
||||||
|
@initializedSession
|
||||||
def user_has_role(self, username, role):
|
def user_has_role(self, username, role):
|
||||||
user = self._get_user(username)
|
user = self._get_user(username)
|
||||||
return role in [role.name for role in user.roles]
|
return role in [role.name for role in user.roles]
|
||||||
|
|
||||||
|
@initializedSession
|
||||||
def user_has_group(self, username, group):
|
def user_has_group(self, username, group):
|
||||||
user = self._get_user(username)
|
user = self._get_user(username)
|
||||||
return (group is None and user.group is None) or \
|
return (group is None and user.group is None) or \
|
||||||
(group is not None and user.group is not None and \
|
(group is not None and user.group is not None and \
|
||||||
group == user.group.name)
|
group == user.group.name)
|
||||||
|
|
||||||
|
@initializedSession
|
||||||
def user_has_password(self, username, password):
|
def user_has_password(self, username, password):
|
||||||
user = self._get_user(username)
|
user = self._get_user(username)
|
||||||
return user.password == self.encrypt(password)
|
return user.password == self.encrypt(password)
|
||||||
|
|
||||||
|
@initializedSession
|
||||||
def user_set_username(self, username, new_username):
|
def user_set_username(self, username, new_username):
|
||||||
user = self._get_user(username)
|
user = self._get_user(username)
|
||||||
user.name = new_username
|
user.name = new_username
|
||||||
self._getSession().update(user)
|
self._getSession().update(user)
|
||||||
self._getSession().commit()
|
self._getSession().commit()
|
||||||
|
|
||||||
|
@initializedSession
|
||||||
def user_set_group(self, username, group, add_if_necessary=False):
|
def user_set_group(self, username, group, add_if_necessary=False):
|
||||||
if add_if_necessary and self._getSession().query(Group).filter_by(
|
if add_if_necessary and self._getSession().query(Group).filter_by(
|
||||||
name=group).count() == 0:
|
name=group).count() == 0:
|
||||||
|
@ -175,6 +199,7 @@ class GVAUsers(Users):
|
||||||
self._getSession().update(user)
|
self._getSession().update(user)
|
||||||
self._getSession().commit()
|
self._getSession().commit()
|
||||||
|
|
||||||
|
@initializedSession
|
||||||
def user_add_role(self, username, role, add_if_necessary=False):
|
def user_add_role(self, username, role, add_if_necessary=False):
|
||||||
if add_if_necessary and self._getSession().query(Role).filter_by(
|
if add_if_necessary and self._getSession().query(Role).filter_by(
|
||||||
name=role).count() == 0:
|
name=role).count() == 0:
|
||||||
|
@ -186,6 +211,7 @@ class GVAUsers(Users):
|
||||||
self._getSession().update(user)
|
self._getSession().update(user)
|
||||||
self._getSession().commit()
|
self._getSession().commit()
|
||||||
|
|
||||||
|
@initializedSession
|
||||||
def user_remove_role(self, username, role):
|
def user_remove_role(self, username, role):
|
||||||
roleobj = self._get_role(role)
|
roleobj = self._get_role(role)
|
||||||
user = self._get_user(username)
|
user = self._get_user(username)
|
||||||
|
@ -193,8 +219,16 @@ class GVAUsers(Users):
|
||||||
del user.roles[roleobj.id]
|
del user.roles[roleobj.id]
|
||||||
self._getSession().commit()
|
self._getSession().commit()
|
||||||
|
|
||||||
|
@initializedSession
|
||||||
def user_remove_group(self, username):
|
def user_remove_group(self, username):
|
||||||
user = self._get_user(username)
|
user = self._get_user(username)
|
||||||
user.group = None
|
user.group = None
|
||||||
self._getSession().update(user)
|
self._getSession().update(user)
|
||||||
self._getSession().commit()
|
self._getSession().commit()
|
||||||
|
|
||||||
|
@initializedSession
|
||||||
|
def user_set_password(self, username, password):
|
||||||
|
user = self._get_user(username)
|
||||||
|
user.password = self.encrypt(password)
|
||||||
|
self._getSession().update(user)
|
||||||
|
self._getSession().commit()
|
||||||
|
|
|
@ -12,5 +12,5 @@ def init_model(engine):
|
||||||
meta.Session = orm.scoped_session(sm)
|
meta.Session = orm.scoped_session(sm)
|
||||||
|
|
||||||
from gnuviechadminweb.model.user import Group, Role, User
|
from gnuviechadminweb.model.user import Group, Role, User
|
||||||
from gnuviechadminweb.model.GVAUsers import GVAUsers
|
from gnuviechadminweb.model.GVAUsers import GVAUsers, sha512
|
||||||
from gnuviechadminweb.model.menu import Menu
|
from gnuviechadminweb.model.menu import Menu
|
||||||
|
|
|
@ -5,7 +5,12 @@ class Menu(object):
|
||||||
('Main page', 'gva', 'index', None),
|
('Main page', 'gva', 'index', None),
|
||||||
('Login', 'login', 'login', []),
|
('Login', 'login', 'login', []),
|
||||||
('Logout', 'login', 'logout', ['*']),
|
('Logout', 'login', 'logout', ['*']),
|
||||||
('Admin', 'gva', 'index', ['admin'])
|
('Manage clients', 'clients', 'index', ['admin']),
|
||||||
|
('Update Profile', 'client', 'changes', ['client']),
|
||||||
|
('System accounts', 'sysuser', 'index', ['admin']),
|
||||||
|
('System account', 'sysuser', 'account', ['client']),
|
||||||
|
('Mail accounts', 'mailaccount', 'index', ['admin', 'sysuser']),
|
||||||
|
('Change password', 'gva', 'password', ['*'])
|
||||||
]
|
]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -30,7 +35,3 @@ class Menu(object):
|
||||||
self.title = title
|
self.title = title
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
self.action = action
|
self.action = action
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
12
gnuviechadminweb/templates/chpassword.mako
Normal file
12
gnuviechadminweb/templates/chpassword.mako
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
<%inherit file="site.mako" />
|
||||||
|
<h1>Change your password</h1>
|
||||||
|
${h.form(h.url(action='updatepassword'), method='post')}
|
||||||
|
Old password: ${h.password_field('oldpassword')}
|
||||||
|
New password: ${h.password_field('password')}
|
||||||
|
Confirm new password: ${h.password_field('confirm')}
|
||||||
|
${h.submit('Change password')}
|
||||||
|
${h.end_form()}
|
||||||
|
<%def name="headlines()">
|
||||||
|
<title>Change your password</title>
|
||||||
|
</%def>
|
|
@ -6,8 +6,7 @@ from pylons import config
|
||||||
|
|
||||||
from gnuviechadminweb.config.environment import load_environment
|
from gnuviechadminweb.config.environment import load_environment
|
||||||
from gnuviechadminweb.model import meta, User, Group, Role
|
from gnuviechadminweb.model import meta, User, Group, Role
|
||||||
from gnuviechadminweb.model.GVAUsers import GVAUsers
|
from gnuviechadminweb.model.GVAUsers import GVAUsers, sha512
|
||||||
from authkit.users import md5
|
|
||||||
|
|
||||||
log = logging.getLogger(__name__)
|
log = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -20,7 +19,7 @@ def setup_config(command, filename, section, vars):
|
||||||
meta.metadata.create_all(bind=meta.engine)
|
meta.metadata.create_all(bind=meta.engine)
|
||||||
|
|
||||||
log.info("Creating default admin user, role and group")
|
log.info("Creating default admin user, role and group")
|
||||||
users = GVAUsers('gnuviechadminweb.model:meta', md5)
|
users = GVAUsers('gnuviechadminweb.model:meta', sha512)
|
||||||
users.role_create("admin")
|
users.role_create("admin")
|
||||||
users.group_create("administrators")
|
users.group_create("administrators")
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue