Merge lp:~vds/usso/validity_check_and_better_auth_failure_handling into lp:usso

Proposed by Vincenzo Di Somma
Status: Merged
Approved by: Vincenzo Di Somma
Approved revision: 43
Merged at revision: 43
Proposed branch: lp:~vds/usso/validity_check_and_better_auth_failure_handling
Merge into: lp:usso
Diff against target: 232 lines (+78/-70)
2 files modified
usso.go (+47/-51)
usso_test.go (+31/-19)
To merge this branch: bzr merge lp:~vds/usso/validity_check_and_better_auth_failure_handling
Reviewer Review Type Date Requested Status
Casey Marshall (community) Approve
Andrew W. Deane (community) Approve
Review via email: mp+208609@code.launchpad.net

Commit message

Improve error handling. Add explicit token validity check.

Description of the change

Improve error handling. Add explicit token validity check.

To post a comment you must log in.
Revision history for this message
Andrew W. Deane (andrew-w-deane) wrote :

Instead of declaring jsonBuffer as an interface at 64+ and then casting to a map at 70+ could jsonBuffer just be declared as a map leaving json.Unmarshal to do the work?

At 75+ if USSO change there source and the json code field is no longer a string then we will panic. If 75+ was replaced with the code below we won't panic should the external source change.

return "", fmt.Errorf("%v",code)

Do you think it is worth changing the code to be on the safe side?

The above questions for 124+, 137+, and 142+ too.

41. By Vincenzo Di Somma

Avoiding useless interface/casting, using fmt to prevent failures due to possible changes in u1 sso.

Revision history for this message
Vincenzo Di Somma (vds) wrote :

> Instead of declaring jsonBuffer as an interface at 64+ and then casting to a
> map at 70+ could jsonBuffer just be declared as a map leaving json.Unmarshal
> to do the work?
>
> At 75+ if USSO change there source and the json code field is no longer a
> string then we will panic. If 75+ was replaced with the code below we won't
> panic should the external source change.
>
> return "", fmt.Errorf("%v",code)
>
> Do you think it is worth changing the code to be on the safe side?
>
> The above questions for 124+, 137+, and 142+ too.

All good suggestions, all fixed, thanks.

42. By Vincenzo Di Somma

Stop using errors module use fmt.Error instead.

43. By Vincenzo Di Somma

Stop using errors module use fmt.Error instead.

Revision history for this message
Andrew W. Deane (andrew-w-deane) :
review: Approve
Revision history for this message
Casey Marshall (cmars) :
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'usso.go'
--- usso.go 2014-02-11 11:10:26 +0000
+++ usso.go 2014-02-27 17:23:23 +0000
@@ -1,12 +1,9 @@
1package usso1package usso
22
3import (3import (
4 "bytes"
5 "encoding/json"4 "encoding/json"
6 "errors"
7 "fmt"5 "fmt"
8 "io/ioutil"6 "io/ioutil"
9 "log"
10 "net/http"7 "net/http"
11 "strings"8 "strings"
12)9)
@@ -56,7 +53,6 @@
56 }53 }
57 jsonCredentials, err := json.Marshal(credentials)54 jsonCredentials, err := json.Marshal(credentials)
58 if err != nil {55 if err != nil {
59 log.Printf("Error: %s\n", err)
60 return nil, err56 return nil, err
61 }57 }
62 response, err := http.Post(58 response, err := http.Post(
@@ -67,20 +63,18 @@
67 return nil, err63 return nil, err
68 }64 }
69 if response.StatusCode == 404 {65 if response.StatusCode == 404 {
70 return nil, errors.New("Wrong credentials.")66 return nil, fmt.Errorf("Wrong credentials.")
71 }67 }
72 if response.StatusCode != 200 && response.StatusCode != 201 {68 if response.StatusCode != 200 && response.StatusCode != 201 {
73 return nil, fmt.Errorf("SSO Error: %s\n", response.Status)69 return nil, fmt.Errorf("SSO Error: %s\n", response.Status)
74 }70 }
75 body, err := ioutil.ReadAll(response.Body)71 body, err := ioutil.ReadAll(response.Body)
76 if err != nil {72 if err != nil {
77 log.Println(err)
78 return nil, err73 return nil, err
79 }74 }
80 ssodata := SSOData{}75 ssodata := SSOData{}
81 err = json.Unmarshal(body, &ssodata)76 err = json.Unmarshal(body, &ssodata)
82 if err != nil {77 if err != nil {
83 log.Println(err)
84 return nil, err78 return nil, err
85 }79 }
86 ssodata.Realm = "API"80 ssodata.Realm = "API"
@@ -105,15 +99,28 @@
105 client := &http.Client{}99 client := &http.Client{}
106 response, err := client.Do(request)100 response, err := client.Do(request)
107 if err != nil {101 if err != nil {
108 fmt.Printf("Error: %s\n", err)102 return "", err
109 }103 }
104
110 body, err := ioutil.ReadAll(response.Body)105 body, err := ioutil.ReadAll(response.Body)
111 if err != nil {106 if err != nil {
112 fmt.Println(err)107 return "", err
113 }108 }
114 var b bytes.Buffer109 if response.StatusCode == 200 {
115 b.Write(body)110 return string(body), nil
116 return fmt.Sprint(b.String()), nil111 } else {
112 var jsonMap map[string]interface{}
113 err = json.Unmarshal(body, &jsonMap)
114 // In theory, this should never happen.
115 if err != nil {
116 return "", fmt.Errorf("NO_JSON_RESPONSE")
117 }
118 code, ok := jsonMap["code"]
119 if !ok {
120 return "", fmt.Errorf("NO_CODE")
121 }
122 return "", fmt.Errorf("%v", code)
123 }
117}124}
118125
119// Given oauth credentials and a request, return it signed.126// Given oauth credentials and a request, return it signed.
@@ -147,46 +154,35 @@
147 client := &http.Client{}154 client := &http.Client{}
148 response, err := client.Do(request)155 response, err := client.Do(request)
149 if err != nil {156 if err != nil {
150 fmt.Printf("Error: %s\n", err)157 return "", err
151 }158 }
152 body, err := ioutil.ReadAll(response.Body)159 body, err := ioutil.ReadAll(response.Body)
153 if err != nil {160 if err != nil {
154 fmt.Println(err)161 return "", err
155 }162 }
156 var b bytes.Buffer163 if response.StatusCode == 200 {
157 b.Write(body)164 return string(body), nil
158 return fmt.Sprint(b.String()), nil165 } else {
159}166 var jsonMap map[string]interface{}
160167 err = json.Unmarshal(body, &jsonMap)
161// Register the toke to the U1 File Sync Service.168 // due to bug #1285176, it is possible to get non json code in the response.
162func (server UbuntuSSOServer) RegisterTokenToU1FileSync(ssodata *SSOData) (err error) {
163 rp := RequestParameters{
164 BaseURL: server.tokenRegistrationUrl,
165 HTTPMethod: "GET",
166 SignatureMethod: HMACSHA1{}}
167
168 request, err := http.NewRequest(rp.HTTPMethod, rp.BaseURL, nil)
169 if err != nil {
170 return err
171 }
172 ssodata.Realm = ""
173 err = SignRequest(ssodata, &rp, request)
174 if err != nil {
175 return err
176 }
177 client := &http.Client{}
178 response, err := client.Do(request)
179 if err != nil {
180 fmt.Printf("Error: %s\n", err)
181 }
182 if response.StatusCode != 200 {
183 body, err := ioutil.ReadAll(response.Body)
184 if err != nil {169 if err != nil {
185 fmt.Println(err)170 return "", fmt.Errorf("INVALID_CREDENTIALS")
186 }171 }
187 var b bytes.Buffer172 code, ok := jsonMap["code"]
188 b.Write(body)173 if !ok {
189 errors.New(fmt.Sprint(b.String()))174 return "", fmt.Errorf("NO_CODE")
190 }175 }
191 return nil176 return "", fmt.Errorf("%v", code)
177 }
178}
179
180// Verify the validity of the token, abusing the API to get the token details.
181func (server UbuntuSSOServer) IsTokenValid(ssodata *SSOData) (bool, error) {
182 details, err := server.GetTokenDetails(ssodata)
183 if details != "" && err == nil {
184 return true, nil
185 } else {
186 return false, err
187 }
192}188}
193189
=== modified file 'usso_test.go'
--- usso_test.go 2014-01-22 16:58:23 +0000
+++ usso_test.go 2014-02-27 17:23:23 +0000
@@ -64,16 +64,6 @@
64 if r.URL.String() == "/api/v2/tokens/oauth/abcs" {64 if r.URL.String() == "/api/v2/tokens/oauth/abcs" {
65 fmt.Fprint(w, tokenDetails)65 fmt.Fprint(w, tokenDetails)
66 return66 return
67 }
68 if r.URL.String() == "/oauth/sso-finished-so-get-tokens/" {
69 fmt.Fprint(w, "ok")
70
71 concat := ""
72 for _, v := range r.Header["Authorization"] {
73 concat += v
74 }
75 requestContent = concat
76 return
77 } else {67 } else {
78 http.Error(w, "404 page not found", http.StatusNotFound)68 http.Error(w, "404 page not found", http.StatusNotFound)
79 return69 return
@@ -170,7 +160,7 @@
170 c.Assert(token_details, Equals, string(jsonTokenDetails))160 c.Assert(token_details, Equals, string(jsonTokenDetails))
171}161}
172162
173func (suite *USSOTestSuite) TestRegisterToken(c *C) {163func (suite *USSOTestSuite) TestTokenValidity(c *C) {
174 // Simulate a valid Ubuntu SSO Server response.164 // Simulate a valid Ubuntu SSO Server response.
175 serverResponseData := map[string]string{165 serverResponseData := map[string]string{
176 "date_updated": "2013-01-16 14:03:36",166 "date_updated": "2013-01-16 14:03:36",
@@ -184,16 +174,38 @@
184 if err != nil {174 if err != nil {
185 panic(err)175 panic(err)
186 }176 }
187 server := newTestServer(string(jsonServerResponseData), "{}", 200)177 tokenDetails := map[string]string{
188 var testSSOServer = &UbuntuSSOServer{server.URL, server.URL + "/oauth/sso-finished-so-get-tokens/"}178 "token_name": tokenName,
179 "date_updated": "2014-01-22T13:35:49.867",
180 "token_key": tokenKey,
181 "href": "/api/v2/tokens/oauth/JckChNpbXxPRmPkElLglSnqnjsnGseWJmNqTJCWfUtNBSsGtoG",
182 "date_created": "2014-01-17T20:03:24.993",
183 "consumer_key": consumerKey,
184 }
185 jsonTokenDetails, err := json.Marshal(tokenDetails)
186 if err != nil {
187 panic(err)
188 }
189 server := newTestServer(string(jsonServerResponseData), string(jsonTokenDetails), 200)
190 var testSSOServer = &UbuntuSSOServer{server.URL, ""}
189 defer server.Close()191 defer server.Close()
190 ssodata, err := testSSOServer.GetToken(email, password, tokenName)192 ssodata, err := testSSOServer.GetToken(email, password, tokenName)
191 err = testSSOServer.RegisterTokenToU1FileSync(ssodata)193 // The returned information is correct.
194 token_details, err := testSSOServer.GetTokenDetails(ssodata)
192 c.Assert(err, IsNil)195 c.Assert(err, IsNil)
193 c.Assert(true, Equals, strings.Contains(*server.requestContent, "oauth_consumer_key=\"rfyzhdQ\""))196 //The request that the fake Ubuntu SSO Server has the token details.
194 c.Assert(true, Equals, strings.Contains(*server.requestContent, "oauth_token=\"abcs\""))197 c.Assert(token_details, Equals, string(jsonTokenDetails))
195 c.Assert(true, Equals, strings.Contains(*server.requestContent, "oauth_signature_method=\"HMAC-SHA1\""))198 validity, err := testSSOServer.IsTokenValid(ssodata)
196 c.Assert(true, Equals, strings.Contains(*server.requestContent, "oauth_version=\"1.0\""))199 c.Assert(validity, Equals, true)
197 c.Assert(true, Equals, strings.Contains(*server.requestContent, ""))200}
198201
202// Check invalid token
203func (suite *USSOTestSuite) TestInvalidToken(c *C) {
204 server := newTestServer("{}", "{}", 200)
205 var testSSOServer = &UbuntuSSOServer{server.URL, ""}
206 defer server.Close()
207 ssodata := SSOData{"WRONG", "", "", "", "", ""}
208 validity, err := testSSOServer.IsTokenValid(&ssodata)
209 c.Assert(err, NotNil)
210 c.Assert(validity, Equals, false)
199}211}

Subscribers

People subscribed via source and target branches

to all changes: