auth
auth/context.go
Use postgres arrays for scope associations. Use the new pqarrays library I wrote to store Scope associations for Tokens and AuthorizationCodes, instead of using our hacky and abstraction-breaking many-to-many code. We also created the authStore.deleteAuthorizationCodesByProfileID method, to clear out the AuthorizationCodes that belong to a Profile (used when the Profile is deleted). So we added the implementation for memstore and for our postgres store. Call Context.DeleteAuthorizationCodesByProfileID when deleting a Profile to clean up after it. Rename sortedScopes to Scopes, which we use pqarrays.StringArray's methods on to fulfill the sql.Scanner and driver.Valuer interfaces. This lets us store Scopes in postgres arrays. Create a stringsToScopes helper function that creates Scope objects, with their IDs filled by the strings specified. Update our GrantType.Validate function signature to return Scopes instead of []string. Create a Scopes.Strings() helper method that returns a []string of the IDs of the Scopes. Update our SQL init file to use the new postgres array definition, instead of the many-to-many definition.
| 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@107 | 10 "code.secondbit.org/uuid.hg" |
| 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@134 | 24 scopes scopeStore |
| paddy@96 | 25 config Config |
| paddy@96 | 26 } |
| paddy@96 | 27 |
| paddy@96 | 28 // NewContext takes a Config instance and uses it to bootstrap a Context |
| paddy@96 | 29 // using the information provided in the Config variable. |
| paddy@96 | 30 func NewContext(config Config) (Context, error) { |
| paddy@102 | 31 if config.iterations == 0 { |
| paddy@102 | 32 return Context{}, ErrConfigNotInitialized |
| paddy@102 | 33 } |
| paddy@96 | 34 context := Context{ |
| paddy@96 | 35 clients: config.ClientStore, |
| paddy@96 | 36 authCodes: config.AuthCodeStore, |
| paddy@96 | 37 profiles: config.ProfileStore, |
| paddy@96 | 38 tokens: config.TokenStore, |
| paddy@96 | 39 sessions: config.SessionStore, |
| paddy@134 | 40 scopes: config.ScopeStore, |
| paddy@96 | 41 template: config.Template, |
| paddy@96 | 42 config: config, |
| paddy@96 | 43 } |
| paddy@96 | 44 var err error |
| paddy@96 | 45 context.loginURI, err = url.Parse(config.LoginURI) |
| paddy@96 | 46 if err != nil { |
| paddy@96 | 47 log.Println(err) |
| paddy@96 | 48 return Context{}, ErrInvalidLoginURI |
| paddy@96 | 49 } |
| paddy@96 | 50 return context, nil |
| paddy@50 | 51 } |
| paddy@50 | 52 |
| paddy@57 | 53 // Render uses the HTML templates associated with the Context to render the |
| paddy@57 | 54 // template specified by name to out using data to fill any template variables. |
| paddy@55 | 55 func (c Context) Render(out io.Writer, name string, data interface{}) { |
| paddy@50 | 56 if c.template == nil { |
| paddy@57 | 57 log.Println("No template set on Context, can't render anything!") |
| paddy@57 | 58 return |
| paddy@50 | 59 } |
| paddy@55 | 60 err := c.template.ExecuteTemplate(out, name, data) |
| paddy@55 | 61 if err != nil { |
| paddy@55 | 62 log.Println("Error executing template", name, ":", err) |
| paddy@55 | 63 } |
| paddy@50 | 64 } |
| paddy@50 | 65 |
| paddy@57 | 66 // GetClient returns a single Client by its ID from the |
| paddy@57 | 67 // clientStore associated with the Context. |
| paddy@50 | 68 func (c Context) GetClient(id uuid.ID) (Client, error) { |
| paddy@50 | 69 if c.clients == nil { |
| paddy@50 | 70 return Client{}, ErrNoClientStore |
| paddy@50 | 71 } |
| paddy@57 | 72 return c.clients.getClient(id) |
| paddy@50 | 73 } |
| paddy@50 | 74 |
| paddy@57 | 75 // SaveClient stores the passed Client in the clientStore |
| paddy@57 | 76 // associated with the Context. |
| paddy@50 | 77 func (c Context) SaveClient(client Client) error { |
| paddy@50 | 78 if c.clients == nil { |
| paddy@50 | 79 return ErrNoClientStore |
| paddy@50 | 80 } |
| paddy@57 | 81 return c.clients.saveClient(client) |
| paddy@50 | 82 } |
| paddy@50 | 83 |
| paddy@57 | 84 // UpdateClient applies the specified ClientChange to the Client |
| paddy@57 | 85 // with the specified ID in the clientStore associated with the |
| paddy@57 | 86 // Context. |
| paddy@50 | 87 func (c Context) UpdateClient(id uuid.ID, change ClientChange) error { |
| paddy@50 | 88 if c.clients == nil { |
| paddy@50 | 89 return ErrNoClientStore |
| paddy@50 | 90 } |
| paddy@57 | 91 return c.clients.updateClient(id, change) |
| paddy@50 | 92 } |
| paddy@50 | 93 |
| paddy@57 | 94 // ListClientsByOwner returns a slice of up to num Clients, starting at offset (inclusive) |
| paddy@57 | 95 // that have the specified OwnerID in the clientStore associated with the Context. |
| paddy@50 | 96 func (c Context) ListClientsByOwner(ownerID uuid.ID, num, offset int) ([]Client, error) { |
| paddy@50 | 97 if c.clients == nil { |
| paddy@50 | 98 return []Client{}, ErrNoClientStore |
| paddy@50 | 99 } |
| paddy@57 | 100 return c.clients.listClientsByOwner(ownerID, num, offset) |
| paddy@50 | 101 } |
| paddy@50 | 102 |
| paddy@151 | 103 // AddEndpoints stores the specified Endpoints in the clientStore associated with the Context. |
| paddy@151 | 104 func (c Context) AddEndpoints(endpoints []Endpoint) error { |
| paddy@50 | 105 if c.clients == nil { |
| paddy@50 | 106 return ErrNoClientStore |
| paddy@50 | 107 } |
| paddy@116 | 108 for pos, endpoint := range endpoints { |
| paddy@116 | 109 u, err := normalizeURIString(endpoint.URI) |
| paddy@116 | 110 if err != nil { |
| paddy@116 | 111 return err |
| paddy@116 | 112 } |
| paddy@116 | 113 endpoint.NormalizedURI = u |
| paddy@116 | 114 endpoints[pos] = endpoint |
| paddy@116 | 115 } |
| paddy@151 | 116 return c.clients.addEndpoints(endpoints) |
| paddy@50 | 117 } |
| paddy@50 | 118 |
| paddy@143 | 119 // GetEndpoint retrieves the Endpoint with the specified ID from the clientStore associated |
| paddy@143 | 120 // with the Context, if and only if it belongs to the Client with the specified ID. |
| paddy@143 | 121 func (c Context) GetEndpoint(client, endpoint uuid.ID) (Endpoint, error) { |
| paddy@143 | 122 if c.clients == nil { |
| paddy@143 | 123 return Endpoint{}, ErrNoClientStore |
| paddy@143 | 124 } |
| paddy@143 | 125 return c.clients.getEndpoint(client, endpoint) |
| paddy@143 | 126 } |
| paddy@143 | 127 |
| paddy@57 | 128 // RemoveEndpoint deletes the Endpoint with the specified ID from the clientStore associated |
| paddy@57 | 129 // with the Context, and disassociates the Endpoint from the specified Client. |
| paddy@50 | 130 func (c Context) RemoveEndpoint(client, endpoint uuid.ID) error { |
| paddy@50 | 131 if c.clients == nil { |
| paddy@50 | 132 return ErrNoClientStore |
| paddy@50 | 133 } |
| paddy@57 | 134 return c.clients.removeEndpoint(client, endpoint) |
| paddy@50 | 135 } |
| paddy@50 | 136 |
| paddy@57 | 137 // CheckEndpoint finds Endpoints in the clientStore associated with the Context that belong |
| paddy@58 | 138 // to the Client specified by the passed ID and match the URI passed. URI matches must be |
| paddy@58 | 139 // performed according to RFC 3986 Section 6. |
| paddy@58 | 140 func (c Context) CheckEndpoint(client uuid.ID, URI string) (bool, error) { |
| paddy@50 | 141 if c.clients == nil { |
| paddy@50 | 142 return false, ErrNoClientStore |
| paddy@50 | 143 } |
| paddy@116 | 144 u, err := normalizeURIString(URI) |
| paddy@116 | 145 if err != nil { |
| paddy@116 | 146 return false, err |
| paddy@116 | 147 } |
| paddy@116 | 148 return c.clients.checkEndpoint(client, u) |
| paddy@50 | 149 } |
| paddy@50 | 150 |
| paddy@57 | 151 // ListEndpoints finds Endpoints in the clientStore associated with the Context that belong |
| paddy@57 | 152 // to the Client specified by the passed ID. It returns up to num endpoints, starting at offset, |
| paddy@57 | 153 // exclusive. |
| paddy@50 | 154 func (c Context) ListEndpoints(client uuid.ID, num, offset int) ([]Endpoint, error) { |
| paddy@50 | 155 if c.clients == nil { |
| paddy@50 | 156 return []Endpoint{}, ErrNoClientStore |
| paddy@50 | 157 } |
| paddy@57 | 158 return c.clients.listEndpoints(client, num, offset) |
| paddy@50 | 159 } |
| paddy@50 | 160 |
| paddy@57 | 161 // CountEndpoints returns the number of Endpoints the are associated with the Client specified by the |
| paddy@57 | 162 // passed ID in the clientStore associated with the Context. |
| paddy@55 | 163 func (c Context) CountEndpoints(client uuid.ID) (int64, error) { |
| paddy@55 | 164 if c.clients == nil { |
| paddy@55 | 165 return 0, ErrNoClientStore |
| paddy@55 | 166 } |
| paddy@57 | 167 return c.clients.countEndpoints(client) |
| paddy@55 | 168 } |
| paddy@55 | 169 |
| paddy@87 | 170 // GetAuthorizationCode returns the AuthorizationCode specified by the provided code from the authorizationCodeStore associated with the |
| paddy@57 | 171 // Context. |
| paddy@87 | 172 func (c Context) GetAuthorizationCode(code string) (AuthorizationCode, error) { |
| paddy@87 | 173 if c.authCodes == nil { |
| paddy@87 | 174 return AuthorizationCode{}, ErrNoAuthorizationCodeStore |
| paddy@50 | 175 } |
| paddy@87 | 176 return c.authCodes.getAuthorizationCode(code) |
| paddy@50 | 177 } |
| paddy@50 | 178 |
| paddy@87 | 179 // SaveAuthorizationCode stores the passed AuthorizationCode in the authorizationCodeStore associated with the Context. |
| paddy@87 | 180 func (c Context) SaveAuthorizationCode(authCode AuthorizationCode) error { |
| paddy@87 | 181 if c.authCodes == nil { |
| paddy@87 | 182 return ErrNoAuthorizationCodeStore |
| paddy@50 | 183 } |
| paddy@87 | 184 return c.authCodes.saveAuthorizationCode(authCode) |
| paddy@50 | 185 } |
| paddy@50 | 186 |
| paddy@87 | 187 // DeleteAuthorizationCode removes the AuthorizationCode specified by the provided code from the authorizationCodeStore associated with |
| paddy@57 | 188 // the Context. |
| paddy@87 | 189 func (c Context) DeleteAuthorizationCode(code string) error { |
| paddy@87 | 190 if c.authCodes == nil { |
| paddy@87 | 191 return ErrNoAuthorizationCodeStore |
| paddy@50 | 192 } |
| paddy@87 | 193 return c.authCodes.deleteAuthorizationCode(code) |
| paddy@50 | 194 } |
| paddy@50 | 195 |
| paddy@163 | 196 // DeleteAuthorizationCodesByProfileID removes the AuthorizationCodes associated with the Profile specified by the provided ID from the |
| paddy@163 | 197 // authorizationCodeStore associated with the Context. |
| paddy@163 | 198 func (c Context) DeleteAuthorizationCodesByProfileID(profileID uuid.ID) error { |
| paddy@163 | 199 if c.authCodes == nil { |
| paddy@163 | 200 return ErrNoAuthorizationCodeStore |
| paddy@163 | 201 } |
| paddy@163 | 202 return c.authCodes.deleteAuthorizationCodesByProfileID(profileID) |
| paddy@163 | 203 } |
| paddy@163 | 204 |
| paddy@94 | 205 // UseAuthorizationCode marks the AuthorizationCode specified by the provided code as used in the authorizationCodeStore associated with |
| paddy@94 | 206 // the Context. Once an AuthorizationCode is marked as used, its Used property will be set to true when retrieved from the authorizationCodeStore. |
| paddy@94 | 207 func (c Context) UseAuthorizationCode(code string) error { |
| paddy@94 | 208 if c.authCodes == nil { |
| paddy@94 | 209 return ErrNoAuthorizationCodeStore |
| paddy@94 | 210 } |
| paddy@94 | 211 return c.authCodes.useAuthorizationCode(code) |
| paddy@94 | 212 } |
| paddy@94 | 213 |
| paddy@57 | 214 // GetProfileByID returns the Profile specified by the provided ID from the profileStore associated with |
| paddy@57 | 215 // the Context. |
| paddy@50 | 216 func (c Context) GetProfileByID(id uuid.ID) (Profile, error) { |
| paddy@50 | 217 if c.profiles == nil { |
| paddy@50 | 218 return Profile{}, ErrNoProfileStore |
| paddy@50 | 219 } |
| paddy@57 | 220 return c.profiles.getProfileByID(id) |
| paddy@50 | 221 } |
| paddy@50 | 222 |
| paddy@57 | 223 // GetProfileByLogin returns the Profile associated with the specified Login from the profileStore associated |
| paddy@57 | 224 // with the Context. |
| paddy@69 | 225 func (c Context) GetProfileByLogin(value string) (Profile, error) { |
| paddy@50 | 226 if c.profiles == nil { |
| paddy@50 | 227 return Profile{}, ErrNoProfileStore |
| paddy@50 | 228 } |
| paddy@69 | 229 return c.profiles.getProfileByLogin(value) |
| paddy@50 | 230 } |
| paddy@50 | 231 |
| paddy@57 | 232 // SaveProfile inserts the passed Profile into the profileStore associated with the Context. |
| paddy@50 | 233 func (c Context) SaveProfile(profile Profile) error { |
| paddy@50 | 234 if c.profiles == nil { |
| paddy@50 | 235 return ErrNoProfileStore |
| paddy@50 | 236 } |
| paddy@57 | 237 return c.profiles.saveProfile(profile) |
| paddy@50 | 238 } |
| paddy@50 | 239 |
| paddy@57 | 240 // UpdateProfile applies the supplied ProfileChange to the Profile that matches the specified ID |
| paddy@57 | 241 // in the profileStore associated with the Context. |
| paddy@50 | 242 func (c Context) UpdateProfile(id uuid.ID, change ProfileChange) error { |
| paddy@50 | 243 if c.profiles == nil { |
| paddy@50 | 244 return ErrNoProfileStore |
| paddy@50 | 245 } |
| paddy@57 | 246 return c.profiles.updateProfile(id, change) |
| paddy@50 | 247 } |
| paddy@50 | 248 |
| paddy@57 | 249 // UpdateProfiles applies the supplied BulkProfileChange to every Profile that matches one of the |
| paddy@57 | 250 // specified IDs in the profileStore associated with the Context. |
| paddy@50 | 251 func (c Context) UpdateProfiles(ids []uuid.ID, change BulkProfileChange) error { |
| paddy@50 | 252 if c.profiles == nil { |
| paddy@50 | 253 return ErrNoProfileStore |
| paddy@50 | 254 } |
| paddy@57 | 255 return c.profiles.updateProfiles(ids, change) |
| paddy@50 | 256 } |
| paddy@50 | 257 |
| paddy@161 | 258 // DeleteProfile removes the specified Profile from the profileStore associated with the Context. |
| paddy@161 | 259 func (c Context) DeleteProfile(id uuid.ID) error { |
| paddy@161 | 260 if c.profiles == nil { |
| paddy@161 | 261 return ErrNoProfileStore |
| paddy@161 | 262 } |
| paddy@161 | 263 return c.profiles.deleteProfile(id) |
| paddy@161 | 264 } |
| paddy@161 | 265 |
| paddy@57 | 266 // AddLogin stores the passed Login in the profileStore associated with the Context. It also associates |
| paddy@57 | 267 // the newly-created Login with the Orofile in login.ProfileID. |
| paddy@50 | 268 func (c Context) AddLogin(login Login) error { |
| paddy@50 | 269 if c.profiles == nil { |
| paddy@50 | 270 return ErrNoProfileStore |
| paddy@50 | 271 } |
| paddy@57 | 272 return c.profiles.addLogin(login) |
| paddy@50 | 273 } |
| paddy@50 | 274 |
| paddy@57 | 275 // RemoveLogin removes the specified Login from the profileStore associated with the Context, provided |
| paddy@57 | 276 // the Login has a ProfileID property that matches the profile ID passed in. It also disassociates the |
| paddy@57 | 277 // deleted Login from the Profile in login.ProfileID. |
| paddy@69 | 278 func (c Context) RemoveLogin(value string, profile uuid.ID) error { |
| paddy@50 | 279 if c.profiles == nil { |
| paddy@50 | 280 return ErrNoProfileStore |
| paddy@50 | 281 } |
| paddy@69 | 282 return c.profiles.removeLogin(value, profile) |
| paddy@50 | 283 } |
| paddy@50 | 284 |
| paddy@160 | 285 // RemoveLoginsByProfile removes all Logins connected to the specified Profile in the profileStore |
| paddy@160 | 286 // associated with the Context and disassociates them from the Profile. |
| paddy@160 | 287 func (c Context) RemoveLoginsByProfile(profile uuid.ID) error { |
| paddy@160 | 288 if c.profiles == nil { |
| paddy@160 | 289 return ErrNoProfileStore |
| paddy@160 | 290 } |
| paddy@160 | 291 return c.profiles.removeLoginsByProfile(profile) |
| paddy@160 | 292 } |
| paddy@160 | 293 |
| paddy@57 | 294 // RecordLoginUse sets the LastUsed property of the Login specified in the profileStore associated with |
| paddy@57 | 295 // the Context to the value passed in as when. |
| paddy@69 | 296 func (c Context) RecordLoginUse(value string, when time.Time) error { |
| paddy@50 | 297 if c.profiles == nil { |
| paddy@50 | 298 return ErrNoProfileStore |
| paddy@50 | 299 } |
| paddy@69 | 300 return c.profiles.recordLoginUse(value, when) |
| paddy@50 | 301 } |
| paddy@50 | 302 |
| paddy@57 | 303 // ListLogins returns a slice of up to num Logins associated with the specified Profile from the profileStore |
| paddy@57 | 304 // associated with the Context, skipping offset Profiles. |
| paddy@50 | 305 func (c Context) ListLogins(profile uuid.ID, num, offset int) ([]Login, error) { |
| paddy@50 | 306 if c.profiles == nil { |
| paddy@50 | 307 return []Login{}, ErrNoProfileStore |
| paddy@50 | 308 } |
| paddy@57 | 309 return c.profiles.listLogins(profile, num, offset) |
| paddy@50 | 310 } |
| paddy@50 | 311 |
| paddy@57 | 312 // GetToken returns the Token specified from the tokenStore associated with the Context. |
| paddy@57 | 313 // If refresh is true, the token input should be compared against the refresh tokens, not the |
| paddy@57 | 314 // access tokens. |
| paddy@50 | 315 func (c Context) GetToken(token string, refresh bool) (Token, error) { |
| paddy@50 | 316 if c.tokens == nil { |
| paddy@50 | 317 return Token{}, ErrNoTokenStore |
| paddy@50 | 318 } |
| paddy@57 | 319 return c.tokens.getToken(token, refresh) |
| paddy@50 | 320 } |
| paddy@50 | 321 |
| paddy@57 | 322 // SaveToken stores the passed Token in the tokenStore associated with the Context. |
| paddy@50 | 323 func (c Context) SaveToken(token Token) error { |
| paddy@50 | 324 if c.tokens == nil { |
| paddy@50 | 325 return ErrNoTokenStore |
| paddy@50 | 326 } |
| paddy@57 | 327 return c.tokens.saveToken(token) |
| paddy@50 | 328 } |
| paddy@50 | 329 |
| paddy@93 | 330 // RevokeToken revokes the Token identfied by the passed token string from the tokenStore associated |
| paddy@93 | 331 // with the context. If refresh is true, the token input should be compared against the refresh tokens, |
| paddy@93 | 332 // not the access tokens. |
| paddy@93 | 333 func (c Context) RevokeToken(token string, refresh bool) error { |
| paddy@93 | 334 if c.tokens == nil { |
| paddy@93 | 335 return ErrNoTokenStore |
| paddy@93 | 336 } |
| paddy@93 | 337 return c.tokens.revokeToken(token, refresh) |
| paddy@93 | 338 } |
| paddy@93 | 339 |
| paddy@162 | 340 // RevokeTokensByProfileID revokes the Tokens associated with the Profile identified by the passed ID in |
| paddy@162 | 341 // the tokenStore associated with the Context. |
| paddy@162 | 342 func (c Context) RevokeTokensByProfileID(profileID uuid.ID) error { |
| paddy@162 | 343 if c.tokens == nil { |
| paddy@162 | 344 return ErrNoTokenStore |
| paddy@162 | 345 } |
| paddy@162 | 346 return c.tokens.revokeTokensByProfileID(profileID) |
| paddy@162 | 347 } |
| paddy@162 | 348 |
| paddy@57 | 349 // GetTokensByProfileID returns a slice of up to num Tokens with a ProfileID that matches the specified |
| paddy@57 | 350 // profileID from the tokenStore associated with the Context, skipping offset Tokens. |
| paddy@50 | 351 func (c Context) GetTokensByProfileID(profileID uuid.ID, num, offset int) ([]Token, error) { |
| paddy@50 | 352 if c.tokens == nil { |
| paddy@50 | 353 return []Token{}, ErrNoTokenStore |
| paddy@50 | 354 } |
| paddy@57 | 355 return c.tokens.getTokensByProfileID(profileID, num, offset) |
| paddy@50 | 356 } |
| paddy@69 | 357 |
| paddy@69 | 358 // CreateSession stores the passed Session in the sessionStore associated with the Context. |
| paddy@69 | 359 func (c Context) CreateSession(session Session) error { |
| paddy@69 | 360 if c.sessions == nil { |
| paddy@69 | 361 return ErrNoSessionStore |
| paddy@69 | 362 } |
| paddy@69 | 363 return c.sessions.createSession(session) |
| paddy@69 | 364 } |
| paddy@69 | 365 |
| paddy@69 | 366 // GetSession returns the Session specified from the sessionStore associated with the Context. |
| paddy@69 | 367 func (c Context) GetSession(id string) (Session, error) { |
| paddy@69 | 368 if c.sessions == nil { |
| paddy@69 | 369 return Session{}, ErrNoSessionStore |
| paddy@69 | 370 } |
| paddy@69 | 371 return c.sessions.getSession(id) |
| paddy@69 | 372 } |
| paddy@69 | 373 |
| paddy@159 | 374 // TerminateSession sets the Session identified by the passed ID as inactive in the sessionStore assocated |
| paddy@159 | 375 // with the Context. |
| paddy@159 | 376 func (c Context) TerminateSession(id string) error { |
| paddy@159 | 377 if c.sessions == nil { |
| paddy@159 | 378 return ErrNoSessionStore |
| paddy@159 | 379 } |
| paddy@159 | 380 return c.sessions.terminateSession(id) |
| paddy@159 | 381 } |
| paddy@159 | 382 |
| paddy@162 | 383 // TerminateSessionsByProfile sets the Sessions associated with the passed Profile ID as inactive in the |
| paddy@162 | 384 // sessionStore associated with the Context. |
| paddy@162 | 385 func (c Context) TerminateSessionsByProfile(profile uuid.ID) error { |
| paddy@162 | 386 if c.sessions == nil { |
| paddy@162 | 387 return ErrNoSessionStore |
| paddy@162 | 388 } |
| paddy@162 | 389 return c.sessions.terminateSessionsByProfile(profile) |
| paddy@162 | 390 } |
| paddy@162 | 391 |
| paddy@69 | 392 // RemoveSession removes the Session identified by the passed ID from the sessionStore associated with |
| paddy@69 | 393 // the Context. |
| paddy@69 | 394 func (c Context) RemoveSession(id string) error { |
| paddy@69 | 395 if c.sessions == nil { |
| paddy@69 | 396 return ErrNoSessionStore |
| paddy@69 | 397 } |
| paddy@69 | 398 return c.sessions.removeSession(id) |
| paddy@69 | 399 } |
| paddy@69 | 400 |
| paddy@69 | 401 // ListSessions returns a slice of up to num Sessions from the sessionStore associated with the Context, |
| paddy@69 | 402 // ordered by the date they were created, descending. If before.IsZero() returns false, only Sessions |
| paddy@69 | 403 // that were created before that time will be returned. If profile is not nil, only Sessions belonging to |
| paddy@69 | 404 // that Profile will be returned. |
| paddy@69 | 405 func (c Context) ListSessions(profile uuid.ID, before time.Time, num int64) ([]Session, error) { |
| paddy@116 | 406 if c.sessions == nil { |
| paddy@69 | 407 return []Session{}, ErrNoSessionStore |
| paddy@69 | 408 } |
| paddy@69 | 409 return c.sessions.listSessions(profile, before, num) |
| paddy@69 | 410 } |
| paddy@134 | 411 |
| paddy@134 | 412 func (c Context) CreateScopes(scopes []Scope) error { |
| paddy@134 | 413 if c.scopes == nil { |
| paddy@134 | 414 return ErrNoScopeStore |
| paddy@134 | 415 } |
| paddy@134 | 416 return c.scopes.createScopes(scopes) |
| paddy@134 | 417 } |
| paddy@134 | 418 |
| paddy@134 | 419 func (c Context) GetScopes(ids []string) ([]Scope, error) { |
| paddy@134 | 420 if c.scopes == nil { |
| paddy@134 | 421 return []Scope{}, ErrNoScopeStore |
| paddy@134 | 422 } |
| paddy@134 | 423 return c.scopes.getScopes(ids) |
| paddy@134 | 424 } |
| paddy@134 | 425 |
| paddy@152 | 426 func (c Context) UpdateScope(id string, change ScopeChange) error { |
| paddy@134 | 427 if c.scopes == nil { |
| paddy@152 | 428 return ErrNoScopeStore |
| paddy@134 | 429 } |
| paddy@152 | 430 return c.scopes.updateScope(id, change) |
| paddy@134 | 431 } |
| paddy@134 | 432 |
| paddy@134 | 433 func (c Context) RemoveScopes(ids []string) error { |
| paddy@134 | 434 if c.scopes == nil { |
| paddy@134 | 435 return ErrNoScopeStore |
| paddy@134 | 436 } |
| paddy@134 | 437 return c.scopes.removeScopes(ids) |
| paddy@134 | 438 } |
| paddy@134 | 439 |
| paddy@134 | 440 func (c Context) ListScopes() ([]Scope, error) { |
| paddy@134 | 441 if c.scopes == nil { |
| paddy@134 | 442 return []Scope{}, ErrNoScopeStore |
| paddy@134 | 443 } |
| paddy@134 | 444 return c.scopes.listScopes() |
| paddy@134 | 445 } |