auth

Paddy 2015-05-17 Parent:581c60f8dd23

170:bdb83e88e1da Go to Latest

auth/token_postgres.go

Instantiate a login verification handler. When starting up the authd binary, get our login verification handler set up. We're going to use environment variables to detect if NSQ is configured. If it is, that'll be used. Otherwise, fall back on logging to stdout.

History
paddy@155 1 package auth
paddy@155 2
paddy@155 3 import (
paddy@155 4 "code.secondbit.org/uuid.hg"
paddy@155 5
paddy@155 6 "github.com/lib/pq"
paddy@155 7 "github.com/secondbit/pan"
paddy@155 8 )
paddy@155 9
paddy@155 10 func (t Token) GetSQLTableName() string {
paddy@155 11 return "tokens"
paddy@155 12 }
paddy@155 13
paddy@155 14 func (p *postgres) getTokenSQL(token string, refresh bool) *pan.Query {
paddy@155 15 var t Token
paddy@155 16 fields, _ := pan.GetFields(t)
paddy@155 17 query := pan.New(pan.POSTGRES, "SELECT "+pan.QueryList(fields)+" FROM "+pan.GetTableName(t))
paddy@155 18 query.IncludeWhere()
paddy@155 19 if !refresh {
paddy@155 20 query.Include(pan.GetUnquotedColumn(t, "AccessToken")+" = ?", token)
paddy@155 21 } else {
paddy@155 22 query.Include(pan.GetUnquotedColumn(t, "RefreshToken")+" = ?", token)
paddy@155 23 }
paddy@155 24 return query.FlushExpressions(" ")
paddy@155 25 }
paddy@155 26
paddy@155 27 func (p *postgres) getToken(token string, refresh bool) (Token, error) {
paddy@155 28 query := p.getTokenSQL(token, refresh)
paddy@155 29 rows, err := p.db.Query(query.String(), query.Args...)
paddy@155 30 if err != nil {
paddy@155 31 return Token{}, err
paddy@155 32 }
paddy@155 33 var t Token
paddy@155 34 var found bool
paddy@155 35 for rows.Next() {
paddy@155 36 err := pan.Unmarshal(rows, &t)
paddy@155 37 if err != nil {
paddy@155 38 return t, err
paddy@155 39 }
paddy@155 40 found = true
paddy@155 41 }
paddy@155 42 if err = rows.Err(); err != nil {
paddy@155 43 return t, err
paddy@155 44 }
paddy@155 45 if !found {
paddy@155 46 return t, ErrTokenNotFound
paddy@155 47 }
paddy@155 48 return t, nil
paddy@155 49 }
paddy@155 50
paddy@155 51 func (p *postgres) saveTokenSQL(token Token) *pan.Query {
paddy@155 52 fields, values := pan.GetFields(token)
paddy@155 53 query := pan.New(pan.POSTGRES, "INSERT INTO "+pan.GetTableName(token))
paddy@155 54 query.Include("(" + pan.QueryList(fields) + ")")
paddy@155 55 query.Include("VALUES")
paddy@155 56 query.Include("("+pan.VariableList(len(values))+")", values...)
paddy@155 57 return query.FlushExpressions(" ")
paddy@155 58 }
paddy@155 59
paddy@155 60 func (p *postgres) saveToken(token Token) error {
paddy@155 61 query := p.saveTokenSQL(token)
paddy@155 62 _, err := p.db.Exec(query.String(), query.Args...)
paddy@155 63 if e, ok := err.(*pq.Error); ok && e.Constraint == "tokens_pkey" {
paddy@155 64 err = ErrTokenAlreadyExists
paddy@155 65 }
paddy@155 66 if err != nil || len(token.Scopes) < 1 {
paddy@155 67 return err
paddy@155 68 }
paddy@155 69 return err
paddy@155 70 }
paddy@155 71
paddy@168 72 func (p *postgres) revokeTokenSQL(token string) *pan.Query {
paddy@155 73 var t Token
paddy@155 74 query := pan.New(pan.POSTGRES, "UPDATE "+pan.GetTableName(t)+" SET ")
paddy@155 75 query.Include(pan.GetUnquotedColumn(t, "Revoked")+" = ?", true)
paddy@155 76 query.IncludeWhere()
paddy@168 77 query.Include(pan.GetUnquotedColumn(t, "RefreshToken")+" = ?", token)
paddy@155 78 return query.FlushExpressions(" ")
paddy@155 79 }
paddy@155 80
paddy@168 81 func (p *postgres) revokeToken(token string) error {
paddy@168 82 query := p.revokeTokenSQL(token)
paddy@155 83 res, err := p.db.Exec(query.String(), query.Args...)
paddy@155 84 if err != nil {
paddy@155 85 return err
paddy@155 86 }
paddy@155 87 rows, err := res.RowsAffected()
paddy@155 88 if err != nil {
paddy@155 89 return err
paddy@155 90 }
paddy@155 91 if rows == 0 {
paddy@155 92 return ErrTokenNotFound
paddy@155 93 }
paddy@155 94 return nil
paddy@155 95 }
paddy@155 96
paddy@162 97 func (p *postgres) revokeTokensByProfileIDSQL(profileID uuid.ID) *pan.Query {
paddy@162 98 var t Token
paddy@162 99 query := pan.New(pan.POSTGRES, "UPDATE "+pan.GetTableName(t)+" SET ")
paddy@162 100 query.Include(pan.GetUnquotedColumn(t, "Revoked")+" = ?", true)
paddy@162 101 query.IncludeWhere()
paddy@162 102 query.Include(pan.GetUnquotedColumn(t, "ProfileID")+" = ?", profileID)
paddy@162 103 return query.FlushExpressions(" ")
paddy@162 104 }
paddy@162 105
paddy@162 106 func (p *postgres) revokeTokensByProfileID(profileID uuid.ID) error {
paddy@162 107 query := p.revokeTokensByProfileIDSQL(profileID)
paddy@162 108 res, err := p.db.Exec(query.String(), query.Args...)
paddy@162 109 if err != nil {
paddy@162 110 return err
paddy@162 111 }
paddy@162 112 rows, err := res.RowsAffected()
paddy@162 113 if err != nil {
paddy@162 114 return err
paddy@162 115 }
paddy@162 116 if rows == 0 {
paddy@162 117 return ErrProfileNotFound
paddy@162 118 }
paddy@162 119 return nil
paddy@162 120 }
paddy@162 121
paddy@164 122 func (p *postgres) revokeTokensByClientIDSQL(clientID uuid.ID) *pan.Query {
paddy@164 123 var t Token
paddy@164 124 query := pan.New(pan.POSTGRES, "UPDATE "+pan.GetTableName(t)+" SET ")
paddy@164 125 query.Include(pan.GetUnquotedColumn(t, "Revoked")+" = ?", true)
paddy@164 126 query.IncludeWhere()
paddy@164 127 query.Include(pan.GetUnquotedColumn(t, "ClientID")+" = ?", clientID)
paddy@164 128 return query.FlushExpressions(" ")
paddy@164 129 }
paddy@164 130
paddy@164 131 func (p *postgres) revokeTokensByClientID(clientID uuid.ID) error {
paddy@164 132 query := p.revokeTokensByClientIDSQL(clientID)
paddy@164 133 res, err := p.db.Exec(query.String(), query.Args...)
paddy@164 134 if err != nil {
paddy@164 135 return err
paddy@164 136 }
paddy@164 137 rows, err := res.RowsAffected()
paddy@164 138 if err != nil {
paddy@164 139 return err
paddy@164 140 }
paddy@164 141 if rows == 0 {
paddy@164 142 return ErrClientNotFound
paddy@164 143 }
paddy@164 144 return nil
paddy@164 145 }
paddy@164 146
paddy@155 147 func (p *postgres) getTokensByProfileIDSQL(profileID uuid.ID, num, offset int) *pan.Query {
paddy@155 148 var token Token
paddy@155 149 fields, _ := pan.GetFields(token)
paddy@155 150 query := pan.New(pan.POSTGRES, "SELECT "+pan.QueryList(fields)+" FROM "+pan.GetTableName(token))
paddy@155 151 query.IncludeWhere()
paddy@155 152 query.Include(pan.GetUnquotedColumn(token, "ProfileID")+" = ?", profileID)
paddy@155 153 query.IncludeLimit(int64(num))
paddy@155 154 query.IncludeOffset(int64(offset))
paddy@155 155 return query.FlushExpressions(" ")
paddy@155 156 }
paddy@155 157
paddy@155 158 func (p *postgres) getTokensByProfileID(profileID uuid.ID, num, offset int) ([]Token, error) {
paddy@155 159 query := p.getTokensByProfileIDSQL(profileID, num, offset)
paddy@155 160 rows, err := p.db.Query(query.String(), query.Args...)
paddy@155 161 if err != nil {
paddy@155 162 return []Token{}, err
paddy@155 163 }
paddy@155 164 var tokens []Token
paddy@155 165 var tokenIDs []string
paddy@155 166 for rows.Next() {
paddy@155 167 var token Token
paddy@155 168 err = pan.Unmarshal(rows, &token)
paddy@155 169 if err != nil {
paddy@155 170 return tokens, err
paddy@155 171 }
paddy@155 172 tokens = append(tokens, token)
paddy@155 173 tokenIDs = append(tokenIDs, token.AccessToken)
paddy@155 174 }
paddy@155 175 if err = rows.Err(); err != nil {
paddy@155 176 return tokens, err
paddy@155 177 }
paddy@155 178 return tokens, nil
paddy@155 179 }