Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
Owo Sugiana
/
web-starter
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Settings
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit 20f4869a
authored
Jan 27, 2021
by
Owo Sugiana
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
Bug fixed manifest
1 parent
1001ca9c
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
123 additions
and
92 deletions
MANIFEST.in
alembic/env.py
alembic/versions/074b33635316_alter_users_date_fields_with_time_zone.py
setup.py
web_starter/models/ziggurat.py
web_starter/scripts/initialize_db.py
web_starter/tools/waktu.py
web_starter/views/group.py
web_starter/views/login.py
web_starter/views/user.py
MANIFEST.in
View file @
20f4869
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
alembic/env.py
View file @
20f4869
...
@@ -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
:
...
...
alembic/versions/074b33635316_alter_users_date_fields_with_time_zone.py
View file @
20f4869
"""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
))
...
...
setup.py
View file @
20f4869
...
@@ -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'
,
]
]
},
},
...
...
web_starter/models/ziggurat.py
View file @
20f4869
...
@@ -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
)
web_starter/scripts/initialize_db.py
View file @
20f4869
...
@@ -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
)
...
...
web_starter/tools/waktu.py
View file @
20f4869
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
)
web_starter/views/group.py
View file @
20f4869
...
@@ -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'
)
...
...
web_starter/views/login.py
View file @
20f4869
...
@@ -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'
))
web_starter/views/user.py
View file @
20f4869
...
@@ -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'
)
...
...
Write
Preview
Markdown
is supported
Attach a file
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to post a comment