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:
......
...@@ -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,23 +67,27 @@ class Resource(ResourceMixin, Base): ...@@ -61,23 +67,27 @@ 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
# """ # """
...@@ -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)
...@@ -12,15 +12,17 @@ def get_timezone(): ...@@ -12,15 +12,17 @@ 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:
...@@ -34,6 +36,7 @@ def create_now(): ...@@ -34,6 +36,7 @@ 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
...@@ -50,12 +53,15 @@ def date_from_str(value): ...@@ -50,12 +53,15 @@ def date_from_str(value):
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
...@@ -64,6 +70,7 @@ def next_month(year, month): ...@@ -64,6 +70,7 @@ def next_month(year, month):
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)
...@@ -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
...@@ -98,6 +97,7 @@ PERMISSIONS = [ ...@@ -98,6 +97,7 @@ 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)
...@@ -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 #
######## ########
...@@ -202,7 +203,9 @@ def view_edit(request): ...@@ -202,7 +203,9 @@ 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'))
......
...@@ -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')
...@@ -170,6 +172,7 @@ def view_change_password(request): ...@@ -170,6 +172,7 @@ 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')
...@@ -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.')
) )
...@@ -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'))
...@@ -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'))
...@@ -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(
...@@ -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'))
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!