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
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
59 additions
and
28 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
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():
with
context
.
begin_transaction
():
context
.
run_migrations
()
if
context
.
is_offline_mode
():
run_migrations_offline
()
else
:
...
...
alembic/versions/074b33635316_alter_users_date_fields_with_time_zone.py
View file @
20f4869
...
...
@@ -17,13 +17,16 @@ depends_on = None
def
upgrade
():
op
.
alter_column
(
'users'
,
'last_login_date'
,
op
.
alter_column
(
'users'
,
'last_login_date'
,
type_
=
sa
.
DateTime
(
timezone
=
True
),
existing_type
=
sa
.
DateTime
(
timezone
=
False
))
op
.
alter_column
(
'users'
,
'registered_date'
,
op
.
alter_column
(
'users'
,
'registered_date'
,
type_
=
sa
.
DateTime
(
timezone
=
True
),
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
),
existing_type
=
sa
.
DateTime
(
timezone
=
False
))
...
...
setup.py
View file @
20f4869
...
...
@@ -32,7 +32,6 @@ requires = [
'deform'
,
'pyramid_beaker'
,
'pyramid_mailer'
,
# 'opensipkd-jsonrpc @ git+https://git.opensipkd.com/sugiana/opensipkd-jsonrpc',
]
tests_require
=
[
...
...
@@ -69,7 +68,8 @@ setup(
'main = web_starter:main'
,
],
'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'
,
]
},
...
...
web_starter/models/ziggurat.py
View file @
20f4869
...
...
@@ -9,12 +9,14 @@ from ziggurat_foundations.models.base import BaseModel
from
ziggurat_foundations.models.external_identity
import
ExternalIdentityMixin
from
ziggurat_foundations.models.group
import
GroupMixin
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.user
import
UserMixin
from
ziggurat_foundations.models.user_group
import
UserGroupMixin
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
.
import
(
Base
,
...
...
@@ -27,13 +29,16 @@ from . import (
ziggurat_foundations
.
models
.
DBSession
=
DBSession
# optional for folks who pass request.db to model methods
# Base is sqlalchemy's Base = declarative_base() from your project
class
Group
(
GroupMixin
,
Base
,
CommonModel
):
pass
class
GroupPermission
(
GroupPermissionMixin
,
Base
):
pass
class
UserGroup
(
UserGroupMixin
,
Base
):
pass
...
...
@@ -45,6 +50,7 @@ class GroupResourcePermission(GroupResourcePermissionMixin, Base):
"resource_id"
,
"perm_name"
),)
class
Resource
(
ResourceMixin
,
Base
):
# ... your own properties....
...
...
@@ -61,23 +67,27 @@ class Resource(ResourceMixin, Base):
ALL_PERMISSIONS
,),
])
return
acls
class
UserPermission
(
UserPermissionMixin
,
Base
):
pass
class
UserResourcePermission
(
UserResourcePermissionMixin
,
Base
):
pass
class
User
(
UserMixin
,
Base
,
CommonModel
):
# ... your own properties....
pass
class
ExternalIdentity
(
ExternalIdentityMixin
,
Base
):
pass
# you can define multiple resource derived models to build a complex
# application like CMS, forum or other permission based solution
#class Entry(Resource):
#
class Entry(Resource):
# """
# Resource of `entry` type
# """
...
...
@@ -105,7 +115,7 @@ class RootFactory:
self
.
__acl__
.
append
((
Allow
,
acl_name
,
gp
.
perm_name
))
#ziggurat_model_init(User, Group, UserGroup, GroupPermission, passwordmanager=None)
ziggurat_model_init
(
User
,
Group
,
UserGroup
,
GroupPermission
,
UserPermission
,
ziggurat_model_init
(
User
,
Group
,
UserGroup
,
GroupPermission
,
UserPermission
,
UserResourcePermission
,
GroupResourcePermission
,
Resource
,
ExternalIdentity
,
passwordmanager
=
None
)
web_starter/scripts/initialize_db.py
View file @
20f4869
web_starter/tools/waktu.py
View file @
20f4869
...
...
@@ -12,15 +12,17 @@ def get_timezone():
return
pytz
.
timezone
(
settings
[
'timezone'
])
def
create_datetime
(
year
,
month
,
day
,
hour
=
0
,
minute
=
7
,
second
=
0
,
microsecond
=
0
):
def
create_datetime
(
year
,
month
,
day
,
hour
=
0
,
minute
=
7
,
second
=
0
,
microsecond
=
0
):
tz
=
get_timezone
()
return
datetime
(
year
,
month
,
day
,
hour
,
minute
,
second
,
microsecond
,
tzinfo
=
tz
)
return
datetime
(
year
,
month
,
day
,
hour
,
minute
,
second
,
microsecond
,
tzinfo
=
tz
)
def
create_date
(
year
,
month
,
day
):
return
create_datetime
(
year
,
month
,
day
)
def
as_timezone
(
tz_date
):
localtz
=
get_timezone
()
if
not
tz_date
.
tzinfo
:
...
...
@@ -34,6 +36,7 @@ def create_now():
tz
=
get_timezone
()
return
datetime
.
now
(
tz
)
def
date_from_str
(
value
):
separator
=
None
value
=
value
.
split
()[
0
]
# dd-mm-yyyy HH:MM:SS
...
...
@@ -50,12 +53,15 @@ def date_from_str(value):
y
,
m
,
d
=
int
(
value
[:
4
]),
int
(
value
[
4
:
6
]),
int
(
value
[
6
:])
return
date
(
y
,
m
,
d
)
def
dmy
(
tgl
):
return
tgl
.
strftime
(
'
%
d-
%
m-
%
Y'
)
def
dmyhms
(
t
):
return
t
.
strftime
(
'
%
d-
%
m-
%
Y
%
H:
%
M:
%
S'
)
def
next_month
(
year
,
month
):
if
month
==
12
:
month
=
1
...
...
@@ -64,6 +70,7 @@ def next_month(year, month):
month
+=
1
return
year
,
month
def
best_date
(
year
,
month
,
day
):
try
:
return
date
(
year
,
month
,
day
)
...
...
@@ -71,6 +78,7 @@ def best_date(year, month, day):
last_day
=
calendar
.
monthrange
(
year
,
month
)[
1
]
return
date
(
year
,
month
,
last_day
)
def
next_month_day
(
year
,
month
,
day
):
year
,
month
=
next_month
(
year
,
month
)
return
best_date
(
year
,
month
,
day
)
web_starter/views/group.py
View file @
20f4869
...
...
@@ -51,8 +51,7 @@ class GroupNameValidator:
group_name
=
clean_name
(
value
)
if
self
.
group
and
self
.
group
.
group_name
.
lower
()
==
group_name
.
lower
():
return
q
=
DBSession
.
query
(
Group
)
.
\
filter
(
Group
.
group_name
.
ilike
(
group_name
))
q
=
DBSession
.
query
(
Group
)
.
filter
(
Group
.
group_name
.
ilike
(
group_name
))
found
=
q
.
first
()
if
not
found
:
return
...
...
@@ -98,6 +97,7 @@ PERMISSIONS = [
(
'edit-user'
,
_
(
'User management'
))
]
def
get_form
(
request
,
class_form
,
group
=
None
):
schema
=
class_form
()
schema
=
schema
.
bind
(
permission_list
=
PERMISSIONS
,
group
=
group
)
...
...
@@ -147,6 +147,7 @@ def view_add(request):
request
.
session
.
flash
(
ts
)
return
HTTPFound
(
location
=
request
.
route_url
(
'group'
))
########
# Edit #
########
...
...
@@ -202,7 +203,9 @@ def view_edit(request):
return
resp
update
(
group
,
dict
(
c
.
items
()))
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
)
return
HTTPFound
(
location
=
request
.
route_url
(
'group'
))
...
...
web_starter/views/login.py
View file @
20f4869
...
...
@@ -119,11 +119,13 @@ def view_login(request):
@view_config
(
route_name
=
'logout'
)
def
view_logout
(
request
):
headers
=
forget
(
request
)
return
HTTPFound
(
location
=
request
.
route_url
(
'home'
),
headers
=
headers
)
return
HTTPFound
(
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
):
return
dict
(
title
=
'Login by code failed'
)
...
...
@@ -170,6 +172,7 @@ def view_change_password(request):
DBSession
.
add
(
request
.
user
)
return
HTTPFound
(
location
=
request
.
route_url
(
'change-password-done'
))
@view_config
(
route_name
=
'change-password-done'
,
renderer
=
'templates/change-password-done.pt'
,
permission
=
'view'
)
...
...
@@ -185,7 +188,7 @@ class ResetPassword(colander.Schema):
colander
.
String
(),
title
=
_
(
'Email'
),
description
=
_
(
'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.'
)
)
...
...
@@ -234,7 +237,8 @@ def regenerate_security_code(user):
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
):
if
authenticated_userid
(
request
):
return
HTTPFound
(
location
=
request
.
route_url
(
'home'
))
...
...
@@ -262,7 +266,7 @@ def view_reset_password(request):
@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
):
return
dict
(
title
=
_
(
'Reset password'
))
web_starter/views/user.py
View file @
20f4869
...
...
@@ -85,8 +85,8 @@ def get_filter_form():
def
query_filter
(
q
,
p
):
if
'group'
in
p
:
q
=
q
.
filter
(
User
.
id
==
UserGroup
.
user_id
,
UserGroup
.
group_id
==
p
[
'group'
])
User
.
id
==
UserGroup
.
user_id
,
UserGroup
.
group_id
==
p
[
'group'
])
if
'name'
in
p
:
pattern
=
'
%
{}
%
'
.
format
(
p
[
'name'
])
q
=
q
.
filter
(
...
...
@@ -184,6 +184,7 @@ class EmailValidator(colander.Email, Validator):
REGEX_ONLY_CONTAIN
=
re
.
compile
(
'([a-z0-9-]*)'
)
REGEX_BEGIN_END_ALPHANUMERIC
=
re
.
compile
(
'^[a-z0-9]+(?:[-][a-z0-9]+)*$'
)
class
UsernameValidator
(
Validator
):
def
__call__
(
self
,
node
,
value
):
username
=
value
.
lower
()
...
...
@@ -227,7 +228,8 @@ class AddSchema(colander.Schema):
email
=
colander
.
SchemaNode
(
colander
.
String
(),
title
=
_
(
'Email'
),
validator
=
deferred_email_validator
)
user_name
=
colander
.
SchemaNode
(
colander
.
String
(),
title
=
_
(
'Username'
),
user_name
=
colander
.
SchemaNode
(
colander
.
String
(),
title
=
_
(
'Username'
),
validator
=
deferred_username_validator
)
groups
=
colander
.
SchemaNode
(
colander
.
Set
(),
widget
=
deferred_group
,
title
=
_
(
'Group'
))
...
...
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