auth
2015-07-13
Parent:6f473576c6ae
auth/session_postgres.go
Add notes about model events. We need to sensibly trigger events about models, so I left some basic notes about triggering an event when a Profile is created.
| paddy@154 | 1 package auth |
| paddy@154 | 2 |
| paddy@154 | 3 import ( |
| paddy@154 | 4 "time" |
| paddy@154 | 5 |
| paddy@154 | 6 "code.secondbit.org/uuid.hg" |
| paddy@154 | 7 |
| paddy@154 | 8 "github.com/lib/pq" |
| paddy@154 | 9 "github.com/secondbit/pan" |
| paddy@154 | 10 ) |
| paddy@154 | 11 |
| paddy@154 | 12 func (s Session) GetSQLTableName() string { |
| paddy@154 | 13 return "sessions" |
| paddy@154 | 14 } |
| paddy@154 | 15 |
| paddy@154 | 16 func (p *postgres) createSessionSQL(session Session) *pan.Query { |
| paddy@154 | 17 fields, values := pan.GetFields(session) |
| paddy@154 | 18 query := pan.New(pan.POSTGRES, "INSERT INTO "+pan.GetTableName(session)) |
| paddy@154 | 19 query.Include("(" + pan.QueryList(fields) + ")") |
| paddy@154 | 20 query.Include("VALUES") |
| paddy@154 | 21 query.Include("("+pan.VariableList(len(values))+")", values...) |
| paddy@154 | 22 return query.FlushExpressions(" ") |
| paddy@154 | 23 } |
| paddy@154 | 24 |
| paddy@154 | 25 func (p *postgres) createSession(session Session) error { |
| paddy@154 | 26 query := p.createSessionSQL(session) |
| paddy@154 | 27 _, err := p.db.Exec(query.String(), query.Args...) |
| paddy@154 | 28 if e, ok := err.(*pq.Error); ok && e.Constraint == "sessions_pkey" { |
| paddy@154 | 29 err = ErrSessionAlreadyExists |
| paddy@154 | 30 } |
| paddy@154 | 31 return err |
| paddy@154 | 32 } |
| paddy@154 | 33 |
| paddy@154 | 34 func (p *postgres) getSessionSQL(id string) *pan.Query { |
| paddy@154 | 35 var session Session |
| paddy@154 | 36 fields, _ := pan.GetFields(session) |
| paddy@154 | 37 query := pan.New(pan.POSTGRES, "SELECT "+pan.QueryList(fields)+" FROM "+pan.GetTableName(session)) |
| paddy@154 | 38 query.IncludeWhere() |
| paddy@154 | 39 query.Include(pan.GetUnquotedColumn(session, "ID")+" = ?", id) |
| paddy@154 | 40 return query.FlushExpressions(" ") |
| paddy@154 | 41 } |
| paddy@154 | 42 |
| paddy@154 | 43 func (p *postgres) getSession(id string) (Session, error) { |
| paddy@154 | 44 query := p.getSessionSQL(id) |
| paddy@154 | 45 rows, err := p.db.Query(query.String(), query.Args...) |
| paddy@154 | 46 if err != nil { |
| paddy@154 | 47 return Session{}, err |
| paddy@154 | 48 } |
| paddy@154 | 49 var session Session |
| paddy@154 | 50 var found bool |
| paddy@154 | 51 for rows.Next() { |
| paddy@154 | 52 err := pan.Unmarshal(rows, &session) |
| paddy@154 | 53 if err != nil { |
| paddy@154 | 54 return session, err |
| paddy@154 | 55 } |
| paddy@154 | 56 found = true |
| paddy@154 | 57 } |
| paddy@154 | 58 if err = rows.Err(); err != nil { |
| paddy@154 | 59 return session, err |
| paddy@154 | 60 } |
| paddy@154 | 61 if !found { |
| paddy@154 | 62 return session, ErrSessionNotFound |
| paddy@154 | 63 } |
| paddy@154 | 64 return session, nil |
| paddy@154 | 65 } |
| paddy@154 | 66 |
| paddy@159 | 67 func (p *postgres) terminateSessionSQL(id string) *pan.Query { |
| paddy@159 | 68 var session Session |
| paddy@159 | 69 query := pan.New(pan.POSTGRES, "UPDATE "+pan.GetTableName(session)+" SET") |
| paddy@159 | 70 query.Include(pan.GetUnquotedColumn(session, "Active")+" = ?", false) |
| paddy@159 | 71 query.IncludeWhere() |
| paddy@159 | 72 query.Include(pan.GetUnquotedColumn(session, "ID")+" = ?", id) |
| paddy@159 | 73 return query.FlushExpressions(" ") |
| paddy@159 | 74 } |
| paddy@159 | 75 |
| paddy@159 | 76 func (p *postgres) terminateSession(id string) error { |
| paddy@159 | 77 query := p.terminateSessionSQL(id) |
| paddy@159 | 78 res, err := p.db.Exec(query.String(), query.Args...) |
| paddy@159 | 79 if err != nil { |
| paddy@159 | 80 return err |
| paddy@159 | 81 } |
| paddy@159 | 82 rows, err := res.RowsAffected() |
| paddy@159 | 83 if err != nil { |
| paddy@159 | 84 return err |
| paddy@159 | 85 } |
| paddy@159 | 86 if rows < 1 { |
| paddy@159 | 87 return ErrSessionNotFound |
| paddy@159 | 88 } |
| paddy@159 | 89 return nil |
| paddy@159 | 90 } |
| paddy@159 | 91 |
| paddy@162 | 92 func (p *postgres) terminateSessionsByProfileSQL(profile uuid.ID) *pan.Query { |
| paddy@162 | 93 var session Session |
| paddy@162 | 94 query := pan.New(pan.POSTGRES, "UPDATE "+pan.GetTableName(session)+" SET") |
| paddy@162 | 95 query.Include(pan.GetUnquotedColumn(session, "Active")+" = ?", false) |
| paddy@162 | 96 query.IncludeWhere() |
| paddy@162 | 97 query.Include(pan.GetUnquotedColumn(session, "ProfileID")+" = ?", profile) |
| paddy@162 | 98 return query.FlushExpressions(" ") |
| paddy@162 | 99 } |
| paddy@162 | 100 |
| paddy@162 | 101 func (p *postgres) terminateSessionsByProfile(profile uuid.ID) error { |
| paddy@162 | 102 query := p.terminateSessionsByProfileSQL(profile) |
| paddy@162 | 103 res, err := p.db.Exec(query.String(), query.Args...) |
| paddy@162 | 104 if err != nil { |
| paddy@162 | 105 return err |
| paddy@162 | 106 } |
| paddy@162 | 107 rows, err := res.RowsAffected() |
| paddy@162 | 108 if err != nil { |
| paddy@162 | 109 return err |
| paddy@162 | 110 } |
| paddy@162 | 111 if rows < 1 { |
| paddy@162 | 112 return ErrProfileNotFound |
| paddy@162 | 113 } |
| paddy@162 | 114 return nil |
| paddy@162 | 115 } |
| paddy@162 | 116 |
| paddy@154 | 117 func (p *postgres) removeSessionSQL(id string) *pan.Query { |
| paddy@154 | 118 var session Session |
| paddy@154 | 119 query := pan.New(pan.POSTGRES, "DELETE FROM "+pan.GetTableName(session)) |
| paddy@154 | 120 query.IncludeWhere() |
| paddy@154 | 121 query.Include(pan.GetUnquotedColumn(session, "ID")+" = ?", id) |
| paddy@154 | 122 return query.FlushExpressions(" ") |
| paddy@154 | 123 } |
| paddy@154 | 124 |
| paddy@154 | 125 func (p *postgres) removeSession(id string) error { |
| paddy@154 | 126 query := p.removeSessionSQL(id) |
| paddy@154 | 127 res, err := p.db.Exec(query.String(), query.Args...) |
| paddy@154 | 128 if err != nil { |
| paddy@154 | 129 return err |
| paddy@154 | 130 } |
| paddy@154 | 131 rows, err := res.RowsAffected() |
| paddy@154 | 132 if err != nil { |
| paddy@154 | 133 return err |
| paddy@154 | 134 } |
| paddy@154 | 135 if rows < 1 { |
| paddy@154 | 136 return ErrSessionNotFound |
| paddy@154 | 137 } |
| paddy@154 | 138 return nil |
| paddy@154 | 139 } |
| paddy@154 | 140 |
| paddy@154 | 141 func (p *postgres) listSessionsSQL(profile uuid.ID, before time.Time, num int64) *pan.Query { |
| paddy@154 | 142 var session Session |
| paddy@154 | 143 fields, _ := pan.GetFields(session) |
| paddy@154 | 144 query := pan.New(pan.POSTGRES, "SELECT "+pan.QueryList(fields)+" FROM "+pan.GetTableName(session)) |
| paddy@154 | 145 query.IncludeWhere() |
| paddy@154 | 146 query.Include(pan.GetUnquotedColumn(session, "ProfileID")+" = ?", profile) |
| paddy@154 | 147 if !before.IsZero() { |
| paddy@154 | 148 query.Include(pan.GetUnquotedColumn(session, "Created")+" < ?", before) |
| paddy@154 | 149 } |
| paddy@154 | 150 query.FlushExpressions(" AND ") |
| paddy@154 | 151 if num > 0 { |
| paddy@154 | 152 query.IncludeLimit(num) |
| paddy@154 | 153 } |
| paddy@154 | 154 return query.FlushExpressions(" ") |
| paddy@154 | 155 } |
| paddy@154 | 156 |
| paddy@154 | 157 func (p *postgres) listSessions(profile uuid.ID, before time.Time, num int64) ([]Session, error) { |
| paddy@154 | 158 query := p.listSessionsSQL(profile, before, num) |
| paddy@154 | 159 rows, err := p.db.Query(query.String(), query.Args...) |
| paddy@154 | 160 if err != nil { |
| paddy@154 | 161 return []Session{}, err |
| paddy@154 | 162 } |
| paddy@154 | 163 var sessions []Session |
| paddy@154 | 164 for rows.Next() { |
| paddy@154 | 165 var session Session |
| paddy@154 | 166 err := pan.Unmarshal(rows, &session) |
| paddy@154 | 167 if err != nil { |
| paddy@154 | 168 return sessions, err |
| paddy@154 | 169 } |
| paddy@154 | 170 sessions = append(sessions, session) |
| paddy@154 | 171 } |
| paddy@154 | 172 if err = rows.Err(); err != nil { |
| paddy@154 | 173 return sessions, err |
| paddy@154 | 174 } |
| paddy@154 | 175 return sessions, nil |
| paddy@154 | 176 } |