auth
163:73e12d5a1124 Browse Files
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.
authcode.go authcode_postgres.go authcode_test.go client.go context.go oauth2.go oauth2_test.go profile.go scope.go scope_postgres.go session.go sql/postgres_empty.sql sql/postgres_init.sql token.go token_postgres.go token_test.go
1.1 --- a/authcode.go Sat Apr 11 19:07:26 2015 -0400 1.2 +++ b/authcode.go Sun Apr 19 23:18:26 2015 -0400 1.3 @@ -37,7 +37,7 @@ 1.4 Created time.Time 1.5 ExpiresIn int32 1.6 ClientID uuid.ID 1.7 - Scopes []string `sql_column:"-"` 1.8 + Scopes Scopes 1.9 RedirectURI string 1.10 State string 1.11 ProfileID uuid.ID 1.12 @@ -48,6 +48,7 @@ 1.13 getAuthorizationCode(code string) (AuthorizationCode, error) 1.14 saveAuthorizationCode(authCode AuthorizationCode) error 1.15 deleteAuthorizationCode(code string) error 1.16 + deleteAuthorizationCodesByProfileID(profileID uuid.ID) error 1.17 useAuthorizationCode(code string) error 1.18 } 1.19 1.20 @@ -83,6 +84,24 @@ 1.21 return nil 1.22 } 1.23 1.24 +func (m *memstore) deleteAuthorizationCodesByProfileID(profileID uuid.ID) error { 1.25 + m.authCodeLock.Lock() 1.26 + defer m.authCodeLock.Unlock() 1.27 + var codes []string 1.28 + for _, code := range m.authCodes { 1.29 + if code.ProfileID.Equal(profileID) { 1.30 + codes = append(codes, code.Code) 1.31 + } 1.32 + } 1.33 + if len(codes) < 1 { 1.34 + return ErrProfileNotFound 1.35 + } 1.36 + for _, code := range codes { 1.37 + delete(m.authCodes, code) 1.38 + } 1.39 + return nil 1.40 +} 1.41 + 1.42 func (m *memstore) useAuthorizationCode(code string) error { 1.43 m.authCodeLock.Lock() 1.44 defer m.authCodeLock.Unlock() 1.45 @@ -95,7 +114,7 @@ 1.46 return nil 1.47 } 1.48 1.49 -func authCodeGrantValidate(w http.ResponseWriter, r *http.Request, context Context) (scopes []string, profileID uuid.ID, valid bool) { 1.50 +func authCodeGrantValidate(w http.ResponseWriter, r *http.Request, context Context) (scopes Scopes, profileID uuid.ID, valid bool) { 1.51 enc := json.NewEncoder(w) 1.52 code := r.PostFormValue("code") 1.53 if code == "" {
2.1 --- a/authcode_postgres.go Sat Apr 11 19:07:26 2015 -0400 2.2 +++ b/authcode_postgres.go Sun Apr 19 23:18:26 2015 -0400 2.3 @@ -1,19 +1,11 @@ 2.4 package auth 2.5 2.6 import ( 2.7 + "code.secondbit.org/uuid.hg" 2.8 "github.com/lib/pq" 2.9 "github.com/secondbit/pan" 2.10 ) 2.11 2.12 -type authCodeScope struct { 2.13 - Code string 2.14 - Scope string 2.15 -} 2.16 - 2.17 -func (acs authCodeScope) GetSQLTableName() string { 2.18 - return "authorization_codes_scopes" 2.19 -} 2.20 - 2.21 func (ac AuthorizationCode) GetSQLTableName() string { 2.22 return "authorization_codes" 2.23 } 2.24 @@ -27,19 +19,6 @@ 2.25 return query.FlushExpressions(" ") 2.26 } 2.27 2.28 -func (p *postgres) getAuthorizationCodeScopesSQL(codes []string) *pan.Query { 2.29 - var acs authCodeScope 2.30 - fields, _ := pan.GetFields(acs) 2.31 - codesI := make([]interface{}, len(codes)) 2.32 - for pos, code := range codes { 2.33 - codesI[pos] = code 2.34 - } 2.35 - query := pan.New(pan.POSTGRES, "SELECT "+pan.QueryList(fields)+" FROM "+pan.GetTableName(acs)) 2.36 - query.IncludeWhere() 2.37 - query.Include(pan.GetUnquotedColumn(acs, "Code")+" IN ("+pan.VariableList(len(codesI))+")", codesI...) 2.38 - return query.FlushExpressions(" ") 2.39 -} 2.40 - 2.41 func (p *postgres) getAuthorizationCode(code string) (AuthorizationCode, error) { 2.42 query := p.getAuthorizationCodeSQL(code) 2.43 rows, err := p.db.Query(query.String(), query.Args...) 2.44 @@ -61,22 +40,6 @@ 2.45 if !found { 2.46 return ac, ErrAuthorizationCodeNotFound 2.47 } 2.48 - query = p.getAuthorizationCodeScopesSQL([]string{code}) 2.49 - rows, err = p.db.Query(query.String(), query.Args...) 2.50 - if err != nil { 2.51 - return ac, err 2.52 - } 2.53 - for rows.Next() { 2.54 - var acs authCodeScope 2.55 - err = pan.Unmarshal(rows, &acs) 2.56 - if err != nil { 2.57 - return ac, err 2.58 - } 2.59 - ac.Scopes = append(ac.Scopes, acs.Scope) 2.60 - } 2.61 - if err = rows.Err(); err != nil { 2.62 - return ac, err 2.63 - } 2.64 return ac, nil 2.65 } 2.66 2.67 @@ -89,34 +52,12 @@ 2.68 return query.FlushExpressions(" ") 2.69 } 2.70 2.71 -func (p *postgres) saveAuthorizationCodeScopesSQL(authCodeScopes []authCodeScope) *pan.Query { 2.72 - fields, _ := pan.GetFields(authCodeScopes[0]) 2.73 - query := pan.New(pan.POSTGRES, "INSERT INTO "+pan.GetTableName(authCodeScopes[0])) 2.74 - query.Include("(" + pan.QueryList(fields) + ")") 2.75 - query.Include("VALUES") 2.76 - query.FlushExpressions(" ") 2.77 - for _, acs := range authCodeScopes { 2.78 - _, values := pan.GetFields(acs) 2.79 - query.Include("("+pan.VariableList(len(values))+")", values...) 2.80 - } 2.81 - return query.FlushExpressions(", ") 2.82 -} 2.83 - 2.84 func (p *postgres) saveAuthorizationCode(authCode AuthorizationCode) error { 2.85 query := p.saveAuthorizationCodeSQL(authCode) 2.86 _, err := p.db.Exec(query.String(), query.Args...) 2.87 if e, ok := err.(*pq.Error); ok && e.Constraint == "authorization_codes_pkey" { 2.88 err = ErrAuthorizationCodeAlreadyExists 2.89 } 2.90 - if err != nil || len(authCode.Scopes) < 1 { 2.91 - return err 2.92 - } 2.93 - var acs []authCodeScope 2.94 - for _, scope := range authCode.Scopes { 2.95 - acs = append(acs, authCodeScope{Code: authCode.Code, Scope: scope}) 2.96 - } 2.97 - query = p.saveAuthorizationCodeScopesSQL(acs) 2.98 - _, err = p.db.Exec(query.String(), query.Args...) 2.99 return err 2.100 } 2.101 2.102 @@ -128,14 +69,6 @@ 2.103 return query.FlushExpressions(" ") 2.104 } 2.105 2.106 -func (p *postgres) deleteAuthorizationCodeScopesSQL(code string) *pan.Query { 2.107 - var acs authCodeScope 2.108 - query := pan.New(pan.POSTGRES, "DELETE FROM "+pan.GetTableName(acs)) 2.109 - query.IncludeWhere() 2.110 - query.Include(pan.GetUnquotedColumn(acs, "Code")+" = ?", code) 2.111 - return query.FlushExpressions(" ") 2.112 -} 2.113 - 2.114 func (p *postgres) deleteAuthorizationCode(code string) error { 2.115 query := p.deleteAuthorizationCodeSQL(code) 2.116 res, err := p.db.Exec(query.String(), query.Args...) 2.117 @@ -149,9 +82,31 @@ 2.118 if rows == 0 { 2.119 return ErrAuthorizationCodeNotFound 2.120 } 2.121 - query = p.deleteAuthorizationCodeScopesSQL(code) 2.122 - _, err = p.db.Exec(query.String(), query.Args...) 2.123 - return err 2.124 + return nil 2.125 +} 2.126 + 2.127 +func (p *postgres) deleteAuthorizationCodesByProfileIDSQL(profileID uuid.ID) *pan.Query { 2.128 + var authCode AuthorizationCode 2.129 + query := pan.New(pan.POSTGRES, "DELETE FROM "+pan.GetTableName(authCode)) 2.130 + query.IncludeWhere() 2.131 + query.Include(pan.GetUnquotedColumn(authCode, "ProfileID")+" = ?", profileID) 2.132 + return query.FlushExpressions(" ") 2.133 +} 2.134 + 2.135 +func (p *postgres) deleteAuthorizationCodesByProfileID(profileID uuid.ID) error { 2.136 + query := p.deleteAuthorizationCodesByProfileIDSQL(profileID) 2.137 + res, err := p.db.Exec(query.String(), query.Args...) 2.138 + if err != nil { 2.139 + return err 2.140 + } 2.141 + rows, err := res.RowsAffected() 2.142 + if err != nil { 2.143 + return err 2.144 + } 2.145 + if rows == 0 { 2.146 + return ErrProfileNotFound 2.147 + } 2.148 + return nil 2.149 } 2.150 2.151 func (p *postgres) useAuthorizationCodeSQL(code string) *pan.Query {
3.1 --- a/authcode_test.go Sat Apr 11 19:07:26 2015 -0400 3.2 +++ b/authcode_test.go Sun Apr 19 23:18:26 2015 -0400 3.3 @@ -69,7 +69,7 @@ 3.4 Created: time.Now().Round(time.Millisecond), 3.5 ExpiresIn: 180, 3.6 ClientID: uuid.NewID(), 3.7 - Scopes: []string{"scope"}, 3.8 + Scopes: stringsToScopes([]string{"scope"}), 3.9 RedirectURI: "redirectURI", 3.10 State: "state", 3.11 } 3.12 @@ -161,7 +161,7 @@ 3.13 Created: time.Now().Round(time.Millisecond), 3.14 ExpiresIn: 180, 3.15 ClientID: uuid.NewID(), 3.16 - Scopes: []string{"scope"}, 3.17 + Scopes: stringsToScopes([]string{"scope"}), 3.18 RedirectURI: "redirectURI", 3.19 State: "state", 3.20 } 3.21 @@ -343,7 +343,7 @@ 3.22 Created: time.Now().Round(time.Millisecond), 3.23 ExpiresIn: 180, 3.24 ClientID: uuid.NewID(), 3.25 - Scopes: []string{"scope"}, 3.26 + Scopes: stringsToScopes([]string{"scope"}), 3.27 RedirectURI: "redirectURI", 3.28 State: "state", 3.29 }
4.1 --- a/client.go Sat Apr 11 19:07:26 2015 -0400 4.2 +++ b/client.go Sun Apr 19 23:18:26 2015 -0400 4.3 @@ -1032,8 +1032,8 @@ 4.4 encode(w, r, http.StatusCreated, resp) 4.5 } 4.6 4.7 -func clientCredentialsValidate(w http.ResponseWriter, r *http.Request, context Context) (scopes []string, profileID uuid.ID, valid bool) { 4.8 - scopes = strings.Split(r.PostFormValue("scope"), " ") 4.9 +func clientCredentialsValidate(w http.ResponseWriter, r *http.Request, context Context) (scopes Scopes, profileID uuid.ID, valid bool) { 4.10 + scopes = stringsToScopes(strings.Split(r.PostFormValue("scope"), " ")) 4.11 valid = true 4.12 return 4.13 }
5.1 --- a/context.go Sat Apr 11 19:07:26 2015 -0400 5.2 +++ b/context.go Sun Apr 19 23:18:26 2015 -0400 5.3 @@ -193,6 +193,15 @@ 5.4 return c.authCodes.deleteAuthorizationCode(code) 5.5 } 5.6 5.7 +// DeleteAuthorizationCodesByProfileID removes the AuthorizationCodes associated with the Profile specified by the provided ID from the 5.8 +// authorizationCodeStore associated with the Context. 5.9 +func (c Context) DeleteAuthorizationCodesByProfileID(profileID uuid.ID) error { 5.10 + if c.authCodes == nil { 5.11 + return ErrNoAuthorizationCodeStore 5.12 + } 5.13 + return c.authCodes.deleteAuthorizationCodesByProfileID(profileID) 5.14 +} 5.15 + 5.16 // UseAuthorizationCode marks the AuthorizationCode specified by the provided code as used in the authorizationCodeStore associated with 5.17 // the Context. Once an AuthorizationCode is marked as used, its Used property will be set to true when retrieved from the authorizationCodeStore. 5.18 func (c Context) UseAuthorizationCode(code string) error {
6.1 --- a/oauth2.go Sat Apr 11 19:07:26 2015 -0400 6.2 +++ b/oauth2.go Sun Apr 19 23:18:26 2015 -0400 6.3 @@ -68,7 +68,7 @@ 6.4 // The ReturnToken will be called when a token is created and needs to be returned to the client. If it returns true, the token 6.5 // was successfully returned and the Invalidate function will be called asynchronously. 6.6 type GrantType struct { 6.7 - Validate func(w http.ResponseWriter, r *http.Request, context Context) (scopes []string, profileID uuid.ID, valid bool) 6.8 + Validate func(w http.ResponseWriter, r *http.Request, context Context) (scopes Scopes, profileID uuid.ID, valid bool) 6.9 Invalidate func(r *http.Request, context Context) error 6.10 ReturnToken func(w http.ResponseWriter, r *http.Request, token Token, context Context) bool 6.11 AuditString func(r *http.Request) string 6.12 @@ -318,7 +318,7 @@ 6.13 Created: time.Now(), 6.14 ExpiresIn: defaultAuthorizationCodeExpiration, 6.15 ClientID: clientID, 6.16 - Scopes: scopeParams, 6.17 + Scopes: scopes, 6.18 RedirectURI: r.URL.Query().Get("redirect_uri"), 6.19 State: state, 6.20 ProfileID: session.ProfileID, 6.21 @@ -337,7 +337,7 @@ 6.22 CreatedFrom: "implicit", 6.23 ExpiresIn: defaultTokenExpiration, 6.24 TokenType: "bearer", 6.25 - Scopes: scopeParams, 6.26 + Scopes: scopes, 6.27 ProfileID: session.ProfileID, 6.28 ClientID: clientID, 6.29 } 6.30 @@ -351,7 +351,7 @@ 6.31 q.Add("access_token", token.AccessToken) 6.32 q.Add("token_type", token.TokenType) 6.33 q.Add("expires_in", strconv.FormatInt(int64(token.ExpiresIn), 10)) 6.34 - q.Add("scope", strings.Join(token.Scopes, " ")) 6.35 + q.Add("scope", strings.Join(token.Scopes.Strings(), " ")) 6.36 q.Add("state", state) // we wiped out the old values, so we need to set the state again 6.37 fragment = true 6.38 }
7.1 --- a/oauth2_test.go Sat Apr 11 19:07:26 2015 -0400 7.2 +++ b/oauth2_test.go Sun Apr 19 23:18:26 2015 -0400 7.3 @@ -791,7 +791,7 @@ 7.4 Created: time.Now().Round(time.Millisecond), 7.5 ExpiresIn: 600, 7.6 ClientID: client.ID, 7.7 - Scopes: []string{"testscope"}, 7.8 + Scopes: stringsToScopes([]string{"testscope"}), 7.9 RedirectURI: "https://client.secondbit.org/", 7.10 State: "teststate", 7.11 ProfileID: uuid.NewID(),
8.1 --- a/profile.go Sat Apr 11 19:07:26 2015 -0400 8.2 +++ b/profile.go Sun Apr 19 23:18:26 2015 -0400 8.3 @@ -440,7 +440,10 @@ 8.4 if err != nil { 8.5 log.Printf("Error revoking tokens associated with profile %s: %+v\n", profile, err) 8.6 } 8.7 - // BUG(paddy): need to delete all the grants associated with the Profile 8.8 + err = context.DeleteAuthorizationCodesByProfileID(profile) 8.9 + if err != nil { 8.10 + log.Printf("Error deleting authorization codes associated with profile %s: %+v\n", profile, err) 8.11 + } 8.12 // BUG(paddy): need to delete all clients associated with the Profile 8.13 } 8.14
9.1 --- a/scope.go Sat Apr 11 19:07:26 2015 -0400 9.2 +++ b/scope.go Sun Apr 19 23:18:26 2015 -0400 9.3 @@ -27,20 +27,36 @@ 9.4 } 9.5 } 9.6 9.7 -type sortedScopes []Scope 9.8 +type Scopes []Scope 9.9 9.10 -func (s sortedScopes) Len() int { 9.11 +func (s Scopes) Len() int { 9.12 return len(s) 9.13 } 9.14 9.15 -func (s sortedScopes) Swap(i, j int) { 9.16 +func (s Scopes) Swap(i, j int) { 9.17 s[i], s[j] = s[j], s[i] 9.18 } 9.19 9.20 -func (s sortedScopes) Less(i, j int) bool { 9.21 +func (s Scopes) Less(i, j int) bool { 9.22 return s[i].ID < s[j].ID 9.23 } 9.24 9.25 +func (s Scopes) Strings() []string { 9.26 + res := make([]string, len(s)) 9.27 + for pos, scope := range s { 9.28 + res[pos] = scope.ID 9.29 + } 9.30 + return res 9.31 +} 9.32 + 9.33 +func stringsToScopes(s []string) Scopes { 9.34 + res := make(Scopes, len(s)) 9.35 + for pos, scope := range s { 9.36 + res[pos] = Scope{ID: scope} 9.37 + } 9.38 + return res 9.39 +} 9.40 + 9.41 // ScopeChange represents a change to a Scope. 9.42 type ScopeChange struct { 9.43 Name *string 9.44 @@ -86,7 +102,7 @@ 9.45 } 9.46 scopes = append(scopes, scope) 9.47 } 9.48 - sorted := sortedScopes(scopes) 9.49 + sorted := Scopes(scopes) 9.50 sort.Sort(sorted) 9.51 scopes = sorted 9.52 return scopes, nil 9.53 @@ -128,7 +144,7 @@ 9.54 for _, scope := range m.scopes { 9.55 scopes = append(scopes, scope) 9.56 } 9.57 - sorted := sortedScopes(scopes) 9.58 + sorted := Scopes(scopes) 9.59 sort.Sort(sorted) 9.60 scopes = sorted 9.61 return scopes, nil
10.1 --- a/scope_postgres.go Sat Apr 11 19:07:26 2015 -0400 10.2 +++ b/scope_postgres.go Sun Apr 19 23:18:26 2015 -0400 10.3 @@ -1,6 +1,8 @@ 10.4 package auth 10.5 10.6 import ( 10.7 + "code.secondbit.org/pqarrays.hg" 10.8 + "database/sql/driver" 10.9 "github.com/lib/pq" 10.10 "github.com/secondbit/pan" 10.11 ) 10.12 @@ -9,6 +11,27 @@ 10.13 return "scopes" 10.14 } 10.15 10.16 +func (s Scopes) Value() (driver.Value, error) { 10.17 + ids := make(pqarrays.StringArray, 0, len(s)) 10.18 + for _, scope := range s { 10.19 + ids = append(ids, scope.ID) 10.20 + } 10.21 + return ids.Value() 10.22 +} 10.23 + 10.24 +func (s *Scopes) Scan(value interface{}) error { 10.25 + *s = (*s)[:0] 10.26 + var ids pqarrays.StringArray 10.27 + err := ids.Scan(value) 10.28 + if err != nil { 10.29 + return err 10.30 + } 10.31 + for _, id := range ids { 10.32 + *s = append(*s, Scope{ID: id}) 10.33 + } 10.34 + return nil 10.35 +} 10.36 + 10.37 func (p *postgres) createScopesSQL(scopes []Scope) *pan.Query { 10.38 fields, _ := pan.GetFields(scopes[0]) 10.39 query := pan.New(pan.POSTGRES, "INSERT INTO "+pan.GetTableName(scopes[0]))
11.1 --- a/session.go Sat Apr 11 19:07:26 2015 -0400 11.2 +++ b/session.go Sun Apr 19 23:18:26 2015 -0400 11.3 @@ -413,11 +413,11 @@ 11.4 encode(w, r, http.StatusOK, response{Sessions: []Session{session}, Errors: errors}) 11.5 } 11.6 11.7 -func credentialsValidate(w http.ResponseWriter, r *http.Request, context Context) (scopes []string, profileID uuid.ID, valid bool) { 11.8 +func credentialsValidate(w http.ResponseWriter, r *http.Request, context Context) (scopes Scopes, profileID uuid.ID, valid bool) { 11.9 enc := json.NewEncoder(w) 11.10 username := r.PostFormValue("username") 11.11 password := r.PostFormValue("password") 11.12 - scopes = strings.Split(r.PostFormValue("scope"), " ") 11.13 + scopes = stringsToScopes(strings.Split(r.PostFormValue("scope"), " ")) 11.14 profile, err := authenticate(username, password, context) 11.15 if err != nil { 11.16 if isAuthError(err) {
12.1 --- a/sql/postgres_empty.sql Sat Apr 11 19:07:26 2015 -0400 12.2 +++ b/sql/postgres_empty.sql Sun Apr 19 23:18:26 2015 -0400 12.3 @@ -5,6 +5,4 @@ 12.4 TRUNCATE scopes; 12.5 TRUNCATE sessions; 12.6 TRUNCATE tokens; 12.7 -TRUNCATE scopes_tokens; 12.8 TRUNCATE authorization_codes; 12.9 -TRUNCATE authorization_codes_scopes;
13.1 --- a/sql/postgres_init.sql Sat Apr 11 19:07:26 2015 -0400 13.2 +++ b/sql/postgres_init.sql Sun Apr 19 23:18:26 2015 -0400 13.3 @@ -68,13 +68,8 @@ 13.4 profile_id VARCHAR(36) NOT NULL, 13.5 client_id VARCHAR(36) NOT NULL, 13.6 revoked BOOLEAN NOT NULL, 13.7 - refresh_revoked BOOLEAN NOT NULL 13.8 -); 13.9 - 13.10 -CREATE TABLE IF NOT EXISTS scopes_tokens ( 13.11 - token VARCHAR(36) NOT NULL, 13.12 - scope VARCHAR(64) NOT NULL, 13.13 - PRIMARY KEY(token, scope) 13.14 + refresh_revoked BOOLEAN NOT NULL, 13.15 + scopes varchar(64)[] NOT NULL 13.16 ); 13.17 13.18 CREATE TABLE IF NOT EXISTS authorization_codes ( 13.19 @@ -85,11 +80,6 @@ 13.20 redirect_uri TEXT NOT NULL, 13.21 state TEXT NOT NULL, 13.22 profile_id VARCHAR(36) NOT NULL, 13.23 - used BOOLEAN NOT NULL 13.24 + used BOOLEAN NOT NULL, 13.25 + scopes varchar(64)[] NOT NULL 13.26 ); 13.27 - 13.28 -CREATE TABLE IF NOT EXISTS authorization_codes_scopes ( 13.29 - code VARCHAR(36) NOT NULL, 13.30 - scope VARCHAR(64) NOT NULL, 13.31 - PRIMARY KEY(code, scope) 13.32 -);
14.1 --- a/token.go Sat Apr 11 19:07:26 2015 -0400 14.2 +++ b/token.go Sun Apr 19 23:18:26 2015 -0400 14.3 @@ -43,7 +43,7 @@ 14.4 CreatedFrom string 14.5 ExpiresIn int32 14.6 TokenType string 14.7 - Scopes []string `sql_column:"-"` 14.8 + Scopes Scopes 14.9 ProfileID uuid.ID 14.10 ClientID uuid.ID 14.11 Revoked bool 14.12 @@ -156,7 +156,7 @@ 14.13 return tokens, nil 14.14 } 14.15 14.16 -func refreshTokenValidate(w http.ResponseWriter, r *http.Request, context Context) (scopes []string, profileID uuid.ID, valid bool) { 14.17 +func refreshTokenValidate(w http.ResponseWriter, r *http.Request, context Context) (scopes Scopes, profileID uuid.ID, valid bool) { 14.18 enc := json.NewEncoder(w) 14.19 refresh := r.PostFormValue("refresh_token") 14.20 if refresh == "" {
15.1 --- a/token_postgres.go Sat Apr 11 19:07:26 2015 -0400 15.2 +++ b/token_postgres.go Sun Apr 19 23:18:26 2015 -0400 15.3 @@ -7,15 +7,6 @@ 15.4 "github.com/secondbit/pan" 15.5 ) 15.6 15.7 -type tokenScope struct { 15.8 - Token string 15.9 - Scope string 15.10 -} 15.11 - 15.12 -func (t tokenScope) GetSQLTableName() string { 15.13 - return "scopes_tokens" 15.14 -} 15.15 - 15.16 func (t Token) GetSQLTableName() string { 15.17 return "tokens" 15.18 } 15.19 @@ -54,22 +45,6 @@ 15.20 if !found { 15.21 return t, ErrTokenNotFound 15.22 } 15.23 - query = p.getTokenScopesSQL([]string{t.AccessToken}) 15.24 - rows, err = p.db.Query(query.String(), query.Args...) 15.25 - if err != nil { 15.26 - return t, err 15.27 - } 15.28 - for rows.Next() { 15.29 - var ts tokenScope 15.30 - err = pan.Unmarshal(rows, &ts) 15.31 - if err != nil { 15.32 - return t, err 15.33 - } 15.34 - t.Scopes = append(t.Scopes, ts.Scope) 15.35 - } 15.36 - if err = rows.Err(); err != nil { 15.37 - return t, err 15.38 - } 15.39 return t, nil 15.40 } 15.41 15.42 @@ -82,19 +57,6 @@ 15.43 return query.FlushExpressions(" ") 15.44 } 15.45 15.46 -func (p *postgres) saveTokenScopesSQL(ts []tokenScope) *pan.Query { 15.47 - fields, _ := pan.GetFields(ts[0]) 15.48 - query := pan.New(pan.POSTGRES, "INSERT INTO "+pan.GetTableName(ts[0])) 15.49 - query.Include("(" + pan.QueryList(fields) + ")") 15.50 - query.Include("VALUES") 15.51 - query.FlushExpressions(" ") 15.52 - for _, t := range ts { 15.53 - _, values := pan.GetFields(t) 15.54 - query.Include("("+pan.VariableList(len(values))+")", values...) 15.55 - } 15.56 - return query.FlushExpressions(", ") 15.57 -} 15.58 - 15.59 func (p *postgres) saveToken(token Token) error { 15.60 query := p.saveTokenSQL(token) 15.61 _, err := p.db.Exec(query.String(), query.Args...) 15.62 @@ -104,12 +66,6 @@ 15.63 if err != nil || len(token.Scopes) < 1 { 15.64 return err 15.65 } 15.66 - var ts []tokenScope 15.67 - for _, scope := range token.Scopes { 15.68 - ts = append(ts, tokenScope{Token: token.AccessToken, Scope: scope}) 15.69 - } 15.70 - query = p.saveTokenScopesSQL(ts) 15.71 - _, err = p.db.Exec(query.String(), query.Args...) 15.72 return err 15.73 } 15.74 15.75 @@ -178,19 +134,6 @@ 15.76 return query.FlushExpressions(" ") 15.77 } 15.78 15.79 -func (p *postgres) getTokenScopesSQL(tokens []string) *pan.Query { 15.80 - var t tokenScope 15.81 - fields, _ := pan.GetFields(t) 15.82 - tokensI := make([]interface{}, len(tokens)) 15.83 - for pos, token := range tokens { 15.84 - tokensI[pos] = token 15.85 - } 15.86 - query := pan.New(pan.POSTGRES, "SELECT "+pan.QueryList(fields)+" FROM "+pan.GetTableName(t)) 15.87 - query.IncludeWhere() 15.88 - query.Include(pan.GetUnquotedColumn(t, "Token")+" IN ("+pan.VariableList(len(tokensI))+")", tokensI...) 15.89 - return query.FlushExpressions(" ") 15.90 -} 15.91 - 15.92 func (p *postgres) getTokensByProfileID(profileID uuid.ID, num, offset int) ([]Token, error) { 15.93 query := p.getTokensByProfileIDSQL(profileID, num, offset) 15.94 rows, err := p.db.Query(query.String(), query.Args...) 15.95 @@ -211,29 +154,5 @@ 15.96 if err = rows.Err(); err != nil { 15.97 return tokens, err 15.98 } 15.99 - if len(tokenIDs) < 1 { 15.100 - return tokens, nil 15.101 - } 15.102 - scopes := map[string][]string{} 15.103 - query = p.getTokenScopesSQL(tokenIDs) 15.104 - rows, err = p.db.Query(query.String(), query.Args...) 15.105 - if err != nil { 15.106 - return tokens, err 15.107 - } 15.108 - for rows.Next() { 15.109 - var t tokenScope 15.110 - err = pan.Unmarshal(rows, &t) 15.111 - if err != nil { 15.112 - return tokens, err 15.113 - } 15.114 - scopes[t.Token] = append(scopes[t.Token], t.Scope) 15.115 - } 15.116 - if err = rows.Err(); err != nil { 15.117 - return tokens, err 15.118 - } 15.119 - for pos, token := range tokens { 15.120 - token.Scopes = scopes[token.AccessToken] 15.121 - tokens[pos] = token 15.122 - } 15.123 return tokens, nil 15.124 }
16.1 --- a/token_test.go Sat Apr 11 19:07:26 2015 -0400 16.2 +++ b/token_test.go Sun Apr 19 23:18:26 2015 -0400 16.3 @@ -64,7 +64,7 @@ 16.4 Created: time.Now().Round(time.Millisecond), 16.5 ExpiresIn: 3600, 16.6 TokenType: "bearer", 16.7 - Scopes: []string{"scope"}, 16.8 + Scopes: stringsToScopes([]string{"scope"}), 16.9 ProfileID: uuid.NewID(), 16.10 } 16.11 for _, store := range tokenStores {