Refactor login flow and error handling in user_login, base_views, and register; …

…add initial test cases for API and HTTP requests
1 parent a2c6ac1a
...@@ -204,11 +204,19 @@ class BaseView(object): ...@@ -204,11 +204,19 @@ class BaseView(object):
children = [] children = []
for c in field.children: for c in field.children:
children.append(self.form2dict(c)) children.append(self.form2dict(c))
value = hasattr(field, "cstruct") and field.cstruct or ""
if type(value)in(colander.null, colander._null):
value = ""
if type(value)==dict:
for k,v in value.items():
if type(v) in (colander.null, colander._null):
value[k]=""
d = { d = {
"id": field.oid, "id": field.oid,
"name": field.name, "name": field.name,
"error" : {"msg": field.error and field.error.msg or ""}, "error" : {"msg": field.error and field.error.msg or ""},
"children":children "children":children,
"value":value
} }
return d return d
...@@ -560,7 +568,8 @@ class BaseView(object): ...@@ -560,7 +568,8 @@ class BaseView(object):
def returned_form(self, form, table=None, **kwargs): def returned_form(self, form, table=None, **kwargs):
if self.req.is_xhr: if self.req.is_xhr:
d = self.form2dict(form.field) d = self.form2dict(form)
import json
return Response(json=d) return Response(json=d)
resources = form.get_widget_resources() resources = form.get_widget_resources()
......
...@@ -146,7 +146,7 @@ def _show_error(request, msg): ...@@ -146,7 +146,7 @@ def _show_error(request, msg):
def show_error(request, msg): def show_error(request, msg):
_show_error(request, msg) _show_error(request, msg)
return HTTPFound(location=get_urls(request.route_url('home'))) return HTTPFound(location=request.route_url('home'))
# def reg_buttons(): # def reg_buttons():
...@@ -317,15 +317,15 @@ class Registrasi(BaseView): ...@@ -317,15 +317,15 @@ class Registrasi(BaseView):
self.bindings = dict(user=None) self.bindings = dict(user=None)
request = self.req request = self.req
if request.user: if request.user:
return HTTPFound(location=get_urls(request.route_url("profile"))) return HTTPFound(location=request.route_url("profile"))
if "g_state" in self.req.cookies: if "g_state" in self.req.cookies:
if "id_info" not in self.ses or not self.ses["id_info"]: if "id_info" not in self.ses or not self.ses["id_info"]:
return HTTPFound(location=get_urls(self.req.route_url("login"))) return HTTPFound(location=self.req.route_url("login"))
reg_form = get_params("reg_form") reg_form = get_params("reg_form")
if reg_form: if reg_form:
return HTTPFound(location=get_urls(self.req.route_url(reg_form))) return HTTPFound(location=self.req.route_url(reg_form))
return super(Registrasi, self).view_add() return super(Registrasi, self).view_add()
...@@ -369,7 +369,7 @@ class Registrasi(BaseView): ...@@ -369,7 +369,7 @@ class Registrasi(BaseView):
self.buttons = (btn_save, btn_cancel) self.buttons = (btn_save, btn_cancel)
reg_form = get_params("reg_form") reg_form = get_params("reg_form")
if reg_form: if reg_form:
return HTTPFound(location=get_urls(self.req.route_url(reg_form))) return HTTPFound(location=self.req.route_url(reg_form))
self.bindings = dict(user=self.req.user) self.bindings = dict(user=self.req.user)
resp = super(Registrasi, self).view_edit() resp = super(Registrasi, self).view_edit()
if not resp: if not resp:
......
...@@ -170,18 +170,23 @@ def oauth2_login(request, params=None): ...@@ -170,18 +170,23 @@ def oauth2_login(request, params=None):
class ViewLogin(BaseView): class ViewLogin(BaseView):
@view_config(route_name='login', renderer='templates/form.pt', require_csrf=True) @view_config(route_name='login', renderer='templates/form.pt', require_csrf=False)
def view_login(self): def view_login(self):
request = self.req request = self.req
request.session["login"] = True request.session["login"] = True
next_url = request.params.get('next', request.referrer) next_url = request.params.get('next', request.referrer)
login_tpl = get_params('login_tpl', 'templates/login.pt') login_tpl = get_params('login_tpl', 'templates/login.pt')
if not next_url: if not next_url:
next_url = get_urls(request.route_url('home')) next_url = request.route_url('home')
if request.authenticated_userid: # (request): if request.authenticated_userid: # (request):
request.session.flash('Anda sudah login', 'error') message = 'Anda sudah login'
return HTTPFound(location=get_urls(f"{request.route_url('home')}")) if self.req.is_xhr:
return Response(json={"success": True,
"msg": message})
request.session.flash(message, 'error')
return HTTPFound(location=f"{request.route_url('home')}")
schema = Login() schema = Login()
schema = schema.bind(request=self.req) schema = schema.bind(request=self.req)
...@@ -197,12 +202,11 @@ class ViewLogin(BaseView): ...@@ -197,12 +202,11 @@ class ViewLogin(BaseView):
msg = 'Login gagal' msg = 'Login gagal'
set_user_log(msg, request, log, identity) set_user_log(msg, request, log, identity)
if self.req.is_xhr: if self.req.is_xhr:
d = self.form2dict(form.field) d = self.form2dict(e.field)
return Response(json=d) return Response(json=d)
request.session.flash(msg, 'error') request.session.flash(msg, 'error')
return HTTPFound(location=request.route_url('login'))
return HTTPFound(location=get_urls(request.route_url('login')))
values = dict(c) values = dict(c)
...@@ -222,7 +226,7 @@ class ViewLogin(BaseView): ...@@ -222,7 +226,7 @@ class ViewLogin(BaseView):
except Exception as e: except Exception as e:
log.warn(str(e)) log.warn(str(e))
request.session.flash(str(e), "error") request.session.flash(str(e), "error")
return HTTPFound(location=get_urls(request.route_url('login'))) return HTTPFound(location=request.route_url('login'))
else: else:
login = LoginUser(self.req) login = LoginUser(self.req)
...@@ -235,7 +239,7 @@ class ViewLogin(BaseView): ...@@ -235,7 +239,7 @@ class ViewLogin(BaseView):
elif 'register' in request.POST: elif 'register' in request.POST:
register_form = get_params("register_form", 'register') register_form = get_params("register_form", 'register')
return HTTPFound(location=get_urls(request.route_url(register_form))) return HTTPFound(location=request.route_url(register_form))
elif 'login failed' in request.session: elif 'login failed' in request.session:
r = dict(form=request.session['login failed']) r = dict(form=request.session['login failed'])
...@@ -252,13 +256,17 @@ class ViewLogin(BaseView): ...@@ -252,13 +256,17 @@ class ViewLogin(BaseView):
login_tpl, dict( login_tpl, dict(
form=form, form=form,
message=message, message=message,
url=get_urls(request.route_url('login')), url=request.route_url('login'),
next_url=next_url, next_url=next_url,
login=login, ), login=login,
css=resources["css"],
js=resources["js"],
scripts="",
readonly=False),
request=request) request=request)
except Oauth2UserExc as e: except Oauth2UserExc as e:
request.session.flash(str(e), 'error') request.session.flash(str(e), 'error')
return HTTPFound(location=get_urls(request.route_url('login'))) return HTTPFound(location=request.route_url('login'))
if user and user.status == 1: if user and user.status == 1:
return redirect_login(request, user) return redirect_login(request, user)
# values = {"csrf_token": new_csrf_token(request)} # values = {"csrf_token": new_csrf_token(request)}
...@@ -266,18 +274,22 @@ class ViewLogin(BaseView): ...@@ -266,18 +274,22 @@ class ViewLogin(BaseView):
# if login_tpl == 'templates/login.pt': # if login_tpl == 'templates/login.pt':
# return dict(form=form.render(), # return dict(form=form.render(),
# message=message, # message=message,
# url=get_urls(request.route_url('login')), # url=request.route_url('login'),
# next_url=next_url, # next_url=next_url,
# login=login, ) # login=login, )
resources = form.get_widget_resources()
return render_to_response( return render_to_response(
renderer_name=login_tpl, renderer_name=login_tpl,
request=request, request=request,
value=dict(form=form, value=dict(form=form,
message=message, message=message,
url=get_urls(request.route_url('login')), url=request.route_url('login'),
next_url=next_url, next_url=next_url,
login=login, ), login=login,
css=resources["css"],
js=resources["js"],
scripts="",
readonly=False),
) )
...@@ -289,9 +301,11 @@ def redirect_login(request, user): ...@@ -289,9 +301,11 @@ def redirect_login(request, user):
headers = get_login_headers(request, user) headers = get_login_headers(request, user)
request.session.flash("Sukses Login") request.session.flash("Sukses Login")
next_url = request.params.get('next') next_url = request.params.get('next')
if request.is_xhr:
return Response(json={"success": True})
if not next_url and request.matched_route.name == 'login': if not next_url and request.matched_route.name == 'login':
url = get_params('modules_default', 'home') url = get_params('modules_default', 'home')
return HTTPFound(location=get_urls(request.route_url(url)), return HTTPFound(location=request.route_url(url),
headers=headers) headers=headers)
return HTTPFound(location=next_url, headers=headers) return HTTPFound(location=next_url, headers=headers)
...@@ -318,8 +332,8 @@ class Logout(BaseView): ...@@ -318,8 +332,8 @@ class Logout(BaseView):
form = self.get_form(LogoutSchema, buttons=(btn_cancel, btn_logout)) form = self.get_form(LogoutSchema, buttons=(btn_cancel, btn_logout))
if 'cancel' in request.POST or "home" in request.POST: if 'cancel' in request.POST or "home" in request.POST:
log.info(get_urls(request.route_url('home'))) log.info(request.route_url('home'))
return HTTPFound(location=get_urls(f"{request.route_url('home')}", )) return HTTPFound(location=f"{request.route_url('home')}", )
elif "logout" in request.POST: elif "logout" in request.POST:
form = self.get_form(LogoutSchema, buttons=(btn_home,)) form = self.get_form(LogoutSchema, buttons=(btn_home,))
...@@ -367,7 +381,7 @@ def view_change_password(request): ...@@ -367,7 +381,7 @@ def view_change_password(request):
""" """
if request.authenticated_userid: if request.authenticated_userid:
request.session.flash('Anda sudah login', 'error') request.session.flash('Anda sudah login', 'error')
return HTTPFound(location=get_urls(f"{request.route_url('home')}")) return HTTPFound(location=f"{request.route_url('home')}")
schema = ChangePassword(validator=change_password_validator) schema = ChangePassword(validator=change_password_validator)
btn_save = Button('save', _('Simpan')) btn_save = Button('save', _('Simpan'))
...@@ -377,7 +391,7 @@ def view_change_password(request): ...@@ -377,7 +391,7 @@ def view_change_password(request):
if not request.POST: if not request.POST:
return dict(form=form.render()) return dict(form=form.render())
if 'save' not in request.POST: if 'save' not in request.POST:
return HTTPFound(location=get_urls(request.route_url('login'))) return HTTPFound(location=request.route_url('login'))
items = request.POST.items() items = request.POST.items()
try: try:
c = form.validate(items) c = form.validate(items)
...@@ -388,7 +402,7 @@ def view_change_password(request): ...@@ -388,7 +402,7 @@ def view_change_password(request):
user = q.first() user = q.first()
if not user or create_now() - user.security_code_date > one_hour: if not user or create_now() - user.security_code_date > one_hour:
request.session.flash('Security code expired', 'error') request.session.flash('Security code expired', 'error')
return HTTPFound(location=get_urls(request.route_url('login'))) return HTTPFound(location=request.route_url('login'))
user.security_code = None user.security_code = None
UserService.set_password(user, c['new_password']) UserService.set_password(user, c['new_password'])
...@@ -396,7 +410,7 @@ def view_change_password(request): ...@@ -396,7 +410,7 @@ def view_change_password(request):
headers = get_login_headers(request, user) headers = get_login_headers(request, user)
request.session.flash('Password baru Anda sudah disimpan.') request.session.flash('Password baru Anda sudah disimpan.')
set_user_log("Change Password", request, log) set_user_log("Change Password", request, log)
return HTTPFound(location=get_urls(f"{request.route_url('home')}"), headers=headers) return HTTPFound(location=f"{request.route_url('home')}", headers=headers)
###################### ######################
...@@ -426,12 +440,12 @@ def view_recreate_api_key(request): ...@@ -426,12 +440,12 @@ def view_recreate_api_key(request):
d = dict(api_key=request.user.api_key) d = dict(api_key=request.user.api_key)
return dict(form=form.render(appstruct=d)) return dict(form=form.render(appstruct=d))
if 'recreate' not in request.POST: if 'recreate' not in request.POST:
return HTTPFound(location=get_urls(f"{request.route_url('home')}")) return HTTPFound(location=f"{request.route_url('home')}")
request.user.api_key = api_key = generate_api_key() request.user.api_key = api_key = generate_api_key()
DBSession.add(request.user) DBSession.add(request.user)
msg = 'API Key Anda yang baru {}'.format(api_key) msg = 'API Key Anda yang baru {}'.format(api_key)
request.session.flash(msg) request.session.flash(msg)
return HTTPFound(location=get_urls(f"{request.route_url('home')}")) return HTTPFound(location=f"{request.route_url('home')}")
################## ##################
...@@ -531,7 +545,7 @@ def regenerate_security_code(user, hour=1.0): ...@@ -531,7 +545,7 @@ def regenerate_security_code(user, hour=1.0):
renderer='templates/reset-password.pt') renderer='templates/reset-password.pt')
def view_reset_password(request): def view_reset_password(request):
if request.authenticated_userid: if request.authenticated_userid:
return HTTPFound(location=get_urls(f"{request.route_url('home')}")) return HTTPFound(location=f"{request.route_url('home')}")
resp = dict(title=_('Reset password')) resp = dict(title=_('Reset password'))
schema = ResetPassword(validator=reset_password_validator) schema = ResetPassword(validator=reset_password_validator)
...@@ -553,7 +567,7 @@ def view_reset_password(request): ...@@ -553,7 +567,7 @@ def view_reset_password(request):
send_email_security_code( send_email_security_code(
request, user, remain, 'Reset password', 'reset-password-body', request, user, remain, 'Reset password', 'reset-password-body',
'reset-password-body.tpl') 'reset-password-body.tpl')
return HTTPFound(location=get_urls(request.route_url('reset-password-sent'))) return HTTPFound(location=request.route_url('reset-password-sent'))
resp['form'] = form.render() resp['form'] = form.render()
return resp return resp
......
File mode changed
@host=http://localhost:6544
###
# @name session
POST {{host}}/login
{
"username": "admin",
"password": "password",
"login": "login"
}
###
# get applications
# @ref session
GET {{host}}/profile
Authorization: Bearer {{session.token}}
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!