Skip to content
Snippets Groups Projects
Commit 8aec1344 authored by Christian Pointner's avatar Christian Pointner
Browse files

use context for session expiry

parent 35c218ac
No related branches found
No related tags found
No related merge requests found
......@@ -191,6 +191,8 @@ func (h *oidcCallbackHandler) ServeHTTP(w http.ResponseWriter, r *http.Request)
return
}
// TODO: handle login error (query parameter: error, error_description)
if !s.updateState(SessionStateLoginStarted, SessionStateLoginFinalizing) {
sendHTTPErrorResponse(w, http.StatusConflict, "this session is already logged in or in an invalid state")
return
......
......@@ -81,10 +81,11 @@ func (s SessionState) MarshalText() (data []byte, err error) {
}
type Session struct {
id string
secret string
state SessionState
expires *time.Time
id string
secret string
state SessionState
ctx context.Context
cancel context.CancelFunc
subs chan struct{}
subsMutex sync.Mutex
......@@ -105,7 +106,7 @@ func NewSession() (s *Session, err error) {
return
}
s.state = SessionStateNew
s.expires = &time.Time{}
s.ctx = context.Background()
return
}
......@@ -139,10 +140,12 @@ func (s *Session) updateState(old, new SessionState) bool {
}
func (s *Session) Expired() bool {
if s.expires == nil {
return false
select {
case <-s.ctx.Done():
return true
default:
}
return s.expires.Before(time.Now())
return false
}
func (s *Session) subscribe() <-chan struct{} {
......@@ -165,7 +168,17 @@ func (s *Session) signalSubscribers() {
}
}
func (s *Session) cleanup() {
if s.cancel != nil {
s.cancel()
}
}
func (s *Session) MarshalJSON() ([]byte, error) {
var expires *time.Time
if deadline, ok := s.ctx.Deadline(); ok {
expires = &deadline
}
return json.Marshal(struct {
ID string `json:"id"`
State SessionState `json:"state"`
......@@ -177,7 +190,7 @@ func (s *Session) MarshalJSON() ([]byte, error) {
}{
ID: s.id,
State: s.State(),
Expires: s.expires,
Expires: expires,
Username: s.Username,
ReadOnly: s.ReadOnly,
AllShows: s.AllShows,
......@@ -264,13 +277,9 @@ func (sm *SessionManager) runMaintenance() {
}
func (sm *SessionManager) insert(s *Session) (err error) {
eMax := time.Now().Add(sm.maxAge)
if s.expires != nil && (s.expires.IsZero() || s.expires.After(eMax)) {
s.expires = &eMax
}
sm.mutex.Lock()
defer sm.mutex.Unlock()
s.ctx, s.cancel = context.WithTimeout(s.ctx, sm.maxAge)
sm.sessions[s.id] = s
auth.dbgLog.Printf("authentication: added new session %s", s.id)
return
......@@ -309,7 +318,8 @@ func (sm *SessionManager) update(id string, s *Session) error {
s.secret = old.secret
s.id = old.id
s.state = old.state
s.expires = old.expires
s.ctx = old.ctx
s.cancel = old.cancel
old.signalSubscribers()
......@@ -327,8 +337,9 @@ func (sm *SessionManager) remove(id string) {
if !ok {
return
}
s.setState(SessionStateRemoved)
delete(sm.sessions, id)
s.setState(SessionStateRemoved)
s.cleanup()
auth.dbgLog.Printf("authentication: removed session %s", id)
}
......@@ -340,8 +351,9 @@ func (sm *SessionManager) cleanup() {
exp := s.Expired()
st := s.State()
if exp || st == SessionStateLoginFailed || st == SessionStateLoginTimeout {
s.setState(SessionStateRemoved)
delete(sm.sessions, id)
s.setState(SessionStateRemoved)
s.cleanup()
reason := st.String()
if exp {
reason = "expired"
......
......@@ -29,16 +29,16 @@ importer:
normalizer: ffmpeg
### uncomment to enable authentication
# auth:
# sessions:
# ## defaults to 24h
# max-age: 12h
# oidc:
# issuer-url: http://localhost:8000/openid
# client-id: ${OIDC_CLIENT_ID}
# client-secret: ${OIDC_CLIENT_SECRET}
# callback-url: http://localhost:8080/auth/oidc/callback
# login-timeout: 1m # defaults to 5 Minutes
auth:
sessions:
## defaults to 24h
max-age: 12h
oidc:
issuer-url: http://localhost:8000/openid
client-id: ${OIDC_CLIENT_ID}
client-secret: ${OIDC_CLIENT_SECRET}
callback-url: http://localhost:8080/auth/oidc/callback
login-timeout: 10m # defaults to 5 Minutes
### uncomment to enable CORS headers
### see: https://godoc.org/github.com/rs/cors#Options
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment