auth
auth/context.go
Actually validate grant requests. Write the logic to validate grant requests and stub out the rendering/error handling/redirecting locations. Finally, we get to the good stuff: implementing the specification. Write some tests to verify that granting requests works the way we think it does.
| paddy@50 | 1 package auth |
| paddy@50 | 2 |
| paddy@50 | 3 import ( |
| paddy@50 | 4 "errors" |
| paddy@50 | 5 "html/template" |
| paddy@50 | 6 "io" |
| paddy@55 | 7 "log" |
| paddy@50 | 8 "time" |
| paddy@50 | 9 |
| paddy@50 | 10 "code.secondbit.org/uuid" |
| paddy@50 | 11 ) |
| paddy@50 | 12 |
| paddy@50 | 13 var ( |
| paddy@50 | 14 ErrNoTemplate = errors.New("no Template specified for the Context") |
| paddy@50 | 15 ) |
| paddy@50 | 16 |
| paddy@50 | 17 type Context struct { |
| paddy@50 | 18 template *template.Template |
| paddy@50 | 19 clients ClientStore |
| paddy@50 | 20 grants GrantStore |
| paddy@50 | 21 profiles ProfileStore |
| paddy@50 | 22 tokens TokenStore |
| paddy@50 | 23 } |
| paddy@50 | 24 |
| paddy@55 | 25 func (c Context) Render(out io.Writer, name string, data interface{}) { |
| paddy@50 | 26 if c.template == nil { |
| paddy@55 | 27 log.Println(ErrNoTemplate) |
| paddy@50 | 28 } |
| paddy@55 | 29 err := c.template.ExecuteTemplate(out, name, data) |
| paddy@55 | 30 if err != nil { |
| paddy@55 | 31 log.Println("Error executing template", name, ":", err) |
| paddy@55 | 32 } |
| paddy@50 | 33 } |
| paddy@50 | 34 |
| paddy@50 | 35 func (c Context) GetClient(id uuid.ID) (Client, error) { |
| paddy@50 | 36 if c.clients == nil { |
| paddy@50 | 37 return Client{}, ErrNoClientStore |
| paddy@50 | 38 } |
| paddy@50 | 39 return c.clients.GetClient(id) |
| paddy@50 | 40 } |
| paddy@50 | 41 |
| paddy@50 | 42 func (c Context) SaveClient(client Client) error { |
| paddy@50 | 43 if c.clients == nil { |
| paddy@50 | 44 return ErrNoClientStore |
| paddy@50 | 45 } |
| paddy@50 | 46 return c.clients.SaveClient(client) |
| paddy@50 | 47 } |
| paddy@50 | 48 |
| paddy@50 | 49 func (c Context) UpdateClient(id uuid.ID, change ClientChange) error { |
| paddy@50 | 50 if c.clients == nil { |
| paddy@50 | 51 return ErrNoClientStore |
| paddy@50 | 52 } |
| paddy@50 | 53 return c.clients.UpdateClient(id, change) |
| paddy@50 | 54 } |
| paddy@50 | 55 |
| paddy@50 | 56 func (c Context) DeleteClient(id uuid.ID) error { |
| paddy@50 | 57 if c.clients == nil { |
| paddy@50 | 58 return ErrNoClientStore |
| paddy@50 | 59 } |
| paddy@50 | 60 return c.clients.DeleteClient(id) |
| paddy@50 | 61 } |
| paddy@50 | 62 |
| paddy@50 | 63 func (c Context) ListClientsByOwner(ownerID uuid.ID, num, offset int) ([]Client, error) { |
| paddy@50 | 64 if c.clients == nil { |
| paddy@50 | 65 return []Client{}, ErrNoClientStore |
| paddy@50 | 66 } |
| paddy@50 | 67 return c.clients.ListClientsByOwner(ownerID, num, offset) |
| paddy@50 | 68 } |
| paddy@50 | 69 |
| paddy@50 | 70 func (c Context) AddEndpoint(client uuid.ID, endpoint Endpoint) error { |
| paddy@50 | 71 if c.clients == nil { |
| paddy@50 | 72 return ErrNoClientStore |
| paddy@50 | 73 } |
| paddy@50 | 74 return c.clients.AddEndpoint(client, endpoint) |
| paddy@50 | 75 } |
| paddy@50 | 76 |
| paddy@50 | 77 func (c Context) RemoveEndpoint(client, endpoint uuid.ID) error { |
| paddy@50 | 78 if c.clients == nil { |
| paddy@50 | 79 return ErrNoClientStore |
| paddy@50 | 80 } |
| paddy@50 | 81 return c.clients.RemoveEndpoint(client, endpoint) |
| paddy@50 | 82 } |
| paddy@50 | 83 |
| paddy@55 | 84 func (c Context) CheckEndpoint(client uuid.ID, URI string, strict bool) (bool, error) { |
| paddy@50 | 85 if c.clients == nil { |
| paddy@50 | 86 return false, ErrNoClientStore |
| paddy@50 | 87 } |
| paddy@55 | 88 return c.clients.CheckEndpoint(client, URI, strict) |
| paddy@50 | 89 } |
| paddy@50 | 90 |
| paddy@50 | 91 func (c Context) ListEndpoints(client uuid.ID, num, offset int) ([]Endpoint, error) { |
| paddy@50 | 92 if c.clients == nil { |
| paddy@50 | 93 return []Endpoint{}, ErrNoClientStore |
| paddy@50 | 94 } |
| paddy@50 | 95 return c.clients.ListEndpoints(client, num, offset) |
| paddy@50 | 96 } |
| paddy@50 | 97 |
| paddy@55 | 98 func (c Context) CountEndpoints(client uuid.ID) (int64, error) { |
| paddy@55 | 99 if c.clients == nil { |
| paddy@55 | 100 return 0, ErrNoClientStore |
| paddy@55 | 101 } |
| paddy@55 | 102 return c.clients.CountEndpoints(client) |
| paddy@55 | 103 } |
| paddy@55 | 104 |
| paddy@50 | 105 func (c Context) GetGrant(code string) (Grant, error) { |
| paddy@50 | 106 if c.grants == nil { |
| paddy@50 | 107 return Grant{}, ErrNoGrantStore |
| paddy@50 | 108 } |
| paddy@50 | 109 return c.grants.GetGrant(code) |
| paddy@50 | 110 } |
| paddy@50 | 111 |
| paddy@50 | 112 func (c Context) SaveGrant(grant Grant) error { |
| paddy@50 | 113 if c.grants == nil { |
| paddy@50 | 114 return ErrNoGrantStore |
| paddy@50 | 115 } |
| paddy@50 | 116 return c.grants.SaveGrant(grant) |
| paddy@50 | 117 } |
| paddy@50 | 118 |
| paddy@50 | 119 func (c Context) DeleteGrant(code string) error { |
| paddy@50 | 120 if c.grants == nil { |
| paddy@50 | 121 return ErrNoGrantStore |
| paddy@50 | 122 } |
| paddy@50 | 123 return c.grants.DeleteGrant(code) |
| paddy@50 | 124 } |
| paddy@50 | 125 |
| paddy@50 | 126 func (c Context) GetProfileByID(id uuid.ID) (Profile, error) { |
| paddy@50 | 127 if c.profiles == nil { |
| paddy@50 | 128 return Profile{}, ErrNoProfileStore |
| paddy@50 | 129 } |
| paddy@50 | 130 return c.profiles.GetProfileByID(id) |
| paddy@50 | 131 } |
| paddy@50 | 132 |
| paddy@50 | 133 func (c Context) GetProfileByLogin(loginType, value string) (Profile, error) { |
| paddy@50 | 134 if c.profiles == nil { |
| paddy@50 | 135 return Profile{}, ErrNoProfileStore |
| paddy@50 | 136 } |
| paddy@50 | 137 return c.profiles.GetProfileByLogin(loginType, value) |
| paddy@50 | 138 } |
| paddy@50 | 139 |
| paddy@50 | 140 func (c Context) SaveProfile(profile Profile) error { |
| paddy@50 | 141 if c.profiles == nil { |
| paddy@50 | 142 return ErrNoProfileStore |
| paddy@50 | 143 } |
| paddy@50 | 144 return c.profiles.SaveProfile(profile) |
| paddy@50 | 145 } |
| paddy@50 | 146 |
| paddy@50 | 147 func (c Context) UpdateProfile(id uuid.ID, change ProfileChange) error { |
| paddy@50 | 148 if c.profiles == nil { |
| paddy@50 | 149 return ErrNoProfileStore |
| paddy@50 | 150 } |
| paddy@50 | 151 return c.profiles.UpdateProfile(id, change) |
| paddy@50 | 152 } |
| paddy@50 | 153 |
| paddy@50 | 154 func (c Context) UpdateProfiles(ids []uuid.ID, change BulkProfileChange) error { |
| paddy@50 | 155 if c.profiles == nil { |
| paddy@50 | 156 return ErrNoProfileStore |
| paddy@50 | 157 } |
| paddy@50 | 158 return c.profiles.UpdateProfiles(ids, change) |
| paddy@50 | 159 } |
| paddy@50 | 160 |
| paddy@50 | 161 func (c Context) DeleteProfile(id uuid.ID) error { |
| paddy@50 | 162 if c.profiles == nil { |
| paddy@50 | 163 return ErrNoProfileStore |
| paddy@50 | 164 } |
| paddy@50 | 165 return c.profiles.DeleteProfile(id) |
| paddy@50 | 166 } |
| paddy@50 | 167 |
| paddy@50 | 168 func (c Context) AddLogin(login Login) error { |
| paddy@50 | 169 if c.profiles == nil { |
| paddy@50 | 170 return ErrNoProfileStore |
| paddy@50 | 171 } |
| paddy@50 | 172 return c.profiles.AddLogin(login) |
| paddy@50 | 173 } |
| paddy@50 | 174 |
| paddy@50 | 175 func (c Context) RemoveLogin(loginType, value string, profile uuid.ID) error { |
| paddy@50 | 176 if c.profiles == nil { |
| paddy@50 | 177 return ErrNoProfileStore |
| paddy@50 | 178 } |
| paddy@50 | 179 return c.profiles.RemoveLogin(loginType, value, profile) |
| paddy@50 | 180 } |
| paddy@50 | 181 |
| paddy@50 | 182 func (c Context) RecordLoginUse(loginType, value string, when time.Time) error { |
| paddy@50 | 183 if c.profiles == nil { |
| paddy@50 | 184 return ErrNoProfileStore |
| paddy@50 | 185 } |
| paddy@50 | 186 return c.profiles.RecordLoginUse(loginType, value, when) |
| paddy@50 | 187 } |
| paddy@50 | 188 |
| paddy@50 | 189 func (c Context) ListLogins(profile uuid.ID, num, offset int) ([]Login, error) { |
| paddy@50 | 190 if c.profiles == nil { |
| paddy@50 | 191 return []Login{}, ErrNoProfileStore |
| paddy@50 | 192 } |
| paddy@50 | 193 return c.profiles.ListLogins(profile, num, offset) |
| paddy@50 | 194 } |
| paddy@50 | 195 |
| paddy@50 | 196 func (c Context) GetToken(token string, refresh bool) (Token, error) { |
| paddy@50 | 197 if c.tokens == nil { |
| paddy@50 | 198 return Token{}, ErrNoTokenStore |
| paddy@50 | 199 } |
| paddy@50 | 200 return c.tokens.GetToken(token, refresh) |
| paddy@50 | 201 } |
| paddy@50 | 202 |
| paddy@50 | 203 func (c Context) SaveToken(token Token) error { |
| paddy@50 | 204 if c.tokens == nil { |
| paddy@50 | 205 return ErrNoTokenStore |
| paddy@50 | 206 } |
| paddy@50 | 207 return c.tokens.SaveToken(token) |
| paddy@50 | 208 } |
| paddy@50 | 209 |
| paddy@50 | 210 func (c Context) RemoveToken(token string) error { |
| paddy@50 | 211 if c.tokens == nil { |
| paddy@50 | 212 return ErrNoTokenStore |
| paddy@50 | 213 } |
| paddy@50 | 214 return c.tokens.RemoveToken(token) |
| paddy@50 | 215 } |
| paddy@50 | 216 |
| paddy@50 | 217 func (c Context) GetTokensByProfileID(profileID uuid.ID, num, offset int) ([]Token, error) { |
| paddy@50 | 218 if c.tokens == nil { |
| paddy@50 | 219 return []Token{}, ErrNoTokenStore |
| paddy@50 | 220 } |
| paddy@50 | 221 return c.tokens.GetTokensByProfileID(profileID, num, offset) |
| paddy@50 | 222 } |