Commit 20f4869a by Owo Sugiana

Bug fixed manifest

1 parent 1001ca9c
include *.txt *.ini *.cfg *.rst include *.txt *.ini *.cfg *.rst
recursive-include web_starter *.ico *.png *.css *.gif *.jpg *.pt *.txt *.mak *.mako *.js *.html *.xml *.jinja2 recursive-include web_starter *.csv *.png *.css *.pt *.mako *.pot *.mo *.po
...@@ -64,6 +64,7 @@ def run_migrations_online(): ...@@ -64,6 +64,7 @@ def run_migrations_online():
with context.begin_transaction(): with context.begin_transaction():
context.run_migrations() context.run_migrations()
if context.is_offline_mode(): if context.is_offline_mode():
run_migrations_offline() run_migrations_offline()
else: else:
......
"""alter users date fields with time zone """alter users date fields with time zone
Revision ID: 074b33635316 Revision ID: 074b33635316
Revises: Revises:
Create Date: 2018-10-11 12:00:48.568483 Create Date: 2018-10-11 12:00:48.568483
""" """
...@@ -17,13 +17,16 @@ depends_on = None ...@@ -17,13 +17,16 @@ depends_on = None
def upgrade(): def upgrade():
op.alter_column('users', 'last_login_date', op.alter_column(
'users', 'last_login_date',
type_=sa.DateTime(timezone=True), type_=sa.DateTime(timezone=True),
existing_type=sa.DateTime(timezone=False)) existing_type=sa.DateTime(timezone=False))
op.alter_column('users', 'registered_date', op.alter_column(
'users', 'registered_date',
type_=sa.DateTime(timezone=True), type_=sa.DateTime(timezone=True),
existing_type=sa.DateTime(timezone=False)) existing_type=sa.DateTime(timezone=False))
op.alter_column('users', 'security_code_date', op.alter_column(
'users', 'security_code_date',
type_=sa.DateTime(timezone=True), type_=sa.DateTime(timezone=True),
existing_type=sa.DateTime(timezone=False)) existing_type=sa.DateTime(timezone=False))
......
...@@ -32,7 +32,6 @@ requires = [ ...@@ -32,7 +32,6 @@ requires = [
'deform', 'deform',
'pyramid_beaker', 'pyramid_beaker',
'pyramid_mailer', 'pyramid_mailer',
# 'opensipkd-jsonrpc @ git+https://git.opensipkd.com/sugiana/opensipkd-jsonrpc',
] ]
tests_require = [ tests_require = [
...@@ -69,7 +68,8 @@ setup( ...@@ -69,7 +68,8 @@ setup(
'main = web_starter:main', 'main = web_starter:main',
], ],
'console_scripts': [ 'console_scripts': [
'initialize_web_starter_db = web_starter.scripts.initialize_db:main', 'initialize_web_starter_db = '
'web_starter.scripts.initialize_db:main',
'send_email = web_starter.scripts.send_email:main', 'send_email = web_starter.scripts.send_email:main',
] ]
}, },
......
...@@ -9,12 +9,14 @@ from ziggurat_foundations.models.base import BaseModel ...@@ -9,12 +9,14 @@ from ziggurat_foundations.models.base import BaseModel
from ziggurat_foundations.models.external_identity import ExternalIdentityMixin from ziggurat_foundations.models.external_identity import ExternalIdentityMixin
from ziggurat_foundations.models.group import GroupMixin from ziggurat_foundations.models.group import GroupMixin
from ziggurat_foundations.models.group_permission import GroupPermissionMixin from ziggurat_foundations.models.group_permission import GroupPermissionMixin
from ziggurat_foundations.models.group_resource_permission import GroupResourcePermissionMixin from ziggurat_foundations.models.group_resource_permission import \
GroupResourcePermissionMixin
from ziggurat_foundations.models.resource import ResourceMixin from ziggurat_foundations.models.resource import ResourceMixin
from ziggurat_foundations.models.user import UserMixin from ziggurat_foundations.models.user import UserMixin
from ziggurat_foundations.models.user_group import UserGroupMixin from ziggurat_foundations.models.user_group import UserGroupMixin
from ziggurat_foundations.models.user_permission import UserPermissionMixin from ziggurat_foundations.models.user_permission import UserPermissionMixin
from ziggurat_foundations.models.user_resource_permission import UserResourcePermissionMixin from ziggurat_foundations.models.user_resource_permission import \
UserResourcePermissionMixin
from ziggurat_foundations import ziggurat_model_init from ziggurat_foundations import ziggurat_model_init
from . import ( from . import (
Base, Base,
...@@ -27,13 +29,16 @@ from . import ( ...@@ -27,13 +29,16 @@ from . import (
ziggurat_foundations.models.DBSession = DBSession ziggurat_foundations.models.DBSession = DBSession
# optional for folks who pass request.db to model methods # optional for folks who pass request.db to model methods
# Base is sqlalchemy's Base = declarative_base() from your project # Base is sqlalchemy's Base = declarative_base() from your project
class Group(GroupMixin, Base, CommonModel): class Group(GroupMixin, Base, CommonModel):
pass pass
class GroupPermission(GroupPermissionMixin, Base): class GroupPermission(GroupPermissionMixin, Base):
pass pass
class UserGroup(UserGroupMixin, Base): class UserGroup(UserGroupMixin, Base):
pass pass
...@@ -45,6 +50,7 @@ class GroupResourcePermission(GroupResourcePermissionMixin, Base): ...@@ -45,6 +50,7 @@ class GroupResourcePermission(GroupResourcePermissionMixin, Base):
"resource_id", "resource_id",
"perm_name"),) "perm_name"),)
class Resource(ResourceMixin, Base): class Resource(ResourceMixin, Base):
# ... your own properties.... # ... your own properties....
...@@ -61,35 +67,39 @@ class Resource(ResourceMixin, Base): ...@@ -61,35 +67,39 @@ class Resource(ResourceMixin, Base):
ALL_PERMISSIONS,), ]) ALL_PERMISSIONS,), ])
return acls return acls
class UserPermission(UserPermissionMixin, Base): class UserPermission(UserPermissionMixin, Base):
pass pass
class UserResourcePermission(UserResourcePermissionMixin, Base): class UserResourcePermission(UserResourcePermissionMixin, Base):
pass pass
class User(UserMixin, Base, CommonModel): class User(UserMixin, Base, CommonModel):
# ... your own properties.... # ... your own properties....
pass pass
class ExternalIdentity(ExternalIdentityMixin, Base): class ExternalIdentity(ExternalIdentityMixin, Base):
pass pass
# you can define multiple resource derived models to build a complex # you can define multiple resource derived models to build a complex
# application like CMS, forum or other permission based solution # application like CMS, forum or other permission based solution
#class Entry(Resource): # class Entry(Resource):
# """ # """
# Resource of `entry` type # Resource of `entry` type
# """ # """
# __tablename__ = 'entries' # __tablename__ = 'entries'
# __mapper_args__ = {'polymorphic_identity': 'entry'} # __mapper_args__ = {'polymorphic_identity': 'entry'}
# resource_id = sa.Column(sa.Integer(), # resource_id = sa.Column(sa.Integer(),
# sa.ForeignKey('resources.resource_id', # sa.ForeignKey('resources.resource_id',
# onupdate='CASCADE', # onupdate='CASCADE',
# ondelete='CASCADE', ), # ondelete='CASCADE', ),
# primary_key=True, ) # primary_key=True, )
# ... your own properties.... # ... your own properties....
# some_property = sa.Column(sa.UnicodeText()) # some_property = sa.Column(sa.UnicodeText())
...@@ -105,7 +115,7 @@ class RootFactory: ...@@ -105,7 +115,7 @@ class RootFactory:
self.__acl__.append((Allow, acl_name, gp.perm_name)) self.__acl__.append((Allow, acl_name, gp.perm_name))
#ziggurat_model_init(User, Group, UserGroup, GroupPermission, passwordmanager=None) ziggurat_model_init(
ziggurat_model_init(User, Group, UserGroup, GroupPermission, UserPermission, User, Group, UserGroup, GroupPermission, UserPermission,
UserResourcePermission, GroupResourcePermission, Resource, UserResourcePermission, GroupResourcePermission, Resource,
ExternalIdentity, passwordmanager=None) ExternalIdentity, passwordmanager=None)
...@@ -62,14 +62,14 @@ def read_file(filename): ...@@ -62,14 +62,14 @@ def read_file(filename):
def alembic_run(ini_file, url): def alembic_run(ini_file, url):
bin_path = os.path.split(sys.executable)[0] bin_path = os.path.split(sys.executable)[0]
alembic_bin = os.path.join(bin_path, 'alembic') alembic_bin = os.path.join(bin_path, 'alembic')
command = (alembic_bin, 'upgrade', 'head') command = (alembic_bin, 'upgrade', 'head')
s = read_file(ini_file) s = read_file(ini_file)
s = s.replace('{db_url}', url) s = s.replace('{db_url}', url)
f = open('alembic.ini', 'w') f = open('alembic.ini', 'w')
f.write(s) f.write(s)
f.close() f.close()
subprocess.call(command) subprocess.call(command)
os.remove('alembic.ini') os.remove('alembic.ini')
...@@ -81,7 +81,7 @@ def get_file(filename): ...@@ -81,7 +81,7 @@ def get_file(filename):
def ask_password(name): def ask_password(name):
localizer = MyLocalizer() localizer = MyLocalizer()
data = dict(name=name) data = dict(name=name)
t_msg1 = _( t_msg1 = _(
'ask-password-1', default='Enter new password for ${name}: ', 'ask-password-1', default='Enter new password for ${name}: ',
mapping=data) mapping=data)
...@@ -105,13 +105,13 @@ def restore_csv(table, filename): ...@@ -105,13 +105,13 @@ def restore_csv(table, filename):
q = DBSession.query(table) q = DBSession.query(table)
if q.first(): if q.first():
return return
with get_file(filename) as f: with get_file(filename) as f:
reader = csv.DictReader(f) reader = csv.DictReader(f)
for cf in reader: for cf in reader:
row = table() row = table()
for fieldname in cf: for fieldname in cf:
val = cf[fieldname] val = cf[fieldname]
if not val: if not val:
continue continue
setattr(row, fieldname, val) setattr(row, fieldname, val)
DBSession.add(row) DBSession.add(row)
...@@ -119,7 +119,7 @@ def restore_csv(table, filename): ...@@ -119,7 +119,7 @@ def restore_csv(table, filename):
def append_csv(table, filename, keys): def append_csv(table, filename, keys):
with get_file(filename) as f: with get_file(filename) as f:
reader = csv.DictReader(f) reader = csv.DictReader(f)
filter_ = dict() filter_ = dict()
for cf in reader: for cf in reader:
...@@ -132,7 +132,7 @@ def append_csv(table, filename, keys): ...@@ -132,7 +132,7 @@ def append_csv(table, filename, keys):
row = table() row = table()
for fieldname in cf: for fieldname in cf:
val = cf[fieldname] val = cf[fieldname]
if not val: if not val:
continue continue
setattr(row, fieldname, val) setattr(row, fieldname, val)
DBSession.add(row) DBSession.add(row)
......
import calendar import calendar
from datetime import ( from datetime import (
date, date,
datetime, datetime,
...@@ -12,50 +12,56 @@ def get_timezone(): ...@@ -12,50 +12,56 @@ def get_timezone():
return pytz.timezone(settings['timezone']) return pytz.timezone(settings['timezone'])
def create_datetime(year, month, day, hour=0, minute=7, second=0, def create_datetime(
microsecond=0): year, month, day, hour=0, minute=7, second=0, microsecond=0):
tz = get_timezone() tz = get_timezone()
return datetime(year, month, day, hour, minute, second, return datetime(
microsecond, tzinfo=tz) year, month, day, hour, minute, second, microsecond, tzinfo=tz)
def create_date(year, month, day): def create_date(year, month, day):
return create_datetime(year, month, day) return create_datetime(year, month, day)
def as_timezone(tz_date): def as_timezone(tz_date):
localtz = get_timezone() localtz = get_timezone()
if not tz_date.tzinfo: if not tz_date.tzinfo:
tz_date = create_datetime(tz_date.year, tz_date.month, tz_date.day, tz_date = create_datetime(tz_date.year, tz_date.month, tz_date.day,
tz_date.hour, tz_date.minute, tz_date.second, tz_date.hour, tz_date.minute, tz_date.second,
tz_date.microsecond) tz_date.microsecond)
return tz_date.astimezone(localtz) return tz_date.astimezone(localtz)
def create_now(): def create_now():
tz = get_timezone() tz = get_timezone()
return datetime.now(tz) return datetime.now(tz)
def date_from_str(value): def date_from_str(value):
separator = None separator = None
value = value.split()[0] # dd-mm-yyyy HH:MM:SS value = value.split()[0] # dd-mm-yyyy HH:MM:SS
for s in ['-', '/']: for s in ['-', '/']:
if value.find(s) > -1: if value.find(s) > -1:
separator = s separator = s
break break
if separator: if separator:
t = map(lambda x: int(x), value.split(separator)) t = map(lambda x: int(x), value.split(separator))
y, m, d = t[2], t[1], t[0] y, m, d = t[2], t[1], t[0]
if d > 999: # yyyy-mm-dd if d > 999: # yyyy-mm-dd
y, d = d, y y, d = d, y
else: else:
y, m, d = int(value[:4]), int(value[4:6]), int(value[6:]) y, m, d = int(value[:4]), int(value[4:6]), int(value[6:])
return date(y, m, d) return date(y, m, d)
def dmy(tgl): def dmy(tgl):
return tgl.strftime('%d-%m-%Y') return tgl.strftime('%d-%m-%Y')
def dmyhms(t): def dmyhms(t):
return t.strftime('%d-%m-%Y %H:%M:%S') return t.strftime('%d-%m-%Y %H:%M:%S')
def next_month(year, month): def next_month(year, month):
if month == 12: if month == 12:
month = 1 month = 1
...@@ -63,7 +69,8 @@ def next_month(year, month): ...@@ -63,7 +69,8 @@ def next_month(year, month):
else: else:
month += 1 month += 1
return year, month return year, month
def best_date(year, month, day): def best_date(year, month, day):
try: try:
return date(year, month, day) return date(year, month, day)
...@@ -71,6 +78,7 @@ def best_date(year, month, day): ...@@ -71,6 +78,7 @@ def best_date(year, month, day):
last_day = calendar.monthrange(year, month)[1] last_day = calendar.monthrange(year, month)[1]
return date(year, month, last_day) return date(year, month, last_day)
def next_month_day(year, month, day): def next_month_day(year, month, day):
year, month = next_month(year, month) year, month = next_month(year, month)
return best_date(year, month, day) return best_date(year, month, day)
...@@ -22,18 +22,18 @@ from ..models.ziggurat import ( ...@@ -22,18 +22,18 @@ from ..models.ziggurat import (
_ = TranslationStringFactory('user') _ = TranslationStringFactory('user')
######## ########
# List # # List #
######## ########
@view_config( @view_config(
route_name='group', renderer='templates/group/list.pt', route_name='group', renderer='templates/group/list.pt',
permission='user-edit') permission='user-edit')
def view_list(request): def view_list(request):
q = DBSession.query(Group).order_by(Group.group_name) q = DBSession.query(Group).order_by(Group.group_name)
return dict(groups=q, title=_('Groups')) return dict(groups=q, title=_('Groups'))
#######
#######
# Add # # Add #
####### #######
def clean_name(s): def clean_name(s):
...@@ -51,8 +51,7 @@ class GroupNameValidator: ...@@ -51,8 +51,7 @@ class GroupNameValidator:
group_name = clean_name(value) group_name = clean_name(value)
if self.group and self.group.group_name.lower() == group_name.lower(): if self.group and self.group.group_name.lower() == group_name.lower():
return return
q = DBSession.query(Group).\ q = DBSession.query(Group).filter(Group.group_name.ilike(group_name))
filter(Group.group_name.ilike(group_name))
found = q.first() found = q.first()
if not found: if not found:
return return
...@@ -92,12 +91,13 @@ class AddSchema(colander.Schema): ...@@ -92,12 +91,13 @@ class AddSchema(colander.Schema):
class EditSchema(AddSchema): class EditSchema(AddSchema):
id = colander.SchemaNode( id = colander.SchemaNode(
colander.String(), widget=HiddenWidget(readonly=True)) colander.String(), widget=HiddenWidget(readonly=True))
PERMISSIONS = [ PERMISSIONS = [
('edit-user', _('User management')) ('edit-user', _('User management'))
] ]
def get_form(request, class_form, group=None): def get_form(request, class_form, group=None):
schema = class_form() schema = class_form()
schema = schema.bind(permission_list=PERMISSIONS, group=group) schema = schema.bind(permission_list=PERMISSIONS, group=group)
...@@ -118,7 +118,7 @@ def insert(values): ...@@ -118,7 +118,7 @@ def insert(values):
gp.group_id = group.id gp.group_id = group.id
gp.perm_name = perm_name gp.perm_name = perm_name
DBSession.add(gp) DBSession.add(gp)
return group return group
@view_config( @view_config(
...@@ -147,6 +147,7 @@ def view_add(request): ...@@ -147,6 +147,7 @@ def view_add(request):
request.session.flash(ts) request.session.flash(ts)
return HTTPFound(location=request.route_url('group')) return HTTPFound(location=request.route_url('group'))
######## ########
# Edit # # Edit #
######## ########
...@@ -175,7 +176,7 @@ def update(group, values): ...@@ -175,7 +176,7 @@ def update(group, values):
gp.perm_name = perm_name gp.perm_name = perm_name
DBSession.add(gp) DBSession.add(gp)
@view_config( @view_config(
route_name='group-edit', renderer='templates/group/edit.pt', route_name='group-edit', renderer='templates/group/edit.pt',
permission='user-edit') permission='user-edit')
...@@ -202,14 +203,16 @@ def view_edit(request): ...@@ -202,14 +203,16 @@ def view_edit(request):
return resp return resp
update(group, dict(c.items())) update(group, dict(c.items()))
data = dict(group_name=group.group_name) data = dict(group_name=group.group_name)
ts = _('group-updated', default='${group_name} group profile updated', mapping=data) ts = _(
'group-updated', default='${group_name} group profile updated',
mapping=data)
request.session.flash(ts) request.session.flash(ts)
return HTTPFound(location=request.route_url('group')) return HTTPFound(location=request.route_url('group'))
########## ##########
# Delete # # Delete #
########## ##########
@view_config( @view_config(
route_name='group-delete', renderer='templates/group/delete.pt', route_name='group-delete', renderer='templates/group/delete.pt',
permission='user-edit') permission='user-edit')
......
...@@ -46,9 +46,9 @@ class Login(colander.Schema): ...@@ -46,9 +46,9 @@ class Login(colander.Schema):
def login_validator(form, value): def login_validator(form, value):
user = form.user user = form.user
if not user or \ if not user or \
not user.status or \ not user.status or \
not user.user_password or \ not user.user_password or \
not UserService.check_password(user, value['password']): not UserService.check_password(user, value['password']):
raise colander.Invalid(form, _('Login failed')) raise colander.Invalid(form, _('Login failed'))
...@@ -70,13 +70,13 @@ def get_user_by_identity(request): ...@@ -70,13 +70,13 @@ def get_user_by_identity(request):
one_hour = timedelta(1/24) one_hour = timedelta(1/24)
two_minutes = timedelta(1/24/60) two_minutes = timedelta(1/24/60)
def login_by_code(request): def login_by_code(request):
q = DBSession.query(User).filter_by(security_code=request.GET['code']) q = DBSession.query(User).filter_by(security_code=request.GET['code'])
user = q.first() user = q.first()
if not user or \ if not user or \
create_now() - user.security_code_date > one_hour: create_now() - user.security_code_date > one_hour:
return HTTPFound(location=request.route_url('login-by-code-failed')) return HTTPFound(location=request.route_url('login-by-code-failed'))
user.security_code = None user.security_code = None
DBSession.add(user) DBSession.add(user)
...@@ -103,7 +103,7 @@ def view_login(request): ...@@ -103,7 +103,7 @@ def view_login(request):
schema = Login(validator=login_validator) schema = Login(validator=login_validator)
btn_submit = Button('submit', _('Submit')) btn_submit = Button('submit', _('Submit'))
form = Form(schema, buttons=(btn_submit,)) form = Form(schema, buttons=(btn_submit,))
if 'submit' not in request.POST: if 'submit' not in request.POST:
resp['form'] = form.render() resp['form'] = form.render()
return resp return resp
controls = request.POST.items() controls = request.POST.items()
...@@ -119,11 +119,13 @@ def view_login(request): ...@@ -119,11 +119,13 @@ def view_login(request):
@view_config(route_name='logout') @view_config(route_name='logout')
def view_logout(request): def view_logout(request):
headers = forget(request) headers = forget(request)
return HTTPFound(location = request.route_url('home'), return HTTPFound(
headers = headers) location=request.route_url('home'), headers=headers)
@view_config(route_name='login-by-code-failed', renderer='templates/login-by-code-failed.pt') @view_config(
route_name='login-by-code-failed',
renderer='templates/login-by-code-failed.pt')
def view_login_by_code_failed(request): def view_login_by_code_failed(request):
return dict(title='Login by code failed') return dict(title='Login by code failed')
...@@ -143,7 +145,7 @@ class ChangePassword(colander.Schema): ...@@ -143,7 +145,7 @@ class ChangePassword(colander.Schema):
def password_validator(form, value): def password_validator(form, value):
if value['new_password'] != value['retype_password']: if value['new_password'] != value['retype_password']:
raise colander.Invalid(form, _('Retype mismatch')) raise colander.Invalid(form, _('Retype mismatch'))
@view_config( @view_config(
route_name='change-password', renderer='templates/change-password.pt', route_name='change-password', renderer='templates/change-password.pt',
...@@ -170,12 +172,13 @@ def view_change_password(request): ...@@ -170,12 +172,13 @@ def view_change_password(request):
DBSession.add(request.user) DBSession.add(request.user)
return HTTPFound(location=request.route_url('change-password-done')) return HTTPFound(location=request.route_url('change-password-done'))
@view_config( @view_config(
route_name='change-password-done', route_name='change-password-done',
renderer='templates/change-password-done.pt', permission='view') renderer='templates/change-password-done.pt', permission='view')
def view_change_password_done(request): def view_change_password_done(request):
return dict(title=_('Change password')) return dict(title=_('Change password'))
################## ##################
# Reset password # # Reset password #
...@@ -185,7 +188,7 @@ class ResetPassword(colander.Schema): ...@@ -185,7 +188,7 @@ class ResetPassword(colander.Schema):
colander.String(), title=_('Email'), colander.String(), title=_('Email'),
description=_( description=_(
'email-reset-password', 'email-reset-password',
default='Enter your email address and we will send you '\ default='Enter your email address and we will send you '
'a link to reset your password.') 'a link to reset your password.')
) )
...@@ -201,7 +204,7 @@ def security_code_age(user): ...@@ -201,7 +204,7 @@ def security_code_age(user):
def send_email_security_code( def send_email_security_code(
request, user, time_remain, subject, body_msg_id, body_default_file): request, user, time_remain, subject, body_msg_id, body_default_file):
settings = get_settings() settings = get_settings()
up = urlparse(request.url) up = urlparse(request.url)
url = '{}://{}/login?code={}'.format( url = '{}://{}/login?code={}'.format(
...@@ -234,7 +237,8 @@ def regenerate_security_code(user): ...@@ -234,7 +237,8 @@ def regenerate_security_code(user):
return one_hour return one_hour
@view_config(route_name='reset-password', renderer='templates/reset-password.pt') @view_config(
route_name='reset-password', renderer='templates/reset-password.pt')
def view_reset_password(request): def view_reset_password(request):
if authenticated_userid(request): if authenticated_userid(request):
return HTTPFound(location=request.route_url('home')) return HTTPFound(location=request.route_url('home'))
...@@ -242,7 +246,7 @@ def view_reset_password(request): ...@@ -242,7 +246,7 @@ def view_reset_password(request):
schema = ResetPassword(validator=reset_password_validator) schema = ResetPassword(validator=reset_password_validator)
btn_submit = Button('submit', _('Send password reset email')) btn_submit = Button('submit', _('Send password reset email'))
form = Form(schema, buttons=(btn_submit,)) form = Form(schema, buttons=(btn_submit,))
if 'submit' in request.POST: if 'submit' in request.POST:
controls = request.POST.items() controls = request.POST.items()
identity = request.POST.get('email') identity = request.POST.get('email')
q = DBSession.query(User).filter_by(email=identity) q = DBSession.query(User).filter_by(email=identity)
...@@ -262,7 +266,7 @@ def view_reset_password(request): ...@@ -262,7 +266,7 @@ def view_reset_password(request):
@view_config( @view_config(
route_name='reset-password-sent', renderer='templates/reset-password-sent.pt') route_name='reset-password-sent',
renderer='templates/reset-password-sent.pt')
def view_reset_password_sent(request): def view_reset_password_sent(request):
return dict(title=_('Reset password')) return dict(title=_('Reset password'))
...@@ -42,7 +42,7 @@ from .login import ( ...@@ -42,7 +42,7 @@ from .login import (
_ = TranslationStringFactory('user') _ = TranslationStringFactory('user')
######## ########
# List # # List #
######## ########
@colander.deferred @colander.deferred
...@@ -71,7 +71,7 @@ my_templates = os.path.join(here, 'templates', 'user') ...@@ -71,7 +71,7 @@ my_templates = os.path.join(here, 'templates', 'user')
search_path = [my_templates, deform_templates] search_path = [my_templates, deform_templates]
my_renderer = ZPTRendererFactory(search_path) my_renderer = ZPTRendererFactory(search_path)
def get_filter_form(): def get_filter_form():
group_list = get_group_list() group_list = get_group_list()
group_list = [('', '')] + group_list group_list = [('', '')] + group_list
...@@ -85,8 +85,8 @@ def get_filter_form(): ...@@ -85,8 +85,8 @@ def get_filter_form():
def query_filter(q, p): def query_filter(q, p):
if 'group' in p: if 'group' in p:
q = q.filter( q = q.filter(
User.id==UserGroup.user_id, User.id == UserGroup.user_id,
UserGroup.group_id==p['group']) UserGroup.group_id == p['group'])
if 'name' in p: if 'name' in p:
pattern = '%{}%'.format(p['name']) pattern = '%{}%'.format(p['name'])
q = q.filter( q = q.filter(
...@@ -136,9 +136,9 @@ def view_list(request): ...@@ -136,9 +136,9 @@ def view_list(request):
q_user = query_filter(q_user, p) q_user = query_filter(q_user, p)
resp['users'] = q_user.order_by(User.email) resp['users'] = q_user.order_by(User.email)
return resp return resp
#######
#######
# Add # # Add #
####### #######
@colander.deferred @colander.deferred
...@@ -184,6 +184,7 @@ class EmailValidator(colander.Email, Validator): ...@@ -184,6 +184,7 @@ class EmailValidator(colander.Email, Validator):
REGEX_ONLY_CONTAIN = re.compile('([a-z0-9-]*)') REGEX_ONLY_CONTAIN = re.compile('([a-z0-9-]*)')
REGEX_BEGIN_END_ALPHANUMERIC = re.compile('^[a-z0-9]+(?:[-][a-z0-9]+)*$') REGEX_BEGIN_END_ALPHANUMERIC = re.compile('^[a-z0-9]+(?:[-][a-z0-9]+)*$')
class UsernameValidator(Validator): class UsernameValidator(Validator):
def __call__(self, node, value): def __call__(self, node, value):
username = value.lower() username = value.lower()
...@@ -227,7 +228,8 @@ class AddSchema(colander.Schema): ...@@ -227,7 +228,8 @@ class AddSchema(colander.Schema):
email = colander.SchemaNode( email = colander.SchemaNode(
colander.String(), title=_('Email'), colander.String(), title=_('Email'),
validator=deferred_email_validator) validator=deferred_email_validator)
user_name = colander.SchemaNode(colander.String(), title=_('Username'), user_name = colander.SchemaNode(
colander.String(), title=_('Username'),
validator=deferred_username_validator) validator=deferred_username_validator)
groups = colander.SchemaNode( groups = colander.SchemaNode(
colander.Set(), widget=deferred_group, title=_('Group')) colander.Set(), widget=deferred_group, title=_('Group'))
...@@ -239,19 +241,19 @@ class EditSchema(AddSchema): ...@@ -239,19 +241,19 @@ class EditSchema(AddSchema):
widget=HiddenWidget(readonly=True)) widget=HiddenWidget(readonly=True))
status = colander.SchemaNode( status = colander.SchemaNode(
colander.String(), widget=deferred_status, title=_('Status')) colander.String(), widget=deferred_status, title=_('Status'))
class MyEditSchema(AddSchema): class MyEditSchema(AddSchema):
id = colander.SchemaNode( id = colander.SchemaNode(
colander.String(), missing=colander.drop, colander.String(), missing=colander.drop,
widget=HiddenWidget(readonly=True)) widget=HiddenWidget(readonly=True))
def get_form(request, class_form, user=None): def get_form(request, class_form, user=None):
status_list = ( status_list = (
(1, _('Active')), (1, _('Active')),
(0, _('Inactive'))) (0, _('Inactive')))
group_list = get_group_list() group_list = get_group_list()
schema = class_form() schema = class_form()
schema = schema.bind( schema = schema.bind(
status_list=status_list, group_list=group_list, user=user) status_list=status_list, group_list=group_list, user=user)
...@@ -282,7 +284,7 @@ def insert(request, values): ...@@ -282,7 +284,7 @@ def insert(request, values):
remain = regenerate_security_code(user) remain = regenerate_security_code(user)
DBSession.add(user) DBSession.add(user)
DBSession.flush() DBSession.flush()
for gid in values['groups']: for gid in values['groups']:
ug = UserGroup(user_id=user.id, group_id=gid) ug = UserGroup(user_id=user.id, group_id=gid)
DBSession.add(ug) DBSession.add(ug)
add_member_count(gid) add_member_count(gid)
...@@ -306,7 +308,7 @@ def view_add(request): ...@@ -306,7 +308,7 @@ def view_add(request):
except ValidationFailure: except ValidationFailure:
resp['form'] = form.render() resp['form'] = form.render()
return resp return resp
user, remain = insert(request, dict(c.items())) user, remain = insert(request, dict(c.items()))
send_email_security_code( send_email_security_code(
request, user, remain, 'Welcome new user', 'email-new-user', request, user, remain, 'Welcome new user', 'email-new-user',
'email-new-user.tpl') 'email-new-user.tpl')
...@@ -346,7 +348,7 @@ def update(request, user, values): ...@@ -346,7 +348,7 @@ def update(request, user, values):
for gid in unused: for gid in unused:
reduce_member_count(gid) reduce_member_count(gid)
new = values['groups'] - existing new = values['groups'] - existing
for gid in new: for gid in new:
ug = UserGroup(user_id=user.id, group_id=gid) ug = UserGroup(user_id=user.id, group_id=gid)
DBSession.add(ug) DBSession.add(ug)
add_member_count(gid) add_member_count(gid)
...@@ -387,7 +389,7 @@ def view_edit(request): ...@@ -387,7 +389,7 @@ def view_edit(request):
########## ##########
# Delete # # Delete #
########## ##########
@view_config( @view_config(
route_name='user-delete', renderer='templates/user/delete.pt', route_name='user-delete', renderer='templates/user/delete.pt',
permission='user-edit') permission='user-edit')
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!