tobe-test

1 parent 9fa85a52
......@@ -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
......
......@@ -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]
......
......@@ -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
......
......@@ -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)
......
......@@ -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'
......
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,,
,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,
,,,,,,,,,,,,,,,,
......
......@@ -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
......
......@@ -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
......
......@@ -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):
......
......@@ -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")
......
......@@ -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>
......
<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>&nbsp;${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>&nbsp;${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>
......@@ -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>
......
......@@ -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'))
<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>
......@@ -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
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!