auth

Paddy 2014-12-13 Parent:1fb166575e69 Child:a22b35677cd5

92:e81407f7ecb1 Go to Latest

auth/context.go

Remove old BUG. We implemented revoking tokens, so let's remove the BUG designation.

History
paddy@50 1 package auth
paddy@50 2
paddy@50 3 import (
paddy@50 4 "html/template"
paddy@50 5 "io"
paddy@55 6 "log"
paddy@77 7 "net/url"
paddy@50 8 "time"
paddy@50 9
paddy@50 10 "code.secondbit.org/uuid"
paddy@50 11 )
paddy@50 12
paddy@57 13 // Context wraps the different storage interfaces and should
paddy@57 14 // be used as the main point of interaction for the data storage
paddy@57 15 // layer.
paddy@50 16 type Context struct {
paddy@87 17 template *template.Template
paddy@87 18 loginURI *url.URL
paddy@87 19 clients clientStore
paddy@87 20 authCodes authorizationCodeStore
paddy@87 21 profiles profileStore
paddy@87 22 tokens tokenStore
paddy@87 23 sessions sessionStore
paddy@50 24 }
paddy@50 25
paddy@57 26 // Render uses the HTML templates associated with the Context to render the
paddy@57 27 // template specified by name to out using data to fill any template variables.
paddy@55 28 func (c Context) Render(out io.Writer, name string, data interface{}) {
paddy@50 29 if c.template == nil {
paddy@57 30 log.Println("No template set on Context, can't render anything!")
paddy@57 31 return
paddy@50 32 }
paddy@55 33 err := c.template.ExecuteTemplate(out, name, data)
paddy@55 34 if err != nil {
paddy@55 35 log.Println("Error executing template", name, ":", err)
paddy@55 36 }
paddy@50 37 }
paddy@50 38
paddy@57 39 // GetClient returns a single Client by its ID from the
paddy@57 40 // clientStore associated with the Context.
paddy@50 41 func (c Context) GetClient(id uuid.ID) (Client, error) {
paddy@50 42 if c.clients == nil {
paddy@50 43 return Client{}, ErrNoClientStore
paddy@50 44 }
paddy@57 45 return c.clients.getClient(id)
paddy@50 46 }
paddy@50 47
paddy@57 48 // SaveClient stores the passed Client in the clientStore
paddy@57 49 // associated with the Context.
paddy@50 50 func (c Context) SaveClient(client Client) error {
paddy@50 51 if c.clients == nil {
paddy@50 52 return ErrNoClientStore
paddy@50 53 }
paddy@57 54 return c.clients.saveClient(client)
paddy@50 55 }
paddy@50 56
paddy@57 57 // UpdateClient applies the specified ClientChange to the Client
paddy@57 58 // with the specified ID in the clientStore associated with the
paddy@57 59 // Context.
paddy@50 60 func (c Context) UpdateClient(id uuid.ID, change ClientChange) error {
paddy@50 61 if c.clients == nil {
paddy@50 62 return ErrNoClientStore
paddy@50 63 }
paddy@57 64 return c.clients.updateClient(id, change)
paddy@50 65 }
paddy@50 66
paddy@57 67 // DeleteClient removes the client with the specified ID from the
paddy@57 68 // clientStore associated with the Context.
paddy@50 69 func (c Context) DeleteClient(id uuid.ID) error {
paddy@50 70 if c.clients == nil {
paddy@50 71 return ErrNoClientStore
paddy@50 72 }
paddy@57 73 return c.clients.deleteClient(id)
paddy@50 74 }
paddy@50 75
paddy@57 76 // ListClientsByOwner returns a slice of up to num Clients, starting at offset (inclusive)
paddy@57 77 // that have the specified OwnerID in the clientStore associated with the Context.
paddy@50 78 func (c Context) ListClientsByOwner(ownerID uuid.ID, num, offset int) ([]Client, error) {
paddy@50 79 if c.clients == nil {
paddy@50 80 return []Client{}, ErrNoClientStore
paddy@50 81 }
paddy@57 82 return c.clients.listClientsByOwner(ownerID, num, offset)
paddy@50 83 }
paddy@50 84
paddy@57 85 // AddEndpoint stores the specified Endpoint in the clientStore associated with the Context,
paddy@57 86 // and associates the newly-stored Endpoint with the Client specified by the passed ID.
paddy@50 87 func (c Context) AddEndpoint(client uuid.ID, endpoint Endpoint) error {
paddy@50 88 if c.clients == nil {
paddy@50 89 return ErrNoClientStore
paddy@50 90 }
paddy@57 91 return c.clients.addEndpoint(client, endpoint)
paddy@50 92 }
paddy@50 93
paddy@57 94 // RemoveEndpoint deletes the Endpoint with the specified ID from the clientStore associated
paddy@57 95 // with the Context, and disassociates the Endpoint from the specified Client.
paddy@50 96 func (c Context) RemoveEndpoint(client, endpoint uuid.ID) error {
paddy@50 97 if c.clients == nil {
paddy@50 98 return ErrNoClientStore
paddy@50 99 }
paddy@57 100 return c.clients.removeEndpoint(client, endpoint)
paddy@50 101 }
paddy@50 102
paddy@57 103 // CheckEndpoint finds Endpoints in the clientStore associated with the Context that belong
paddy@58 104 // to the Client specified by the passed ID and match the URI passed. URI matches must be
paddy@58 105 // performed according to RFC 3986 Section 6.
paddy@58 106 func (c Context) CheckEndpoint(client uuid.ID, URI string) (bool, error) {
paddy@50 107 if c.clients == nil {
paddy@50 108 return false, ErrNoClientStore
paddy@50 109 }
paddy@58 110 return c.clients.checkEndpoint(client, URI)
paddy@50 111 }
paddy@50 112
paddy@57 113 // ListEndpoints finds Endpoints in the clientStore associated with the Context that belong
paddy@57 114 // to the Client specified by the passed ID. It returns up to num endpoints, starting at offset,
paddy@57 115 // exclusive.
paddy@50 116 func (c Context) ListEndpoints(client uuid.ID, num, offset int) ([]Endpoint, error) {
paddy@50 117 if c.clients == nil {
paddy@50 118 return []Endpoint{}, ErrNoClientStore
paddy@50 119 }
paddy@57 120 return c.clients.listEndpoints(client, num, offset)
paddy@50 121 }
paddy@50 122
paddy@57 123 // CountEndpoints returns the number of Endpoints the are associated with the Client specified by the
paddy@57 124 // passed ID in the clientStore associated with the Context.
paddy@55 125 func (c Context) CountEndpoints(client uuid.ID) (int64, error) {
paddy@55 126 if c.clients == nil {
paddy@55 127 return 0, ErrNoClientStore
paddy@55 128 }
paddy@57 129 return c.clients.countEndpoints(client)
paddy@55 130 }
paddy@55 131
paddy@87 132 // GetAuthorizationCode returns the AuthorizationCode specified by the provided code from the authorizationCodeStore associated with the
paddy@57 133 // Context.
paddy@87 134 func (c Context) GetAuthorizationCode(code string) (AuthorizationCode, error) {
paddy@87 135 if c.authCodes == nil {
paddy@87 136 return AuthorizationCode{}, ErrNoAuthorizationCodeStore
paddy@50 137 }
paddy@87 138 return c.authCodes.getAuthorizationCode(code)
paddy@50 139 }
paddy@50 140
paddy@87 141 // SaveAuthorizationCode stores the passed AuthorizationCode in the authorizationCodeStore associated with the Context.
paddy@87 142 func (c Context) SaveAuthorizationCode(authCode AuthorizationCode) error {
paddy@87 143 if c.authCodes == nil {
paddy@87 144 return ErrNoAuthorizationCodeStore
paddy@50 145 }
paddy@87 146 return c.authCodes.saveAuthorizationCode(authCode)
paddy@50 147 }
paddy@50 148
paddy@87 149 // DeleteAuthorizationCode removes the AuthorizationCode specified by the provided code from the authorizationCodeStore associated with
paddy@57 150 // the Context.
paddy@87 151 func (c Context) DeleteAuthorizationCode(code string) error {
paddy@87 152 if c.authCodes == nil {
paddy@87 153 return ErrNoAuthorizationCodeStore
paddy@50 154 }
paddy@87 155 return c.authCodes.deleteAuthorizationCode(code)
paddy@50 156 }
paddy@50 157
paddy@57 158 // GetProfileByID returns the Profile specified by the provided ID from the profileStore associated with
paddy@57 159 // the Context.
paddy@50 160 func (c Context) GetProfileByID(id uuid.ID) (Profile, error) {
paddy@50 161 if c.profiles == nil {
paddy@50 162 return Profile{}, ErrNoProfileStore
paddy@50 163 }
paddy@57 164 return c.profiles.getProfileByID(id)
paddy@50 165 }
paddy@50 166
paddy@57 167 // GetProfileByLogin returns the Profile associated with the specified Login from the profileStore associated
paddy@57 168 // with the Context.
paddy@69 169 func (c Context) GetProfileByLogin(value string) (Profile, error) {
paddy@50 170 if c.profiles == nil {
paddy@50 171 return Profile{}, ErrNoProfileStore
paddy@50 172 }
paddy@69 173 return c.profiles.getProfileByLogin(value)
paddy@50 174 }
paddy@50 175
paddy@57 176 // SaveProfile inserts the passed Profile into the profileStore associated with the Context.
paddy@50 177 func (c Context) SaveProfile(profile Profile) error {
paddy@50 178 if c.profiles == nil {
paddy@50 179 return ErrNoProfileStore
paddy@50 180 }
paddy@57 181 return c.profiles.saveProfile(profile)
paddy@50 182 }
paddy@50 183
paddy@57 184 // UpdateProfile applies the supplied ProfileChange to the Profile that matches the specified ID
paddy@57 185 // in the profileStore associated with the Context.
paddy@50 186 func (c Context) UpdateProfile(id uuid.ID, change ProfileChange) error {
paddy@50 187 if c.profiles == nil {
paddy@50 188 return ErrNoProfileStore
paddy@50 189 }
paddy@57 190 return c.profiles.updateProfile(id, change)
paddy@50 191 }
paddy@50 192
paddy@57 193 // UpdateProfiles applies the supplied BulkProfileChange to every Profile that matches one of the
paddy@57 194 // specified IDs in the profileStore associated with the Context.
paddy@50 195 func (c Context) UpdateProfiles(ids []uuid.ID, change BulkProfileChange) error {
paddy@50 196 if c.profiles == nil {
paddy@50 197 return ErrNoProfileStore
paddy@50 198 }
paddy@57 199 return c.profiles.updateProfiles(ids, change)
paddy@50 200 }
paddy@50 201
paddy@57 202 // DeleteProfile removes the Profile specified by the passed ID from the profileStore associated
paddy@57 203 // with the Context.
paddy@50 204 func (c Context) DeleteProfile(id uuid.ID) error {
paddy@50 205 if c.profiles == nil {
paddy@50 206 return ErrNoProfileStore
paddy@50 207 }
paddy@57 208 return c.profiles.deleteProfile(id)
paddy@50 209 }
paddy@50 210
paddy@57 211 // AddLogin stores the passed Login in the profileStore associated with the Context. It also associates
paddy@57 212 // the newly-created Login with the Orofile in login.ProfileID.
paddy@50 213 func (c Context) AddLogin(login Login) error {
paddy@50 214 if c.profiles == nil {
paddy@50 215 return ErrNoProfileStore
paddy@50 216 }
paddy@57 217 return c.profiles.addLogin(login)
paddy@50 218 }
paddy@50 219
paddy@57 220 // RemoveLogin removes the specified Login from the profileStore associated with the Context, provided
paddy@57 221 // the Login has a ProfileID property that matches the profile ID passed in. It also disassociates the
paddy@57 222 // deleted Login from the Profile in login.ProfileID.
paddy@69 223 func (c Context) RemoveLogin(value string, profile uuid.ID) error {
paddy@50 224 if c.profiles == nil {
paddy@50 225 return ErrNoProfileStore
paddy@50 226 }
paddy@69 227 return c.profiles.removeLogin(value, profile)
paddy@50 228 }
paddy@50 229
paddy@57 230 // RecordLoginUse sets the LastUsed property of the Login specified in the profileStore associated with
paddy@57 231 // the Context to the value passed in as when.
paddy@69 232 func (c Context) RecordLoginUse(value string, when time.Time) error {
paddy@50 233 if c.profiles == nil {
paddy@50 234 return ErrNoProfileStore
paddy@50 235 }
paddy@69 236 return c.profiles.recordLoginUse(value, when)
paddy@50 237 }
paddy@50 238
paddy@57 239 // ListLogins returns a slice of up to num Logins associated with the specified Profile from the profileStore
paddy@57 240 // associated with the Context, skipping offset Profiles.
paddy@50 241 func (c Context) ListLogins(profile uuid.ID, num, offset int) ([]Login, error) {
paddy@50 242 if c.profiles == nil {
paddy@50 243 return []Login{}, ErrNoProfileStore
paddy@50 244 }
paddy@57 245 return c.profiles.listLogins(profile, num, offset)
paddy@50 246 }
paddy@50 247
paddy@57 248 // GetToken returns the Token specified from the tokenStore associated with the Context.
paddy@57 249 // If refresh is true, the token input should be compared against the refresh tokens, not the
paddy@57 250 // access tokens.
paddy@50 251 func (c Context) GetToken(token string, refresh bool) (Token, error) {
paddy@50 252 if c.tokens == nil {
paddy@50 253 return Token{}, ErrNoTokenStore
paddy@50 254 }
paddy@57 255 return c.tokens.getToken(token, refresh)
paddy@50 256 }
paddy@50 257
paddy@57 258 // SaveToken stores the passed Token in the tokenStore associated with the Context.
paddy@50 259 func (c Context) SaveToken(token Token) error {
paddy@50 260 if c.tokens == nil {
paddy@50 261 return ErrNoTokenStore
paddy@50 262 }
paddy@57 263 return c.tokens.saveToken(token)
paddy@50 264 }
paddy@50 265
paddy@57 266 // RemoveToken removes the Token identified by the passed token string from the tokenStore associated
paddy@57 267 // with the Context.
paddy@50 268 func (c Context) RemoveToken(token string) error {
paddy@50 269 if c.tokens == nil {
paddy@50 270 return ErrNoTokenStore
paddy@50 271 }
paddy@57 272 return c.tokens.removeToken(token)
paddy@50 273 }
paddy@50 274
paddy@57 275 // GetTokensByProfileID returns a slice of up to num Tokens with a ProfileID that matches the specified
paddy@57 276 // profileID from the tokenStore associated with the Context, skipping offset Tokens.
paddy@50 277 func (c Context) GetTokensByProfileID(profileID uuid.ID, num, offset int) ([]Token, error) {
paddy@50 278 if c.tokens == nil {
paddy@50 279 return []Token{}, ErrNoTokenStore
paddy@50 280 }
paddy@57 281 return c.tokens.getTokensByProfileID(profileID, num, offset)
paddy@50 282 }
paddy@69 283
paddy@69 284 // CreateSession stores the passed Session in the sessionStore associated with the Context.
paddy@69 285 func (c Context) CreateSession(session Session) error {
paddy@69 286 if c.sessions == nil {
paddy@69 287 return ErrNoSessionStore
paddy@69 288 }
paddy@69 289 return c.sessions.createSession(session)
paddy@69 290 }
paddy@69 291
paddy@69 292 // GetSession returns the Session specified from the sessionStore associated with the Context.
paddy@69 293 func (c Context) GetSession(id string) (Session, error) {
paddy@69 294 if c.sessions == nil {
paddy@69 295 return Session{}, ErrNoSessionStore
paddy@69 296 }
paddy@69 297 return c.sessions.getSession(id)
paddy@69 298 }
paddy@69 299
paddy@69 300 // RemoveSession removes the Session identified by the passed ID from the sessionStore associated with
paddy@69 301 // the Context.
paddy@69 302 func (c Context) RemoveSession(id string) error {
paddy@69 303 if c.sessions == nil {
paddy@69 304 return ErrNoSessionStore
paddy@69 305 }
paddy@69 306 return c.sessions.removeSession(id)
paddy@69 307 }
paddy@69 308
paddy@69 309 // ListSessions returns a slice of up to num Sessions from the sessionStore associated with the Context,
paddy@69 310 // ordered by the date they were created, descending. If before.IsZero() returns false, only Sessions
paddy@69 311 // that were created before that time will be returned. If profile is not nil, only Sessions belonging to
paddy@69 312 // that Profile will be returned.
paddy@69 313 func (c Context) ListSessions(profile uuid.ID, before time.Time, num int64) ([]Session, error) {
paddy@69 314 if c.sessions != nil {
paddy@69 315 return []Session{}, ErrNoSessionStore
paddy@69 316 }
paddy@69 317 return c.sessions.listSessions(profile, before, num)
paddy@69 318 }