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 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 ( import (
"crypto/aes" "crypto/aes"
"github.com/bmizerany/assert" "github.com/bmizerany/assert"
"strings"
"testing" "testing"
) )
@ -21,3 +22,54 @@ func TestEncodeAndDecodeAccessToken(t *testing.T) {
assert.NotEqual(t, access_token, encoded_token) assert.NotEqual(t, access_token, encoded_token)
assert.Equal(t, access_token, decoded_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 // set cookie, or deny
if p.Validator(email) { if p.Validator(email) {
log.Printf("%s authenticating %s completed", remoteAddr, email) log.Printf("%s authenticating %s completed", remoteAddr, email)
encoded_token := "" value, err := buildCookieValue(
if p.AesCipher != nil { email, p.AesCipher, access_token)
encoded_token, err = encodeAccessToken(p.AesCipher, access_token) if err != nil {
if err != nil { log.Printf(err.Error())
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)
} }
p.SetCookie(rw, req, value)
http.Redirect(rw, req, redirect, 302) http.Redirect(rw, req, redirect, 302)
return return
} else { } else {
@ -452,15 +444,13 @@ func (p *OauthProxy) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
if err == nil { if err == nil {
var value string var value string
value, ok = validateCookie(cookie, p.CookieSeed) value, ok = validateCookie(cookie, p.CookieSeed)
components := strings.Split(value, "|") if ok {
email = components[0] email, user, access_token, err = parseCookieValue(
if len(components) == 2 { value, p.AesCipher)
access_token, err = decodeAccessToken(p.AesCipher, components[1])
if err != nil { if err != nil {
log.Printf("error decoding access token: %s", err) log.Printf(err.Error())
} }
} }
user = strings.Split(email, "@")[0]
} }
} }