added login referer

This commit is contained in:
ston1th 2019-01-21 19:46:31 +01:00
commit 4e5d554105
7 changed files with 55 additions and 15 deletions

View file

@ -10,6 +10,7 @@ import (
"github.com/gorilla/mux"
"html/template"
"net/http"
"net/url"
"time"
)
@ -23,6 +24,7 @@ const (
titleClaim = "title"
totpClaim = "totp"
rememberClaim = "remember"
refererClaim = "referer"
)
func newContext(w http.ResponseWriter, r *http.Request, s *HTTPServer) (ctx *Context) {
@ -30,7 +32,8 @@ func newContext(w http.ResponseWriter, r *http.Request, s *HTTPServer) (ctx *Con
h.Set("X-Frame-Options", "DENY")
h.Set("X-Content-Type-Options", "nosniff")
h.Set("X-XSS-Protection", "1; mode=block")
h.Set("Content-Security-Policy", "default-src 'none';style-src 'self';img-src 'self' data:;frame-ancestors 'none'")
h.Set("Content-Security-Policy", "default-src 'none';style-src 'self';img-src 'self' https: data:;connect-src 'self';frame-ancestors 'none'")
h.Set("Referrer-Policy", "same-origin")
ctx = &Context{
Request: r,
Response: w,
@ -53,7 +56,7 @@ func newContext(w http.ResponseWriter, r *http.Request, s *HTTPServer) (ctx *Con
return
}
if t.Claims.GetString(totpClaim) != "" {
if path == core.TotpURI || path == core.LoginURI {
if path == core.TotpURI || path == core.LoginURI || path == core.LogoutURI {
ctx.Token = *t
return
}
@ -107,6 +110,11 @@ type webData struct {
Data interface{}
}
type loginData struct {
User string
Referer string
}
func (c *Context) Exec() {
defer c.log()
if c.T == nil {
@ -201,6 +209,14 @@ func (c *Context) Path() string {
return c.Request.URL.Path
}
func (c *Context) RefererURI() string {
u, err := url.Parse(c.Request.Header.Get("Referer"))
if err != nil {
return ""
}
return u.RequestURI()
}
func (c *Context) FormSlice(name string) []string {
// does nothing if called twice
c.Request.ParseForm()
@ -286,6 +302,10 @@ func (c *Context) Remember() string {
return c.Token.Claims.GetString(rememberClaim)
}
func (c *Context) Referer() string {
return c.Token.Claims.GetString(refererClaim)
}
func (c *Context) Admin() bool {
return c.Token.Claims.GetBool(adminClaim)
}

View file

@ -93,23 +93,28 @@ func loginHandler(ctx *Context) {
Title: "Login",
BodyTitle: "Login",
}
var user string
var data loginData
switch ctx.Method() {
case "GET":
ctx.Data.Data = user
data.Referer = ctx.RefererURI()
ctx.Data.Data = data
ctx.Exec()
case "POST":
if !ctx.CheckXsrf() {
return
}
user = ctx.Form("user")
ctx.Data.Data = user
data.User = ctx.Form("user")
data.Referer = ctx.Form("referer")
ctx.Data.Data = data
if data.Referer == "" {
data.Referer = core.IndexURI
}
password := ctx.Form("password")
if user == "" || password == "" {
if data.User == "" || password == "" {
ctx.Error("empty user or password")
return
}
u, err := ctx.Srv.DB.Login(user, password)
u, err := ctx.Srv.DB.Login(data.User, password)
if err != nil {
ctx.Error(err)
return
@ -117,12 +122,13 @@ func loginHandler(ctx *Context) {
if u.Secret == "" {
log.Println("login:", u.Username)
ctx.Login(u, ctx.Form("remember"))
ctx.Redirect(core.IndexURI, http.StatusFound)
ctx.Redirect(data.Referer, http.StatusFound)
return
}
ctx.SetCookie(jwt.Claims{
totpClaim: u.Username,
rememberClaim: ctx.Form("remember"),
refererClaim: data.Referer,
}, time.Minute)
ctx.Redirect(core.TotpURI, http.StatusFound)
}
@ -155,9 +161,10 @@ func loginTotpHandler(ctx *Context) {
ctx.Error(err)
return
}
ref := ctx.Referer()
log.Println("login:", u.Username)
ctx.Login(u, ctx.Remember())
ctx.Redirect(core.IndexURI, http.StatusFound)
ctx.Redirect(ref, http.StatusFound)
}
}
@ -682,7 +689,11 @@ func userDelHandler(ctx *Context) {
}
func logoutHandler(ctx *Context) {
log.Println("logout:", ctx.User())
user := ctx.User()
if user == "" {
user = ctx.Totp() + " (totp)"
}
log.Println("logout:", user)
ctx.Srv.JWT.Invalidate(&ctx.Token)
ctx.SetCookie(nil, 0)
ctx.Redirect(core.IndexURI, http.StatusFound)

View file

@ -66,6 +66,8 @@ const (
<title>GoWiki | {{.Title}}</title>
<link rel="stylesheet" type="text/css" href="/bootstrap.css" media="screen" integrity="sha256-NeLmQ7cX66J4MdtgGlG3O/TgvsSyP1b9WbaQtxYZUbQ="></link>
<link rel="stylesheet" type="text/css" href="/custom.css" media="screen" integrity="sha256-/SZfW8eVqFuioMg+QXacvK1Zc3XLtT5LGu9tMle65Jc="></link>
<meta name="theme-color" content="#375a7f">
<meta name="description" content="{{.Title}}">
</head>
<body id="top">
<div class="navbar navbar-expand fixed-top navbar-dark bg-primary">
@ -114,9 +116,10 @@ const (
<div class="card-body">
<form class="form-horizontal" action="/login" method="post">
<input type="hidden" name="token" value="{{.Token}}">
<input type="hidden" name="referer" value="{{.Data.Referer}}">
<div class="form-group">
<label class="col-form-label" for="user">Username</label>
<input class="form-control input-sm" type="text" id="user" name="user" value="{{.Data}}" autofocus required>
<input class="form-control input-sm" type="text" id="user" name="user" value="{{.Data.User}}" autofocus required>
</div>
<div class="form-group">
<label class="col-form-label" for="password">Password</label>
@ -152,6 +155,7 @@ const (
<input class="form-control input-sm" type="text" id="pin" name="pin" autocomplete="off" autofocus required>
</div>
<button class="btn btn-sm btn-primary" type="submit">Verify</button>
<a href="/logout" class="btn btn-sm btn-primary">Cancel</a>
</form>
</div>
</div>