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
     1.1 --- a/authcode_postgres.go	Sat Apr 11 19:07:26 2015 -0400
     1.2 +++ b/authcode_postgres.go	Sun Apr 19 23:18:26 2015 -0400
     1.3 @@ -1,19 +1,11 @@
     1.4  package auth
     1.5  
     1.6  import (
     1.7 +	"code.secondbit.org/uuid.hg"
     1.8  	"github.com/lib/pq"
     1.9  	"github.com/secondbit/pan"
    1.10  )
    1.11  
    1.12 -type authCodeScope struct {
    1.13 -	Code  string
    1.14 -	Scope string
    1.15 -}
    1.16 -
    1.17 -func (acs authCodeScope) GetSQLTableName() string {
    1.18 -	return "authorization_codes_scopes"
    1.19 -}
    1.20 -
    1.21  func (ac AuthorizationCode) GetSQLTableName() string {
    1.22  	return "authorization_codes"
    1.23  }
    1.24 @@ -27,19 +19,6 @@
    1.25  	return query.FlushExpressions(" ")
    1.26  }
    1.27  
    1.28 -func (p *postgres) getAuthorizationCodeScopesSQL(codes []string) *pan.Query {
    1.29 -	var acs authCodeScope
    1.30 -	fields, _ := pan.GetFields(acs)
    1.31 -	codesI := make([]interface{}, len(codes))
    1.32 -	for pos, code := range codes {
    1.33 -		codesI[pos] = code
    1.34 -	}
    1.35 -	query := pan.New(pan.POSTGRES, "SELECT "+pan.QueryList(fields)+" FROM "+pan.GetTableName(acs))
    1.36 -	query.IncludeWhere()
    1.37 -	query.Include(pan.GetUnquotedColumn(acs, "Code")+" IN ("+pan.VariableList(len(codesI))+")", codesI...)
    1.38 -	return query.FlushExpressions(" ")
    1.39 -}
    1.40 -
    1.41  func (p *postgres) getAuthorizationCode(code string) (AuthorizationCode, error) {
    1.42  	query := p.getAuthorizationCodeSQL(code)
    1.43  	rows, err := p.db.Query(query.String(), query.Args...)
    1.44 @@ -61,22 +40,6 @@
    1.45  	if !found {
    1.46  		return ac, ErrAuthorizationCodeNotFound
    1.47  	}
    1.48 -	query = p.getAuthorizationCodeScopesSQL([]string{code})
    1.49 -	rows, err = p.db.Query(query.String(), query.Args...)
    1.50 -	if err != nil {
    1.51 -		return ac, err
    1.52 -	}
    1.53 -	for rows.Next() {
    1.54 -		var acs authCodeScope
    1.55 -		err = pan.Unmarshal(rows, &acs)
    1.56 -		if err != nil {
    1.57 -			return ac, err
    1.58 -		}
    1.59 -		ac.Scopes = append(ac.Scopes, acs.Scope)
    1.60 -	}
    1.61 -	if err = rows.Err(); err != nil {
    1.62 -		return ac, err
    1.63 -	}
    1.64  	return ac, nil
    1.65  }
    1.66  
    1.67 @@ -89,34 +52,12 @@
    1.68  	return query.FlushExpressions(" ")
    1.69  }
    1.70  
    1.71 -func (p *postgres) saveAuthorizationCodeScopesSQL(authCodeScopes []authCodeScope) *pan.Query {
    1.72 -	fields, _ := pan.GetFields(authCodeScopes[0])
    1.73 -	query := pan.New(pan.POSTGRES, "INSERT INTO "+pan.GetTableName(authCodeScopes[0]))
    1.74 -	query.Include("(" + pan.QueryList(fields) + ")")
    1.75 -	query.Include("VALUES")
    1.76 -	query.FlushExpressions(" ")
    1.77 -	for _, acs := range authCodeScopes {
    1.78 -		_, values := pan.GetFields(acs)
    1.79 -		query.Include("("+pan.VariableList(len(values))+")", values...)
    1.80 -	}
    1.81 -	return query.FlushExpressions(", ")
    1.82 -}
    1.83 -
    1.84  func (p *postgres) saveAuthorizationCode(authCode AuthorizationCode) error {
    1.85  	query := p.saveAuthorizationCodeSQL(authCode)
    1.86  	_, err := p.db.Exec(query.String(), query.Args...)
    1.87  	if e, ok := err.(*pq.Error); ok && e.Constraint == "authorization_codes_pkey" {
    1.88  		err = ErrAuthorizationCodeAlreadyExists
    1.89  	}
    1.90 -	if err != nil || len(authCode.Scopes) < 1 {
    1.91 -		return err
    1.92 -	}
    1.93 -	var acs []authCodeScope
    1.94 -	for _, scope := range authCode.Scopes {
    1.95 -		acs = append(acs, authCodeScope{Code: authCode.Code, Scope: scope})
    1.96 -	}
    1.97 -	query = p.saveAuthorizationCodeScopesSQL(acs)
    1.98 -	_, err = p.db.Exec(query.String(), query.Args...)
    1.99  	return err
   1.100  }
   1.101  
   1.102 @@ -128,14 +69,6 @@
   1.103  	return query.FlushExpressions(" ")
   1.104  }
   1.105  
   1.106 -func (p *postgres) deleteAuthorizationCodeScopesSQL(code string) *pan.Query {
   1.107 -	var acs authCodeScope
   1.108 -	query := pan.New(pan.POSTGRES, "DELETE FROM "+pan.GetTableName(acs))
   1.109 -	query.IncludeWhere()
   1.110 -	query.Include(pan.GetUnquotedColumn(acs, "Code")+" = ?", code)
   1.111 -	return query.FlushExpressions(" ")
   1.112 -}
   1.113 -
   1.114  func (p *postgres) deleteAuthorizationCode(code string) error {
   1.115  	query := p.deleteAuthorizationCodeSQL(code)
   1.116  	res, err := p.db.Exec(query.String(), query.Args...)
   1.117 @@ -149,9 +82,31 @@
   1.118  	if rows == 0 {
   1.119  		return ErrAuthorizationCodeNotFound
   1.120  	}
   1.121 -	query = p.deleteAuthorizationCodeScopesSQL(code)
   1.122 -	_, err = p.db.Exec(query.String(), query.Args...)
   1.123 -	return err
   1.124 +	return nil
   1.125 +}
   1.126 +
   1.127 +func (p *postgres) deleteAuthorizationCodesByProfileIDSQL(profileID uuid.ID) *pan.Query {
   1.128 +	var authCode AuthorizationCode
   1.129 +	query := pan.New(pan.POSTGRES, "DELETE FROM "+pan.GetTableName(authCode))
   1.130 +	query.IncludeWhere()
   1.131 +	query.Include(pan.GetUnquotedColumn(authCode, "ProfileID")+" = ?", profileID)
   1.132 +	return query.FlushExpressions(" ")
   1.133 +}
   1.134 +
   1.135 +func (p *postgres) deleteAuthorizationCodesByProfileID(profileID uuid.ID) error {
   1.136 +	query := p.deleteAuthorizationCodesByProfileIDSQL(profileID)
   1.137 +	res, err := p.db.Exec(query.String(), query.Args...)
   1.138 +	if err != nil {
   1.139 +		return err
   1.140 +	}
   1.141 +	rows, err := res.RowsAffected()
   1.142 +	if err != nil {
   1.143 +		return err
   1.144 +	}
   1.145 +	if rows == 0 {
   1.146 +		return ErrProfileNotFound
   1.147 +	}
   1.148 +	return nil
   1.149  }
   1.150  
   1.151  func (p *postgres) useAuthorizationCodeSQL(code string) *pan.Query {