Mercurial > gemma
view pkg/auth/session.go @ 904:e4b72a199258
New default bottleneck colors
Mainly to make the stroke color one actually selectable in the ui.
In addition the pink does better match the collors used on the ECDIS layer.
author | Sascha Wilde <wilde@intevation.de> |
---|---|
date | Tue, 02 Oct 2018 13:34:59 +0200 |
parents | e1466e65bc35 |
children | a244b18cb916 |
line wrap: on
line source
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 }