2015-03-02 18:04:31 +02:00
|
|
|
package authboss
|
|
|
|
|
|
|
|
import (
|
2017-03-05 20:01:46 +02:00
|
|
|
"context"
|
2015-03-02 18:04:31 +02:00
|
|
|
"net/http"
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
|
|
|
var nowTime = time.Now
|
|
|
|
|
2017-03-05 20:01:46 +02:00
|
|
|
// TimeToExpiry returns zero if the user session is expired else the time
|
|
|
|
// until expiry. Takes in the allowed idle duration.
|
2018-02-01 21:51:43 +02:00
|
|
|
func TimeToExpiry(r *http.Request, expireAfter time.Duration) time.Duration {
|
2017-03-05 20:01:46 +02:00
|
|
|
return timeToExpiry(r, expireAfter)
|
2015-03-02 18:04:31 +02:00
|
|
|
}
|
|
|
|
|
2017-03-05 20:01:46 +02:00
|
|
|
func timeToExpiry(r *http.Request, expireAfter time.Duration) time.Duration {
|
|
|
|
dateStr, ok := GetSession(r, SessionLastAction)
|
2015-03-02 18:04:31 +02:00
|
|
|
if !ok {
|
2017-03-05 20:01:46 +02:00
|
|
|
return expireAfter
|
2015-03-02 18:04:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
date, err := time.Parse(time.RFC3339, dateStr)
|
|
|
|
if err != nil {
|
|
|
|
panic("last_action is not a valid RFC3339 date")
|
|
|
|
}
|
|
|
|
|
2017-03-05 20:01:46 +02:00
|
|
|
remaining := date.Add(expireAfter).Sub(nowTime().UTC())
|
2015-03-02 18:04:31 +02:00
|
|
|
if remaining > 0 {
|
|
|
|
return remaining
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2017-03-05 20:01:46 +02:00
|
|
|
// RefreshExpiry updates the last action for the user, so he doesn't
|
|
|
|
// become expired.
|
|
|
|
func RefreshExpiry(w http.ResponseWriter, r *http.Request) {
|
|
|
|
refreshExpiry(w)
|
2015-03-02 18:04:31 +02:00
|
|
|
}
|
|
|
|
|
2017-03-05 20:01:46 +02:00
|
|
|
func refreshExpiry(w http.ResponseWriter) {
|
|
|
|
PutSession(w, SessionLastAction, nowTime().UTC().Format(time.RFC3339))
|
2015-03-02 18:04:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
type expireMiddleware struct {
|
2015-03-31 21:34:03 +02:00
|
|
|
ab *Authboss
|
2015-03-02 18:04:31 +02:00
|
|
|
next http.Handler
|
|
|
|
}
|
|
|
|
|
|
|
|
// ExpireMiddleware ensures that the user's expiry information is kept up-to-date
|
|
|
|
// on each request. Deletes the SessionKey from the session if the user is
|
2015-03-31 21:34:03 +02:00
|
|
|
// expired (a.ExpireAfter duration since SessionLastAction).
|
2015-04-11 07:23:54 +02:00
|
|
|
// This middleware conflicts with use of the Remember module, don't enable both
|
|
|
|
// at the same time.
|
2015-03-31 21:34:03 +02:00
|
|
|
func (a *Authboss) ExpireMiddleware(next http.Handler) http.Handler {
|
|
|
|
return expireMiddleware{a, next}
|
2015-03-02 18:04:31 +02:00
|
|
|
}
|
|
|
|
|
2017-03-05 20:01:46 +02:00
|
|
|
// ServeHTTP removes the session and hides the loaded user from the handlers
|
|
|
|
// below it.
|
2015-03-02 18:04:31 +02:00
|
|
|
func (m expireMiddleware) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
2017-03-05 20:01:46 +02:00
|
|
|
if _, ok := GetSession(r, SessionKey); ok {
|
2018-02-02 01:42:48 +02:00
|
|
|
ttl := timeToExpiry(r, m.ab.Modules.ExpireAfter)
|
2017-03-05 20:01:46 +02:00
|
|
|
if ttl == 0 {
|
|
|
|
DelSession(w, SessionKey)
|
|
|
|
DelSession(w, SessionLastAction)
|
|
|
|
ctx := context.WithValue(r.Context(), ctxKeyPID, nil)
|
|
|
|
ctx = context.WithValue(ctx, ctxKeyUser, nil)
|
|
|
|
r = r.WithContext(ctx)
|
|
|
|
} else {
|
|
|
|
refreshExpiry(w)
|
2015-03-02 18:04:31 +02:00
|
|
|
}
|
2017-03-05 20:01:46 +02:00
|
|
|
}
|
2015-03-02 18:04:31 +02:00
|
|
|
|
2017-03-05 20:01:46 +02:00
|
|
|
m.next.ServeHTTP(w, r)
|
2015-03-02 18:04:31 +02:00
|
|
|
}
|