auth

Paddy 2015-04-11 Parent:5f670aba87b4 Child:cf6c1f05eb21

157:202e991accc2 Go to Latest

auth/session_postgres.go

Wire up the postgres database for authd. Have authd use the AUTH_PG_DB environment variable to detect support for the postgres *Stores, and if postgres is supported, use it. If postgres isn't supported, fall back on the in-memory store. Also create-if-not-exists the test scopes, instead of panicking when the scope already exists.

History
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@154 67 func (p *postgres) removeSessionSQL(id string) *pan.Query {
paddy@154 68 var session Session
paddy@154 69 query := pan.New(pan.POSTGRES, "DELETE FROM "+pan.GetTableName(session))
paddy@154 70 query.IncludeWhere()
paddy@154 71 query.Include(pan.GetUnquotedColumn(session, "ID")+" = ?", id)
paddy@154 72 return query.FlushExpressions(" ")
paddy@154 73 }
paddy@154 74
paddy@154 75 func (p *postgres) removeSession(id string) error {
paddy@154 76 query := p.removeSessionSQL(id)
paddy@154 77 res, err := p.db.Exec(query.String(), query.Args...)
paddy@154 78 if err != nil {
paddy@154 79 return err
paddy@154 80 }
paddy@154 81 rows, err := res.RowsAffected()
paddy@154 82 if err != nil {
paddy@154 83 return err
paddy@154 84 }
paddy@154 85 if rows < 1 {
paddy@154 86 return ErrSessionNotFound
paddy@154 87 }
paddy@154 88 return nil
paddy@154 89 }
paddy@154 90
paddy@154 91 func (p *postgres) listSessionsSQL(profile uuid.ID, before time.Time, num int64) *pan.Query {
paddy@154 92 var session Session
paddy@154 93 fields, _ := pan.GetFields(session)
paddy@154 94 query := pan.New(pan.POSTGRES, "SELECT "+pan.QueryList(fields)+" FROM "+pan.GetTableName(session))
paddy@154 95 query.IncludeWhere()
paddy@154 96 query.Include(pan.GetUnquotedColumn(session, "ProfileID")+" = ?", profile)
paddy@154 97 if !before.IsZero() {
paddy@154 98 query.Include(pan.GetUnquotedColumn(session, "Created")+" < ?", before)
paddy@154 99 }
paddy@154 100 query.FlushExpressions(" AND ")
paddy@154 101 if num > 0 {
paddy@154 102 query.IncludeLimit(num)
paddy@154 103 }
paddy@154 104 return query.FlushExpressions(" ")
paddy@154 105 }
paddy@154 106
paddy@154 107 func (p *postgres) listSessions(profile uuid.ID, before time.Time, num int64) ([]Session, error) {
paddy@154 108 query := p.listSessionsSQL(profile, before, num)
paddy@154 109 rows, err := p.db.Query(query.String(), query.Args...)
paddy@154 110 if err != nil {
paddy@154 111 return []Session{}, err
paddy@154 112 }
paddy@154 113 var sessions []Session
paddy@154 114 for rows.Next() {
paddy@154 115 var session Session
paddy@154 116 err := pan.Unmarshal(rows, &session)
paddy@154 117 if err != nil {
paddy@154 118 return sessions, err
paddy@154 119 }
paddy@154 120 sessions = append(sessions, session)
paddy@154 121 }
paddy@154 122 if err = rows.Err(); err != nil {
paddy@154 123 return sessions, err
paddy@154 124 }
paddy@154 125 return sessions, nil
paddy@154 126 }