Refactor cookie building and parsing

Extracts buildCookieValue() and parseCookieValue() from OauthProxy.ServeHTTP()
and adds tests for both.
This commit is contained in:
Mike Bland 2015-04-05 10:51:17 -04:00
parent cf79fd9e4c
commit 9887ac3be5
3 changed files with 92 additions and 19 deletions

View File

@ -97,3 +97,34 @@ func decodeAccessToken(aes_cipher cipher.Block, encoded_access_token string) (st
return string(encrypted_access_token), nil
}
func buildCookieValue(email string, aes_cipher cipher.Block,
access_token string) (string, error) {
if aes_cipher == nil {
return email, nil
}
encoded_token, err := encodeAccessToken(aes_cipher, access_token)
if err != nil {
return email, fmt.Errorf(
"error encoding access token for %s: %s", email, err)
}
return email + "|" + encoded_token, nil
}
func parseCookieValue(value string, aes_cipher cipher.Block) (email, user,
access_token string, err error) {
components := strings.Split(value, "|")
email = components[0]
user = strings.Split(email, "@")[0]
if aes_cipher != nil && len(components) == 2 {
access_token, err = decodeAccessToken(aes_cipher, components[1])
if err != nil {
err = fmt.Errorf(
"error decoding access token for %s: %s",
email, err)
}
}
return email, user, access_token, err
}

View File

@ -3,6 +3,7 @@ package main
import (
"crypto/aes"
"github.com/bmizerany/assert"
"strings"
"testing"
)
@ -21,3 +22,54 @@ func TestEncodeAndDecodeAccessToken(t *testing.T) {
assert.NotEqual(t, access_token, encoded_token)
assert.Equal(t, access_token, decoded_token)
}
func TestBuildCookieValueWithoutAccessToken(t *testing.T) {
value, err := buildCookieValue("michael.bland@gsa.gov", nil, "")
assert.Equal(t, nil, err)
assert.Equal(t, "michael.bland@gsa.gov", value)
}
func TestBuildCookieValueWithAccessTokenAndNilCipher(t *testing.T) {
value, err := buildCookieValue("michael.bland@gsa.gov", nil,
"access token")
assert.Equal(t, nil, err)
assert.Equal(t, "michael.bland@gsa.gov", value)
}
func TestParseCookieValueWithoutAccessToken(t *testing.T) {
email, user, access_token, err := parseCookieValue(
"michael.bland@gsa.gov", nil)
assert.Equal(t, nil, err)
assert.Equal(t, "michael.bland@gsa.gov", email)
assert.Equal(t, "michael.bland", user)
assert.Equal(t, "", access_token)
}
func TestParseCookieValueWithAccessTokenAndNilCipher(t *testing.T) {
email, user, access_token, err := parseCookieValue(
"michael.bland@gsa.gov|access_token", nil)
assert.Equal(t, nil, err)
assert.Equal(t, "michael.bland@gsa.gov", email)
assert.Equal(t, "michael.bland", user)
assert.Equal(t, "", access_token)
}
func TestBuildAndParseCookieValueWithAccessToken(t *testing.T) {
aes_cipher, err := aes.NewCipher([]byte("0123456789abcdef"))
assert.Equal(t, nil, err)
value, err := buildCookieValue("michael.bland@gsa.gov", aes_cipher,
"access_token")
assert.Equal(t, nil, err)
prefix := "michael.bland@gsa.gov|"
if !strings.HasPrefix(value, prefix) {
t.Fatal("cookie value does not start with \"%s\": %s",
prefix, value)
}
email, user, access_token, err := parseCookieValue(value, aes_cipher)
assert.Equal(t, nil, err)
assert.Equal(t, "michael.bland@gsa.gov", email)
assert.Equal(t, "michael.bland", user)
assert.Equal(t, "access_token", access_token)
}

View File

@ -425,20 +425,12 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
// set cookie, or deny
if p.Validator(email) {
log.Printf("%s authenticating %s completed", remoteAddr, email)
encoded_token := ""
if p.AesCipher != nil {
encoded_token, err = encodeAccessToken(p.AesCipher, access_token)
if err != nil {
log.Printf("error encoding access token: %s", err)
}
}
access_token = ""
if encoded_token != "" {
p.SetCookie(rw, req, email+"|"+encoded_token)
} else {
p.SetCookie(rw, req, email)
value, err := buildCookieValue(
email, p.AesCipher, access_token)
if err != nil {
log.Printf(err.Error())
}
p.SetCookie(rw, req, value)
http.Redirect(rw, req, redirect, 302)
return
} else {
@ -452,15 +444,13 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if err == nil {
var value string
value, ok = validateCookie(cookie, p.CookieSeed)
components := strings.Split(value, "|")
email = components[0]
if len(components) == 2 {
access_token, err = decodeAccessToken(p.AesCipher, components[1])
if ok {
email, user, access_token, err = parseCookieValue(
value, p.AesCipher)
if err != nil {
log.Printf("error decoding access token: %s", err)
log.Printf(err.Error())
}
}
user = strings.Split(email, "@")[0]
}
}