mirror of
https://github.com/YunoHost/SSOwat.git
synced 2024-09-03 20:06:27 +02:00
User info view + password edition
This commit is contained in:
parent
96067e62c8
commit
92d2e8848f
7 changed files with 185 additions and 19 deletions
105
access.lua
105
access.lua
|
@ -93,7 +93,7 @@ function delete_redirect_cookie ()
|
||||||
cook("SSOwAuthRedirect=;" ..cookie_str)
|
cook("SSOwAuthRedirect=;" ..cookie_str)
|
||||||
end
|
end
|
||||||
|
|
||||||
function check_cookie ()
|
function is_logged_in ()
|
||||||
|
|
||||||
-- Check if cookie is set
|
-- Check if cookie is set
|
||||||
if ngx.var.cookie_SSOwAuthExpire and ngx.var.cookie_SSOwAuthExpire ~= ""
|
if ngx.var.cookie_SSOwAuthExpire and ngx.var.cookie_SSOwAuthExpire ~= ""
|
||||||
|
@ -129,15 +129,18 @@ function authenticate (user, password)
|
||||||
end
|
end
|
||||||
|
|
||||||
function set_headers (user)
|
function set_headers (user)
|
||||||
if not cache[user]["uid"] then
|
user = user or ngx.var.cookie_SSOwAuthUser
|
||||||
|
if not cache[user]["mail"] then
|
||||||
ldap = lualdap.open_simple("localhost")
|
ldap = lualdap.open_simple("localhost")
|
||||||
for dn, attribs in ldap:search {
|
for dn, attribs in ldap:search {
|
||||||
base = "uid=".. user ..",ou=users,dc=yunohost,dc=org",
|
base = "uid=".. user ..",ou=users,dc=yunohost,dc=org",
|
||||||
scope = "base",
|
scope = "base",
|
||||||
sizelimit = 1,
|
sizelimit = 1,
|
||||||
attrs = {"uid", "givenName", "sn", "cn", "homeDirectory", "mail"}
|
attrs = {"uid", "givenname", "sn", "cn", "homedirectory", "mail", "maildrop"}
|
||||||
} do
|
} do
|
||||||
for k,v in pairs(attribs) do cache[user][k] = v end
|
for k,v in pairs(attribs) do
|
||||||
|
cache[user][k] = v
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -159,8 +162,12 @@ function serve(uri)
|
||||||
|
|
||||||
-- Load login.html as index
|
-- Load login.html as index
|
||||||
if rel_path == "/" then
|
if rel_path == "/" then
|
||||||
|
if is_logged_in() then
|
||||||
|
rel_path = "/info.html"
|
||||||
|
else
|
||||||
rel_path = "/login.html"
|
rel_path = "/login.html"
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
-- Access to directory root: forbidden
|
-- Access to directory root: forbidden
|
||||||
if string.ends(rel_path, "/") then
|
if string.ends(rel_path, "/") then
|
||||||
|
@ -215,6 +222,7 @@ function serve(uri)
|
||||||
end
|
end
|
||||||
|
|
||||||
function get_data_for(view)
|
function get_data_for(view)
|
||||||
|
local user = ngx.var.cookie_SSOwAuthUser
|
||||||
local data = {}
|
local data = {}
|
||||||
data['flash_fail'] = {flashs["fail"]}
|
data['flash_fail'] = {flashs["fail"]}
|
||||||
data['flash_win'] = {flashs["win"] }
|
data['flash_win'] = {flashs["win"] }
|
||||||
|
@ -222,10 +230,69 @@ function get_data_for(view)
|
||||||
|
|
||||||
if view == "login.html" then
|
if view == "login.html" then
|
||||||
data["title"] = "YunoHost Login"
|
data["title"] = "YunoHost Login"
|
||||||
|
elseif view == "info.html" then
|
||||||
|
set_headers()
|
||||||
|
data["title"] = cache[user]["uid"].." <small>"..cache[user]["cn"].."</small>"
|
||||||
|
data["connected"] = true
|
||||||
|
data["uid"] = cache[user]["uid"]
|
||||||
|
data["cn"] = cache[user]["cn"]
|
||||||
|
data["mailalias"] = {}
|
||||||
|
data["maildrop"] = {}
|
||||||
|
if type(cache[user]["mail"]) == "table" then
|
||||||
|
data["mail"] = cache[user]["mail"][1]
|
||||||
|
for k, mail in ipairs(cache[user]["mail"]) do
|
||||||
|
if k ~= 1 then table.insert(data["mailalias"], mail) end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
data["mail"] = cache[user]["mail"]
|
||||||
|
end
|
||||||
|
if type(cache[user]["maildrop"]) == "table" then
|
||||||
|
for k, mail in ipairs(cache[user]["maildrop"]) do
|
||||||
|
if k ~= 1 then table.insert(data["maildrop"], mail) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
elseif view == "password.html" then
|
||||||
|
data["title"] = "Change password"
|
||||||
|
data["connected"] = true
|
||||||
end
|
end
|
||||||
return data
|
return data
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function do_edit ()
|
||||||
|
ngx.req.read_body()
|
||||||
|
local args = ngx.req.get_post_args()
|
||||||
|
|
||||||
|
if is_logged_in() and args
|
||||||
|
then
|
||||||
|
ngx.status = ngx.HTTP_CREATED
|
||||||
|
if string.ends(ngx.var.uri, "password.html") then
|
||||||
|
if args.actualpassword
|
||||||
|
and args.actualpassword == cache[ngx.var.cookie_SSOwAuthUser]["password"]
|
||||||
|
then
|
||||||
|
if args.newpassword == args.confirm then
|
||||||
|
local dn = "uid="..ngx.var.cookie_SSOwAuthUser..",ou=users,dc=yunohost,dc=org"
|
||||||
|
local ldap = lualdap.open_simple("localhost", dn, args.actualpassword)
|
||||||
|
local password = "{SHA}"..ngx.encode_base64(ngx.sha1_bin(args.newpassword))
|
||||||
|
if ldap:modify(dn, {'=', userPassword = password }) then
|
||||||
|
flash("win", "Password successfully changed")
|
||||||
|
cache[ngx.var.cookie_SSOwAuthUser]["password"] = args.newpassword
|
||||||
|
return redirect(portal_url.."info.html")
|
||||||
|
else
|
||||||
|
flash("fail", "An error occured on password changing")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
flash("fail", "New passwords don't match")
|
||||||
|
end
|
||||||
|
else
|
||||||
|
flash("fail", "Actual password is wrong")
|
||||||
|
end
|
||||||
|
return redirect(portal_url.."password.html")
|
||||||
|
elseif string.ends(ngx.var.uri, "edit.html") then
|
||||||
|
return redirect(portal_url.."edit.html")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function do_login ()
|
function do_login ()
|
||||||
ngx.req.read_body()
|
ngx.req.read_body()
|
||||||
local args = ngx.req.get_post_args()
|
local args = ngx.req.get_post_args()
|
||||||
|
@ -256,7 +323,7 @@ end
|
||||||
|
|
||||||
function do_logout()
|
function do_logout()
|
||||||
local args = ngx.req.get_uri_args()
|
local args = ngx.req.get_uri_args()
|
||||||
if check_cookie() then
|
if is_logged_in() then
|
||||||
local redirect_url = portal_url
|
local redirect_url = portal_url
|
||||||
if args.r then
|
if args.r then
|
||||||
redirect_url = ngx.decode_base64(args.r)
|
redirect_url = ngx.decode_base64(args.r)
|
||||||
|
@ -270,7 +337,7 @@ function do_logout()
|
||||||
end
|
end
|
||||||
return redirect(ngx.var.scheme.."://"..ngx.var.http_host.."/?ssologout="..user)
|
return redirect(ngx.var.scheme.."://"..ngx.var.http_host.."/?ssologout="..user)
|
||||||
else
|
else
|
||||||
flash("info", "You are already logged out")
|
flash("info", "Logged out")
|
||||||
return redirect(portal_url)
|
return redirect(portal_url)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -286,7 +353,9 @@ function login_walkthrough (user)
|
||||||
-- All the redirections has been made
|
-- All the redirections has been made
|
||||||
local redirect_url = login[user]["redirect_url"]
|
local redirect_url = login[user]["redirect_url"]
|
||||||
login[user] = nil
|
login[user] = nil
|
||||||
flash("win", "Successfully logged in")
|
if redirect_url == portal_url then
|
||||||
|
flash("win", "Logged in")
|
||||||
|
end
|
||||||
return redirect(redirect_url)
|
return redirect(redirect_url)
|
||||||
else
|
else
|
||||||
-- Redirect to the next domain
|
-- Redirect to the next domain
|
||||||
|
@ -307,7 +376,9 @@ function logout_walkthrough (user)
|
||||||
-- All the redirections has been made
|
-- All the redirections has been made
|
||||||
local redirect_url = logout[user]["redirect_url"]
|
local redirect_url = logout[user]["redirect_url"]
|
||||||
logout[user] = nil
|
logout[user] = nil
|
||||||
flash("win", "Successfully logged out")
|
if redirect_url == portal_url then
|
||||||
|
flash("info", "Logged out")
|
||||||
|
end
|
||||||
return redirect(redirect_url)
|
return redirect(redirect_url)
|
||||||
else
|
else
|
||||||
-- Redirect to the next domain
|
-- Redirect to the next domain
|
||||||
|
@ -367,7 +438,7 @@ then
|
||||||
-- Logout
|
-- Logout
|
||||||
return do_logout()
|
return do_logout()
|
||||||
|
|
||||||
elseif check_cookie() -- Authenticated
|
elseif is_logged_in() -- Authenticated
|
||||||
or ngx.var.uri == conf["portal_path"] -- OR Want to serve portal login
|
or ngx.var.uri == conf["portal_path"] -- OR Want to serve portal login
|
||||||
or (string.starts(ngx.var.uri, conf["portal_path"].."assets")
|
or (string.starts(ngx.var.uri, conf["portal_path"].."assets")
|
||||||
and ngx.var.http_referer
|
and ngx.var.http_referer
|
||||||
|
@ -384,9 +455,15 @@ then
|
||||||
|
|
||||||
elseif ngx.var.request_method == "POST" then
|
elseif ngx.var.request_method == "POST" then
|
||||||
|
|
||||||
if string.starts(ngx.var.http_referer, portal_url) then
|
|
||||||
-- CSRF protection
|
-- CSRF protection
|
||||||
|
if string.starts(ngx.var.http_referer, portal_url) then
|
||||||
|
if string.ends(ngx.var.uri, conf["portal_path"].."password.html")
|
||||||
|
or string.ends(ngx.var.uri, conf["portal_path"].."edit.html")
|
||||||
|
then
|
||||||
|
return do_edit()
|
||||||
|
else
|
||||||
return do_login()
|
return do_login()
|
||||||
|
end
|
||||||
else
|
else
|
||||||
-- Redirect to portal
|
-- Redirect to portal
|
||||||
flash("fail", "Please log in from the portal")
|
flash("fail", "Please log in from the portal")
|
||||||
|
@ -411,8 +488,8 @@ end
|
||||||
|
|
||||||
for _, url in ipairs(conf["unprotected_urls"]) do
|
for _, url in ipairs(conf["unprotected_urls"]) do
|
||||||
if string.starts(ngx.var.host..ngx.var.uri, url) then
|
if string.starts(ngx.var.host..ngx.var.uri, url) then
|
||||||
if check_cookie() then
|
if is_logged_in() then
|
||||||
set_headers(ngx.var.cookie_SSOwAuthUser)
|
set_headers()
|
||||||
end
|
end
|
||||||
return pass()
|
return pass()
|
||||||
end
|
end
|
||||||
|
@ -422,8 +499,8 @@ end
|
||||||
-- Cookie validation
|
-- Cookie validation
|
||||||
--
|
--
|
||||||
|
|
||||||
if check_cookie() then
|
if is_logged_in() then
|
||||||
set_headers(ngx.var.cookie_SSOwAuthUser)
|
set_headers()
|
||||||
return pass()
|
return pass()
|
||||||
else
|
else
|
||||||
delete_cookie()
|
delete_cookie()
|
||||||
|
|
BIN
portal/assets/img/avatar.png
Normal file
BIN
portal/assets/img/avatar.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 569 B |
0
portal/edit.html
Normal file
0
portal/edit.html
Normal file
|
@ -1,2 +1,7 @@
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="height: 20px"></div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,13 +1,23 @@
|
||||||
<html>
|
<html>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" >
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" >
|
||||||
<head>
|
<head>
|
||||||
<title>{{title}}</title>
|
<title>YunoHost</title>
|
||||||
<link rel="stylesheet" href="assets/css/bootstrap.min.css" type="text/css"/>
|
<link rel="stylesheet" href="assets/css/bootstrap.min.css" type="text/css"/>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<!-- Padding bootstrap style -->
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-sm-4 col-sm-offset-4">
|
<div class="col-xs-1 visible-xs"></div>
|
||||||
<h1>{{title}}</h1>
|
<div class="col-sm-10 col-sm-offset-1 col-xs-10 col-xs-offest-1">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6 col-sm-offset-3 col-xs-12">
|
||||||
|
|
||||||
|
<h2>{{{title}}}</h2>
|
||||||
|
{{#connected}}
|
||||||
|
<div class="pull-right" style="margin-top: -31px">
|
||||||
|
<a href="?action=logout">Logout</a>
|
||||||
|
</div>
|
||||||
|
{{/connected}}
|
||||||
<hr>
|
<hr>
|
||||||
|
|
||||||
{{#flash_win}}
|
{{#flash_win}}
|
||||||
|
|
43
portal/info.html
Normal file
43
portal/info.html
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-4 text-center">
|
||||||
|
<img src="assets/img/avatar.png">
|
||||||
|
</div>
|
||||||
|
<div class="visible-sm" style="height: 20px"></div>
|
||||||
|
<div class="col-md-8">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-4 text-right hidden-xs"><strong>Mail</strong></div>
|
||||||
|
<div class="col-sm-4 visible-xs "><h4>Mail</h4></div>
|
||||||
|
<div class="col-sm-8"><blockquote>{{mail}}</blockquote></div>
|
||||||
|
<div class="clearfix"></div><br>
|
||||||
|
<div class="col-sm-4 text-right hidden-xs"><strong>Aliases</strong></div>
|
||||||
|
<div class="col-sm-4 visible-xs "><h4>Aliases</h4></div>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<blockquote>
|
||||||
|
{{#mailalias}}
|
||||||
|
<div style="line-height: 25px">{{.}}</div>
|
||||||
|
{{/mailalias}}
|
||||||
|
</blockquote>
|
||||||
|
</div>
|
||||||
|
<div class="clearfix"></div><br>
|
||||||
|
<div class="col-sm-4 text-right hidden-xs"><strong>Forward</strong></div>
|
||||||
|
<div class="col-sm-4 visible-xs "><h4>Forward</h4></div>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<blockquote>
|
||||||
|
{{#maildrop}}
|
||||||
|
<div style="line-height: 25px">{{.}}</div>
|
||||||
|
{{/maildrop}}
|
||||||
|
</blockquote>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6 text-center">
|
||||||
|
<a href="password.html" class="btn btn-lg btn-primary">Change password</a>
|
||||||
|
</div>
|
||||||
|
<div class="visible-xs" style="height: 20px"></div>
|
||||||
|
<div class="col-sm-6 text-center">
|
||||||
|
<a href="edit.html" class="btn btn-lg btn-info">Edit</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
31
portal/password.html
Normal file
31
portal/password.html
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<form class="form-horizontal" role="form" method="POST" action="password.html">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="actualpassword" class="col-md-5 control-label">Actual password</label>
|
||||||
|
<div class="col-md-7">
|
||||||
|
<input type="password" class="form-control" id="actualpassword" name="actualpassword">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="newpassword" class="col-md-5 control-label">New password</label>
|
||||||
|
<div class="col-md-7">
|
||||||
|
<input type="password" class="form-control" id="newpassword" name="newpassword">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="confirm" class="col-md-5 control-label">Confirm</label>
|
||||||
|
<div class="col-md-7">
|
||||||
|
<input type="password" class="form-control" id="confirm" name="confirm">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-6 text-center">
|
||||||
|
<input type="submit" class="btn btn-lg btn-primary" value="OK">
|
||||||
|
</div>
|
||||||
|
<div class="visible-xs" style="height: 20px"></div>
|
||||||
|
<div class="col-sm-6 text-center">
|
||||||
|
<a href="info.html" class="btn btn-lg btn-default">Cancel</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
Loading…
Reference in a new issue