git.iko.soy/typeable/oauth2-proxy
on master help sign in
Merge branch 'master' into verified
commitd00e3bddf55ae72d7af97dbecffd190f68fd2ff3 authorJoel Speed <Joel.speed@hotmail.co.uk> dateThu 11 Apr 2019, 13:49 (8 years ago) parent24f36f23f4420f
12 files changed+230−19
CHANGELOG.md+4 README.md+8−5 http.go+39 http_test.go+105 logging_handler.go+10 logging_handler_test.go+5 main.go+10−1 oauthproxy.go+5−3 options.go+6−4 options_test.go+6 providers/session_state.go+26 providers/session_state_test.go+6−6
CHANGELOG.md+4
@@ -3,10 +3,13 @@
33## Changes since v3.1.0
44
55- [#96](https://github.com/bitly/oauth2_proxy/pull/96) Check if email is verified on GitHub (@caarlos0)
6+- [#110](https://github.com/pusher/oauth2_proxy/pull/110) Added GCP healthcheck option (@timothy-spencer)
7+- [#112](https://github.com/pusher/oauth2_proxy/pull/112) Improve websocket support (@gyson)
68- [#63](https://github.com/pusher/oauth2_proxy/pull/63) Use encoding/json for SessionState serialization (@yaegashi)
79 - Use JSON to encode session state to be stored in browser cookies
810 - Implement legacy decode function to support existing cookies generated by older versions
911 - Add detailed table driven tests in session_state_test.go
12+- [#120](https://github.com/pusher/oauth2_proxy/pull/120) Encrypting user/email from cookie (@costelmoraru)
1013- [#55](https://github.com/pusher/oauth2_proxy/pull/55) Added login.gov provider (@timothy-spencer)
1114- [#55](https://github.com/pusher/oauth2_proxy/pull/55) Added environment variables for all config options (@timothy-spencer)
1215- [#70](https://github.com/pusher/oauth2_proxy/pull/70) Fix handling of splitted cookies (@einfachchr)
@@ -17,6 +20,7 @@
1720- [#41](https://github.com/pusher/oauth2_proxy/pull/41) Added option to manually specify OIDC endpoints instead of relying on discovery
1821- [#83](https://github.com/pusher/oauth2_proxy/pull/83) Add `id_token` refresh to Google provider (@leki75)
1922- [#10](https://github.com/pusher/oauth2_proxy/pull/10) fix redirect url param handling (@dt-rush)
23+- [#122](https://github.com/pusher/oauth2_proxy/pull/122) Expose -cookie-path as configuration parameter (@costelmoraru)
2024
2125# v3.1.0
2226
README.md+8−5
@@ -48,7 +48,7 @@ Valid providers are :
4848- [GitHub](#github-auth-provider)
4949- [GitLab](#gitlab-auth-provider)
5050- [LinkedIn](#linkedin-auth-provider)
51−- [login.gov](#login.gov-provider)
51+- [login.gov](#logingov-provider)
5252
5353The provider can be selected using the `provider` configuration value.
5454
@@ -172,12 +172,12 @@ OpenID Connect is a spec for OAUTH 2.0 + identity that is implemented by many ma
172172login.gov is an OIDC provider for the US Government.
173173If you are a US Government agency, you can contact the login.gov team through the contact information
174174that you can find on https://login.gov/developers/ and work with them to understand how to get login.gov
175−accounts for integration/test and production access.
175+accounts for integration/test and production access.
176176
177177A developer guide is available here: https://developers.login.gov/, though this proxy handles everything
178178but the data you need to create to register your application in the login.gov dashboard.
179179
180−As a demo, we will assume that you are running your application that you want to secure locally on
180+As a demo, we will assume that you are running your application that you want to secure locally on
181181http://localhost:3000/, that you will be starting your proxy up on http://localhost:4180/, and that
182182you have an agency integration account for testing.
183183
@@ -261,6 +261,7 @@ Usage of oauth2_proxy:
261261 -client-secret string: the OAuth Client Secret
262262 -config string: path to config file
263263 -cookie-domain string: an optional cookie domain to force cookies to (ie: .yourcompany.com)
264+ -cookie-path string: an optional cookie path to force cookies to (ie: /foo)
264265 -cookie-expire duration: expire timeframe for cookie (default 168h0m0s)
265266 -cookie-httponly: set HttpOnly cookie flag (default true)
266267 -cookie-name string: the name of the cookie that the oauth_proxy creates (default "_oauth2_proxy")
@@ -272,6 +273,7 @@ Usage of oauth2_proxy:
272273 -email-domain value: authenticate emails with the specified domain (may be given multiple times). Use * to authenticate any email
273274 -flush-interval: period between flushing response buffers when streaming responses (default "1s")
274275 -footer string: custom footer string. Use "-" to disable default footer.
276+ -gcp-healthchecks: will enable /liveness_check, /readiness_check, and / (with the proper user-agent) endpoints that will make it work well with GCP App Engine and GKE Ingresses (default false)
275277 -github-org string: restrict logins to members of this organisation
276278 -github-team string: restrict logins to members of any of these teams (slug), separated by a comma
277279 -google-admin-email string: the google admin to impersonate for api calls
@@ -335,6 +337,7 @@ The following environment variables can be used in place of the corresponding co
335337- `OAUTH2_PROXY_COOKIE_NAME`
336338- `OAUTH2_PROXY_COOKIE_SECRET`
337339- `OAUTH2_PROXY_COOKIE_DOMAIN`
340+- `OAUTH2_PROXY_COOKIE_PATH`
338341- `OAUTH2_PROXY_COOKIE_EXPIRE`
339342- `OAUTH2_PROXY_COOKIE_REFRESH`
340343- `OAUTH2_PROXY_SIGNATURE_KEY`
@@ -411,7 +414,7 @@ The command line to run `oauth2_proxy` in this configuration would look like thi
411414OAuth2 Proxy responds directly to the following endpoints. All other endpoints will be proxied upstream when authenticated. The `/oauth2` prefix can be changed with the `--proxy-prefix` config variable.
412415
413416- /robots.txt - returns a 200 OK response that disallows all User-agents from all paths; see [robotstxt.org](http://www.robotstxt.org/) for more info
414−- /ping - returns a 200 OK response, which is intended for use with health checks
417+- /ping - returns a 200 OK response, which is intended for use with health checks
415418- /oauth2/sign_in - the login page, which also doubles as a sign out page (it clears cookies)
416419- /oauth2/start - a URL that will redirect to start the OAuth cycle
417420- /oauth2/callback - the URL used at the end of the OAuth cycle. The oauth app will be configured with this as the callback url.
@@ -505,7 +508,7 @@ server {
505508 auth_request_set $auth_cookie $upstream_http_set_cookie;
506509 add_header Set-Cookie $auth_cookie;
507510
508− # When using the --set-authorization flag, some provider's cookies can exceed the 4kb
511+ # When using the --set-authorization-header flag, some provider's cookies can exceed the 4kb
509512 # limit and so the OAuth2 Proxy splits these into multiple parts.
510513 # Nginx normally only copies the first `Set-Cookie` header from the auth_request to the response,
511514 # so if your cookies are larger than 4kb, you will need to extract additional cookies manually.
http.go+39
@@ -24,6 +24,45 @@ func (s *Server) ListenAndServe() {
2424 }
2525}
2626
27+// Used with gcpHealthcheck()
28+const userAgentHeader = "User-Agent"
29+const googleHealthCheckUserAgent = "GoogleHC/1.0"
30+const rootPath = "/"
31+
32+// gcpHealthcheck handles healthcheck queries from GCP.
33+func gcpHealthcheck(h http.Handler) http.Handler {
34+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
35+ // Check for liveness and readiness: used for Google App Engine
36+ if r.URL.EscapedPath() == "/liveness_check" {
37+ w.WriteHeader(http.StatusOK)
38+ w.Write([]byte("OK"))
39+ return
40+ }
41+ if r.URL.EscapedPath() == "/readiness_check" {
42+ w.WriteHeader(http.StatusOK)
43+ w.Write([]byte("OK"))
44+ return
45+ }
46+
47+ // Check for GKE ingress healthcheck: The ingress requires the root
48+ // path of the target to return a 200 (OK) to indicate the service's good health. This can be quite a challenging demand
49+ // depending on the application's path structure. This middleware filters out the requests from the health check by
50+ //
51+ // 1. checking that the request path is indeed the root path
52+ // 2. ensuring that the User-Agent is "GoogleHC/1.0", the health checker
53+ // 3. ensuring the request method is "GET"
54+ if r.URL.Path == rootPath &&
55+ r.Header.Get(userAgentHeader) == googleHealthCheckUserAgent &&
56+ r.Method == http.MethodGet {
57+
58+ w.WriteHeader(http.StatusOK)
59+ return
60+ }
61+
62+ h.ServeHTTP(w, r)
63+ })
64+}
65+
2766// ServeHTTP constructs a net.Listener and starts handling HTTP requests
2867func (s *Server) ServeHTTP() {
2968 HTTPAddress := s.Opts.HTTPAddress
http_test.gonew file+105
@@ -0,0 +1,105 @@
1+package main
2+
3+import (
4+ "net/http"
5+ "net/http/httptest"
6+ "testing"
7+
8+ "github.com/stretchr/testify/assert"
9+)
10+
11+func TestGCPHealthcheckLiveness(t *testing.T) {
12+ handler := func(w http.ResponseWriter, req *http.Request) {
13+ w.Write([]byte("test"))
14+ }
15+
16+ h := gcpHealthcheck(http.HandlerFunc(handler))
17+ rw := httptest.NewRecorder()
18+ r, _ := http.NewRequest("GET", "/liveness_check", nil)
19+ r.RemoteAddr = "127.0.0.1"
20+ r.Host = "test-server"
21+ h.ServeHTTP(rw, r)
22+
23+ assert.Equal(t, 200, rw.Code)
24+ assert.Equal(t, "OK", rw.Body.String())
25+}
26+
27+func TestGCPHealthcheckReadiness(t *testing.T) {
28+ handler := func(w http.ResponseWriter, req *http.Request) {
29+ w.Write([]byte("test"))
30+ }
31+
32+ h := gcpHealthcheck(http.HandlerFunc(handler))
33+ rw := httptest.NewRecorder()
34+ r, _ := http.NewRequest("GET", "/readiness_check", nil)
35+ r.RemoteAddr = "127.0.0.1"
36+ r.Host = "test-server"
37+ h.ServeHTTP(rw, r)
38+
39+ assert.Equal(t, 200, rw.Code)
40+ assert.Equal(t, "OK", rw.Body.String())
41+}
42+
43+func TestGCPHealthcheckNotHealthcheck(t *testing.T) {
44+ handler := func(w http.ResponseWriter, req *http.Request) {
45+ w.Write([]byte("test"))
46+ }
47+
48+ h := gcpHealthcheck(http.HandlerFunc(handler))
49+ rw := httptest.NewRecorder()
50+ r, _ := http.NewRequest("GET", "/not_any_check", nil)
51+ r.RemoteAddr = "127.0.0.1"
52+ r.Host = "test-server"
53+ h.ServeHTTP(rw, r)
54+
55+ assert.Equal(t, "test", rw.Body.String())
56+}
57+
58+func TestGCPHealthcheckIngress(t *testing.T) {
59+ handler := func(w http.ResponseWriter, req *http.Request) {
60+ w.Write([]byte("test"))
61+ }
62+
63+ h := gcpHealthcheck(http.HandlerFunc(handler))
64+ rw := httptest.NewRecorder()
65+ r, _ := http.NewRequest("GET", "/", nil)
66+ r.RemoteAddr = "127.0.0.1"
67+ r.Host = "test-server"
68+ r.Header.Set(userAgentHeader, googleHealthCheckUserAgent)
69+ h.ServeHTTP(rw, r)
70+
71+ assert.Equal(t, 200, rw.Code)
72+ assert.Equal(t, "", rw.Body.String())
73+}
74+
75+func TestGCPHealthcheckNotIngress(t *testing.T) {
76+ handler := func(w http.ResponseWriter, req *http.Request) {
77+ w.Write([]byte("test"))
78+ }
79+
80+ h := gcpHealthcheck(http.HandlerFunc(handler))
81+ rw := httptest.NewRecorder()
82+ r, _ := http.NewRequest("GET", "/foo", nil)
83+ r.RemoteAddr = "127.0.0.1"
84+ r.Host = "test-server"
85+ r.Header.Set(userAgentHeader, googleHealthCheckUserAgent)
86+ h.ServeHTTP(rw, r)
87+
88+ assert.Equal(t, "test", rw.Body.String())
89+}
90+
91+func TestGCPHealthcheckNotIngressPut(t *testing.T) {
92+ handler := func(w http.ResponseWriter, req *http.Request) {
93+ w.Write([]byte("test"))
94+ }
95+
96+ h := gcpHealthcheck(http.HandlerFunc(handler))
97+ rw := httptest.NewRecorder()
98+ r, _ := http.NewRequest("PUT", "/", nil)
99+ r.RemoteAddr = "127.0.0.1"
100+ r.Host = "test-server"
101+ r.Header.Set(userAgentHeader, googleHealthCheckUserAgent)
102+ h.ServeHTTP(rw, r)
103+
104+ assert.Equal(t, "test", rw.Body.String())
105+}
logging_handler.go+10
@@ -4,6 +4,8 @@
44package main
55
66import (
7+ "bufio"
8+ "errors"
79 "fmt"
810 "io"
911 "net"
@@ -32,6 +34,14 @@ func (l *responseLogger) Header() http.Header {
3234 return l.w.Header()
3335}
3436
37+// Support Websocket
38+func (l *responseLogger) Hijack() (rwc net.Conn, buf *bufio.ReadWriter, err error) {
39+ if hj, ok := l.w.(http.Hijacker); ok {
40+ return hj.Hijack()
41+ }
42+ return nil, nil, errors.New("http.Hijacker is not available on writer")
43+}
44+
3545// ExtractGAPMetadata extracts and removes GAP headers from the ResponseWriter's
3646// Header
3747func (l *responseLogger) ExtractGAPMetadata() {
logging_handler_test.go+5
@@ -24,6 +24,11 @@ func TestLoggingHandler_ServeHTTP(t *testing.T) {
2424 for _, test := range tests {
2525 buf := bytes.NewBuffer(nil)
2626 handler := func(w http.ResponseWriter, req *http.Request) {
27+ _, ok := w.(http.Hijacker)
28+ if !ok {
29+ t.Error("http.Hijacker is not available")
30+ }
31+
2732 w.Write([]byte("test"))
2833 }
2934
main.go+10−1
@@ -5,6 +5,7 @@ import (
55 "fmt"
66 "log"
77 "math/rand"
8+ "net/http"
89 "os"
910 "runtime"
1011 "strings"
@@ -68,6 +69,7 @@ func main() {
6869 flagSet.String("cookie-name", "_oauth2_proxy", "the name of the cookie that the oauth_proxy creates")
6970 flagSet.String("cookie-secret", "", "the seed string for secure cookies (optionally base64 encoded)")
7071 flagSet.String("cookie-domain", "", "an optional cookie domain to force cookies to (ie: .yourcompany.com)*")
72+ flagSet.String("cookie-path", "/", "an optional cookie path to force cookies to (ie: /poc/)*")
7173 flagSet.Duration("cookie-expire", time.Duration(168)*time.Hour, "expire timeframe for cookie")
7274 flagSet.Duration("cookie-refresh", time.Duration(0), "refresh the cookie after this duration; 0 to disable")
7375 flagSet.Bool("cookie-secure", true, "set secure (HTTPS) cookie flag")
@@ -92,6 +94,7 @@ func main() {
9294 flagSet.String("acr-values", "http://idmanagement.gov/ns/assurance/loa/1", "acr values string: optional, used by login.gov")
9395 flagSet.String("jwt-key", "", "private key used to sign JWT: required by login.gov")
9496 flagSet.String("pubjwk-url", "", "JWK pubkey access endpoint: required by login.gov")
97+ flagSet.Bool("gcp-healthchecks", false, "Enable GCP/GKE healthcheck endpoints")
9598
9699 flagSet.Parse(os.Args[1:])
97100
@@ -139,8 +142,14 @@ func main() {
139142
140143 rand.Seed(time.Now().UnixNano())
141144
145+ var handler http.Handler
146+ if opts.GCPHealthChecks {
147+ handler = gcpHealthcheck(LoggingHandler(os.Stdout, oauthproxy, opts.RequestLogging, opts.RequestLoggingFormat))
148+ } else {
149+ handler = LoggingHandler(os.Stdout, oauthproxy, opts.RequestLogging, opts.RequestLoggingFormat)
150+ }
142151 s := &Server{
143− Handler: LoggingHandler(os.Stdout, oauthproxy, opts.RequestLogging, opts.RequestLoggingFormat),
152+ Handler: handler,
144153 Opts: opts,
145154 }
146155 s.ListenAndServe()
oauthproxy.go+5−3
@@ -56,6 +56,7 @@ type OAuthProxy struct {
5656 CookieName string
5757 CSRFCookieName string
5858 CookieDomain string
59+ CookiePath string
5960 CookieSecure bool
6061 CookieHTTPOnly bool
6162 CookieExpire time.Duration
@@ -110,7 +111,7 @@ func (u *UpstreamProxy) ServeHTTP(w http.ResponseWriter, r *http.Request) {
110111 r.Header.Set("GAP-Auth", w.Header().Get("GAP-Auth"))
111112 u.auth.SignRequest(r)
112113 }
113− if u.wsHandler != nil && r.Header.Get("Connection") == "Upgrade" && r.Header.Get("Upgrade") == "websocket" {
114+ if u.wsHandler != nil && strings.ToLower(r.Header.Get("Connection")) == "upgrade" && r.Header.Get("Upgrade") == "websocket" {
114115 u.wsHandler.ServeHTTP(w, r)
115116 } else {
116117 u.handler.ServeHTTP(w, r)
@@ -214,7 +215,7 @@ func NewOAuthProxy(opts *Options, validator func(string) bool) *OAuthProxy {
214215 refresh = fmt.Sprintf("after %s", opts.CookieRefresh)
215216 }
216217
217− log.Printf("Cookie settings: name:%s secure(https):%v httponly:%v expiry:%s domain:%s refresh:%s", opts.CookieName, opts.CookieSecure, opts.CookieHTTPOnly, opts.CookieExpire, opts.CookieDomain, refresh)
218+ log.Printf("Cookie settings: name:%s secure(https):%v httponly:%v expiry:%s domain:%s path:%s refresh:%s", opts.CookieName, opts.CookieSecure, opts.CookieHTTPOnly, opts.CookieExpire, opts.CookieDomain, opts.CookiePath, refresh)
218219
219220 var cipher *cookie.Cipher
220221 if opts.PassAccessToken || opts.SetAuthorization || opts.PassAuthorization || (opts.CookieRefresh != time.Duration(0)) {
@@ -230,6 +231,7 @@ func NewOAuthProxy(opts *Options, validator func(string) bool) *OAuthProxy {
230231 CSRFCookieName: fmt.Sprintf("%v_%v", opts.CookieName, "csrf"),
231232 CookieSeed: opts.CookieSecret,
232233 CookieDomain: opts.CookieDomain,
234+ CookiePath: opts.CookiePath,
233235 CookieSecure: opts.CookieSecure,
234236 CookieHTTPOnly: opts.CookieHTTPOnly,
235237 CookieExpire: opts.CookieExpire,
@@ -430,7 +432,7 @@ func (p *OAuthProxy) makeCookie(req *http.Request, name string, value string, ex
430432 return &http.Cookie{
431433 Name: name,
432434 Value: value,
433− Path: "/",
435+ Path: p.CookiePath,
434436 Domain: p.CookieDomain,
435437 HttpOnly: p.CookieHTTPOnly,
436438 Secure: p.CookieSecure,
options.go+6−4
@@ -49,6 +49,7 @@ type Options struct {
4949 CookieName string `flag:"cookie-name" cfg:"cookie_name" env:"OAUTH2_PROXY_COOKIE_NAME"`
5050 CookieSecret string `flag:"cookie-secret" cfg:"cookie_secret" env:"OAUTH2_PROXY_COOKIE_SECRET"`
5151 CookieDomain string `flag:"cookie-domain" cfg:"cookie_domain" env:"OAUTH2_PROXY_COOKIE_DOMAIN"`
52+ CookiePath string `flag:"cookie-path" cfg:"cookie_path" env:"OAUTH2_PROXY_COOKIE_PATH"`
5253 CookieExpire time.Duration `flag:"cookie-expire" cfg:"cookie_expire" env:"OAUTH2_PROXY_COOKIE_EXPIRE"`
5354 CookieRefresh time.Duration `flag:"cookie-refresh" cfg:"cookie_refresh" env:"OAUTH2_PROXY_COOKIE_REFRESH"`
5455 CookieSecure bool `flag:"cookie-secure" cfg:"cookie_secure" env:"OAUTH2_PROXY_COOKIE_SECURE"`
@@ -86,10 +87,11 @@ type Options struct {
8687 RequestLogging bool `flag:"request-logging" cfg:"request_logging" env:"OAUTH2_PROXY_REQUEST_LOGGING"`
8788 RequestLoggingFormat string `flag:"request-logging-format" cfg:"request_logging_format" env:"OAUTH2_PROXY_REQUEST_LOGGING_FORMAT"`
8889
89− SignatureKey string `flag:"signature-key" cfg:"signature_key" env:"OAUTH2_PROXY_SIGNATURE_KEY"`
90− AcrValues string `flag:"acr-values" cfg:"acr_values" env:"OAUTH2_PROXY_ACR_VALUES"`
91− JWTKey string `flag:"jwt-key" cfg:"jwt_key" env:"OAUTH2_PROXY_JWT_KEY"`
92− PubJWKURL string `flag:"pubjwk-url" cfg:"pubjwk_url" env:"OAUTH2_PROXY_PUBJWK_URL"`
90+ SignatureKey string `flag:"signature-key" cfg:"signature_key" env:"OAUTH2_PROXY_SIGNATURE_KEY"`
91+ AcrValues string `flag:"acr-values" cfg:"acr_values" env:"OAUTH2_PROXY_ACR_VALUES"`
92+ JWTKey string `flag:"jwt-key" cfg:"jwt_key" env:"OAUTH2_PROXY_JWT_KEY"`
93+ PubJWKURL string `flag:"pubjwk-url" cfg:"pubjwk_url" env:"OAUTH2_PROXY_PUBJWK_URL"`
94+ GCPHealthChecks bool `flag:"gcp-healthchecks" cfg:"gcp_healthchecks" env:"OAUTH2_PROXY_GCP_HEALTHCHECKS"`
9395
9496 // internal values that are set after config validation
9597 redirectURL *url.URL
options_test.go+6
@@ -268,3 +268,9 @@ func TestSkipOIDCDiscovery(t *testing.T) {
268268
269269 assert.Equal(t, nil, o.Validate())
270270}
271+
272+func TestGCPHealthcheck(t *testing.T) {
273+ o := testOptions()
274+ o.GCPHealthChecks = true
275+ assert.Equal(t, nil, o.Validate())
276+}
providers/session_state.go+26
@@ -62,6 +62,18 @@ func (s *SessionState) EncodeSessionState(c *cookie.Cipher) (string, error) {
6262 } else {
6363 ss = *s
6464 var err error
65+ if ss.Email != "" {
66+ ss.Email, err = c.Encrypt(ss.Email)
67+ if err != nil {
68+ return "", err
69+ }
70+ }
71+ if ss.User != "" {
72+ ss.User, err = c.Encrypt(ss.User)
73+ if err != nil {
74+ return "", err
75+ }
76+ }
6577 if ss.AccessToken != "" {
6678 ss.AccessToken, err = c.Encrypt(ss.AccessToken)
6779 if err != nil {
@@ -172,6 +184,20 @@ func DecodeSessionState(v string, c *cookie.Cipher) (*SessionState, error) {
172184 User: ss.User,
173185 }
174186 } else {
187+ // Backward compatibility with using unecrypted Email
188+ if ss.Email != "" {
189+ decryptedEmail, errEmail := c.Decrypt(ss.Email)
190+ if errEmail == nil {
191+ ss.Email = decryptedEmail
192+ }
193+ }
194+ // Backward compatibility with using unecrypted User
195+ if ss.User != "" {
196+ decryptedUser, errUser := c.Decrypt(ss.User)
197+ if errUser == nil {
198+ ss.User = decryptedUser
199+ }
200+ }
175201 if ss.AccessToken != "" {
176202 ss.AccessToken, err = c.Decrypt(ss.AccessToken)
177203 if err != nil {
providers/session_state_test.go+6−6
@@ -41,8 +41,8 @@ func TestSessionStateSerialization(t *testing.T) {
4141 ss, err = DecodeSessionState(encoded, c2)
4242 t.Logf("%#v", ss)
4343 assert.Equal(t, nil, err)
44− assert.Equal(t, "user", ss.User)
45− assert.Equal(t, s.Email, ss.Email)
44+ assert.NotEqual(t, "user", ss.User)
45+ assert.NotEqual(t, s.Email, ss.Email)
4646 assert.Equal(t, s.ExpiresOn.Unix(), ss.ExpiresOn.Unix())
4747 assert.NotEqual(t, s.AccessToken, ss.AccessToken)
4848 assert.NotEqual(t, s.IDToken, ss.IDToken)
@@ -77,8 +77,8 @@ func TestSessionStateSerializationWithUser(t *testing.T) {
7777 ss, err = DecodeSessionState(encoded, c2)
7878 t.Logf("%#v", ss)
7979 assert.Equal(t, nil, err)
80− assert.Equal(t, s.User, ss.User)
81− assert.Equal(t, s.Email, ss.Email)
80+ assert.NotEqual(t, s.User, ss.User)
81+ assert.NotEqual(t, s.Email, ss.Email)
8282 assert.Equal(t, s.ExpiresOn.Unix(), ss.ExpiresOn.Unix())
8383 assert.NotEqual(t, s.AccessToken, ss.AccessToken)
8484 assert.NotEqual(t, s.RefreshToken, ss.RefreshToken)
@@ -229,7 +229,7 @@ func TestDecodeSessionState(t *testing.T) {
229229 ExpiresOn: e,
230230 RefreshToken: "refresh4321",
231231 },
232− Encoded: fmt.Sprintf(`{"Email":"user@domain.com","User":"just-user","AccessToken":"I6s+ml+/MldBMgHIiC35BTKTh57skGX24w==","IDToken":"xojNdyyjB1HgYWh6XMtXY/Ph5eCVxa1cNsklJw==","RefreshToken":"qEX0x6RmASxo4dhlBG6YuRs9Syn/e9sHu/+K","ExpiresOn":%s}`, eString),
232+ Encoded: fmt.Sprintf(`{"Email":"FsKKYrTWZWrxSOAqA/fTNAUZS5QWCqOBjuAbBlbVOw==","User":"rT6JP3dxQhxUhkWrrd7yt6c1mDVyQCVVxw==","AccessToken":"I6s+ml+/MldBMgHIiC35BTKTh57skGX24w==","IDToken":"xojNdyyjB1HgYWh6XMtXY/Ph5eCVxa1cNsklJw==","RefreshToken":"qEX0x6RmASxo4dhlBG6YuRs9Syn/e9sHu/+K","ExpiresOn":%s}`, eString),
233233 Cipher: c,
234234 },
235235 {
@@ -237,7 +237,7 @@ func TestDecodeSessionState(t *testing.T) {
237237 Email: "user@domain.com",
238238 User: "just-user",
239239 },
240− Encoded: `{"Email":"user@domain.com","User":"just-user"}`,
240+ Encoded: `{"Email":"EGTllJcOFC16b7LBYzLekaHAC5SMMSPdyUrg8hd25g==","User":"rT6JP3dxQhxUhkWrrd7yt6c1mDVyQCVVxw=="}`,
241241 Cipher: c,
242242 },
243243 {