auth

Paddy 2015-04-07 Child:73e12d5a1124

156:2809016184f6 Go to Latest

auth/authcode_postgres.go

Implement postgres version of authCodeStore. Create an authCodeStore that keeps data in Postgres. Again, we run into the problem where Scopes can't be stored in Postgres arrays, as discussed in 762953f6a7f2. I wish we could do better, but for now, it will suffice. We also added the postgres authCodeStore to our slice of authCodeStores to test when the correct environment variables are present. Wrote initialization SQL for the tables required by the postgres authCodeStore. Added SQL to the SQL script that empties our database, to properly empty our new tables.

History
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/authcode_postgres.go	Tue Apr 07 02:51:13 2015 -0400
     1.3 @@ -0,0 +1,180 @@
     1.4 +package auth
     1.5 +
     1.6 +import (
     1.7 +	"github.com/lib/pq"
     1.8 +	"github.com/secondbit/pan"
     1.9 +)
    1.10 +
    1.11 +type authCodeScope struct {
    1.12 +	Code  string
    1.13 +	Scope string
    1.14 +}
    1.15 +
    1.16 +func (acs authCodeScope) GetSQLTableName() string {
    1.17 +	return "authorization_codes_scopes"
    1.18 +}
    1.19 +
    1.20 +func (ac AuthorizationCode) GetSQLTableName() string {
    1.21 +	return "authorization_codes"
    1.22 +}
    1.23 +
    1.24 +func (p *postgres) getAuthorizationCodeSQL(code string) *pan.Query {
    1.25 +	var ac AuthorizationCode
    1.26 +	fields, _ := pan.GetFields(ac)
    1.27 +	query := pan.New(pan.POSTGRES, "SELECT "+pan.QueryList(fields)+" FROM "+pan.GetTableName(ac))
    1.28 +	query.IncludeWhere()
    1.29 +	query.Include(pan.GetUnquotedColumn(ac, "Code")+" = ?", code)
    1.30 +	return query.FlushExpressions(" ")
    1.31 +}
    1.32 +
    1.33 +func (p *postgres) getAuthorizationCodeScopesSQL(codes []string) *pan.Query {
    1.34 +	var acs authCodeScope
    1.35 +	fields, _ := pan.GetFields(acs)
    1.36 +	codesI := make([]interface{}, len(codes))
    1.37 +	for pos, code := range codes {
    1.38 +		codesI[pos] = code
    1.39 +	}
    1.40 +	query := pan.New(pan.POSTGRES, "SELECT "+pan.QueryList(fields)+" FROM "+pan.GetTableName(acs))
    1.41 +	query.IncludeWhere()
    1.42 +	query.Include(pan.GetUnquotedColumn(acs, "Code")+" IN ("+pan.VariableList(len(codesI))+")", codesI...)
    1.43 +	return query.FlushExpressions(" ")
    1.44 +}
    1.45 +
    1.46 +func (p *postgres) getAuthorizationCode(code string) (AuthorizationCode, error) {
    1.47 +	query := p.getAuthorizationCodeSQL(code)
    1.48 +	rows, err := p.db.Query(query.String(), query.Args...)
    1.49 +	if err != nil {
    1.50 +		return AuthorizationCode{}, err
    1.51 +	}
    1.52 +	var ac AuthorizationCode
    1.53 +	var found bool
    1.54 +	for rows.Next() {
    1.55 +		err := pan.Unmarshal(rows, &ac)
    1.56 +		if err != nil {
    1.57 +			return ac, err
    1.58 +		}
    1.59 +		found = true
    1.60 +	}
    1.61 +	if err = rows.Err(); err != nil {
    1.62 +		return ac, err
    1.63 +	}
    1.64 +	if !found {
    1.65 +		return ac, ErrAuthorizationCodeNotFound
    1.66 +	}
    1.67 +	query = p.getAuthorizationCodeScopesSQL([]string{code})
    1.68 +	rows, err = p.db.Query(query.String(), query.Args...)
    1.69 +	if err != nil {
    1.70 +		return ac, err
    1.71 +	}
    1.72 +	for rows.Next() {
    1.73 +		var acs authCodeScope
    1.74 +		err = pan.Unmarshal(rows, &acs)
    1.75 +		if err != nil {
    1.76 +			return ac, err
    1.77 +		}
    1.78 +		ac.Scopes = append(ac.Scopes, acs.Scope)
    1.79 +	}
    1.80 +	if err = rows.Err(); err != nil {
    1.81 +		return ac, err
    1.82 +	}
    1.83 +	return ac, nil
    1.84 +}
    1.85 +
    1.86 +func (p *postgres) saveAuthorizationCodeSQL(authCode AuthorizationCode) *pan.Query {
    1.87 +	fields, values := pan.GetFields(authCode)
    1.88 +	query := pan.New(pan.POSTGRES, "INSERT INTO "+pan.GetTableName(authCode))
    1.89 +	query.Include("(" + pan.QueryList(fields) + ")")
    1.90 +	query.Include("VALUES")
    1.91 +	query.Include("("+pan.VariableList(len(values))+")", values...)
    1.92 +	return query.FlushExpressions(" ")
    1.93 +}
    1.94 +
    1.95 +func (p *postgres) saveAuthorizationCodeScopesSQL(authCodeScopes []authCodeScope) *pan.Query {
    1.96 +	fields, _ := pan.GetFields(authCodeScopes[0])
    1.97 +	query := pan.New(pan.POSTGRES, "INSERT INTO "+pan.GetTableName(authCodeScopes[0]))
    1.98 +	query.Include("(" + pan.QueryList(fields) + ")")
    1.99 +	query.Include("VALUES")
   1.100 +	query.FlushExpressions(" ")
   1.101 +	for _, acs := range authCodeScopes {
   1.102 +		_, values := pan.GetFields(acs)
   1.103 +		query.Include("("+pan.VariableList(len(values))+")", values...)
   1.104 +	}
   1.105 +	return query.FlushExpressions(", ")
   1.106 +}
   1.107 +
   1.108 +func (p *postgres) saveAuthorizationCode(authCode AuthorizationCode) error {
   1.109 +	query := p.saveAuthorizationCodeSQL(authCode)
   1.110 +	_, err := p.db.Exec(query.String(), query.Args...)
   1.111 +	if e, ok := err.(*pq.Error); ok && e.Constraint == "authorization_codes_pkey" {
   1.112 +		err = ErrAuthorizationCodeAlreadyExists
   1.113 +	}
   1.114 +	if err != nil || len(authCode.Scopes) < 1 {
   1.115 +		return err
   1.116 +	}
   1.117 +	var acs []authCodeScope
   1.118 +	for _, scope := range authCode.Scopes {
   1.119 +		acs = append(acs, authCodeScope{Code: authCode.Code, Scope: scope})
   1.120 +	}
   1.121 +	query = p.saveAuthorizationCodeScopesSQL(acs)
   1.122 +	_, err = p.db.Exec(query.String(), query.Args...)
   1.123 +	return err
   1.124 +}
   1.125 +
   1.126 +func (p *postgres) deleteAuthorizationCodeSQL(code string) *pan.Query {
   1.127 +	var authCode AuthorizationCode
   1.128 +	query := pan.New(pan.POSTGRES, "DELETE FROM "+pan.GetTableName(authCode))
   1.129 +	query.IncludeWhere()
   1.130 +	query.Include(pan.GetUnquotedColumn(authCode, "Code")+" = ?", code)
   1.131 +	return query.FlushExpressions(" ")
   1.132 +}
   1.133 +
   1.134 +func (p *postgres) deleteAuthorizationCodeScopesSQL(code string) *pan.Query {
   1.135 +	var acs authCodeScope
   1.136 +	query := pan.New(pan.POSTGRES, "DELETE FROM "+pan.GetTableName(acs))
   1.137 +	query.IncludeWhere()
   1.138 +	query.Include(pan.GetUnquotedColumn(acs, "Code")+" = ?", code)
   1.139 +	return query.FlushExpressions(" ")
   1.140 +}
   1.141 +
   1.142 +func (p *postgres) deleteAuthorizationCode(code string) error {
   1.143 +	query := p.deleteAuthorizationCodeSQL(code)
   1.144 +	res, err := p.db.Exec(query.String(), query.Args...)
   1.145 +	if err != nil {
   1.146 +		return err
   1.147 +	}
   1.148 +	rows, err := res.RowsAffected()
   1.149 +	if err != nil {
   1.150 +		return err
   1.151 +	}
   1.152 +	if rows == 0 {
   1.153 +		return ErrAuthorizationCodeNotFound
   1.154 +	}
   1.155 +	query = p.deleteAuthorizationCodeScopesSQL(code)
   1.156 +	_, err = p.db.Exec(query.String(), query.Args...)
   1.157 +	return err
   1.158 +}
   1.159 +
   1.160 +func (p *postgres) useAuthorizationCodeSQL(code string) *pan.Query {
   1.161 +	var authCode AuthorizationCode
   1.162 +	query := pan.New(pan.POSTGRES, "UPDATE "+pan.GetTableName(authCode)+" SET ")
   1.163 +	query.Include(pan.GetUnquotedColumn(authCode, "Used")+" = ?", true)
   1.164 +	query.IncludeWhere()
   1.165 +	query.Include(pan.GetUnquotedColumn(authCode, "Code")+" = ?", code)
   1.166 +	return query.FlushExpressions(" ")
   1.167 +}
   1.168 +
   1.169 +func (p *postgres) useAuthorizationCode(code string) error {
   1.170 +	query := p.useAuthorizationCodeSQL(code)
   1.171 +	res, err := p.db.Exec(query.String(), query.Args...)
   1.172 +	if err != nil {
   1.173 +		return err
   1.174 +	}
   1.175 +	rows, err := res.RowsAffected()
   1.176 +	if err != nil {
   1.177 +		return err
   1.178 +	}
   1.179 +	if rows == 0 {
   1.180 +		return ErrAuthorizationCodeNotFound
   1.181 +	}
   1.182 +	return nil
   1.183 +}