auth

Paddy 2014-11-02 Parent:b3cd7765a7c8 Child:42bc3e44f4fe

63:dd75d24475c0 Go to Latest

auth/context.go

Turn our TODO into a BUG. Lack of CSRF protection is most decidedly a bug, so let's list it as such.

History
1 package auth
3 import (
4 "html/template"
5 "io"
6 "log"
7 "time"
9 "code.secondbit.org/uuid"
10 )
12 // Context wraps the different storage interfaces and should
13 // be used as the main point of interaction for the data storage
14 // layer.
15 type Context struct {
16 template *template.Template
17 clients clientStore
18 grants grantStore
19 profiles profileStore
20 tokens tokenStore
21 }
23 // Render uses the HTML templates associated with the Context to render the
24 // template specified by name to out using data to fill any template variables.
25 func (c Context) Render(out io.Writer, name string, data interface{}) {
26 if c.template == nil {
27 log.Println("No template set on Context, can't render anything!")
28 return
29 }
30 err := c.template.ExecuteTemplate(out, name, data)
31 if err != nil {
32 log.Println("Error executing template", name, ":", err)
33 }
34 }
36 // GetClient returns a single Client by its ID from the
37 // clientStore associated with the Context.
38 func (c Context) GetClient(id uuid.ID) (Client, error) {
39 if c.clients == nil {
40 return Client{}, ErrNoClientStore
41 }
42 return c.clients.getClient(id)
43 }
45 // SaveClient stores the passed Client in the clientStore
46 // associated with the Context.
47 func (c Context) SaveClient(client Client) error {
48 if c.clients == nil {
49 return ErrNoClientStore
50 }
51 return c.clients.saveClient(client)
52 }
54 // UpdateClient applies the specified ClientChange to the Client
55 // with the specified ID in the clientStore associated with the
56 // Context.
57 func (c Context) UpdateClient(id uuid.ID, change ClientChange) error {
58 if c.clients == nil {
59 return ErrNoClientStore
60 }
61 return c.clients.updateClient(id, change)
62 }
64 // DeleteClient removes the client with the specified ID from the
65 // clientStore associated with the Context.
66 func (c Context) DeleteClient(id uuid.ID) error {
67 if c.clients == nil {
68 return ErrNoClientStore
69 }
70 return c.clients.deleteClient(id)
71 }
73 // ListClientsByOwner returns a slice of up to num Clients, starting at offset (inclusive)
74 // that have the specified OwnerID in the clientStore associated with the Context.
75 func (c Context) ListClientsByOwner(ownerID uuid.ID, num, offset int) ([]Client, error) {
76 if c.clients == nil {
77 return []Client{}, ErrNoClientStore
78 }
79 return c.clients.listClientsByOwner(ownerID, num, offset)
80 }
82 // AddEndpoint stores the specified Endpoint in the clientStore associated with the Context,
83 // and associates the newly-stored Endpoint with the Client specified by the passed ID.
84 func (c Context) AddEndpoint(client uuid.ID, endpoint Endpoint) error {
85 if c.clients == nil {
86 return ErrNoClientStore
87 }
88 return c.clients.addEndpoint(client, endpoint)
89 }
91 // RemoveEndpoint deletes the Endpoint with the specified ID from the clientStore associated
92 // with the Context, and disassociates the Endpoint from the specified Client.
93 func (c Context) RemoveEndpoint(client, endpoint uuid.ID) error {
94 if c.clients == nil {
95 return ErrNoClientStore
96 }
97 return c.clients.removeEndpoint(client, endpoint)
98 }
100 // CheckEndpoint finds Endpoints in the clientStore associated with the Context that belong
101 // to the Client specified by the passed ID and match the URI passed. URI matches must be
102 // performed according to RFC 3986 Section 6.
103 func (c Context) CheckEndpoint(client uuid.ID, URI string) (bool, error) {
104 if c.clients == nil {
105 return false, ErrNoClientStore
106 }
107 return c.clients.checkEndpoint(client, URI)
108 }
110 // ListEndpoints finds Endpoints in the clientStore associated with the Context that belong
111 // to the Client specified by the passed ID. It returns up to num endpoints, starting at offset,
112 // exclusive.
113 func (c Context) ListEndpoints(client uuid.ID, num, offset int) ([]Endpoint, error) {
114 if c.clients == nil {
115 return []Endpoint{}, ErrNoClientStore
116 }
117 return c.clients.listEndpoints(client, num, offset)
118 }
120 // CountEndpoints returns the number of Endpoints the are associated with the Client specified by the
121 // passed ID in the clientStore associated with the Context.
122 func (c Context) CountEndpoints(client uuid.ID) (int64, error) {
123 if c.clients == nil {
124 return 0, ErrNoClientStore
125 }
126 return c.clients.countEndpoints(client)
127 }
129 // GetGrant returns the Grant specified by the provided code from the grantStore associated with the
130 // Context.
131 func (c Context) GetGrant(code string) (Grant, error) {
132 if c.grants == nil {
133 return Grant{}, ErrNoGrantStore
134 }
135 return c.grants.getGrant(code)
136 }
138 // SaveGrant stores the passed Grant in the grantStore associated with the Context.
139 func (c Context) SaveGrant(grant Grant) error {
140 if c.grants == nil {
141 return ErrNoGrantStore
142 }
143 return c.grants.saveGrant(grant)
144 }
146 // DeleteGrant removes the Grant specified by the provided code from the grantStore associated with
147 // the Context.
148 func (c Context) DeleteGrant(code string) error {
149 if c.grants == nil {
150 return ErrNoGrantStore
151 }
152 return c.grants.deleteGrant(code)
153 }
155 // GetProfileByID returns the Profile specified by the provided ID from the profileStore associated with
156 // the Context.
157 func (c Context) GetProfileByID(id uuid.ID) (Profile, error) {
158 if c.profiles == nil {
159 return Profile{}, ErrNoProfileStore
160 }
161 return c.profiles.getProfileByID(id)
162 }
164 // GetProfileByLogin returns the Profile associated with the specified Login from the profileStore associated
165 // with the Context.
166 func (c Context) GetProfileByLogin(loginType, value string) (Profile, error) {
167 if c.profiles == nil {
168 return Profile{}, ErrNoProfileStore
169 }
170 return c.profiles.getProfileByLogin(loginType, value)
171 }
173 // SaveProfile inserts the passed Profile into the profileStore associated with the Context.
174 func (c Context) SaveProfile(profile Profile) error {
175 if c.profiles == nil {
176 return ErrNoProfileStore
177 }
178 return c.profiles.saveProfile(profile)
179 }
181 // UpdateProfile applies the supplied ProfileChange to the Profile that matches the specified ID
182 // in the profileStore associated with the Context.
183 func (c Context) UpdateProfile(id uuid.ID, change ProfileChange) error {
184 if c.profiles == nil {
185 return ErrNoProfileStore
186 }
187 return c.profiles.updateProfile(id, change)
188 }
190 // UpdateProfiles applies the supplied BulkProfileChange to every Profile that matches one of the
191 // specified IDs in the profileStore associated with the Context.
192 func (c Context) UpdateProfiles(ids []uuid.ID, change BulkProfileChange) error {
193 if c.profiles == nil {
194 return ErrNoProfileStore
195 }
196 return c.profiles.updateProfiles(ids, change)
197 }
199 // DeleteProfile removes the Profile specified by the passed ID from the profileStore associated
200 // with the Context.
201 func (c Context) DeleteProfile(id uuid.ID) error {
202 if c.profiles == nil {
203 return ErrNoProfileStore
204 }
205 return c.profiles.deleteProfile(id)
206 }
208 // AddLogin stores the passed Login in the profileStore associated with the Context. It also associates
209 // the newly-created Login with the Orofile in login.ProfileID.
210 func (c Context) AddLogin(login Login) error {
211 if c.profiles == nil {
212 return ErrNoProfileStore
213 }
214 return c.profiles.addLogin(login)
215 }
217 // RemoveLogin removes the specified Login from the profileStore associated with the Context, provided
218 // the Login has a ProfileID property that matches the profile ID passed in. It also disassociates the
219 // deleted Login from the Profile in login.ProfileID.
220 func (c Context) RemoveLogin(loginType, value string, profile uuid.ID) error {
221 if c.profiles == nil {
222 return ErrNoProfileStore
223 }
224 return c.profiles.removeLogin(loginType, value, profile)
225 }
227 // RecordLoginUse sets the LastUsed property of the Login specified in the profileStore associated with
228 // the Context to the value passed in as when.
229 func (c Context) RecordLoginUse(loginType, value string, when time.Time) error {
230 if c.profiles == nil {
231 return ErrNoProfileStore
232 }
233 return c.profiles.recordLoginUse(loginType, value, when)
234 }
236 // ListLogins returns a slice of up to num Logins associated with the specified Profile from the profileStore
237 // associated with the Context, skipping offset Profiles.
238 func (c Context) ListLogins(profile uuid.ID, num, offset int) ([]Login, error) {
239 if c.profiles == nil {
240 return []Login{}, ErrNoProfileStore
241 }
242 return c.profiles.listLogins(profile, num, offset)
243 }
245 // GetToken returns the Token specified from the tokenStore associated with the Context.
246 // If refresh is true, the token input should be compared against the refresh tokens, not the
247 // access tokens.
248 func (c Context) GetToken(token string, refresh bool) (Token, error) {
249 if c.tokens == nil {
250 return Token{}, ErrNoTokenStore
251 }
252 return c.tokens.getToken(token, refresh)
253 }
255 // SaveToken stores the passed Token in the tokenStore associated with the Context.
256 func (c Context) SaveToken(token Token) error {
257 if c.tokens == nil {
258 return ErrNoTokenStore
259 }
260 return c.tokens.saveToken(token)
261 }
263 // RemoveToken removes the Token identified by the passed token string from the tokenStore associated
264 // with the Context.
265 func (c Context) RemoveToken(token string) error {
266 if c.tokens == nil {
267 return ErrNoTokenStore
268 }
269 return c.tokens.removeToken(token)
270 }
272 // GetTokensByProfileID returns a slice of up to num Tokens with a ProfileID that matches the specified
273 // profileID from the tokenStore associated with the Context, skipping offset Tokens.
274 func (c Context) GetTokensByProfileID(profileID uuid.ID, num, offset int) ([]Token, error) {
275 if c.tokens == nil {
276 return []Token{}, ErrNoTokenStore
277 }
278 return c.tokens.getTokensByProfileID(profileID, num, offset)
279 }