auth

Paddy 2014-11-11 Parent:e45bfa2abc00 Child:4cb65cf90217

69:42bc3e44f4fe Go to Latest

auth/grant.go

Stub out sessions. Stop using the Login type when getting profile by Login, removing Logins, or recording Login use. The Login value has to be unique, anyways, and we don't actually know the Login type when getting a profile by Login. That's sort of the point. Create the concept of Sessions and a sessionStore type to manage our authentication sessions with the server. As per OWASP, we're basically just going to use a transparent, SHA256-generated random string as an ID, and store it client-side and server-side and just pass it back and forth. Add the ProfileID to the Grant type, because we need to remember who granted access. That's sort of important. Set a defaultGrantExpiration constant to an hour, so we have that one constant when creating new Grants. Create a helper that pulls the session ID out of an auth cookie, checks it against the sessionStore, and returns the Session if it's valid. Create a helper that pulls the username and password out of a basic auth header. Create a helper that authenticates a user's login and passphrase, checking them against the profileStore securely. Stub out how the cookie checking is going to work for getting grant approval. Fix the stored Grant RedirectURI to be the passed in redirect URI, not the RedirectURI that we ultimately redirect to. This is in accordance with the spec. Store the profile ID from our session in the created Grant. Stub out a GetTokenHandler that will allow users to exchange a Grant for a Token. Set a constant for the current passphrase scheme, which we will increment for each revision to the passphrase scheme, for backwards compatibility. Change the Profile iterations property to an int, not an int64, to match the code.secondbit.org/pass library (which is matching the PBKDF2 library).

History
1 package auth
3 import (
4 "errors"
5 "time"
7 "code.secondbit.org/uuid"
8 )
10 var (
11 // ErrNoGrantStore is returned when a Context tries to act on a grantStore without setting one first.
12 ErrNoGrantStore = errors.New("no grantStore was specified for the Context")
13 // ErrGrantNotFound is returned when a Grant is requested but not found in the grantStore.
14 ErrGrantNotFound = errors.New("grant not found in grantStore")
15 // ErrGrantAlreadyExists is returned when a Grant is added to a grantStore, but another Grant with the
16 // same Code already exists in the grantStore.
17 ErrGrantAlreadyExists = errors.New("grant already exists in grantStore")
18 )
20 // Grant represents an authorization grant made by a user to a Client, to
21 // access user data within a defined Scope for a limited amount of time.
22 type Grant struct {
23 Code string
24 Created time.Time
25 ExpiresIn int32
26 ClientID uuid.ID
27 Scope string
28 RedirectURI string
29 State string
30 ProfileID uuid.ID
31 }
33 type grantStore interface {
34 getGrant(code string) (Grant, error)
35 saveGrant(grant Grant) error
36 deleteGrant(code string) error
37 }
39 func (m *memstore) getGrant(code string) (Grant, error) {
40 m.grantLock.RLock()
41 defer m.grantLock.RUnlock()
42 grant, ok := m.grants[code]
43 if !ok {
44 return Grant{}, ErrGrantNotFound
45 }
46 return grant, nil
47 }
49 func (m *memstore) saveGrant(grant Grant) error {
50 m.grantLock.Lock()
51 defer m.grantLock.Unlock()
52 _, ok := m.grants[grant.Code]
53 if ok {
54 return ErrGrantAlreadyExists
55 }
56 m.grants[grant.Code] = grant
57 return nil
58 }
60 func (m *memstore) deleteGrant(code string) error {
61 m.grantLock.Lock()
62 defer m.grantLock.Unlock()
63 _, ok := m.grants[code]
64 if !ok {
65 return ErrGrantNotFound
66 }
67 delete(m.grants, code)
68 return nil
69 }