Skip to content
Toggle navigation
Projects
Groups
Snippets
Help
aa.gusti
/
opensipkd-base
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Settings
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Commit 166dae29
authored
May 06, 2025
by
aa.gustiana@gmail.com
Browse Files
Options
Browse Files
Tag
Download
Email Patches
Plain Diff
tobe-test
1 parent
9fa85a52
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
720 additions
and
615 deletions
development.ini
development.ini.tpl
opensipkd/base/__init__.py
opensipkd/base/models/base.py
opensipkd/base/models/partner.py
opensipkd/base/scripts/data/routes.csv
opensipkd/base/views/__init__.py
opensipkd/base/views/base_views.py
opensipkd/base/views/partner.py
opensipkd/base/views/register.py
opensipkd/base/views/templates/base5.pt
opensipkd/base/views/templates/form9.pt → opensipkd/base/views/templates/form8.pt
opensipkd/base/views/templates/login.pt
opensipkd/base/views/user_login.py
opensipkd/base/widgets/templates/readonly/form.pt
opensipkd/base/widgets/widget_os.py
development.ini
View file @
166dae2
...
...
@@ -16,13 +16,12 @@ pyramid.debug_templates = true
default_locale_name
=
id
sqlalchemy.url
=
postgresql://aagusti:a@localhost:5432/demo2
session.url
=
postgresql://aagusti:a@localhost:5432/demo2
pyramid.includes
=
pyramid_tm
pyramid_beaker
pyramid_chameleon
pyramid_debugtoolbar
pyramid_rpc.jsonrpc
pyramid_debugtoolbar
session.type
=
ext:database
...
...
@@ -73,7 +72,7 @@ login_captcha = 1
;
;modules =
menus
=
login:Login
; pjdl
:PJDL
register
:PJDL
; bphtb:BPHTB
; five:Five
;app_name = GAJI ASN
...
...
@@ -117,20 +116,19 @@ port = 6543
keys
=
root, opensipkd, sqlalchemy
[handlers]
keys
=
console
#, filelog, tabel
keys
=
console, filelog
#, tabel
[formatters]
keys
=
generic
[logger_root]
level
=
WARN
handlers
=
console
#,
filelog,
tabel
handlers
=
#, tabel
[logger_opensipkd]
level
=
DEBUG
handlers
=
handlers
=
console, filelog
qualname
=
opensipkd
[logger_sqlalchemy]
...
...
@@ -143,8 +141,9 @@ qualname = sqlalchemy.engine
[handler_filelog]
class
=
FileHandler
args
=
('log_file_location','a')
level
=
INFO
; args = ('log_file','a')
args
=
('/tmp/logs/opensipkd.log','a')
level
=
DEBUG
formatter
=
generic
...
...
development.ini.tpl
View file @
166dae2
...
...
@@ -15,16 +15,14 @@ pyramid.debug_routematch = true
pyramid.debug_templates = true
default_locale_name = id
sqlalchemy.url = postgresql://aagusti:a@localhost:5432/demo2
session.url = postgresql://aagusti:a@localhost:5433/demo2
temp_dir = C:\tmp
allow_register = true
session.url = postgresql://aagusti:a@localhost:5432/demo2
pyramid.includes =
pyramid_tm
pyramid_beaker
pyramid_chameleon
pyramid_debugtoolbar
pyramid_rpc.jsonrpc
pyramid_debugtoolbar
session.type = ext:database
session.secret = s0s3cr3ts
...
...
@@ -37,6 +35,20 @@ timezone = Asia/Jakarta
#localization = Indonesian_indonesia.1252
localization = English_Australia.1252
# Base Configuration
temp_files = C:\tmp
partner_doc = C:\\tmp\\docs\\partner\\
# Registrasi User
allow_register = 1
reg_form =
reg_idcard = 1
reg_captcha = 1
reg_verify = 1
;reg_form =
login_tpl =
login_captcha = 1
;login_tpl = opensipkd.samsat.jabar.views:templates/login.pt
;static_files = %(here)s/../files
...
...
@@ -60,7 +72,7 @@ localization = English_Australia.1252
;
;modules =
menus = login:Login
; pjdl
:PJDL
register
:PJDL
; bphtb:BPHTB
; five:Five
;app_name = GAJI ASN
...
...
@@ -68,13 +80,7 @@ menus = login:Login
;change_unit = False
;departemen_chg_id = 3
# Registrasi User
;captcha_files = /tmp/captcha
;reg_captcha = 0
;reg_idcard = 1
;reg_verify = 1
;reg_form =
;login_tpl =
# digunakan jika akan menggunakan form registrasi sendiri
...
...
@@ -110,20 +116,19 @@ port = 6543
keys = root, opensipkd, sqlalchemy
[handlers]
keys = console
#, filelog, tabel
keys = console, filelog
#, tabel
[formatters]
keys = generic
[logger_root]
level = WARN
handlers =
console
#,
filelog,
tabel
handlers =
#, tabel
[logger_opensipkd]
level = DEBUG
handlers =
handlers =
console, filelog
qualname = opensipkd
[logger_sqlalchemy]
...
...
@@ -136,8 +141,9 @@ qualname = sqlalchemy.engine
[handler_filelog]
class = FileHandler
args = ('log_file_location','a')
level = INFO
; args = ('log_file','a')
args = ('/tmp/logs/opensipkd.log','a')
level = DEBUG
formatter = generic
...
...
@@ -163,7 +169,7 @@ script_location = ziggurat_foundations:migrations
sqlalchemy.url = postgresql://aagusti:a@localhost:5432/demo2
[alembic_base]
script_location = opensipkd.base:alembic
script_location = opensipkd.base
.scripts
:alembic
sqlalchemy.url = postgresql://aagusti:a@localhost:5432/demo2
[pytest]
...
...
opensipkd/base/__init__.py
View file @
166dae2
...
...
@@ -397,6 +397,7 @@ class BaseApp():
self
.
reg_form
=
""
self
.
reg_captcha
=
""
self
.
captcha_files
=
""
self
.
login_captcha
=
0
def
static_view
(
self
,
config
,
settings
=
None
):
self
.
partner_doc
=
get_params
(
...
...
@@ -421,10 +422,12 @@ class BaseApp():
self
.
captcha_files
=
os
.
path
.
join
(
self
.
temp_files
,
"captcha"
)
+
os
.
sep
if
not
os
.
path
.
exists
(
self
.
captcha_files
):
os
.
makedirs
(
self
.
captcha_files
)
config
.
add_static_view
(
'captcha'
,
self
.
captcha_files
,
cache_max_age
=
0
)
self
.
login_tpl
=
get_params
(
"login_tpl"
,
""
,
settings
=
settings
)
self
.
login_captcha
=
get_params
(
"login_captcha"
,
0
,
settings
=
settings
)
def
add_menu
(
self
,
config
,
route_menus
,
parent
=
None
,
paket
=
"opensipkd.base.views"
):
route_names
=
[]
...
...
@@ -523,6 +526,7 @@ class BaseApp():
self
.
add_menu
(
config
,
new_routes
,
paket
)
def
get_menus
(
self
):
_logging
.
debug
(
f
"Menus: {self.menus}"
)
return
self
.
menus
...
...
@@ -543,6 +547,8 @@ def has_permission_(request, perm_names, context=None):
@subscriber
(
BeforeRender
)
def
add_global
(
event
):
event
[
'has_permission'
]
=
has_permission_
event
[
'get_base_menus'
]
=
BASE_CLASS
.
get_menus
# event['has_modules'] = has_modules_
# event['urlencode'] = urlencode
# event['quote_plus'] = quote_plus
...
...
opensipkd/base/models/base.py
View file @
166dae2
...
...
@@ -110,7 +110,7 @@ class DefaultModel(CommonModel):
return
query
@classmethod
def
query_from
(
cls
,
db_session
=
DBSession
,
columns
=
None
,
filters
=
None
):
def
query_from
(
cls
,
db_session
=
DBSession
,
columns
=
[]
,
filters
=
None
):
query
=
db_session
.
query
()
.
select_from
(
cls
)
for
c
in
columns
:
query
=
query
.
add_columns
(
c
)
...
...
opensipkd/base/models/partner.py
View file @
166dae2
...
...
@@ -97,6 +97,13 @@ class Partner(Base, PartnerModel):
row
=
cls
.
query
()
.
filter_by
(
mobile
=
ident
)
.
first
()
return
row
@classmethod
def
query_register
(
cls
):
columns
=
[
cls
.
kode
,
cls
.
nama
,
cls
.
mobile
,
cls
.
email
,
cls
.
status
]
return
cls
.
query_from
(
columns
=
columns
)
class
PartnerFiles
(
Base
,
StandarModel
):
__tablename__
=
'partner_files'
...
...
opensipkd/base/scripts/data/routes.csv
View file @
166dae2
kode,path,module,file_name,class_name,func_name,order_id,permission,parent_id/routes.kode,nama,status,type,app_id,is_menu,template,csrf,
base-home,/,base,__init__,Home,view_home,1,,,Home,1,0,,1,home.pt,,
base-login,/login,base,user_login,ViewLogin,view_login,1,,,Login,1,0,,1,,1,
base-logout,/logout,base,user_login,ViewLogout,view_logout,1,,,Logout,1,0,,1,logout.pt,,
base-admin,,base,,,,,,,,,,,1,,,
base-login,/login,base,user_login,ViewAuth,view_login,1,,,Login,1,0,,0,form6.pt,1,
base-logout,/logout,base,user_login,ViewAuth,view_logout,1,,,Logout,1,0,,0,logout.pt,,
base-password-reset,/password/reset,base,user_login,ViewPassword,reset_password,,,,Reset Password,1,0,,0,form6.pt,,
base-password,/password,base,user_login,ViewPassword,change_password,1,view,,Change Password,1,0,,0,form8.pt,,
base-password-request,/password/{code}/request,base,user_login,ViewPassword,change_password_request,1,,,Change Password,1,0,,0,form8.pt,,
base-profile,/profile,base,register,,view_profile,,,,Profile,1,0,,0,form.pt,,
base-register,/register,base,register,,view_register,,,,Register,1,0,,0,form.pt,,
base-user,/user,base,user,,view_list,,user-view,,User List,1,0,,1,form.pt,,
base-user-act,/user/{act}/act,base,user,,,,user-view,,User Action,1,0,,,json,,
base-user-add,/user/add,base,user,,,,user-edit,,User Add,1,0,,,form6.pt,,
base-user-edit,/user/{id}/edit,base,user,,,,user-edit,,User Edit,1,0,,,form6.pt,,
base-user-view,/user/{id}/view,base,user,,,,user-view,,User View,1,0,,,form6.pt,,
base-user-delete,/user/{id}/delete,base,user,,,,user-edit,,User Delete,1,0,,,form6.pt,,
base-partner,/partner,base,partner,,view_list,,admin,,Partner,1,0,,1,form.pt,,
base-partner-act,/partner/{act}/act,base,partner,,,,admin,,Partner Action,1,0,,,json,,
base-partner-add,/partner/add,base,partner,,,,admin,,Partner Add,1,0,,,form6.pt,,
base-partner-edit,/partner/{id}/edit,base,partner,,,,admin,,Partner Edit,1,0,,,form6.pt,,
base-partner-view,/partner/{id}/view,base,partner,,,,admin,,Partner View,1,0,,,form6.pt,,
base-partner-delete,/partner/{id}/delete,base,partner,,,,admin,,Partner Delete,1,0,,,form6.pt,,
base-partner-upload,/partner/upload,base,partner,,,,admin,,Partner Uload,1,0,,,form6.pt,,
base-recreate-api-key,/recreate-api-key,base,register,ViewPassword,recreate-api-key,,,,Get Api Key,1,0,,0,recreate-api-key.pt,,
base-admin,#,,,,,,view,,Administrator,1,0,,1,,,
base-user,/user,base,user,,view_list,,user-view,base-admin,User,1,0,,1,form.pt,,
base-user-act,/user/{act}/act,base,user,,,,user-view,base-user,User Action,1,0,,,json,,
base-user-add,/user/add,base,user,,,,user-edit,base-user,User Add,1,0,,,form6.pt,,
base-user-edit,/user/{id}/edit,base,user,,,,user-edit,base-user,User Edit,1,0,,,form6.pt,,
base-user-view,/user/{id}/view,base,user,,,,user-view,base-user,User View,1,0,,,form6.pt,,
base-user-delete,/user/{id}/delete,base,user,,,,user-edit,base-user,User Delete,1,0,,,form6.pt,,
base-partner,/partner,base,partner,,view_list,,admin,base-admin,Partner,1,0,,1,form.pt,,
base-partner-act,/partner/{act}/act,base,partner,,,,admin,base-partner,Partner Action,1,0,,,json,,
base-partner-add,/partner/add,base,partner,,,,admin,base-partner,Partner Add,1,0,,,form6.pt,,
base-partner-edit,/partner/{id}/edit,base,partner,,,,admin,base-partner,Partner Edit,1,0,,,form6.pt,,
base-partner-view,/partner/{id}/view,base,partner,,,,admin,base-partner,Partner View,1,0,,,form6.pt,,
base-partner-delete,/partner/{id}/delete,base,partner,,,,admin,base-partner,Partner Delete,1,0,,,form6.pt,,
base-partner-upload,/partner/upload,base,partner,,,,admin,base-partner,Partner Uload,1,0,,,form6.pt,,
,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,
...
...
opensipkd/base/views/__init__.py
View file @
166dae2
...
...
@@ -49,7 +49,7 @@ def http_forbidden(request):
# next_url = get_urls(
# request.route_url(
# 'login', _query={'next': request.url}))
next_url
=
request
.
route_url
(
'login'
,
_query
=
{
'next'
:
request
.
url
})
next_url
=
request
.
route_url
(
'
base-
login'
,
_query
=
{
'next'
:
request
.
url
})
return
HTTPSeeOther
(
location
=
next_url
)
request
.
response
.
status
=
403
...
...
opensipkd/base/views/base_views.py
View file @
166dae2
...
...
@@ -556,16 +556,16 @@ class BaseView(object):
def
get_bindings
(
self
,
row
=
None
):
return
{
"row"
:
row
}
#
def next_edit(self, form, **kwargs):
#
"""Digunakan untuk memproses button post yang lainnya
def
next_edit
(
self
,
form
,
**
kwargs
):
"""Digunakan untuk memproses button post yang lainnya
#
Args:
#
form (_type_): _description_
Args:
form (_type_): _description_
#
Returns:
#
_type_: _description_
#
"""
#
return self.route_list(**kwargs)
Returns:
_type_: _description_
"""
return
self
.
route_list
(
**
kwargs
)
def
returned_form
(
self
,
form
,
table
=
None
,
**
kwargs
):
resources
=
form
.
get_widget_resources
()
...
...
@@ -576,8 +576,6 @@ class BaseView(object):
resources
[
"js"
]
.
extend
(
set
(
table
[
"js"
])
-
set
(
resources
[
"js"
]))
resources
[
"css"
]
.
extend
(
set
(
table
[
"css"
])
-
set
(
resources
[
"css"
]))
table
=
table
[
"form"
]
# resources["js"] = list(resources["js"])
# resources["css"] = list(resources["css"])
if
is_object
:
return
dict
(
form
=
form
,
table
=
table
and
table
.
render
()
or
None
,
...
...
@@ -747,19 +745,19 @@ class BaseView(object):
"""
return
self
.
route_list
(
**
kwargs
)
#
def get_captcha_url(self):
# return get_urls("/captcha/") + get_captcha(self.req
)
#
def update_value(self, value, cstruct):
#
for k in cstruct:
#
val = cstruct.get(k)
#
if type(val) is dict:
#
if k not in value:
#
value[k] = {}
#
value[k] = self.update_value(value[k], val)
#
elif val:
#
value[k] = cstruct.get(k)
#
return value
def
get_captcha_url
(
self
):
return
self
.
req
.
static_url
(
BASE_CLASS
.
captcha_files
)
def
update_value
(
self
,
value
,
cstruct
):
for
k
in
cstruct
:
val
=
cstruct
.
get
(
k
)
if
type
(
val
)
is
dict
:
if
k
not
in
value
:
value
[
k
]
=
{}
value
[
k
]
=
self
.
update_value
(
value
[
k
],
val
)
elif
val
:
value
[
k
]
=
cstruct
.
get
(
k
)
return
value
def
view_add
(
self
,
**
kwargs
):
# bindings = self.get_bindings()
...
...
@@ -800,7 +798,7 @@ class BaseView(object):
return
self
.
returned_form
(
form
,
table
,
**
kwargs
)
def
save
(
self
,
values
,
user
,
row
=
None
):
log
.
info
(
"Save"
)
log
.
debug
(
"Save"
)
log
.
debug
(
values
)
values
.
pop
(
"id"
,
None
)
self
.
ses
[
"old_email"
]
=
user
and
user
.
email
or
None
...
...
opensipkd/base/views/partner.py
View file @
166dae2
...
...
@@ -134,10 +134,6 @@ class Views(BaseView):
# }
# return super().view_list(new_buttons=new_buttons)
# # @view_config(route_name='partner-act', renderer='json',
# permission='user-view')
# def view_act(self):
# return super().view_act()
def
next_act
(
self
):
request
=
self
.
req
...
...
@@ -203,26 +199,6 @@ class Views(BaseView):
r
.
append
(
d
)
return
r
# @view_config(route_name='partner-add', renderer='templates/form.pt',
# permission='user-edit')
# def view_add(self):
# return super().view_add()
# @view_config(route_name='partner-edit', renderer='templates/form.pt',
# permission='user-edit')
# def view_edt(self):
# return super().view_edit()
# @view_config(route_name='partner-view', renderer='templates/form.pt',
# permission='user-edit')
# def view_view(self):
# return super().view_view()
# @view_config(route_name='partner-delete', renderer='templates/form.pt',
# permission='user-edit')
# def view_delete(self):
# return super().view_delete()
def
form_validator
(
self
,
form
,
value
):
def
err_kode
():
raise
colander
.
Invalid
(
form
,
...
...
@@ -254,12 +230,6 @@ class Views(BaseView):
else
:
value
.
pop
(
"idcard"
)
# value['is_vendor'] = 'is_vendor' in value and \
# value['is_vendor'] and 1 or 0
# value['is_customer'] = 'is_customer' in value and \
# value['is_customer'] and 1 or 0
# value["status"] = 'status' in value and value['status'] and 1 or 0
def
get_bindings
(
self
,
row
=
None
):
result
=
super
()
.
get_bindings
(
row
)
# provinsi_list = ResProvinsi.get_list()
...
...
@@ -279,7 +249,7 @@ class Views(BaseView):
return
result
def
save_request
(
self
,
values
,
row
=
None
):
#
def save_request(self, values, row=None):
# if "idcard" in values and values["idcard"]:
# if str(self.req.POST['upload']) != "":
# folder = self.get_params("idcard_folder", '/tmp/idcard')
...
...
@@ -289,8 +259,8 @@ class Views(BaseView):
# else:
# del values["idcard"]
row
=
super
()
.
save_request
(
values
,
row
)
return
row
#
row = super().save_request(values, row)
#
return row
def
get_values
(
self
,
row
,
istime
=
False
):
d
=
super
()
.
get_values
(
row
,
istime
)
...
...
@@ -308,6 +278,8 @@ class Views(BaseView):
def
before_delete
(
self
,
row
):
PartnerFiles
.
query
()
.
filter_by
(
partner_id
=
row
.
id
)
.
delete
()
def
before_delete
(
self
,
row
):
PartnerFiles
.
query
()
.
filter_by
(
partner_id
=
row
.
id
)
.
delete
()
@colander.deferred
def
partner_widget
(
node
,
kw
):
...
...
opensipkd/base/views/register.py
View file @
166dae2
...
...
@@ -30,10 +30,10 @@ import logging
from
datetime
import
datetime
import
colander
from
deform
import
(
widget
,
FileData
,
ValidationFailure
)
from
deform
import
(
widget
,
FileData
,
ValidationFailure
,
Button
)
from
opensipkd.base
import
BASE_CLASS
from
opensipkd.tools
import
Upload
,
mem_tmp_store
,
image_validator
,
date_from_str
from
opensipkd.tools.buttons
import
btn_cancel
,
btn_
register
,
btn_
save
from
opensipkd.tools.buttons
import
btn_cancel
,
btn_save
from
pyramid.httpexceptions
import
HTTPFound
,
HTTPNotFound
from
pyramid.i18n
import
TranslationStringFactory
# from pyramid.security import forget
...
...
@@ -45,7 +45,7 @@ from opensipkd.base.views.user import email_validator, add_member_count
from
..models
import
User
,
DBSession
,
Partner
,
Group
,
UserGroup
from
..widgets
import
widget_os
# from .base_views import need_captcha, get_url_captcha
#
from .user_login import regenerate_security_code, send_email_security_code
from
.user_login
import
regenerate_security_code
,
send_email_security_code
from
..views
import
BaseView
# from .. import get_urls
...
...
@@ -90,7 +90,7 @@ class AddSchema(colander.Schema):
self
[
"email"
]
.
missing
=
colander
.
drop
self
[
"email"
]
.
validator
=
None
if
is_id_card
==
'1'
or
is_id_card
==
"True"
or
is_id_card
==
"true"
:
if
is_id_card
:
self
[
"kode"
]
=
colander
.
SchemaNode
(
colander
.
String
(),
widget
=
widget
.
TextInputWidget
(),
...
...
@@ -106,14 +106,12 @@ class AddSchema(colander.Schema):
if
not
request
.
user
and
BASE_CLASS
.
reg_captcha
:
self
[
"captcha"
]
=
colander
.
SchemaNode
(
colander
.
String
(),
widget
=
widget_os
.
CaptchaWidget
(
request
=
request
,
url
=
request
.
static_url
(
BASE_CLASS
.
captcha_files
)),
widget
=
widget_os
.
CaptchaWidget
(
request
=
request
,
url
=
request
.
static_url
(
BASE_CLASS
.
captcha_files
)),
oid
=
"captcha"
,
title
=
_
(
"Captcha"
))
if
request
.
user
and
request
.
user
.
id
and
not
external_user
:
# todo: external user tidak ada password
# validasi harusnya menggunakan authentikasi ke provider lagi
self
[
"password"
]
=
colander
.
SchemaNode
(
colander
.
String
(),
widget
=
widget
.
PasswordWidget
(),
...
...
@@ -127,20 +125,20 @@ class EditSchema(AddSchema):
del
self
[
"email"
]
#
def user_found(identity):
#
return User.get_by_identity(identity)
def
user_found
(
identity
):
return
User
.
get_by_identity
(
identity
)
# def mobile_found_partner(mobile):
# return Partner.query_mobile(mobile)
#
def email_found_partner(email):
#
return Partner.query_email(email).first()
def
email_found_partner
(
email
):
return
Partner
.
query_email
(
email
)
.
first
()
#
def nik_found(nik):
#
return Partner.query_kode(nik).first()
def
nik_found
(
nik
):
return
Partner
.
query_kode
(
nik
)
.
first
()
# def _show_error(request, msg):
...
...
@@ -153,8 +151,7 @@ class EditSchema(AddSchema):
# # def reg_buttons():
# # btn_register = Button(name='save', css_class='btn-success', type="submit",
# # title="Register")
# # btn_cancel = Button(name='batal', css_class='btn-primary', type="submit")
# # return btn_cancel, btn_register
...
...
@@ -163,137 +160,138 @@ class Views(BaseView):
def
__init__
(
self
,
request
):
super
()
.
__init__
(
request
)
self
.
autocomplete
=
"off"
btn_register
=
Button
(
name
=
'save'
,
css_class
=
'btn-success'
,
type
=
"submit"
,
title
=
"Register"
)
self
.
buttons
=
(
btn_register
,
btn_cancel
)
self
.
add_schema
=
AddSchema
self
.
edit_schema
=
EditSchema
self
.
table
=
Partner
self
.
list_route
=
"home"
# def form_validator(self, form, value):
# """
# Default "value"
# user_name = mobile
# kode = mobile
# Validasi saat Register
# 1. Cek email pada Users jika ada dan Users.id beda reject
# 2. Cek email pada Partner jika ada dan Partner.id beda reject
# 3. Cek kode pada Partner jika ada dan Partner.id beda reject
# 4. Cek mobile pada Partner jika ada dan Users.id beda reject
# """
# _logging.debug(value)
# form_exc = colander.Invalid(form, '')
# request = form.request
# session = request.session
# def raise_err(field, msg):
# form_exc[field] = msg
# raise form_exc
# def err_captcha():
# msg = 'Captcha berbeda'
# raise_err('captcha', msg)
# def err_email():
# msg = 'e-mail %s sudah ada yang menggunakan' % value['email']
# raise_err('email', msg)
# def err_user():
# if 'user_name' in form:
# msg = 'User name %s sudah ada yang menggunakan' % value[
# 'user_name']
# raise_err('user_name', msg)
# else:
# msg = 'Email %s sudah ada yang menggunakan' % value['email']
# raise_err('email', msg)
# def err_nik():
# if "kode" in form:
# msg = 'NIK %s sudah ada yang menggunakan' % value['kode']
# raise_err('kode', msg)
# else:
# msg = 'Mobile %s sudah ada yang menggunakan' % value['kode']
# raise_err('mobile', msg)
# def err_login():
# msg = 'User atau Password tidak sesuai'
# raise_err('password', msg)
# if not request.user and need_captcha():
# captcha = 'captcha' in value and value['captcha'].upper() or None
# ses_captcha = request.session.pop('captcha')
# if captcha != ses_captcha:
# err_captcha()
# user = request.user
# if "email" not in value and "id_info" in session:
# value["email"] = session["id_info"]["email"]
# if not user and (
# "user_name" not in value or not value["user_name"]):
# value["user_name"] = value["email"]
# if 'user_name' in value:
# user_name = value["user_name"]
# found = user_found(user_name)
# if found and not user:
# err_user()
# if found and user:
# if user.id != found.id:
# err_user()
# # Check Data Partner
# if user:
# q = DBSession.query(Partner).filter_by(email=user.email)
# partner = q.first()
# else:
# partner = None
# if not user:
# email = value["email"]
# found = user_found(email)
# if found and not user:
# err_email()
# if found and user:
# if user.id != found.id:
# err_email()
# found = email_found_partner(email)
# if partner:
# if found and found.id != partner.id:
# err_email()
# elif found:
# err_email()
# if "kode" not in value or not value["kode"]:
# value["kode"] = value["mobile"]
# if 'kode' in value:
# found_nik = nik_found(value['kode'])
# if partner:
# if found_nik and found_nik.id != partner.id:
# err_nik()
# elif found_nik:
# err_nik()
# if 'password' in value:
# if not user or not UserService.check_password(
# user, value['password']):
# err_login()
# if "idcard" in value and value["idcard"]:
# idcard = value["idcard"]
# if "fp" in idcard and idcard["fp"] and idcard["fp"] != b'':
# path = get_id_card_folder()
# _logging.debug(idcard["fp"])
# upload = Upload(path)
# value["idcard"] = upload.save_fp(idcard)
# else:
# value.pop("idcard")
# value["groups"] = "Guest"
self
.
list_route
=
"base-home"
def
form_validator
(
self
,
form
,
value
):
"""
Default "value"
user_name = mobile
kode = mobile
Validasi saat Register
1. Cek email pada Users jika ada dan Users.id beda reject
2. Cek email pada Partner jika ada dan Partner.id beda reject
3. Cek kode pada Partner jika ada dan Partner.id beda reject
4. Cek mobile pada Partner jika ada dan Users.id beda reject
"""
_logging
.
debug
(
value
)
form_exc
=
colander
.
Invalid
(
form
,
''
)
request
=
form
.
request
session
=
request
.
session
def
raise_err
(
field
,
msg
):
form_exc
[
field
]
=
msg
raise
form_exc
# def err_captcha():
# msg = 'Captcha berbeda'
# raise_err('captcha', msg)
def
err_email
():
msg
=
'e-mail
%
s sudah ada yang menggunakan'
%
value
[
'email'
]
raise_err
(
'email'
,
msg
)
def
err_user
():
if
'user_name'
in
form
:
msg
=
'User name
%
s sudah ada yang menggunakan'
%
value
[
'user_name'
]
raise_err
(
'user_name'
,
msg
)
else
:
msg
=
'Email
%
s sudah ada yang menggunakan'
%
value
[
'email'
]
raise_err
(
'email'
,
msg
)
def
err_nik
():
if
"kode"
in
form
:
msg
=
'NIK
%
s sudah ada yang menggunakan'
%
value
[
'kode'
]
raise_err
(
'kode'
,
msg
)
else
:
msg
=
'Mobile
%
s sudah ada yang menggunakan'
%
value
[
'kode'
]
raise_err
(
'mobile'
,
msg
)
def
err_login
():
msg
=
'User atau Password tidak sesuai'
raise_err
(
'password'
,
msg
)
# if not request.user and need_captcha():
# captcha = 'captcha' in value and value['captcha'].upper() or None
# ses_captcha = request.session.pop('captcha')
# if captcha != ses_captcha:
# err_captcha()
user
=
request
.
user
if
"email"
not
in
value
and
"id_info"
in
session
:
value
[
"email"
]
=
session
[
"id_info"
][
"email"
]
if
not
user
and
(
"user_name"
not
in
value
or
not
value
[
"user_name"
]):
value
[
"user_name"
]
=
value
[
"email"
]
if
'user_name'
in
value
:
user_name
=
value
[
"user_name"
]
found
=
user_found
(
user_name
)
if
found
and
not
user
:
err_user
()
if
found
and
user
:
if
user
.
id
!=
found
.
id
:
err_user
()
# Check Data Partner
if
user
:
q
=
DBSession
.
query
(
Partner
)
.
filter_by
(
email
=
user
.
email
)
partner
=
q
.
first
()
else
:
partner
=
None
if
not
user
:
email
=
value
[
"email"
]
found
=
user_found
(
email
)
if
found
and
not
user
:
err_email
()
if
found
and
user
:
if
user
.
id
!=
found
.
id
:
err_email
()
found
=
email_found_partner
(
email
)
if
partner
:
if
found
and
found
.
id
!=
partner
.
id
:
err_email
()
elif
found
:
err_email
()
if
"kode"
not
in
value
or
not
value
[
"kode"
]:
value
[
"kode"
]
=
value
[
"mobile"
]
if
'kode'
in
value
:
found_nik
=
nik_found
(
value
[
'kode'
])
if
partner
:
if
found_nik
and
found_nik
.
id
!=
partner
.
id
:
err_nik
()
elif
found_nik
:
err_nik
()
if
'password'
in
value
:
if
not
user
or
not
UserService
.
check_password
(
user
,
value
[
'password'
]):
err_login
()
if
"idcard"
in
value
and
value
[
"idcard"
]:
idcard
=
value
[
"idcard"
]
if
"fp"
in
idcard
and
idcard
[
"fp"
]
and
idcard
[
"fp"
]
!=
b
''
:
path
=
BASE_CLASS
.
reg_id_card
_logging
.
debug
(
idcard
[
"fp"
])
upload
=
Upload
(
path
)
value
[
"idcard"
]
=
upload
.
save_fp
(
idcard
)
else
:
value
.
pop
(
"idcard"
)
value
[
"groups"
]
=
"Guest"
def
before_add
(
self
):
result
=
{}
...
...
@@ -315,13 +313,13 @@ class Views(BaseView):
# self.ses.delete()
def
view_register
(
self
):
if
not
BASE_CLASS
.
allow_register
:
return
HTTPNotFound
()
self
.
bindings
=
dict
(
user
=
None
)
request
=
self
.
req
if
not
BASE_CLASS
.
allow_register
:
return
HTTPFound
(
location
=
request
.
route_url
(
"base-home"
))
if
request
.
user
:
return
HTTPFound
(
location
=
request
.
route_url
(
"profile"
))
return
HTTPFound
(
location
=
request
.
route_url
(
"
base-
profile"
))
self
.
bindings
=
dict
(
user
=
None
)
if
"g_state"
in
self
.
req
.
cookies
:
if
"id_info"
not
in
self
.
ses
or
not
self
.
ses
[
"id_info"
]:
return
HTTPFound
(
location
=
self
.
req
.
route_url
(
"login"
))
...
...
@@ -329,92 +327,98 @@ class Views(BaseView):
reg_form
=
BASE_CLASS
.
reg_form
if
reg_form
!=
"base-register"
:
return
HTTPFound
(
location
=
self
.
req
.
route_url
(
reg_form
))
return
super
()
.
view_add
()
# def query_id(self):
# return DBSession.query(Partner). \
# filter(Partner.email == self.req.user.email)
def
save_request
(
self
,
values
,
row
=
None
):
if
not
"email"
in
values
or
not
values
[
"email"
]:
values
[
"email"
]
=
self
.
req
.
user
and
self
.
req
.
user
.
email
or
""
if
not
row
:
values
[
"is_vendor"
]
=
0
values
[
"is_customer"
]
=
1
row
=
super
()
.
save_request
(
values
,
row
)
def
after_save
(
self
,
values
,
row
):
# User Baru
if
not
self
.
req
.
user
:
#todo: simplikasi lagi disini
user
=
User
()
user
.
email
=
row
.
email
user
.
user_name
=
row
.
email
user
.
registered_date
=
datetime
.
now
()
self
.
db_session
.
add
(
user
)
self
.
db_session
.
flush
()
if
'groups'
in
values
and
values
[
'groups'
]:
gr
=
Group
.
query_group_name
(
values
[
'groups'
])
.
first
()
ug
=
UserGroup
()
ug
.
user_id
=
user
.
id
ug
.
group_id
=
gr
.
id
self
.
db_session
.
add
(
ug
)
add_member_count
(
gr
.
id
)
self
.
db_session
.
flush
()
remain
=
regenerate_security_code
(
user
)
send_email_security_code
(
self
.
req
,
user
,
remain
,
'Welcome new user'
,
'email-new-user'
,
'email-new-user.tpl'
)
ts
=
_
(
'user-added'
,
default
=
'${email} berhasil ditambahkan dan email untuk ubah '
'kata kunci sudah dikirim.'
,
mapping
=
{
"email"
:
row
.
email
})
self
.
ses
.
flash
(
ts
)
return
super
()
.
after_save
(
values
,
row
)
return
row
def
query_id
(
self
):
return
DBSession
.
query
(
Partner
)
.
\
filter
(
Partner
.
email
==
self
.
req
.
user
.
email
)
# def id_not_found(self, **kwargs):
# return
# def get_values(self, row, istime=False):
# d = super().get_values(row, istime)
# partner = DBSession.query(Partner). \
# filter(Partner.email == self.req.user.email).first()
# if partner:
# fields = ["nama", "alamat_1", "alamat_2", "mobile", "email", "kode",
# "idcard"]
# for f in fields:
# d[f] = hasattr(partner, f) and getattr(partner, f) or ""
# if "idcard" in d:
# if d["idcard"]:
# filename = d["idcard"]
# preview_url = "/".join(
# [self.req.static_url(get_id_card_folder('/')),
# filename])
# d["idcard"] = {"uid": filename.split(".")[0],
# "filename": filename,
# "preview_url": preview_url
# }
# else:
# d.pop("idcard")
# else:
# d.pop("idcard")
# return d
# # def before_add(self):
# @view_config(route_name='profile', renderer='templates/form.pt',
# permission='view')
def
get_values
(
self
,
row
,
istime
=
False
):
d
=
super
()
.
get_values
(
row
,
istime
)
partner
=
DBSession
.
query
(
Partner
)
.
\
filter
(
Partner
.
email
==
self
.
req
.
user
.
email
)
.
first
()
if
partner
:
fields
=
[
"nama"
,
"alamat_1"
,
"alamat_2"
,
"mobile"
,
"email"
,
"kode"
,
"idcard"
]
for
f
in
fields
:
d
[
f
]
=
hasattr
(
partner
,
f
)
and
getattr
(
partner
,
f
)
or
""
if
"idcard"
in
d
:
if
d
[
"idcard"
]:
filename
=
d
[
"idcard"
]
preview_url
=
"/"
.
join
(
[
self
.
req
.
static_url
(
BASE_CLASS
.
reg_id_card
),
filename
])
d
[
"idcard"
]
=
{
"uid"
:
filename
.
split
(
"."
)[
0
],
"filename"
:
filename
,
"preview_url"
:
preview_url
}
else
:
d
.
pop
(
"idcard"
)
else
:
d
.
pop
(
"idcard"
)
return
d
# def before_add(self):
def
view_profile
(
self
):
self
.
buttons
=
(
btn_save
,
btn_cancel
)
reg_form
=
get_params
(
"reg_form"
)
if
reg_form
:
return
HTTPFound
(
location
=
get_urls
(
self
.
req
.
route_url
(
reg_form
)))
reg_form
=
BASE_CLASS
.
reg_form
if
reg_form
and
reg_form
!=
"base-register"
:
return
HTTPFound
(
location
=
self
.
req
.
route_url
(
reg_form
))
self
.
bindings
=
dict
(
user
=
self
.
req
.
user
)
resp
=
super
(
Registrasi
,
self
)
.
view_edit
()
if
not
resp
:
resp
=
super
(
Registrasi
,
self
)
.
view_add
()
partner
=
Partner
.
query_email
(
self
.
req
.
user
.
email
)
.
first
()
if
not
partner
:
resp
=
super
()
.
view_add
()
else
:
resp
=
super
()
.
view_edit
()
return
resp
# def save_request(self, values, row=None):
# if not "email" in values or not values["email"]:
# values["email"] = self.req.user and self.req.user.email or ""
# if not row:
# values["is_vendor"] = 0
# values["is_customer"] = 1
# row = super().save_request(values, row)
# if not self.req.user: # User Baru
# user = User()
# user.email = row.email
# user.user_name = row.email
# user.registered_date = datetime.now()
# DBSession.add(user)
# DBSession.flush()
# if 'groups' in values and values['groups']:
# gr = Group.query_group_name(values['groups']).first()
# ug = UserGroup()
# ug.user_id = user.id
# ug.group_id = gr.id
# DBSession.add(ug)
# add_member_count(gr.id)
# DBSession.flush()
# remain = regenerate_security_code(user)
# send_email_security_code(
# self.req, user, remain, 'Welcome new user', 'email-new-user',
# 'email-new-user.tpl')
# ts = _(
# 'user-added',
# default='${email} berhasil ditambahkan dan email untuk ubah '
# 'kata kunci sudah dikirim.',
# mapping={"email": row.email})
# self.ses.flash(ts)
# return row
# def next_add(self, form, **kwargs):
# table = kwargs.get("table")
...
...
opensipkd/base/views/templates/base5.pt
View file @
166dae2
...
...
@@ -125,12 +125,14 @@
</span>
<i
class=
"fa fa-angle-down"
></i>
</a>
<ul
class=
"dropdown-menu pull-right"
>
<li><a
style=
"text-transform:capitalize"
href=
"{request.route_url('profile')}"
>
Profile
</a></li>
<li><a
style=
"text-transform:capitalize"
href=
"${request.route_url('base-profile')}"
>
Profile
</a>
</li>
<li
tal:condition=
"not request.user.external"
>
<a
style=
"text-transform:capitalize"
href=
"
{request.route_url('
password')}"
>
Ubah
<a
style=
"text-transform:capitalize"
href=
"
${request.route_url('base-
password')}"
>
Ubah
password
</a>
</li>
<li><a
style=
"text-transform:capitalize"
href=
"${request.route_url('base-logout')}"
>
Logout
</a></li>
<li><a
style=
"text-transform:capitalize"
href=
"${request.route_url('base-logout')}"
>
Logout
</a>
</li>
<li
tal:condition=
"request.user.api_key"
><a
style=
"text-transform:capitalize"
href=
"${home}/recreate-api-key"
>
API Key
</a></li>
<!-- <li talcondition="'core' in request.modules and change_unit(request)">
...
...
@@ -150,92 +152,51 @@
<!-- Left panel : Navigation area -->
<!-- Note: This width of the aside area can be adjusted through LESS variables -->
<aside
id=
"left-panel"
style=
"padding-bottom:67px"
>
Menu
<!-- NAVIGATION : This navigation is also responsive-->
<nav
style=
"
"
>
<nav
class=
"smart-menu"
id=
"menu
"
>
<!-- Modul Menu -->
<ul
metal:define-slot=
"navs"
></ul>
<!-- Admin Menu -->
<ul
tal:condition=
"has_permission(request, user_path)"
style=
"margin-top: 0; padding-top: 0;"
>
<li>
<a
href=
"#"
><i
class=
"fa fa-lg fa-fw fa-shield"
></i><span
class=
"menu-item-parent"
>
Admin
</span></a>
<ul>
<li
tal:condition=
"has_permission(request, ['user-view', 'user-edit'])"
tal:attributes=
"class route_name in user_path and 'active'"
>
<a
href=
"${home}/user"
>
User
</a>
</li>
<li
tal:condition=
"has_permission(request, ['user-view', 'user-edit'])"
tal:attributes=
"class route_name in user_area_path and 'active'"
>
<a
href=
"${home}/user/area"
>
User Area
</a>
</li>
<li
tal:condition=
"has_permission(request, ['user-view', 'user-edit'])"
tal:attributes=
"class route_name in user_dep_path and 'active'"
>
<a
href=
"${home}/user/departemen"
>
User Departemen
</a>
</li>
<li
tal:condition=
"has_permission(request, ['user-view', 'user-edit'])"
tal:attributes=
"class route_name in user_ext_path and 'active'"
>
<a
href=
"${home}/user/ext"
>
External User
</a>
</li>
<li
tal:condition=
"has_permission(request, ['user-view', 'user-edit'])"
tal:attributes=
"class route_name in group_path and 'active'"
>
<a
href=
"${home}/group"
>
Group
</a>
</li>
<li
tal:condition=
"has_permission(request, 'upload-logo')"
tal:attributes=
"class route_name in ['upload-logo'] and 'active'"
>
<a
href=
"${home}/upload/logo"
>
Upload Logo
</a>
</li>
<li
tal:condition=
"has_permission(request, 'parameter')"
tal:attributes=
"class route_name in param_path and 'active'"
>
<a
href=
"${home}/parameter"
>
Parameter
</a>
</li>
<li
tal:condition=
"has_permission(request, 'company')"
tal:attributes=
"class route_name in company_path and 'active'"
>
<a
href=
"${home}/company"
>
Pemerintah
</a>
</li>
<li
tal:condition=
"has_permission(request, 'eselon')"
tal:attributes=
"class route_name in eselon_path and 'active'"
>
<a
href=
"${home}/eselon"
>
Eselon
</a>
</li>
<li
tal:condition=
"has_permission(request, 'jabatan')"
tal:attributes=
"class route_name in jabatan_path and 'active'"
>
<a
href=
"${home}/jabatan"
>
Jabatan
</a>
</li>
<li
tal:condition=
"has_permission(request, 'departemen')"
tal:attributes=
"class route_name in dep_path and 'active'"
>
<a
href=
"${home}/departemen"
>
Departemen
</a>
</li>
<li
tal:condition=
"has_permission(request, 'partner')"
tal:attributes=
"class route_name in partner_path and 'active'"
>
<a
href=
"${home}/partner"
>
Partner
</a>
</li>
<li
tal:condition=
"has_permission(request, 'partner-departemen')"
tal:attributes=
"class route_name in part_dep_path and 'active'"
>
<a
href=
"${home}/partner/departemen"
>
Partner Departemen
</a>
</li>
<li
tal:condition=
"has_permission(request, 'provinsi')"
tal:attributes=
"class route_name in provinsi_path and 'active'"
>
<a
href=
"${home}/provinsi"
>
Provinsi
</a>
</li>
<li
tal:condition=
"has_permission(request, 'dati2')"
tal:attributes=
"class route_name in dati2_path and 'active'"
>
<a
href=
"${home}/dati2"
>
Kabupaten/Kota
</a>
</li>
<li
tal:condition=
"has_permission(request, 'kecamatan')"
tal:attributes=
"class route_name in kecamatan_path and 'active'"
>
<a
href=
"${home}/kecamatan"
>
Kecamatan
</a>
</li>
<li
tal:condition=
"has_permission(request, 'desa')"
tal:attributes=
"class route_name in desa_path and 'active'"
>
<a
href=
"${home}/desa"
>
Desa/Kelurahan
</a>
</li>
<li
tal:condition=
"has_permission(request, 'log')"
tal:attributes=
"class route_name in ['log'] and 'active'"
>
<a
href=
"${home}/log"
>
Log
</a>
<ul
metal:define-slot=
"navs"
></ul>
<ul
style=
"margin-top: 0; padding-top: 0;"
>
<li
tal:repeat=
"menu get_base_menus()"
tal:attributes=
"class route_name in menu['route_name'] and 'active'"
>
<a
tal:condition=
"python:not menu['children'] and has_permission(request, menu['permission'])"
href=
"${home}${menu['path']}"
>
<i
tal:condition=
"menu['icon']"
class=
"fa fa-lg fa-fw ${menu['icon']}"
></i>
<span>
${menu['nama']}
</span>
</a>
<a
tal:condition=
"python:menu['children'] and has_permission(request, menu['permission'])"
href=
"#"
>
<i
tal:condition=
"menu['icon']"
class=
"fa fa-lg fa-fw ${menu['icon']}"
></i>
<span
class=
"menu-item-parent"
>
${menu['nama']}
</span>
</a>
<ul
tal:condition=
"python:menu['children'] and has_permission(request, menu['permission'])"
>
<li
tal:repeat=
"submenu menu['children']"
tal:attributes=
"class route_name in submenu['route_name'] and 'active'"
>
<a
tal:condition=
"python:not submenu['children'] and has_permission(request, submenu['permission'])"
href=
"${home}${submenu['path']}"
>
<i
tal:condition=
"submenu['icon']"
class=
"fa fa-lg fa-fw ${submenu['icon']}"
></i>
<span>
${submenu['nama']}
</span>
</a>
<a
tal:condition=
"submenu['children']"
href=
"#"
>
<i
tal:condition=
"submenu['icon']"
class=
"fa fa-lg fa-fw ${submenu['icon']}"
></i>
<span
class=
"menu-item-parent"
>
${submenu['nama']}
</span>
</a>
<ul
tal:condition=
"submenu['children']"
>
<li
tal:repeat=
"submenu2 submenu['children']"
tal:attributes=
"class route_name in submenu2['route_name'] and 'active'"
>
<a
href=
"${home}${submenu2['path']}"
>
${submenu2['nama']}
</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</nav>
<span
class=
"minifyme"
data-action=
"minifyMenu"
>
<i
class=
"fa fa-arrow-circle-left hit"
></i>
...
...
opensipkd/base/views/templates/form
9
.pt
→
opensipkd/base/views/templates/form
8
.pt
View file @
166dae2
<html
metal:use-macro=
"load: ./base5.pt"
tal:define=
"scripts scripts|scripts"
>
<div
metal:fill-slot=
"content"
>
<div
class=
"col-md-8 col-md-offset-2"
>
<div
class=
"panel panel-default"
>
<!-- <div class="panel-heading"> -->
<!-- <h3 class="panel-title"><i class="fa fa-fw fa-plus"></i> ${request.title}</h3> -->
<!-- </div> -->
<div
class=
"panel-body"
>
<div
tal:content=
"structure form"
></div>
</div>
</div>
</div>
</div>
<div
metal:fill-slot=
"scripts"
>
<script>
$
(
document
).
ready
(
function
()
{
// $(".read-only").attr("readonly", true);
$
(
".readonly"
).
attr
(
"readonly"
,
true
);
$
(
".date"
).
attr
(
"readonly"
,
true
);
// $(".date").datepicker({
// format: 'dd-mm-yyyy'
// });
$
{
structure
:
scripts
}
});
</script>
<div
metal:define-slot=
"scripts"
></div>
</div>
</html>
<html
metal:use-macro=
"load: ./base5.pt"
tal:define=
"scripts scripts|scripts"
>
<div
metal:fill-slot=
"content"
>
<div
class=
"col-md-8 col-md-offset-2"
>
<div
class=
"panel panel-default"
>
<!-- <div class="panel-heading"> -->
<!-- <h3 class="panel-title"><i class="fa fa-fw fa-plus"></i> ${request.title}</h3> -->
<!-- </div> -->
<div
class=
"panel-body"
>
<div
tal:content=
"structure form"
></div>
</div>
</div>
</div>
</div>
<div
metal:fill-slot=
"scripts"
>
<script>
$
(
document
).
ready
(
function
()
{
// $(".read-only").attr("readonly", true);
$
(
".readonly"
).
attr
(
"readonly"
,
true
);
$
(
".date"
).
attr
(
"readonly"
,
true
);
// $(".date").datepicker({
// format: 'dd-mm-yyyy'
// });
$
{
structure
:
scripts
}
});
</script>
<div
metal:define-slot=
"scripts"
></div>
</div>
</html>
opensipkd/base/views/templates/login.pt
View file @
166dae2
...
...
@@ -79,6 +79,7 @@
<b
class=
"tooltip tooltip-top-right"
><i
class=
"fa fa-lock txt-color-teal"
></i>
ISI
DENGAN PASSWORD ANDA
</b>
</label>
</section>
<section>
<div
class=
"form-group"
>
<label
class=
" checkbox checkbox-inline"
>
...
...
@@ -87,15 +88,17 @@
<a
href=
"${home}/reset-password"
id=
"lupa"
>
Lupa Password?
</a>
</div>
</div>
</section>
<section
tal:condition=
"'captcha' in form"
>
<div
tal:define=
"field form['captcha']"
>
${structure:field.serialize()}
</div>
</section>
<section>
<div
tal:condition=
"'csrf_token' in form"
>
<div
tal:define=
"field form['csrf_token']"
style=
"display: none;"
>
${structure:field.serialize()}
</div>
<section
tal:condition=
"'csrf_token' in form"
>
<div
tal:define=
"field form['csrf_token']"
style=
"display: none;"
>
${structure:field.serialize()}
</div>
</section>
...
...
opensipkd/base/views/user_login.py
View file @
166dae2
...
...
@@ -23,7 +23,9 @@ import os
import
re
from
datetime
import
timedelta
,
datetime
from
importlib
import
import_module
from
urllib
import
request
from
bak.opensipkd.base.tools
import
buttons
import
colander
from
deform
import
widget
,
Form
,
ValidationFailure
,
Button
from
pyramid.csrf
import
new_csrf_token
...
...
@@ -36,7 +38,7 @@ from ziggurat_foundations.models.services.external_identity import \
ExternalIdentityService
from
ziggurat_foundations.models.services.user
import
UserService
from
opensipkd.base
import
BASE_CLASS
,
DBSession
,
get_params
from
opensipkd.base
import
BASE_CLASS
,
DBSession
,
get_params
,
scripts
from
.
import
one_hour
,
two_minutes
from
..models.users
import
User
,
ExternalIdentity
# , Partner
...
...
@@ -45,6 +47,8 @@ from opensipkd.tools.buttons import btn_cancel
# from .. import get_urls
from
.base_views
import
CSRFSchema
,
BaseView
from
pyramid.i18n
import
TranslationStringFactory
from
..widgets
import
widget_os
_
=
TranslationStringFactory
(
'login'
)
log
=
__import__
(
"logging"
)
.
getLogger
(
__name__
)
...
...
@@ -59,15 +63,22 @@ class Login(CSRFSchema):
)
password
=
colander
.
SchemaNode
(
colander
.
String
(),
widget
=
widget
.
PasswordWidget
())
# def after_bind(self, schema, kwargs):
# request = kwargs["request"]
# csrf_token = new_csrf_token(request)
# log.error(csrf_token)
# self["csrf_token"] = colander.SchemaNode(
# colander.String(), widget=widget.HiddenWidget(),
# default=csrf_token
# )
def
after_bind
(
self
,
schema
,
kwargs
):
request
=
kwargs
[
"request"
]
csrf_token
=
new_csrf_token
(
request
)
log
.
debug
(
csrf_token
)
self
[
"csrf_token"
]
=
colander
.
SchemaNode
(
colander
.
String
(),
widget
=
widget
.
HiddenWidget
(),
default
=
csrf_token
)
if
BASE_CLASS
.
login_captcha
:
self
[
"captcha"
]
=
colander
.
SchemaNode
(
colander
.
String
(),
widget
=
widget_os
.
CaptchaWidget
(
request
=
request
,
url
=
request
.
static_url
(
BASE_CLASS
.
captcha_files
)),
oid
=
"captcha"
,
title
=
_
(
"Captcha"
))
# http://deformdemo.repoze.org/interfield/
...
...
@@ -172,27 +183,31 @@ def oauth2_login(request, params=None):
return
user
class
ViewLogin
(
BaseView
):
# @view_config(route_name='login', renderer='templates/form.pt', require_csrf=True)
class
ViewAuth
(
BaseView
):
def
view_login
(
self
):
request
=
self
.
req
request
.
session
[
"login"
]
=
True
next_url
=
request
.
params
.
get
(
'next'
,
request
.
referrer
)
login_tpl
=
get_params
(
'login_tpl'
,
'templates/login.pt'
)
login_tpl
=
BASE_CLASS
.
login_tpl
if
not
next_url
:
# next_url = get_urls(request.route_url('home'))
next_url
=
request
.
home
if
request
.
authenticated_userid
:
# (request):
request
.
session
.
flash
(
'Anda sudah login'
,
'error'
)
# return HTTPFound(location=get_urls(f"{request.route_url('home')}"))
return
HTTPFound
(
location
=
f
"{request.route_url('base-home')}"
)
return
HTTPFound
(
location
=
f
"{request.home}"
)
schema
=
Login
()
schema
=
schema
.
bind
(
request
=
self
.
req
)
form
=
Form
(
schema
,
buttons
=
(
'login'
,))
buttons
=
(
Button
(
'login'
,
_
(
'Login'
)),)
if
BASE_CLASS
.
allow_register
:
buttons
+=
(
Button
(
'register'
,
_
(
'Register'
)),)
buttons
+=
(
Button
(
'reset'
,
_
(
'Reset'
)),
btn_cancel
,)
form
=
Form
(
schema
,
buttons
=
buttons
)
message
=
""
if
'login'
in
request
.
POST
:
if
'cancel'
in
request
.
POST
:
return
HTTPFound
(
location
=
request
.
home
)
elif
'login'
in
request
.
POST
:
identity
=
request
.
POST
.
get
(
'username'
)
user
=
schema
.
user
=
User
.
get_by_identity
(
identity
)
controls
=
request
.
POST
.
items
()
...
...
@@ -202,7 +217,7 @@ class ViewLogin(BaseView):
msg
=
'Login gagal'
set_user_log
(
msg
,
request
,
log
,
identity
)
request
.
session
.
flash
(
msg
,
'error'
)
return
HTTPFound
(
location
=
get_urls
(
request
.
route_url
(
'login'
)
))
return
HTTPFound
(
location
=
request
.
route_url
(
'base-login'
))
values
=
dict
(
c
)
...
...
@@ -222,21 +237,20 @@ class ViewLogin(BaseView):
except
Exception
as
e
:
log
.
warn
(
str
(
e
))
request
.
session
.
flash
(
str
(
e
),
"error"
)
return
HTTPFound
(
location
=
get_urls
(
request
.
route_url
(
'login'
)
))
return
HTTPFound
(
location
=
request
.
route_url
(
'base-login'
))
else
:
login
=
LoginUser
(
self
.
req
)
if
not
login
.
login
(
values
,
user
):
request
.
session
.
flash
(
login
.
message
,
"error"
)
next_url
=
get_urls
(
f
"{request.route_url('login')}?next={next_url}"
)
next_url
=
f
"{request.route_url('base-login')}?next={next_url}"
return
HTTPFound
(
location
=
next_url
)
return
redirect_login
(
request
,
user
)
elif
'register'
in
request
.
POST
:
# register_form = get_params("register_form", 'register')
return
HTTPFound
(
location
=
request
.
route_url
(
BASE_CLASS
.
reg_form
))
elif
'reset'
in
request
.
POST
:
return
HTTPFound
(
location
=
request
.
route_url
(
'base-password-reset'
))
elif
'login failed'
in
request
.
session
:
r
=
dict
(
form
=
request
.
session
[
'login failed'
])
del
request
.
session
[
'login failed'
]
...
...
@@ -252,13 +266,13 @@ class ViewLogin(BaseView):
login_tpl
,
dict
(
form
=
form
,
message
=
message
,
url
=
get_urls
(
request
.
route_url
(
'login'
)
),
url
=
request
.
route_url
(
'base-login'
),
next_url
=
next_url
,
login
=
login
,
),
request
=
request
)
except
Oauth2UserExc
as
e
:
request
.
session
.
flash
(
str
(
e
),
'error'
)
return
HTTPFound
(
location
=
get_urls
(
request
.
route_url
(
'login'
)
))
return
HTTPFound
(
location
=
request
.
route_url
(
'base-login'
))
if
user
and
user
.
status
==
1
:
return
redirect_login
(
request
,
user
)
# values = {"csrf_token": new_csrf_token(request)}
...
...
@@ -269,18 +283,41 @@ class ViewLogin(BaseView):
# url=get_urls(request.route_url('login')),
# next_url=next_url,
# login=login, )
return
render_to_response
(
renderer_name
=
login_tpl
,
request
=
request
,
value
=
dict
(
form
=
form
,
message
=
message
,
# url=get_urls(request.route_url('login')),
url
=
request
.
route_url
(
'base-login'
),
next_url
=
next_url
,
login
=
login
,
),
if
login_tpl
:
return
render_to_response
(
renderer_name
=
login_tpl
,
request
=
request
,
value
=
dict
(
form
=
form
,
message
=
message
,
url
=
request
.
route_url
(
'base-login'
),
next_url
=
next_url
,
login
=
login
,
),
)
return
dict
(
form
=
form
.
render
(),
scripts
=
""
)
def
view_logout
(
self
):
request
=
self
.
req
if
not
request
.
user
:
if
"g_state"
in
request
.
cookies
:
request
.
response
.
delete_cookie
(
"g_state"
,
'/'
)
form
=
self
.
get_form
(
LogoutSchema
,
buttons
=
(
btn_cancel
,
btn_logout
))
if
'cancel'
in
request
.
POST
or
"home"
in
request
.
POST
:
return
HTTPFound
(
location
=
request
.
home
)
elif
"logout"
in
request
.
POST
:
form
=
self
.
get_form
(
LogoutSchema
,
buttons
=
(
btn_home
,))
set_user_log
(
"Logout"
,
request
,
log
)
headers
=
forget
(
request
)
request
.
session
.
delete
()
request
.
response
.
headers
.
update
(
headers
)
if
"g_state"
in
request
.
cookies
:
request
.
response
.
delete_cookie
(
"g_state"
,
'/'
)
form
.
set_appstruct
({
"message"
:
"Sukses Logout"
})
request
.
session
[
"login"
]
=
False
return
dict
(
form
=
form
.
render
())
def
redirect_login
(
request
,
user
):
set_user_log
(
"Login Sukses"
,
request
,
log
,
user
.
user_name
)
...
...
@@ -291,8 +328,8 @@ def redirect_login(request, user):
request
.
session
.
flash
(
"Sukses Login"
)
next_url
=
request
.
params
.
get
(
'next'
)
if
not
next_url
and
request
.
matched_route
.
name
==
'login'
:
url
=
get_params
(
'modules_default'
,
'home'
)
return
HTTPFound
(
location
=
get_urls
(
request
.
route_url
(
url
)
),
url
=
get_params
(
'modules_default'
,
'
base-
home'
)
return
HTTPFound
(
location
=
request
.
route_url
(
url
),
headers
=
headers
)
if
not
next_url
:
next_url
=
request
.
home
...
...
@@ -312,42 +349,169 @@ btn_logout = Button("logout", css_class="btn-danger")
btn_home
=
Button
(
"home"
,
css_class
=
"btn-success"
)
class
ViewLogout
(
BaseView
):
#
class ViewLogout(BaseView):
# @view_config(route_name='logout', renderer="templates/logout.pt", require_csrf=False)
def
view_logout
(
self
):
request
=
self
.
req
if
not
request
.
user
:
if
"g_state"
in
request
.
cookies
:
request
.
response
.
delete_cookie
(
"g_state"
,
'/'
)
form
=
self
.
get_form
(
LogoutSchema
,
buttons
=
(
btn_cancel
,
btn_logout
))
if
'cancel'
in
request
.
POST
or
"home"
in
request
.
POST
:
# log.info(get_urls(request.route_url('home')))
# return HTTPFound(location=get_urls(f"{request.route_url('home')}", ))
class
ViewPassword
(
BaseView
):
def
reset_password
(
self
):
request
=
self
.
req
if
request
.
authenticated_userid
:
return
HTTPFound
(
location
=
f
"{request.home}"
)
resp
=
dict
(
title
=
_
(
'Reset password'
))
resp
[
'scripts'
]
=
""
schema
=
ResetPassword
(
validator
=
reset_password_validator
)
btn_submit
=
Button
(
'submit'
,
_
(
'Send password reset email'
))
form
=
Form
(
schema
,
buttons
=
(
btn_submit
,
btn_cancel
))
if
'submit'
in
request
.
POST
:
controls
=
request
.
POST
.
items
()
identity
=
request
.
POST
.
get
(
'email'
)
q
=
DBSession
.
query
(
User
)
.
filter_by
(
email
=
identity
)
schema
.
user
=
user
=
q
.
first
()
try
:
c
=
form
.
validate
(
controls
)
except
ValidationFailure
:
resp
[
'form'
]
=
form
.
render
()
return
resp
remain
=
regenerate_security_code
(
user
)
set_user_log
(
"Reset password to {}"
.
format
(
user
.
email
),
request
,
log
,
user
.
user_name
)
send_email_security_code
(
request
,
user
,
remain
,
'Reset password'
,
'reset-password-body'
,
'reset-password-body.tpl'
)
self
.
ses
.
flash
(
'Email reset password sudah dikirim ke {}'
.
format
(
user
.
email
))
return
HTTPFound
(
location
=
request
.
home
)
elif
'cancel'
in
request
.
POST
:
return
HTTPFound
(
location
=
request
.
route_url
(
'base-login'
))
resp
[
'form'
]
=
form
.
render
()
return
resp
def
change_password
(
self
):
"""
Digunakan untuk change password
1. Jika sudah login maka redirect ke home
2. Jika form valid maka akan menyimpan password baru ke database
3. User di logout dan di redirect ke home
"""
request
=
self
.
req
elif
"logout"
in
request
.
POST
:
form
=
self
.
get_form
(
LogoutSchema
,
buttons
=
(
btn_home
,))
set_user_log
(
"Logout"
,
request
,
log
)
headers
=
forget
(
request
)
request
.
session
.
delete
()
request
.
response
.
headers
.
update
(
headers
)
if
"g_state"
in
request
.
cookies
:
request
.
response
.
delete_cookie
(
"g_state"
,
'/'
)
form
.
set_appstruct
({
"message"
:
"Sukses Logout"
})
request
.
session
[
"login"
]
=
False
schema
=
ChangePassword
(
validator
=
change_password_validator
)
btn_save
=
Button
(
'save'
,
_
(
'Simpan'
))
btn_cancel
=
Button
(
'cancel'
,
_
(
'Batalkan'
))
buttons
=
(
btn_save
,
btn_cancel
)
form
=
Form
(
schema
,
buttons
=
buttons
)
if
not
request
.
POST
:
return
dict
(
form
=
form
.
render
(),
scripts
=
""
)
if
'save'
not
in
request
.
POST
:
return
HTTPFound
(
location
=
request
.
route_url
(
'base-login'
))
items
=
request
.
POST
.
items
()
try
:
c
=
form
.
validate
(
items
)
except
ValidationFailure
as
e
:
return
dict
(
form
=
e
.
render
())
user
=
request
.
user
user
.
security_code
=
None
if
not
UserService
.
check_password
(
user
,
c
[
'password'
]):
request
.
session
.
flash
(
'Password lama tidak sesuai'
,
'error'
)
return
HTTPFound
(
location
=
request
.
route_url
(
'base-password'
))
UserService
.
set_password
(
user
,
c
[
'new_password'
])
self
.
db_session
.
add
(
user
)
self
.
db_session
.
flush
()
headers
=
forget
(
request
)
request
.
session
.
flash
(
'Password baru Anda sudah disimpan.'
)
set_user_log
(
"Change Password"
,
request
,
log
)
return
HTTPFound
(
location
=
f
"{request.home}"
,
headers
=
headers
)
def
change_password_request
(
self
):
"""
Digunakan untuk change password url dari email (register, reset password)
1. Jika sudah login maka redirect ke home
2. Jika code tidak ada atau tidak valid maka akan redirect ke get code
2. Jika code valid maka akan menampilkan form untuk change password
3. Jika form valid maka akan menyimpan password baru ke database
"""
request
=
self
.
req
if
request
.
authenticated_userid
:
request
.
session
.
flash
(
'Anda sudah login'
,
'error'
)
return
HTTPFound
(
location
=
f
"{request.home}"
)
code
=
request
.
matchdict
[
'code'
]
q
=
DBSession
.
query
(
User
)
.
filter_by
(
security_code
=
code
)
user
=
q
.
first
()
now
=
create_now
()
if
not
user
or
now
-
user
.
security_code_date
>
one_hour
:
request
.
session
.
flash
(
'Security code expired'
,
'error'
)
return
HTTPFound
(
location
=
request
.
route_url
(
'base-login'
))
schema
=
ChangePasswordRequest
(
validator
=
change_password_validator
)
btn_save
=
Button
(
'save'
,
_
(
'Simpan'
))
btn_cancel
=
Button
(
'cancel'
,
_
(
'Batalkan'
))
buttons
=
(
btn_save
,
btn_cancel
)
form
=
Form
(
schema
,
buttons
=
buttons
)
if
not
request
.
POST
:
return
dict
(
form
=
form
.
render
(),
scripts
=
""
)
if
'save'
not
in
request
.
POST
:
return
HTTPFound
(
location
=
request
.
route_url
(
'base-login'
))
items
=
request
.
POST
.
items
()
try
:
c
=
form
.
validate
(
items
)
except
ValidationFailure
as
e
:
return
dict
(
form
=
e
.
render
())
return
dict
(
form
=
form
.
render
())
user
.
security_code
=
None
UserService
.
set_password
(
user
,
c
[
'new_password'
])
DBSession
.
add
(
user
)
headers
=
get_login_headers
(
request
,
user
)
request
.
session
.
flash
(
'Password baru Anda sudah disimpan.'
)
set_user_log
(
"Change Password"
,
request
,
log
)
return
HTTPFound
(
location
=
f
"{request.home}"
,
headers
=
headers
)
# def view_recreate_api_key(self):
# request = self.req
# if not request.user.api_key:
# return HTTPNotFound()
# schema = APIKey()
# btn_submit = Button('recreate', _('Buat ulang'))
# btn_cancel = Button('cancel', _('Batalkan'))
# buttons = (btn_submit, btn_cancel)
# form = Form(schema, buttons=buttons)
# if not request.POST:
# d = dict(api_key=request.user.api_key)
# return dict(form=form.render(appstruct=d))
# if 'recreate' not in request.POST:
# return HTTPFound(location=f"{request.home}")
# request.user.api_key = api_key = generate_api_key()
# DBSession.add(request.user)
# msg = 'API Key Anda yang baru {}'.format(api_key)
# request.session.flash(msg)
# return HTTPFound(location=f"{request.home}")
class
ChangePasswordRequest
(
colander
.
Schema
):
new_password
=
colander
.
SchemaNode
(
colander
.
String
(),
widget
=
widget
.
CheckedPasswordWidget
())
class
ChangePassword
(
colander
.
Schema
):
class
ChangePassword
(
ChangePasswordRequest
):
new_password
=
colander
.
SchemaNode
(
colander
.
String
(),
widget
=
widget
.
CheckedPasswordWidget
())
# retype_password = colander.SchemaNode(
# colander.String(), widget=widget.PasswordWidget())
# password = colander.SchemaNode(colander.String(),
# widget=widget.PasswordWidget(),
# title=_("Old Password"))
password
=
colander
.
SchemaNode
(
colander
.
String
(),
widget
=
widget
.
PasswordWidget
(),
title
=
_
(
"Old Password"
))
def
change_password_validator
(
form
,
value
):
...
...
@@ -364,44 +528,7 @@ def change_password_validator(form, value):
# raise exc
# @view_config(route_name='change-password',
# renderer='templates/change-password.pt')
def
view_change_password
(
request
):
"""
Digunakan untuk change password url dari email (register, reset password)
"""
if
request
.
authenticated_userid
:
request
.
session
.
flash
(
'Anda sudah login'
,
'error'
)
return
HTTPFound
(
location
=
get_urls
(
f
"{request.route_url('home')}"
))
schema
=
ChangePassword
(
validator
=
change_password_validator
)
btn_save
=
Button
(
'save'
,
_
(
'Simpan'
))
btn_cancel
=
Button
(
'cancel'
,
_
(
'Batalkan'
))
buttons
=
(
btn_save
,
btn_cancel
)
form
=
Form
(
schema
,
buttons
=
buttons
)
if
not
request
.
POST
:
return
dict
(
form
=
form
.
render
())
if
'save'
not
in
request
.
POST
:
return
HTTPFound
(
location
=
get_urls
(
request
.
route_url
(
'login'
)))
items
=
request
.
POST
.
items
()
try
:
c
=
form
.
validate
(
items
)
except
ValidationFailure
as
e
:
return
dict
(
form
=
e
.
render
())
code
=
request
.
matchdict
[
'code'
]
q
=
DBSession
.
query
(
User
)
.
filter_by
(
security_code
=
code
)
user
=
q
.
first
()
if
not
user
or
create_now
()
-
user
.
security_code_date
>
one_hour
:
request
.
session
.
flash
(
'Security code expired'
,
'error'
)
return
HTTPFound
(
location
=
get_urls
(
request
.
route_url
(
'login'
)))
user
.
security_code
=
None
UserService
.
set_password
(
user
,
c
[
'new_password'
])
DBSession
.
add
(
user
)
headers
=
get_login_headers
(
request
,
user
)
request
.
session
.
flash
(
'Password baru Anda sudah disimpan.'
)
set_user_log
(
"Change Password"
,
request
,
log
)
return
HTTPFound
(
location
=
get_urls
(
f
"{request.route_url('home')}"
),
headers
=
headers
)
######################
...
...
@@ -416,27 +543,7 @@ def generate_api_key():
return
UserService
.
generate_random_string
(
64
)
# @view_config(
# route_name='recreate-api-key', renderer='templates/recreate-api-key.pt',
# permission='view')
def
view_recreate_api_key
(
request
):
if
not
request
.
user
.
api_key
:
return
HTTPNotFound
()
schema
=
APIKey
()
btn_submit
=
Button
(
'recreate'
,
_
(
'Buat ulang'
))
btn_cancel
=
Button
(
'cancel'
,
_
(
'Batalkan'
))
buttons
=
(
btn_submit
,
btn_cancel
)
form
=
Form
(
schema
,
buttons
=
buttons
)
if
not
request
.
POST
:
d
=
dict
(
api_key
=
request
.
user
.
api_key
)
return
dict
(
form
=
form
.
render
(
appstruct
=
d
))
if
'recreate'
not
in
request
.
POST
:
return
HTTPFound
(
location
=
get_urls
(
f
"{request.route_url('home')}"
))
request
.
user
.
api_key
=
api_key
=
generate_api_key
()
DBSession
.
add
(
request
.
user
)
msg
=
'API Key Anda yang baru {}'
.
format
(
api_key
)
request
.
session
.
flash
(
msg
)
return
HTTPFound
(
location
=
get_urls
(
f
"{request.route_url('home')}"
))
##################
...
...
@@ -473,7 +580,7 @@ def send_email_security_code(
if
'mail.sender_name'
not
in
settings
or
'mail.username'
not
in
settings
:
return
url
=
'{}/password/{}?password={}'
.
format
(
url
=
'{}/password/{}?password={}
/request
'
.
format
(
request
.
home
,
user
.
security_code
,
password
)
minutes
=
int
(
time_remain
.
seconds
/
60
)
...
...
@@ -525,46 +632,16 @@ def regenerate_security_code(user, hour=1.0):
age
=
security_code_age
(
user
)
remain
=
hour
-
age
if
user
.
security_code
and
age
<
hour
and
remain
>
two_minutes
:
log
.
debug
(
"Security code:
%
s"
,
user
.
security_code
)
return
remain
UserService
.
regenerate_security_code
(
user
)
user
.
security_code_date
=
create_now
()
log
.
debug
(
"Security code:
%
s"
,
user
.
security_code
)
DBSession
.
add
(
user
)
return
hour
# @view_config(route_name='reset-password',
# renderer='templates/reset-password.pt')
def
view_reset_password
(
request
):
if
request
.
authenticated_userid
:
return
HTTPFound
(
location
=
get_urls
(
f
"{request.route_url('home')}"
))
resp
=
dict
(
title
=
_
(
'Reset password'
))
schema
=
ResetPassword
(
validator
=
reset_password_validator
)
btn_submit
=
Button
(
'submit'
,
_
(
'Send password reset email'
))
form
=
Form
(
schema
,
buttons
=
(
btn_submit
,))
if
'submit'
in
request
.
POST
:
controls
=
request
.
POST
.
items
()
identity
=
request
.
POST
.
get
(
'email'
)
q
=
DBSession
.
query
(
User
)
.
filter_by
(
email
=
identity
)
schema
.
user
=
user
=
q
.
first
()
try
:
c
=
form
.
validate
(
controls
)
except
ValidationFailure
:
resp
[
'form'
]
=
form
.
render
()
return
resp
remain
=
regenerate_security_code
(
user
)
set_user_log
(
"Reset password to {}"
.
format
(
user
.
email
),
request
,
log
,
user
.
user_name
)
send_email_security_code
(
request
,
user
,
remain
,
'Reset password'
,
'reset-password-body'
,
'reset-password-body.tpl'
)
return
HTTPFound
(
location
=
get_urls
(
request
.
route_url
(
'reset-password-sent'
)))
resp
[
'form'
]
=
form
.
render
()
return
resp
# @view_config(
# route_name='reset-password-sent',
# renderer='templates/reset-password-sent.pt')
def
view_reset_password_sent
(
request
):
return
dict
(
title
=
_
(
'Reset password'
))
opensipkd/base/widgets/templates/readonly/form.pt
0 → 100644
View file @
166dae2
<form
tal:define="style style|field.widget.style;
css_class css_class|string:${field.widget.css_class or field.css_class or ''};
item_template item_template|field.widget.readonly_item_template;
title title|field.title;
errormsg errormsg|field.errormsg;
description description|field.description;
buttons buttons|field.buttons;
use_ajax use_ajax|field.use_ajax;
ajax_options ajax_options|field.ajax_options;
formid formid|field.formid;
method method|field.method;"
tal:attributes="style style;
class css_class;"
id="${formid}"
method="${method}"
enctype="multipart/form-data"
accept-charset="utf-8"
i18n:domain="deform"
class="deform ${field.bootstrap_form_style | 'form-horizontal'}"
>
<fieldset class="deform-form-fieldset">
<div class="row">
<legend tal:condition="title">${title}</legend>
<p class="section first" tal:condition="description">
${description}
</p>
<div tal:repeat="child field"
tal:replace="structure child.render_template(item_template)"/>
</div>
<div class="row">
<div class="form-group deform-form-buttons">
<tal:loop tal:repeat="button buttons">
<button
tal:define="btn_disposition repeat.button.start and 'btn-primary' or 'btn-default';"
tal:attributes="disabled button.disabled if button.disabled else None;
attributes|button.attributes|{};"
id="${formid+button.name}"
name="${button.name}"
type="${button.type}"
class="btn ${button.css_class or btn_disposition}"
value="${button.value}"
tal:condition="button.type != 'link'">
<span tal:condition="button.icon" class="glyphicon glyphicon-${button.icon}"></span>
${button.title}
</button>
<a
tal:define="btn_disposition repeat.button.start and 'btn-primary' or 'btn-default';
btn_href button.value|''"
class="btn ${button.css_class or btn_disposition}"
id="${field.formid + button.name}"
href="${btn_href}"
tal:condition="button.type == 'link'">
<span tal:condition="button.icon" class="glyphicon glyphicon-${button.icon}"></span>
${button.title}
</a>
</tal:loop>
</div>
</div>
</fieldset>
</form>
opensipkd/base/widgets/widget_os.py
View file @
166dae2
...
...
@@ -378,8 +378,6 @@ class CaptchaWidget(Widget):
kode_captcha
,
file_name
=
img_captcha
(
self
.
request
)
self
.
request
.
session
[
"captcha"
]
=
kode_captcha
cstruct
=
self
.
url
+
file_name
# if cstruct in (null, None):
# cstruct = ""
readonly
=
kw
.
get
(
"readonly"
,
self
.
readonly
)
template
=
readonly
and
self
.
readonly_template
or
self
.
template
values
=
self
.
get_template_values
(
field
,
cstruct
,
kw
)
...
...
@@ -394,6 +392,8 @@ class CaptchaWidget(Widget):
pstruct
=
pstruct
.
strip
()
if
not
pstruct
:
return
null
if
pstruct
!=
self
.
request
.
session
[
"captcha"
]:
raise
Invalid
(
field
.
schema
,
"Captcha tidak sesuai"
)
return
pstruct
...
...
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