auth

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

155:762953f6a7f2 Go to Latest

auth/session_test.go

Implement postgres version of the tokenStore. Create a postgres implementation for the tokenStore. Note that because pq doesn't support Postgres' array types (see https://github.com/lib/pq/issues/49), we couldn't just store the token.Scopes field as a Postgres array of varchars, which would have been the ideal. Instead, we need a many-to-many table that maps tokens to scopes. This meant we needed a special tokenScope type for our database mapping, and we needed to complicate the token storage/retrieval functions a little bit. It's kind of ugly, I'm not a huge fan of it, and I'd much rather be using the Postgres array types, but... well, here we are. We also added the postgres tokenStore to our slice of tokenStores to test when the correct environment variables are present. We wrote initialization SQL for the tables required by the postgres tokenStore. Also, added a helper script for emptying the test database, because I got tired of doing it by hand. We should be doing that in an automated fashion in the tests themselves, but that would mean extending the *Store interfaces.

History
paddy@77 1 package auth
paddy@77 2
paddy@77 3 import (
paddy@154 4 "os"
paddy@77 5 "testing"
paddy@77 6 "time"
paddy@77 7
paddy@107 8 "code.secondbit.org/uuid.hg"
paddy@77 9 )
paddy@77 10
paddy@154 11 func init() {
paddy@154 12 if os.Getenv("PG_TEST_DB") != "" {
paddy@154 13 p, err := NewPostgres(os.Getenv("PG_TEST_DB"))
paddy@154 14 if err != nil {
paddy@154 15 panic(err)
paddy@154 16 }
paddy@154 17 sessionStores = append(sessionStores, &p)
paddy@154 18 }
paddy@154 19 }
paddy@154 20
paddy@77 21 var sessionStores = []sessionStore{NewMemstore()}
paddy@77 22
paddy@77 23 func compareSessions(session1, session2 Session) (success bool, field string, val1, val2 interface{}) {
paddy@77 24 if session1.ID != session2.ID {
paddy@77 25 return false, "ID", session1.ID, session2.ID
paddy@77 26 }
paddy@77 27 if session1.IP != session2.IP {
paddy@77 28 return false, "IP", session1.IP, session2.IP
paddy@77 29 }
paddy@77 30 if session1.UserAgent != session2.UserAgent {
paddy@77 31 return false, "UserAgent", session1.UserAgent, session2.UserAgent
paddy@77 32 }
paddy@77 33 if !session1.ProfileID.Equal(session2.ProfileID) {
paddy@77 34 return false, "ProfileID", session1.ProfileID, session2.ProfileID
paddy@77 35 }
paddy@77 36 if !session1.Created.Equal(session2.Created) {
paddy@77 37 return false, "Created", session1.Created, session2.Created
paddy@77 38 }
paddy@132 39 if !session1.Expires.Equal(session2.Expires) {
paddy@132 40 return false, "Expires", session1.Expires, session2.Expires
paddy@132 41 }
paddy@77 42 if session1.Login != session2.Login {
paddy@77 43 return false, "Login", session1.Login, session2.Login
paddy@77 44 }
paddy@77 45 if session1.Active != session2.Active {
paddy@77 46 return false, "Active", session1.Active, session2.Active
paddy@77 47 }
paddy@132 48 if session1.CSRFToken != session2.CSRFToken {
paddy@132 49 return false, "CSRFToken", session1.CSRFToken, session2.CSRFToken
paddy@132 50 }
paddy@77 51 return true, "", nil, nil
paddy@77 52 }
paddy@77 53
paddy@77 54 func TestSessionStoreSuccess(t *testing.T) {
paddy@77 55 t.Parallel()
paddy@77 56 session := Session{
paddy@77 57 ID: uuid.NewID().String() + uuid.NewID().String(),
paddy@77 58 IP: "127.0.0.1",
paddy@77 59 UserAgent: "TestRunner",
paddy@77 60 ProfileID: uuid.NewID(),
paddy@149 61 Created: time.Now().Round(time.Millisecond),
paddy@77 62 Login: "test@example.com",
paddy@77 63 Active: true,
paddy@77 64 }
paddy@77 65 for _, store := range sessionStores {
paddy@116 66 context := Context{sessions: store}
paddy@116 67 err := context.CreateSession(session)
paddy@77 68 if err != nil {
paddy@77 69 t.Errorf("Error saving session to %T: %s", store, err)
paddy@77 70 }
paddy@116 71 err = context.CreateSession(session)
paddy@77 72 if err != ErrSessionAlreadyExists {
paddy@77 73 t.Errorf("Expected ErrSessionAlreadyExists from %T, got %s", store, err)
paddy@77 74 }
paddy@116 75 retrieved, err := context.GetSession(session.ID)
paddy@77 76 if err != nil {
paddy@77 77 t.Errorf("Error retrieving session from %T: %s", store, err)
paddy@77 78 }
paddy@77 79 success, field, expectation, result := compareSessions(session, retrieved)
paddy@77 80 if !success {
paddy@77 81 t.Errorf("Expected field %s to be %v, but got %v from %T", field, expectation, result, store)
paddy@77 82 }
paddy@116 83 retrievedList, err := context.ListSessions(session.ProfileID, time.Time{}, 10)
paddy@77 84 if err != nil {
paddy@77 85 t.Errorf("Error retrieving sessions by profile from %T: %s", store, err)
paddy@77 86 }
paddy@77 87 if len(retrievedList) != 1 {
paddy@77 88 t.Errorf("Expected 1 session retrieved by profile from %T, got %d", store, len(retrievedList))
paddy@77 89 }
paddy@77 90 success, field, expectation, result = compareSessions(session, retrievedList[0])
paddy@77 91 if !success {
paddy@77 92 t.Errorf("Expected field %s to be %v, but got %v from %T", field, expectation, result, store)
paddy@77 93 }
paddy@116 94 err = context.RemoveSession(session.ID)
paddy@77 95 if err != nil {
paddy@77 96 t.Errorf("Error removing session from %T: %s", store, err)
paddy@77 97 }
paddy@116 98 retrieved, err = context.GetSession(session.ID)
paddy@77 99 if err != ErrSessionNotFound {
paddy@77 100 t.Errorf("Expected ErrSessionNotFound from %T, got %s", store, err)
paddy@77 101 }
paddy@116 102 retrievedList, err = context.ListSessions(session.ProfileID, time.Time{}, 10)
paddy@77 103 if err != nil {
paddy@77 104 t.Errorf("Error retrieving sessions by profile from %T: %s", store, err)
paddy@77 105 }
paddy@77 106 if len(retrievedList) != 0 {
paddy@77 107 t.Errorf("Expected 0 sessions retrieved by profile from %T, got %d", store, len(retrievedList))
paddy@77 108 }
paddy@116 109 err = context.RemoveSession(session.ID)
paddy@77 110 if err != ErrSessionNotFound {
paddy@77 111 t.Errorf("Expected ErrSessionNotFound from %T, got %s", store, err)
paddy@77 112 }
paddy@77 113 }
paddy@77 114 }
paddy@128 115
paddy@128 116 // BUG(paddy): We need to test the CreateSessionHandler.
paddy@128 117 // BUG(paddy): We need to test the credentialsValidate function.