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