Mercurial > gemma
view pkg/auth/session.go @ 1133:dd4071019676
Delete contour lines with their sounding result
Contour lines are no independent data sets and thus can safely be
deleted with sounding results.
In passing, name the primary key as such.
author | Tom Gottfried <tom@intevation.de> |
---|---|
date | Wed, 07 Nov 2018 18:13:02 +0100 |
parents | a244b18cb916 |
children | 176c42053562 |
line wrap: on
line source
// This is Free Software under GNU Affero General Public License v >= 3.0 // without warranty, see README.md and license for details. // // SPDX-License-Identifier: AGPL-3.0-or-later // License-Filename: LICENSES/AGPL-3.0.txt // // Copyright (C) 2018 by via donau // – Österreichische Wasserstraßen-Gesellschaft mbH // Software engineering by Intevation GmbH // // Author(s): // * Sascha L. Teichmann <sascha.teichmann@intevation.de> package auth import ( "encoding/base64" "errors" "io" "sync" "time" "gemma.intevation.de/gemma/pkg/common" "gemma.intevation.de/gemma/pkg/misc" ) type Roles []string type Session struct { ExpiresAt int64 `json:"expires"` User string `json:"user"` Roles Roles `json:"roles"` // private fields for managing expiration. access time.Time mu sync.Mutex } func (r Roles) Has(role string) bool { for _, x := range r { if x == role { return true } } return false } func (r Roles) HasAny(roles ...string) bool { for _, y := range roles { if r.Has(y) { return true } } return false } const ( sessionKeyLength = 20 maxTokenValid = time.Hour * 3 ) func NewSession(user, password string, roles Roles) *Session { // Create the Claims return &Session{ ExpiresAt: time.Now().Add(maxTokenValid).Unix(), User: user, Roles: roles, } } func (s *Session) serialize(w io.Writer) error { access, err := s.last().MarshalText() if err != nil { return err } wr := misc.BinWriter{w, nil} wr.WriteBin(s.ExpiresAt) wr.WriteString(s.User) wr.WriteBin(uint32(len(s.Roles))) for _, role := range s.Roles { wr.WriteString(role) } wr.WriteBin(uint32(len(access))) wr.WriteBin(access) return wr.Err } func (s *Session) deserialize(r io.Reader) error { var session Session var n uint32 rd := misc.BinReader{r, nil} rd.ReadBin(&session.ExpiresAt) rd.ReadString(&session.User) rd.ReadBin(&n) session.Roles = make(Roles, n) for i := uint32(0); n > 0 && i < n; i++ { rd.ReadString(&session.Roles[i]) } if rd.Err != nil { return rd.Err } var l uint32 rd.ReadBin(&l) access := make([]byte, l) rd.ReadBin(access) if rd.Err != nil { return rd.Err } var t time.Time if err := t.UnmarshalText(access); err != nil { return err } session.access = t *s = session return nil } func (c *Session) touch() { c.mu.Lock() c.access = time.Now() c.mu.Unlock() } func (c *Session) last() time.Time { c.mu.Lock() access := c.access c.mu.Unlock() return access } func GenerateSessionKey() string { return base64.URLEncoding.EncodeToString( common.GenerateRandomKey(sessionKeyLength)) } var ErrInvalidRole = errors.New("Invalid role") func GenerateSession(user, password string) (string, *Session, error) { roles, err := AllOtherRoles(user, password) if err != nil { return "", nil, err } if !roles.HasAny("sys_admin", "waterway_admin", "waterway_user") { return "", nil, ErrInvalidRole } token := GenerateSessionKey() session := NewSession(user, password, roles) Sessions.Add(token, session) return token, session, nil }