auth

Paddy 2015-01-28 Parent:23c1a07c8a61 Child:d30a3a12d387

132:163ce22fa4c9 Go to Latest

auth/oauth2_test.go

Enable CSRF protection, add expiration to sessions. Sessions gain a CSRF token, which is passed as a parameter to the login page. The login page now checks for that CSRF token, and logs a CSRF attempt if the token does not match. I also added an expiration to sessions, so they don't last forever. Sessions should be pretty short--we just need to stay logged in for long enough to approve the OAuth request. Everything after that should be cookie based. Finally, I added a configuration parameter to control whether the session cookie should be set to Secure, requiring the use of HTTPS. For production use, this flag is a requirement, but it makes testing extremely difficult, so we need a way to disable it.

History
     1.1 --- a/oauth2_test.go	Sat Jan 24 10:34:33 2015 -0500
     1.2 +++ b/oauth2_test.go	Wed Jan 28 07:27:32 2015 -0500
     1.3 @@ -71,6 +71,8 @@
     1.4  		ID:        "testsession",
     1.5  		Active:    true,
     1.6  		ProfileID: profile.ID,
     1.7 +		CSRFToken: "nosurf",
     1.8 +		Expires:   time.Now().Add(time.Hour),
     1.9  	}
    1.10  	err = testContext.CreateSession(session)
    1.11  	if err != nil {
    1.12 @@ -117,6 +119,7 @@
    1.13  		w = httptest.NewRecorder()
    1.14  		data := url.Values{}
    1.15  		data.Set("grant", "approved")
    1.16 +		data.Set("csrftoken", session.CSRFToken)
    1.17  		body := bytes.NewBufferString(data.Encode())
    1.18  		req.Body = ioutil.NopCloser(body)
    1.19  		GetAuthorizationCodeHandler(w, req, testContext)
    1.20 @@ -129,6 +132,7 @@
    1.21  			t.Fatalf(`Being redirected to a non-URL "%s" threw error "%s" for "%s"\n`, redirectedTo, err, req.URL.String())
    1.22  		}
    1.23  		t.Log("Redirected to", redirectedTo)
    1.24 +		t.Log("Body", w.Body.String())
    1.25  		if red.Query().Get("code") == "" {
    1.26  			t.Fatalf(`Expected code param in redirect URL to be set, but it wasn't for %s`, req.URL.String())
    1.27  		}
    1.28 @@ -173,8 +177,10 @@
    1.29  		t.Fatal("Can't store client:", err)
    1.30  	}
    1.31  	session := Session{
    1.32 -		ID:     "testsession",
    1.33 -		Active: true,
    1.34 +		ID:        "testsession",
    1.35 +		Active:    true,
    1.36 +		CSRFToken: "nosurf",
    1.37 +		Expires:   time.Now().Add(time.Hour),
    1.38  	}
    1.39  	err = testContext.CreateSession(session)
    1.40  	if err != nil {
    1.41 @@ -246,8 +252,10 @@
    1.42  		t.Fatal("Can't store client:", err)
    1.43  	}
    1.44  	session := Session{
    1.45 -		ID:     "testsession",
    1.46 -		Active: true,
    1.47 +		ID:        "testsession",
    1.48 +		Active:    true,
    1.49 +		CSRFToken: "nosurf",
    1.50 +		Expires:   time.Now().Add(time.Hour),
    1.51  	}
    1.52  	err = testContext.CreateSession(session)
    1.53  	if err != nil {
    1.54 @@ -362,8 +370,10 @@
    1.55  		t.Fatal("Can't store endpoint:", err)
    1.56  	}
    1.57  	session := Session{
    1.58 -		ID:     "testsession",
    1.59 -		Active: true,
    1.60 +		ID:        "testsession",
    1.61 +		Active:    true,
    1.62 +		CSRFToken: "nosurf",
    1.63 +		Expires:   time.Now().Add(time.Hour),
    1.64  	}
    1.65  	err = testContext.CreateSession(session)
    1.66  	if err != nil {
    1.67 @@ -465,8 +475,10 @@
    1.68  		t.Fatal("Can't store endpoint:", err)
    1.69  	}
    1.70  	session := Session{
    1.71 -		ID:     "testsession",
    1.72 -		Active: true,
    1.73 +		ID:        "testsession",
    1.74 +		Active:    true,
    1.75 +		CSRFToken: "nosurf",
    1.76 +		Expires:   time.Now().Add(time.Hour),
    1.77  	}
    1.78  	err = testContext.CreateSession(session)
    1.79  	if err != nil {
    1.80 @@ -489,8 +501,10 @@
    1.81  	params.Set("state", "my super secure state string")
    1.82  	data := url.Values{}
    1.83  	data.Set("grant", "denied")
    1.84 +	data.Set("csrftoken", session.CSRFToken)
    1.85  	req.URL.RawQuery = params.Encode()
    1.86  	req.Body = ioutil.NopCloser(bytes.NewBufferString(data.Encode()))
    1.87 +	req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
    1.88  	req.Method = "POST"
    1.89  	w := httptest.NewRecorder()
    1.90  	GetAuthorizationCodeHandler(w, req, testContext)
    1.91 @@ -566,8 +580,10 @@
    1.92  		t.Errorf("Expected ErrNoSession, got %s", err)
    1.93  	}
    1.94  	session = Session{
    1.95 -		ID:     "testsession",
    1.96 -		Active: true,
    1.97 +		ID:        "testsession",
    1.98 +		Active:    true,
    1.99 +		CSRFToken: "nosurf",
   1.100 +		Expires:   time.Now().Add(time.Hour),
   1.101  	}
   1.102  	err = testContext.CreateSession(session)
   1.103  	if err != nil {