auth
auth/scope_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.
| paddy@152 | 1 package auth |
| paddy@152 | 2 |
| paddy@152 | 3 import ( |
| paddy@153 | 4 "github.com/lib/pq" |
| paddy@152 | 5 "github.com/secondbit/pan" |
| paddy@152 | 6 ) |
| paddy@152 | 7 |
| paddy@152 | 8 func (s Scope) GetSQLTableName() string { |
| paddy@152 | 9 return "scopes" |
| paddy@152 | 10 } |
| paddy@152 | 11 |
| paddy@152 | 12 func (p *postgres) createScopesSQL(scopes []Scope) *pan.Query { |
| paddy@152 | 13 fields, _ := pan.GetFields(scopes[0]) |
| paddy@152 | 14 query := pan.New(pan.POSTGRES, "INSERT INTO "+pan.GetTableName(scopes[0])) |
| paddy@152 | 15 query.Include("(" + pan.QueryList(fields) + ")") |
| paddy@152 | 16 query.Include("VALUES") |
| paddy@153 | 17 query.FlushExpressions(" ") |
| paddy@152 | 18 for _, scope := range scopes { |
| paddy@152 | 19 _, values := pan.GetFields(scope) |
| paddy@152 | 20 query.Include("("+pan.VariableList(len(values))+")", values...) |
| paddy@152 | 21 } |
| paddy@153 | 22 return query.FlushExpressions(", ") |
| paddy@152 | 23 } |
| paddy@152 | 24 |
| paddy@152 | 25 func (p *postgres) createScopes(scopes []Scope) error { |
| paddy@152 | 26 if len(scopes) < 1 { |
| paddy@152 | 27 return nil |
| paddy@152 | 28 } |
| paddy@152 | 29 query := p.createScopesSQL(scopes) |
| paddy@152 | 30 _, err := p.db.Exec(query.String(), query.Args...) |
| paddy@153 | 31 if e, ok := err.(*pq.Error); ok && e.Constraint == "scopes_pkey" { |
| paddy@153 | 32 err = ErrScopeAlreadyExists |
| paddy@153 | 33 } |
| paddy@152 | 34 return err |
| paddy@152 | 35 } |
| paddy@152 | 36 |
| paddy@152 | 37 func (p *postgres) getScopesSQL(ids []string) *pan.Query { |
| paddy@152 | 38 var scope Scope |
| paddy@152 | 39 intids := make([]interface{}, len(ids)) |
| paddy@152 | 40 for pos, id := range ids { |
| paddy@152 | 41 intids[pos] = id |
| paddy@152 | 42 } |
| paddy@152 | 43 fields, _ := pan.GetFields(scope) |
| paddy@152 | 44 query := pan.New(pan.POSTGRES, "SELECT "+pan.QueryList(fields)+" FROM "+pan.GetTableName(scope)) |
| paddy@152 | 45 query.IncludeWhere() |
| paddy@152 | 46 query.Include(pan.GetUnquotedColumn(scope, "ID") + " IN") |
| paddy@152 | 47 query.Include("("+pan.VariableList(len(ids))+")", intids...) |
| paddy@152 | 48 return query.FlushExpressions(" ") |
| paddy@152 | 49 } |
| paddy@152 | 50 |
| paddy@152 | 51 func (p *postgres) getScopes(ids []string) ([]Scope, error) { |
| paddy@152 | 52 query := p.getScopesSQL(ids) |
| paddy@152 | 53 rows, err := p.db.Query(query.String(), query.Args...) |
| paddy@152 | 54 if err != nil { |
| paddy@152 | 55 return []Scope{}, err |
| paddy@152 | 56 } |
| paddy@152 | 57 var scopes []Scope |
| paddy@152 | 58 for rows.Next() { |
| paddy@152 | 59 var scope Scope |
| paddy@152 | 60 err := pan.Unmarshal(rows, &scope) |
| paddy@152 | 61 if err != nil { |
| paddy@152 | 62 return scopes, err |
| paddy@152 | 63 } |
| paddy@152 | 64 scopes = append(scopes, scope) |
| paddy@152 | 65 } |
| paddy@152 | 66 if err = rows.Err(); err != nil { |
| paddy@152 | 67 return scopes, err |
| paddy@152 | 68 } |
| paddy@152 | 69 return scopes, nil |
| paddy@152 | 70 } |
| paddy@152 | 71 |
| paddy@152 | 72 func (p *postgres) updateScopeSQL(id string, change ScopeChange) *pan.Query { |
| paddy@152 | 73 var scope Scope |
| paddy@152 | 74 query := pan.New(pan.POSTGRES, "UPDATE "+pan.GetTableName(scope)+" SET ") |
| paddy@152 | 75 query.IncludeIfNotNil(pan.GetUnquotedColumn(scope, "Name")+" = ?", change.Name) |
| paddy@152 | 76 query.IncludeIfNotNil(pan.GetUnquotedColumn(scope, "Description")+" = ?", change.Description) |
| paddy@152 | 77 query.FlushExpressions(", ") |
| paddy@152 | 78 query.IncludeWhere() |
| paddy@152 | 79 query.Include(pan.GetUnquotedColumn(scope, "ID")+" = ?", id) |
| paddy@152 | 80 return query.FlushExpressions(" ") |
| paddy@152 | 81 } |
| paddy@152 | 82 |
| paddy@152 | 83 func (p *postgres) updateScope(id string, change ScopeChange) error { |
| paddy@152 | 84 if change.Empty() { |
| paddy@152 | 85 return nil |
| paddy@152 | 86 } |
| paddy@152 | 87 query := p.updateScopeSQL(id, change) |
| paddy@153 | 88 res, err := p.db.Exec(query.String(), query.Args...) |
| paddy@153 | 89 if err != nil { |
| paddy@153 | 90 return err |
| paddy@153 | 91 } |
| paddy@153 | 92 rows, err := res.RowsAffected() |
| paddy@153 | 93 if err != nil { |
| paddy@153 | 94 return err |
| paddy@153 | 95 } |
| paddy@153 | 96 if rows < 1 { |
| paddy@153 | 97 return ErrScopeNotFound |
| paddy@153 | 98 } |
| paddy@152 | 99 return err |
| paddy@152 | 100 } |
| paddy@152 | 101 |
| paddy@152 | 102 func (p *postgres) removeScopesSQL(ids []string) *pan.Query { |
| paddy@152 | 103 var scope Scope |
| paddy@152 | 104 intids := make([]interface{}, len(ids)) |
| paddy@152 | 105 for pos, id := range ids { |
| paddy@152 | 106 intids[pos] = id |
| paddy@152 | 107 } |
| paddy@152 | 108 query := pan.New(pan.POSTGRES, "DELETE FROM "+pan.GetTableName(scope)) |
| paddy@152 | 109 query.IncludeWhere() |
| paddy@152 | 110 query.Include(pan.GetUnquotedColumn(scope, "ID") + " IN") |
| paddy@152 | 111 query.Include("("+pan.VariableList(len(ids))+")", intids...) |
| paddy@152 | 112 return query.FlushExpressions(" ") |
| paddy@152 | 113 } |
| paddy@152 | 114 |
| paddy@152 | 115 func (p *postgres) removeScopes(ids []string) error { |
| paddy@152 | 116 query := p.removeScopesSQL(ids) |
| paddy@153 | 117 res, err := p.db.Exec(query.String(), query.Args...) |
| paddy@152 | 118 if err != nil { |
| paddy@152 | 119 return err |
| paddy@152 | 120 } |
| paddy@153 | 121 rows, err := res.RowsAffected() |
| paddy@153 | 122 if err != nil { |
| paddy@153 | 123 return err |
| paddy@153 | 124 } |
| paddy@153 | 125 if rows < 1 { |
| paddy@153 | 126 return ErrScopeNotFound |
| paddy@153 | 127 } |
| paddy@152 | 128 return nil |
| paddy@152 | 129 } |
| paddy@152 | 130 |
| paddy@152 | 131 func (p *postgres) listScopesSQL() *pan.Query { |
| paddy@152 | 132 var scope Scope |
| paddy@152 | 133 fields, _ := pan.GetFields(scope) |
| paddy@152 | 134 query := pan.New(pan.POSTGRES, "SELECT "+pan.QueryList(fields)+" FROM "+pan.GetTableName(scope)) |
| paddy@152 | 135 return query.FlushExpressions(" ") |
| paddy@152 | 136 } |
| paddy@152 | 137 |
| paddy@152 | 138 func (p *postgres) listScopes() ([]Scope, error) { |
| paddy@152 | 139 query := p.listScopesSQL() |
| paddy@152 | 140 rows, err := p.db.Query(query.String(), query.Args...) |
| paddy@152 | 141 if err != nil { |
| paddy@152 | 142 return []Scope{}, err |
| paddy@152 | 143 } |
| paddy@152 | 144 var scopes []Scope |
| paddy@152 | 145 for rows.Next() { |
| paddy@152 | 146 var scope Scope |
| paddy@152 | 147 err = pan.Unmarshal(rows, &scope) |
| paddy@152 | 148 if err != nil { |
| paddy@152 | 149 return scopes, err |
| paddy@152 | 150 } |
| paddy@152 | 151 scopes = append(scopes, scope) |
| paddy@152 | 152 } |
| paddy@152 | 153 if err = rows.Err(); err != nil { |
| paddy@152 | 154 return scopes, err |
| paddy@152 | 155 } |
| paddy@152 | 156 return scopes, nil |
| paddy@152 | 157 } |