Refactor cookie building and parsing
Extracts buildCookieValue() and parseCookieValue() from OauthProxy.ServeHTTP() and adds tests for both.
This commit is contained in:
		
							parent
							
								
									cf79fd9e4c
								
							
						
					
					
						commit
						9887ac3be5
					
				
							
								
								
									
										31
									
								
								cookies.go
								
								
								
								
							
							
						
						
									
										31
									
								
								cookies.go
								
								
								
								
							|  | @ -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 | ||||
| } | ||||
|  |  | |||
|  | @ -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) | ||||
| } | ||||
|  |  | |||
|  | @ -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] | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue