auth

Paddy 2015-04-19 Parent:2809016184f6 Child:cf1aef6eb81f

163:73e12d5a1124 Go to Latest

auth/authcode_postgres.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.

History
paddy@156 1 package auth
paddy@156 2
paddy@156 3 import (
paddy@163 4 "code.secondbit.org/uuid.hg"
paddy@156 5 "github.com/lib/pq"
paddy@156 6 "github.com/secondbit/pan"
paddy@156 7 )
paddy@156 8
paddy@156 9 func (ac AuthorizationCode) GetSQLTableName() string {
paddy@156 10 return "authorization_codes"
paddy@156 11 }
paddy@156 12
paddy@156 13 func (p *postgres) getAuthorizationCodeSQL(code string) *pan.Query {
paddy@156 14 var ac AuthorizationCode
paddy@156 15 fields, _ := pan.GetFields(ac)
paddy@156 16 query := pan.New(pan.POSTGRES, "SELECT "+pan.QueryList(fields)+" FROM "+pan.GetTableName(ac))
paddy@156 17 query.IncludeWhere()
paddy@156 18 query.Include(pan.GetUnquotedColumn(ac, "Code")+" = ?", code)
paddy@156 19 return query.FlushExpressions(" ")
paddy@156 20 }
paddy@156 21
paddy@156 22 func (p *postgres) getAuthorizationCode(code string) (AuthorizationCode, error) {
paddy@156 23 query := p.getAuthorizationCodeSQL(code)
paddy@156 24 rows, err := p.db.Query(query.String(), query.Args...)
paddy@156 25 if err != nil {
paddy@156 26 return AuthorizationCode{}, err
paddy@156 27 }
paddy@156 28 var ac AuthorizationCode
paddy@156 29 var found bool
paddy@156 30 for rows.Next() {
paddy@156 31 err := pan.Unmarshal(rows, &ac)
paddy@156 32 if err != nil {
paddy@156 33 return ac, err
paddy@156 34 }
paddy@156 35 found = true
paddy@156 36 }
paddy@156 37 if err = rows.Err(); err != nil {
paddy@156 38 return ac, err
paddy@156 39 }
paddy@156 40 if !found {
paddy@156 41 return ac, ErrAuthorizationCodeNotFound
paddy@156 42 }
paddy@156 43 return ac, nil
paddy@156 44 }
paddy@156 45
paddy@156 46 func (p *postgres) saveAuthorizationCodeSQL(authCode AuthorizationCode) *pan.Query {
paddy@156 47 fields, values := pan.GetFields(authCode)
paddy@156 48 query := pan.New(pan.POSTGRES, "INSERT INTO "+pan.GetTableName(authCode))
paddy@156 49 query.Include("(" + pan.QueryList(fields) + ")")
paddy@156 50 query.Include("VALUES")
paddy@156 51 query.Include("("+pan.VariableList(len(values))+")", values...)
paddy@156 52 return query.FlushExpressions(" ")
paddy@156 53 }
paddy@156 54
paddy@156 55 func (p *postgres) saveAuthorizationCode(authCode AuthorizationCode) error {
paddy@156 56 query := p.saveAuthorizationCodeSQL(authCode)
paddy@156 57 _, err := p.db.Exec(query.String(), query.Args...)
paddy@156 58 if e, ok := err.(*pq.Error); ok && e.Constraint == "authorization_codes_pkey" {
paddy@156 59 err = ErrAuthorizationCodeAlreadyExists
paddy@156 60 }
paddy@156 61 return err
paddy@156 62 }
paddy@156 63
paddy@156 64 func (p *postgres) deleteAuthorizationCodeSQL(code string) *pan.Query {
paddy@156 65 var authCode AuthorizationCode
paddy@156 66 query := pan.New(pan.POSTGRES, "DELETE FROM "+pan.GetTableName(authCode))
paddy@156 67 query.IncludeWhere()
paddy@156 68 query.Include(pan.GetUnquotedColumn(authCode, "Code")+" = ?", code)
paddy@156 69 return query.FlushExpressions(" ")
paddy@156 70 }
paddy@156 71
paddy@156 72 func (p *postgres) deleteAuthorizationCode(code string) error {
paddy@156 73 query := p.deleteAuthorizationCodeSQL(code)
paddy@156 74 res, err := p.db.Exec(query.String(), query.Args...)
paddy@156 75 if err != nil {
paddy@156 76 return err
paddy@156 77 }
paddy@156 78 rows, err := res.RowsAffected()
paddy@156 79 if err != nil {
paddy@156 80 return err
paddy@156 81 }
paddy@156 82 if rows == 0 {
paddy@156 83 return ErrAuthorizationCodeNotFound
paddy@156 84 }
paddy@163 85 return nil
paddy@163 86 }
paddy@163 87
paddy@163 88 func (p *postgres) deleteAuthorizationCodesByProfileIDSQL(profileID uuid.ID) *pan.Query {
paddy@163 89 var authCode AuthorizationCode
paddy@163 90 query := pan.New(pan.POSTGRES, "DELETE FROM "+pan.GetTableName(authCode))
paddy@163 91 query.IncludeWhere()
paddy@163 92 query.Include(pan.GetUnquotedColumn(authCode, "ProfileID")+" = ?", profileID)
paddy@163 93 return query.FlushExpressions(" ")
paddy@163 94 }
paddy@163 95
paddy@163 96 func (p *postgres) deleteAuthorizationCodesByProfileID(profileID uuid.ID) error {
paddy@163 97 query := p.deleteAuthorizationCodesByProfileIDSQL(profileID)
paddy@163 98 res, err := p.db.Exec(query.String(), query.Args...)
paddy@163 99 if err != nil {
paddy@163 100 return err
paddy@163 101 }
paddy@163 102 rows, err := res.RowsAffected()
paddy@163 103 if err != nil {
paddy@163 104 return err
paddy@163 105 }
paddy@163 106 if rows == 0 {
paddy@163 107 return ErrProfileNotFound
paddy@163 108 }
paddy@163 109 return nil
paddy@156 110 }
paddy@156 111
paddy@156 112 func (p *postgres) useAuthorizationCodeSQL(code string) *pan.Query {
paddy@156 113 var authCode AuthorizationCode
paddy@156 114 query := pan.New(pan.POSTGRES, "UPDATE "+pan.GetTableName(authCode)+" SET ")
paddy@156 115 query.Include(pan.GetUnquotedColumn(authCode, "Used")+" = ?", true)
paddy@156 116 query.IncludeWhere()
paddy@156 117 query.Include(pan.GetUnquotedColumn(authCode, "Code")+" = ?", code)
paddy@156 118 return query.FlushExpressions(" ")
paddy@156 119 }
paddy@156 120
paddy@156 121 func (p *postgres) useAuthorizationCode(code string) error {
paddy@156 122 query := p.useAuthorizationCodeSQL(code)
paddy@156 123 res, err := p.db.Exec(query.String(), query.Args...)
paddy@156 124 if err != nil {
paddy@156 125 return err
paddy@156 126 }
paddy@156 127 rows, err := res.RowsAffected()
paddy@156 128 if err != nil {
paddy@156 129 return err
paddy@156 130 }
paddy@156 131 if rows == 0 {
paddy@156 132 return ErrAuthorizationCodeNotFound
paddy@156 133 }
paddy@156 134 return nil
paddy@156 135 }