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