Mercurial > gemma
view pkg/auth/session.go @ 942:912d016275ee
client: add arrow to drawn linesegment
* Add styling function that will place an icon png image at the end
of each drawn line segment, in the right rotation.
Note that this does not look perfectly centered, see comment in the
code.
author | Bernhard Reiter <bernhard@intevation.de> |
---|---|
date | Tue, 09 Oct 2018 18:39:01 +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 }