auth

Paddy 2015-01-05 Parent:c03b5eb3179e Child:da2a0954e8d3

111:224f0610d3e7 Go to Latest

auth/authcode_test.go

Fill in gaps in AuthorizationCodeStore tests, add authCodeGrantValidate tests. Fill in some holes in AuthorizationCodeStore tests (mainly the lack of ProfileID and Used being compared, and the omission of useAuthorizationCode in the TestauthorizationCodeStore test). Start testing the authCodeGrantValidate function, that tests a grant claim made using an AuthorizationCode. Right now, we're only testing that omitting a code yields an invalid_request error.

History
paddy@29 1 package auth
paddy@29 2
paddy@29 3 import (
paddy@111 4 "bytes"
paddy@111 5 "io/ioutil"
paddy@111 6 "net/http"
paddy@111 7 "net/http/httptest"
paddy@111 8 "net/url"
paddy@111 9 "strings"
paddy@29 10 "testing"
paddy@29 11 "time"
paddy@29 12
paddy@107 13 "code.secondbit.org/uuid.hg"
paddy@29 14 )
paddy@29 15
paddy@87 16 var authCodeStores = []authorizationCodeStore{NewMemstore()}
paddy@29 17
paddy@87 18 func compareAuthorizationCodes(authCode1, authCode2 AuthorizationCode) (success bool, field string, authCode1val, authCode2val interface{}) {
paddy@87 19 if authCode1.Code != authCode2.Code {
paddy@87 20 return false, "code", authCode1.Code, authCode2.Code
paddy@34 21 }
paddy@87 22 if !authCode1.Created.Equal(authCode2.Created) {
paddy@87 23 return false, "created", authCode1.Created, authCode2.Created
paddy@34 24 }
paddy@87 25 if authCode1.ExpiresIn != authCode2.ExpiresIn {
paddy@87 26 return false, "expires in", authCode1.ExpiresIn, authCode2.ExpiresIn
paddy@34 27 }
paddy@87 28 if !authCode1.ClientID.Equal(authCode2.ClientID) {
paddy@87 29 return false, "client ID", authCode1.ClientID, authCode2.ClientID
paddy@34 30 }
paddy@87 31 if authCode1.Scope != authCode2.Scope {
paddy@87 32 return false, "scope", authCode1.Scope, authCode2.Scope
paddy@34 33 }
paddy@87 34 if authCode1.RedirectURI != authCode2.RedirectURI {
paddy@87 35 return false, "redirect URI", authCode1.RedirectURI, authCode2.RedirectURI
paddy@34 36 }
paddy@87 37 if authCode1.State != authCode2.State {
paddy@87 38 return false, "state", authCode1.State, authCode2.State
paddy@34 39 }
paddy@111 40 if !authCode1.ProfileID.Equal(authCode2.ProfileID) {
paddy@111 41 return false, "profile ID", authCode1.ProfileID, authCode2.ProfileID
paddy@111 42 }
paddy@111 43 if authCode1.Used != authCode2.Used {
paddy@111 44 return false, "used", authCode1.Used, authCode2.Used
paddy@111 45 }
paddy@34 46 return true, "", nil, nil
paddy@34 47 }
paddy@34 48
paddy@111 49 func TestAuthorizationCodeStore(t *testing.T) {
paddy@36 50 t.Parallel()
paddy@87 51 authCode := AuthorizationCode{
paddy@29 52 Code: "code",
paddy@29 53 Created: time.Now(),
paddy@29 54 ExpiresIn: 180,
paddy@29 55 ClientID: uuid.NewID(),
paddy@29 56 Scope: "scope",
paddy@29 57 RedirectURI: "redirectURI",
paddy@29 58 State: "state",
paddy@29 59 }
paddy@87 60 for _, store := range authCodeStores {
paddy@87 61 err := store.saveAuthorizationCode(authCode)
paddy@29 62 if err != nil {
paddy@87 63 t.Errorf("Error saving auth code to %T: %s", store, err)
paddy@34 64 }
paddy@87 65 err = store.saveAuthorizationCode(authCode)
paddy@87 66 if err != ErrAuthorizationCodeAlreadyExists {
paddy@87 67 t.Errorf("Expected ErrAuthorizationCodeAlreadyExists from %T, got %+v", store, err)
paddy@29 68 }
paddy@87 69 retrieved, err := store.getAuthorizationCode(authCode.Code)
paddy@29 70 if err != nil {
paddy@87 71 t.Errorf("Error retrieving auth code from %T: %s", store, err)
paddy@29 72 }
paddy@87 73 match, field, expectation, result := compareAuthorizationCodes(authCode, retrieved)
paddy@34 74 if !match {
paddy@87 75 t.Errorf("Expected `%v` in the `%s` field of auth code retrieved from %T, got `%v`", expectation, field, store, result)
paddy@34 76 }
paddy@111 77 err = store.useAuthorizationCode(authCode.Code)
paddy@111 78 if err != nil {
paddy@111 79 t.Errorf("Error retrieving auth code from %T: %s", store, err)
paddy@111 80 }
paddy@111 81 retrieved, err = store.getAuthorizationCode(authCode.Code)
paddy@111 82 if err != nil {
paddy@111 83 t.Errorf("Error retrieving auth code from %T: %s", store, err)
paddy@111 84 }
paddy@111 85 authCode.Used = true
paddy@111 86 match, field, expectation, result = compareAuthorizationCodes(authCode, retrieved)
paddy@111 87 if !match {
paddy@111 88 t.Errorf("Expected `%v` in the `%s` field of auth code retrieved from %T, got `%v`", expectation, field, store, result)
paddy@111 89 }
paddy@87 90 err = store.deleteAuthorizationCode(authCode.Code)
paddy@29 91 if err != nil {
paddy@87 92 t.Errorf("Error removing auth code from %T: %s", store, err)
paddy@29 93 }
paddy@87 94 retrieved, err = store.getAuthorizationCode(authCode.Code)
paddy@87 95 if err != ErrAuthorizationCodeNotFound {
paddy@87 96 t.Errorf("Expected ErrAuthorizationCodeNotFound from %T, got %+v and %+v", store, retrieved, err)
paddy@34 97 }
paddy@87 98 err = store.deleteAuthorizationCode(authCode.Code)
paddy@87 99 if err != ErrAuthorizationCodeNotFound {
paddy@87 100 t.Errorf("Expected ErrAuthorizationCodeNotFound from %T, got %+v", store, err)
paddy@29 101 }
paddy@111 102 err = store.useAuthorizationCode(authCode.Code)
paddy@111 103 if err != ErrAuthorizationCodeNotFound {
paddy@111 104 t.Errorf("Expected ErrAuthorizationCodeNotFound from %T, got %+v", store, err)
paddy@111 105 }
paddy@29 106 }
paddy@29 107 }
paddy@111 108
paddy@111 109 func TestAuthCodeGrantValidate(t *testing.T) {
paddy@111 110 t.Parallel()
paddy@111 111 store := NewMemstore()
paddy@111 112 testContext := Context{
paddy@111 113 clients: store,
paddy@111 114 authCodes: store,
paddy@111 115 profiles: store,
paddy@111 116 tokens: store,
paddy@111 117 sessions: store,
paddy@111 118 }
paddy@111 119 client := Client{
paddy@111 120 ID: uuid.NewID(),
paddy@111 121 Secret: "super secret!",
paddy@111 122 OwnerID: uuid.NewID(),
paddy@111 123 Name: "My test client",
paddy@111 124 Logo: "https://secondbit.org/logo.png",
paddy@111 125 Website: "https://secondbit.org/",
paddy@111 126 Type: "public",
paddy@111 127 }
paddy@111 128 uri, err := url.Parse("https://test.secondbit.org/redirect")
paddy@111 129 if err != nil {
paddy@111 130 t.Fatal("Can't parse URL:", err)
paddy@111 131 }
paddy@111 132 endpoint := Endpoint{
paddy@111 133 ID: uuid.NewID(),
paddy@111 134 ClientID: client.ID,
paddy@111 135 URI: *uri,
paddy@111 136 Added: time.Now(),
paddy@111 137 }
paddy@111 138 err = testContext.SaveClient(client)
paddy@111 139 if err != nil {
paddy@111 140 t.Fatal("Can't store client:", err)
paddy@111 141 }
paddy@111 142 err = testContext.AddEndpoint(client.ID, endpoint)
paddy@111 143 if err != nil {
paddy@111 144 t.Fatal("Can't store endpoint:", err)
paddy@111 145 }
paddy@111 146 code := AuthorizationCode{
paddy@111 147 Code: "myauthcode",
paddy@111 148 Created: time.Now(),
paddy@111 149 ExpiresIn: 180,
paddy@111 150 ClientID: uuid.NewID(),
paddy@111 151 Scope: "scope",
paddy@111 152 RedirectURI: "redirectURI",
paddy@111 153 State: "state",
paddy@111 154 }
paddy@111 155 err = testContext.SaveAuthorizationCode(code)
paddy@111 156 if err != nil {
paddy@111 157 t.Fatal("Can't add auth code:", err)
paddy@111 158 }
paddy@111 159 req, err := http.NewRequest("POST", "https://test.auth.secondbit.org/oauth2/grant", nil)
paddy@111 160 if err != nil {
paddy@111 161 t.Fatal("Can't build request:", err)
paddy@111 162 }
paddy@111 163 w := httptest.NewRecorder()
paddy@111 164 params := url.Values{}
paddy@111 165 body := bytes.NewBufferString(params.Encode())
paddy@111 166 req.Body = ioutil.NopCloser(body)
paddy@111 167 scope, profileID, valid := authCodeGrantValidate(w, req, testContext)
paddy@111 168 if valid {
paddy@111 169 t.Fatal("Expected invalid auth code, got scope `%s` and profileID `%s`.", scope, profileID)
paddy@111 170 }
paddy@111 171 if w.Code != http.StatusBadRequest {
paddy@111 172 t.Errorf("Expected status %d, got %d", http.StatusBadRequest, w.Code)
paddy@111 173 }
paddy@111 174 expectation := `{"error":"invalid_request"}`
paddy@111 175 if strings.TrimSpace(w.Body.String()) != expectation {
paddy@111 176 t.Errorf("Expected body of `%s`, got `%s`", expectation, strings.TrimSpace(w.Body.String()))
paddy@111 177 }
paddy@111 178 }