You've already forked oauth2-proxy
							
							
				mirror of
				https://github.com/oauth2-proxy/oauth2-proxy.git
				synced 2025-10-30 23:47:52 +02:00 
			
		
		
		
	Move SessionStore tests to independent package
This commit is contained in:
		| @@ -33,3 +33,9 @@ issues: | ||||
|         - bodyclose | ||||
|         - unconvert | ||||
|         - gocritic | ||||
|     # If we have tests in shared test folders, these can be less strictly linted | ||||
|     - path: tests/.*_tests\.go | ||||
|       linters: | ||||
|         - golint | ||||
|         - bodyclose | ||||
|         - stylecheck | ||||
|   | ||||
| @@ -8,6 +8,7 @@ | ||||
|  | ||||
| ## Changes since v6.0.0 | ||||
|  | ||||
| - [#542](https://github.com/oauth2-proxy/oauth2-proxy/pull/542) Move SessionStore tests to independent package (@JoelSpeed) | ||||
| - [#577](https://github.com/oauth2-proxy/oauth2-proxy/pull/577) Move Cipher and Session Store initialisation out of Validation (@JoelSpeed) | ||||
|  | ||||
| # v6.0.0 | ||||
|   | ||||
							
								
								
									
										6
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								go.mod
									
									
									
									
									
								
							| @@ -4,8 +4,7 @@ go 1.14 | ||||
|  | ||||
| require ( | ||||
| 	github.com/Bose/minisentinel v0.0.0-20200130220412-917c5a9223bb | ||||
| 	github.com/alicebob/miniredis v2.5.0+incompatible // indirect | ||||
| 	github.com/alicebob/miniredis/v2 v2.11.2 | ||||
| 	github.com/alicebob/miniredis/v2 v2.13.0 | ||||
| 	github.com/bitly/go-simplejson v0.5.0 | ||||
| 	github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect | ||||
| 	github.com/coreos/go-oidc v2.2.1+incompatible | ||||
| @@ -15,7 +14,6 @@ require ( | ||||
| 	github.com/justinas/alice v1.2.0 | ||||
| 	github.com/kr/pretty v0.2.0 // indirect | ||||
| 	github.com/mbland/hmacauth v0.0.0-20170912233209-44256dfd4bfa | ||||
| 	github.com/mdempsky/maligned v0.0.0-20180708014732-6e39bd26a8c8 // indirect | ||||
| 	github.com/mitchellh/mapstructure v1.1.2 | ||||
| 	github.com/onsi/ginkgo v1.12.0 | ||||
| 	github.com/onsi/gomega v1.9.0 | ||||
| @@ -27,8 +25,8 @@ require ( | ||||
| 	golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550 | ||||
| 	golang.org/x/net v0.0.0-20200226121028-0de0cce0169b | ||||
| 	golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d | ||||
| 	golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 // indirect | ||||
| 	google.golang.org/api v0.20.0 | ||||
| 	gopkg.in/natefinch/lumberjack.v2 v2.0.0 | ||||
| 	gopkg.in/square/go-jose.v2 v2.4.1 | ||||
| 	mvdan.cc/unparam v0.0.0-20200501210554-b37ab49443f7 // indirect | ||||
| ) | ||||
|   | ||||
							
								
								
									
										27
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										27
									
								
								go.sum
									
									
									
									
									
								
							| @@ -6,17 +6,18 @@ github.com/Bose/minisentinel v0.0.0-20200130220412-917c5a9223bb h1:ZVN4Iat3runWO | ||||
| github.com/Bose/minisentinel v0.0.0-20200130220412-917c5a9223bb/go.mod h1:WsAABbY4HQBgd3mGuG4KMNTbHJCPvx9IVBHzysbknss= | ||||
| github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= | ||||
| github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= | ||||
| github.com/FZambia/sentinel v1.0.0 h1:KJ0ryjKTZk5WMp0dXvSdNqp3lFaW1fNFuEYfrkLOYIc= | ||||
| github.com/FZambia/sentinel v1.0.0/go.mod h1:ytL1Am/RLlAoAXG6Kj5LNuw/TRRQrv2rt2FT26vP5gI= | ||||
| github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= | ||||
| github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= | ||||
| github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= | ||||
| github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6 h1:45bxf7AZMwWcqkLzDAQugVEwedisr5nRJ1r+7LYnv0U= | ||||
| github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= | ||||
| github.com/alicebob/miniredis v2.5.0+incompatible h1:yBHoLpsyjupjz3NL3MhKMVkR41j82Yjf3KFv7ApYzUI= | ||||
| github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk= | ||||
| github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a h1:HbKu58rmZpUGpz5+4FfNmIU+FmZg2P3Xaj2v2bfNWmk= | ||||
| github.com/alicebob/gopher-json v0.0.0-20200520072559-a9ecdc9d1d3a/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= | ||||
| github.com/alicebob/miniredis/v2 v2.11.1/go.mod h1:UA48pmi7aSazcGAvcdKcBB49z521IC9VjTTRz2nIaJE= | ||||
| github.com/alicebob/miniredis/v2 v2.11.2 h1:OtWO7akm5otuhssnE/sNfsWxG4gZ8DbGhShDtRrByJs= | ||||
| github.com/alicebob/miniredis/v2 v2.11.2/go.mod h1:VL3UDEfAH59bSa7MuHMuFToxkqyHh69s/WUbYlOAuyg= | ||||
| github.com/alicebob/miniredis/v2 v2.13.0 h1:QPosMaxm+r6Qs+YcCtL2Z2a2RSdC9VfXJLpd80l8ICU= | ||||
| github.com/alicebob/miniredis/v2 v2.13.0/go.mod h1:0UIBNuf97uxrWhdVBpJvPtafKyGpL2NS2pYe0tYM97k= | ||||
| github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= | ||||
| github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= | ||||
| github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= | ||||
| @@ -70,6 +71,8 @@ github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs | ||||
| github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||
| github.com/gomodule/redigo v1.7.1-0.20190322064113-39e2c31b7ca3 h1:6amM4HsNPOvMLVc2ZnyqrjeQ92YAVWn7T4WBKK87inY= | ||||
| github.com/gomodule/redigo v1.7.1-0.20190322064113-39e2c31b7ca3/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= | ||||
| github.com/gomodule/redigo v1.8.1 h1:Abmo0bI7Xf0IhdIPc7HZQzZcShdnmxeoVuDDtIQp8N8= | ||||
| github.com/gomodule/redigo v1.8.1/go.mod h1:P9dn9mFrCBvWhGE1wpxx6fgq7BAeLBk+UUUzlpkBYO0= | ||||
| github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= | ||||
| github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= | ||||
| github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= | ||||
| @@ -117,12 +120,11 @@ github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= | ||||
| github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= | ||||
| github.com/magiconair/properties v1.8.1 h1:ZC2Vc7/ZFkGmsVC9KvOjumD+G5lXy2RtTKyzRKO2BQ4= | ||||
| github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= | ||||
| github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A= | ||||
| github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= | ||||
| github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= | ||||
| github.com/mbland/hmacauth v0.0.0-20170912233209-44256dfd4bfa h1:hI1uC2A3vJFjwvBn0G0a7QBRdBUp6Y048BtLAHRTKPo= | ||||
| github.com/mbland/hmacauth v0.0.0-20170912233209-44256dfd4bfa/go.mod h1:8vxFeeg++MqgCHwehSuwTlYCF0ALyDJbYJ1JsKi7v6s= | ||||
| github.com/mdempsky/maligned v0.0.0-20180708014732-6e39bd26a8c8 h1:zvpKif6gkrh82wAd2JIffdLyCL52N8r+ABwHxdIOvWM= | ||||
| github.com/mdempsky/maligned v0.0.0-20180708014732-6e39bd26a8c8/go.mod h1:oGVD62YTpMEWw0JqJ2Vl48dzHywJBMlapkfsmhtokOU= | ||||
| github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= | ||||
| github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= | ||||
| github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | ||||
| @@ -134,7 +136,6 @@ github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W | ||||
| github.com/onsi/ginkgo v1.10.1/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= | ||||
| github.com/onsi/ginkgo v1.12.0 h1:Iw5WCbBcaAAd0fpRb1c9r5YCylv4XDoCSigm1zLevwU= | ||||
| github.com/onsi/ginkgo v1.12.0/go.mod h1:oUhWkIvk5aDxtKvDDuw8gItl8pKl42LzjC9KZE0HfGg= | ||||
| github.com/onsi/ginkgo v1.12.3 h1:+RYp9QczoWz9zfUyLP/5SLXQVhfr6gZOoKGfQqHuLZQ= | ||||
| github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= | ||||
| github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= | ||||
| github.com/onsi/gomega v1.9.0 h1:R1uwffexN6Pr340GtYRIdZmAiN4J+iw6WG4wog1DUXg= | ||||
| @@ -157,7 +158,6 @@ github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R | ||||
| github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= | ||||
| github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= | ||||
| github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= | ||||
| github.com/rogpeppe/go-internal v1.5.2/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= | ||||
| github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= | ||||
| github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= | ||||
| github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= | ||||
| @@ -188,7 +188,6 @@ github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q | ||||
| github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= | ||||
| github.com/yhat/wsutil v0.0.0-20170731153501-1d66fa95c997 h1:1+FQ4Ns+UZtUiQ4lP0sTCyKSQ0EXoiwAdHZB0Pd5t9Q= | ||||
| github.com/yhat/wsutil v0.0.0-20170731153501-1d66fa95c997/go.mod h1:DIGbh/f5XMAessMV/uaIik81gkDVjUeQ9ApdaU7wRKE= | ||||
| github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= | ||||
| github.com/yuin/gopher-lua v0.0.0-20190206043414-8bfc7677f583/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ= | ||||
| github.com/yuin/gopher-lua v0.0.0-20191213034115-f46add6fdb5c/go.mod h1:gqRgreBUhTSL0GeU64rtZ3Uq3wtjOa/TB2YfrtkCbVQ= | ||||
| github.com/yuin/gopher-lua v0.0.0-20191220021717-ab39c6098bdb h1:ZkM6LRnq40pR1Ox0hTHlnpkcOTuFIDQpZ1IN8rKKhX0= | ||||
| @@ -210,7 +209,6 @@ golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvx | ||||
| golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= | ||||
| golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= | ||||
| golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= | ||||
| golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= | ||||
| golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| @@ -223,7 +221,6 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn | ||||
| golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c h1:uOCk1iQW6Vc18bnC13MfzScl+wdKBmM9Y9kU7Z83/lw= | ||||
| golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||||
| golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= | ||||
| golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||
| golang.org/x/net v0.0.0-20190923162816-aa69164e4478 h1:l5EDrHhldLYb3ZRHDUhXF7Om7MvYXnkV9/iQNo1lX6g= | ||||
| golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||
| golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8= | ||||
| @@ -239,7 +236,6 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ | ||||
| golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= | ||||
| golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| @@ -269,12 +265,8 @@ golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3 | ||||
| golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= | ||||
| golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135 h1:5Beo0mZN8dRzgrMMkDp0jc8YXQKx9DiJ2k1dkvGsn5A= | ||||
| golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= | ||||
| golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= | ||||
| golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b h1:zSzQJAznWxAh9fZxiPy2FZo+ZZEYoYFYYDYdOrU7AaM= | ||||
| golang.org/x/tools v0.0.0-20200426102838-f3a5411a4c3b/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= | ||||
| golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7 h1:9zdDQZ7Thm29KFXgAX/+yaf3eVbP7djjWp/dXAppNCc= | ||||
| golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||
| golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||
| golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= | ||||
| golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= | ||||
| google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= | ||||
| @@ -300,7 +292,6 @@ gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8 | ||||
| gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= | ||||
| gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= | ||||
| gopkg.in/fsnotify.v1 v1.4.7 h1:xOHLXZwVvI9hhs+cLKq5+I5onOuwQLhQwiu63xxlHs4= | ||||
| gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= | ||||
| gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= | ||||
| @@ -321,5 +312,3 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||||
| honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||||
| honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= | ||||
| mvdan.cc/unparam v0.0.0-20200501210554-b37ab49443f7 h1:kAREL6MPwpsk1/PQPFD3Eg7WAQR5mPTWZJaBiG5LDbY= | ||||
| mvdan.cc/unparam v0.0.0-20200501210554-b37ab49443f7/go.mod h1:HGC5lll35J70Y5v7vCGb9oLhHoScFwkHDJm/05RdSTc= | ||||
|   | ||||
| @@ -5,9 +5,30 @@ import ( | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/oauth2-proxy/oauth2-proxy/pkg/apis/options" | ||||
| 	sessionsapi "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/sessions" | ||||
| 	"github.com/oauth2-proxy/oauth2-proxy/pkg/logger" | ||||
| 	"github.com/oauth2-proxy/oauth2-proxy/pkg/sessions/tests" | ||||
| 	. "github.com/onsi/ginkgo" | ||||
| 	. "github.com/onsi/gomega" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| ) | ||||
|  | ||||
| func TestSessionStore(t *testing.T) { | ||||
| 	logger.SetOutput(GinkgoWriter) | ||||
| 	RegisterFailHandler(Fail) | ||||
| 	RunSpecs(t, "Cookie SessionStore") | ||||
| } | ||||
|  | ||||
| var _ = Describe("Cookie SessionStore Tests", func() { | ||||
| 	tests.RunSessionStoreTests( | ||||
| 		func(opts *options.SessionOptions, cookieOpts *options.CookieOptions) (sessionsapi.SessionStore, error) { | ||||
| 			// Set the connection URL | ||||
| 			opts.Type = options.CookieSessionStoreType | ||||
| 			return NewCookieSessionStore(opts, cookieOpts) | ||||
| 		}, nil) | ||||
| }) | ||||
|  | ||||
| func Test_copyCookie(t *testing.T) { | ||||
| 	expire, _ := time.Parse(time.RFC3339, "2020-03-17T00:00:00Z") | ||||
| 	c := &http.Cookie{ | ||||
|   | ||||
| @@ -1,69 +0,0 @@ | ||||
| package redis | ||||
|  | ||||
| import ( | ||||
| 	"crypto/rand" | ||||
| 	"net/http" | ||||
| 	"net/http/httptest" | ||||
| 	"net/url" | ||||
| 	"testing" | ||||
|  | ||||
| 	"github.com/Bose/minisentinel" | ||||
| 	"github.com/alicebob/miniredis/v2" | ||||
| 	"github.com/oauth2-proxy/oauth2-proxy/pkg/apis/options" | ||||
| 	"github.com/oauth2-proxy/oauth2-proxy/pkg/apis/sessions" | ||||
| 	"github.com/stretchr/testify/assert" | ||||
| 	"github.com/stretchr/testify/require" | ||||
| ) | ||||
|  | ||||
| func TestRedisStore(t *testing.T) { | ||||
| 	secret := make([]byte, 32) | ||||
| 	_, err := rand.Read(secret) | ||||
| 	assert.NoError(t, err) | ||||
|  | ||||
| 	t.Run("save session on redis standalone", func(t *testing.T) { | ||||
| 		redisServer, err := miniredis.Run() | ||||
| 		require.NoError(t, err) | ||||
| 		defer redisServer.Close() | ||||
| 		opts := options.NewOptions() | ||||
| 		redisURL := url.URL{ | ||||
| 			Scheme: "redis", | ||||
| 			Host:   redisServer.Addr(), | ||||
| 		} | ||||
| 		opts.Session.Redis.ConnectionURL = redisURL.String() | ||||
|  | ||||
| 		opts.Cookie.Secret = string(secret) | ||||
| 		redisStore, err := NewRedisSessionStore(&opts.Session, &opts.Cookie) | ||||
| 		require.NoError(t, err) | ||||
| 		err = redisStore.Save( | ||||
| 			httptest.NewRecorder(), | ||||
| 			httptest.NewRequest(http.MethodGet, "/", nil), | ||||
| 			&sessions.SessionState{}) | ||||
| 		assert.NoError(t, err) | ||||
| 	}) | ||||
| 	t.Run("save session on redis sentinel", func(t *testing.T) { | ||||
| 		redisServer, err := miniredis.Run() | ||||
| 		require.NoError(t, err) | ||||
| 		defer redisServer.Close() | ||||
| 		sentinel := minisentinel.NewSentinel(redisServer) | ||||
| 		err = sentinel.Start() | ||||
| 		require.NoError(t, err) | ||||
| 		defer sentinel.Close() | ||||
| 		opts := options.NewOptions() | ||||
| 		sentinelURL := url.URL{ | ||||
| 			Scheme: "redis", | ||||
| 			Host:   sentinel.Addr(), | ||||
| 		} | ||||
| 		opts.Session.Redis.SentinelConnectionURLs = []string{sentinelURL.String()} | ||||
| 		opts.Session.Redis.UseSentinel = true | ||||
| 		opts.Session.Redis.SentinelMasterName = sentinel.MasterInfo().Name | ||||
|  | ||||
| 		opts.Cookie.Secret = string(secret) | ||||
| 		redisStore, err := NewRedisSessionStore(&opts.Session, &opts.Cookie) | ||||
| 		require.NoError(t, err) | ||||
| 		err = redisStore.Save( | ||||
| 			httptest.NewRecorder(), | ||||
| 			httptest.NewRequest(http.MethodGet, "/", nil), | ||||
| 			&sessions.SessionState{}) | ||||
| 		assert.NoError(t, err) | ||||
| 	}) | ||||
| } | ||||
							
								
								
									
										101
									
								
								pkg/sessions/redis/session_store_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								pkg/sessions/redis/session_store_test.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| package redis | ||||
|  | ||||
| import ( | ||||
| 	"log" | ||||
| 	"os" | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/Bose/minisentinel" | ||||
| 	"github.com/alicebob/miniredis/v2" | ||||
| 	"github.com/go-redis/redis/v7" | ||||
| 	"github.com/oauth2-proxy/oauth2-proxy/pkg/apis/options" | ||||
| 	sessionsapi "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/sessions" | ||||
| 	"github.com/oauth2-proxy/oauth2-proxy/pkg/logger" | ||||
| 	"github.com/oauth2-proxy/oauth2-proxy/pkg/sessions/tests" | ||||
| 	. "github.com/onsi/ginkgo" | ||||
| 	. "github.com/onsi/gomega" | ||||
| ) | ||||
|  | ||||
| func TestSessionStore(t *testing.T) { | ||||
| 	logger.SetOutput(GinkgoWriter) | ||||
|  | ||||
| 	redisLogger := log.New(os.Stderr, "redis: ", log.LstdFlags|log.Lshortfile) | ||||
| 	redisLogger.SetOutput(GinkgoWriter) | ||||
| 	redis.SetLogger(redisLogger) | ||||
|  | ||||
| 	RegisterFailHandler(Fail) | ||||
| 	RunSpecs(t, "Redis SessionStore") | ||||
| } | ||||
|  | ||||
| var _ = Describe("Redis SessionStore Tests", func() { | ||||
| 	var mr *miniredis.Miniredis | ||||
|  | ||||
| 	BeforeEach(func() { | ||||
| 		var err error | ||||
| 		mr, err = miniredis.Run() | ||||
| 		Expect(err).ToNot(HaveOccurred()) | ||||
| 	}) | ||||
|  | ||||
| 	AfterEach(func() { | ||||
| 		mr.Close() | ||||
| 	}) | ||||
|  | ||||
| 	tests.RunSessionStoreTests( | ||||
| 		func(opts *options.SessionOptions, cookieOpts *options.CookieOptions) (sessionsapi.SessionStore, error) { | ||||
| 			// Set the connection URL | ||||
| 			opts.Type = options.RedisSessionStoreType | ||||
| 			opts.Redis.ConnectionURL = "redis://" + mr.Addr() | ||||
| 			return NewRedisSessionStore(opts, cookieOpts) | ||||
| 		}, | ||||
| 		func(d time.Duration) error { | ||||
| 			mr.FastForward(d) | ||||
| 			return nil | ||||
| 		}, | ||||
| 	) | ||||
|  | ||||
| 	Context("with sentinel", func() { | ||||
| 		var ms *minisentinel.Sentinel | ||||
|  | ||||
| 		BeforeEach(func() { | ||||
| 			ms = minisentinel.NewSentinel(mr) | ||||
| 			Expect(ms.Start()).To(Succeed()) | ||||
| 		}) | ||||
|  | ||||
| 		AfterEach(func() { | ||||
| 			go ms.Close() | ||||
| 		}) | ||||
|  | ||||
| 		tests.RunSessionStoreTests( | ||||
| 			func(opts *options.SessionOptions, cookieOpts *options.CookieOptions) (sessionsapi.SessionStore, error) { | ||||
| 				// Set the sentinel connection URL | ||||
| 				sentinelAddr := "redis://" + ms.Addr() | ||||
| 				opts.Type = options.RedisSessionStoreType | ||||
| 				opts.Redis.SentinelConnectionURLs = []string{sentinelAddr} | ||||
| 				opts.Redis.UseSentinel = true | ||||
| 				opts.Redis.SentinelMasterName = ms.MasterInfo().Name | ||||
| 				return NewRedisSessionStore(opts, cookieOpts) | ||||
| 			}, | ||||
| 			func(d time.Duration) error { | ||||
| 				mr.FastForward(d) | ||||
| 				return nil | ||||
| 			}, | ||||
| 		) | ||||
| 	}) | ||||
|  | ||||
| 	Context("with cluster", func() { | ||||
| 		tests.RunSessionStoreTests( | ||||
| 			func(opts *options.SessionOptions, cookieOpts *options.CookieOptions) (sessionsapi.SessionStore, error) { | ||||
| 				clusterAddr := "redis://" + mr.Addr() | ||||
| 				opts.Type = options.RedisSessionStoreType | ||||
| 				opts.Redis.ClusterConnectionURLs = []string{clusterAddr} | ||||
| 				opts.Redis.UseCluster = true | ||||
| 				return NewRedisSessionStore(opts, cookieOpts) | ||||
| 			}, | ||||
| 			func(d time.Duration) error { | ||||
| 				mr.FastForward(d) | ||||
| 				return nil | ||||
| 			}, | ||||
| 		) | ||||
| 	}) | ||||
| }) | ||||
| @@ -1,20 +1,12 @@ | ||||
| package sessions_test | ||||
|  | ||||
| import ( | ||||
| 	"crypto/rand" | ||||
| 	"encoding/base64" | ||||
| 	"net/http" | ||||
| 	"net/http/httptest" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"math/rand" | ||||
| 	"testing" | ||||
| 	"time" | ||||
|  | ||||
| 	miniredis "github.com/alicebob/miniredis/v2" | ||||
| 	"github.com/oauth2-proxy/oauth2-proxy/pkg/apis/options" | ||||
| 	sessionsapi "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/sessions" | ||||
| 	cookiesapi "github.com/oauth2-proxy/oauth2-proxy/pkg/cookies" | ||||
| 	"github.com/oauth2-proxy/oauth2-proxy/pkg/encryption" | ||||
| 	"github.com/oauth2-proxy/oauth2-proxy/pkg/logger" | ||||
| 	"github.com/oauth2-proxy/oauth2-proxy/pkg/sessions" | ||||
| 	sessionscookie "github.com/oauth2-proxy/oauth2-proxy/pkg/sessions/cookie" | ||||
| @@ -34,341 +26,7 @@ var _ = Describe("NewSessionStore", func() { | ||||
| 	var opts *options.SessionOptions | ||||
| 	var cookieOpts *options.CookieOptions | ||||
|  | ||||
| 	var request *http.Request | ||||
| 	var response *httptest.ResponseRecorder | ||||
| 	var session *sessionsapi.SessionState | ||||
| 	var ss sessionsapi.SessionStore | ||||
| 	var mr *miniredis.Miniredis | ||||
|  | ||||
| 	CheckCookieOptions := func() { | ||||
| 		Context("the cookies returned", func() { | ||||
| 			var cookies []*http.Cookie | ||||
| 			BeforeEach(func() { | ||||
| 				cookies = response.Result().Cookies() | ||||
| 			}) | ||||
|  | ||||
| 			It("have the correct name set", func() { | ||||
| 				if len(cookies) == 1 { | ||||
| 					Expect(cookies[0].Name).To(Equal(cookieOpts.Name)) | ||||
| 				} else { | ||||
| 					for _, cookie := range cookies { | ||||
| 						Expect(cookie.Name).To(ContainSubstring(cookieOpts.Name)) | ||||
| 					} | ||||
| 				} | ||||
| 			}) | ||||
|  | ||||
| 			It("have the correct path set", func() { | ||||
| 				for _, cookie := range cookies { | ||||
| 					Expect(cookie.Path).To(Equal(cookieOpts.Path)) | ||||
| 				} | ||||
| 			}) | ||||
|  | ||||
| 			It("have the correct domain set", func() { | ||||
| 				for _, cookie := range cookies { | ||||
| 					specifiedDomain := "" | ||||
| 					if len(cookieOpts.Domains) > 0 { | ||||
| 						specifiedDomain = cookieOpts.Domains[0] | ||||
| 					} | ||||
| 					Expect(cookie.Domain).To(Equal(specifiedDomain)) | ||||
| 				} | ||||
| 			}) | ||||
|  | ||||
| 			It("have the correct HTTPOnly set", func() { | ||||
| 				for _, cookie := range cookies { | ||||
| 					Expect(cookie.HttpOnly).To(Equal(cookieOpts.HTTPOnly)) | ||||
| 				} | ||||
| 			}) | ||||
|  | ||||
| 			It("have the correct secure set", func() { | ||||
| 				for _, cookie := range cookies { | ||||
| 					Expect(cookie.Secure).To(Equal(cookieOpts.Secure)) | ||||
| 				} | ||||
| 			}) | ||||
|  | ||||
| 			It("have the correct SameSite set", func() { | ||||
| 				for _, cookie := range cookies { | ||||
| 					Expect(cookie.SameSite).To(Equal(cookiesapi.ParseSameSite(cookieOpts.SameSite))) | ||||
| 				} | ||||
| 			}) | ||||
|  | ||||
| 			It("have a signature timestamp matching session.CreatedAt", func() { | ||||
| 				for _, cookie := range cookies { | ||||
| 					if cookie.Value != "" { | ||||
| 						parts := strings.Split(cookie.Value, "|") | ||||
| 						Expect(parts).To(HaveLen(3)) | ||||
| 						Expect(parts[1]).To(Equal(strconv.Itoa(int(session.CreatedAt.Unix())))) | ||||
| 					} | ||||
| 				} | ||||
| 			}) | ||||
|  | ||||
| 		}) | ||||
| 	} | ||||
|  | ||||
| 	// The following should only be for server stores | ||||
| 	PersistentSessionStoreTests := func() { | ||||
| 		Context("when Clear is called on a persistent store", func() { | ||||
| 			var resultCookies []*http.Cookie | ||||
|  | ||||
| 			BeforeEach(func() { | ||||
| 				req := httptest.NewRequest("GET", "http://example.com/", nil) | ||||
| 				saveResp := httptest.NewRecorder() | ||||
| 				err := ss.Save(saveResp, req, session) | ||||
| 				Expect(err).ToNot(HaveOccurred()) | ||||
|  | ||||
| 				resultCookies = saveResp.Result().Cookies() | ||||
| 				for _, c := range resultCookies { | ||||
| 					request.AddCookie(c) | ||||
| 				} | ||||
| 				err = ss.Clear(response, request) | ||||
| 				Expect(err).ToNot(HaveOccurred()) | ||||
| 			}) | ||||
|  | ||||
| 			Context("attempting to Load", func() { | ||||
| 				var loadedAfterClear *sessionsapi.SessionState | ||||
| 				var loadErr error | ||||
|  | ||||
| 				BeforeEach(func() { | ||||
| 					loadReq := httptest.NewRequest("GET", "http://example.com/", nil) | ||||
| 					for _, c := range resultCookies { | ||||
| 						loadReq.AddCookie(c) | ||||
| 					} | ||||
|  | ||||
| 					loadedAfterClear, loadErr = ss.Load(loadReq) | ||||
| 				}) | ||||
|  | ||||
| 				It("returns an empty session", func() { | ||||
| 					Expect(loadedAfterClear).To(BeNil()) | ||||
| 				}) | ||||
|  | ||||
| 				It("returns an error", func() { | ||||
| 					Expect(loadErr).To(HaveOccurred()) | ||||
| 				}) | ||||
| 			}) | ||||
|  | ||||
| 			CheckCookieOptions() | ||||
| 		}) | ||||
| 	} | ||||
|  | ||||
| 	SessionStoreInterfaceTests := func(persistent bool) { | ||||
| 		Context("when Save is called", func() { | ||||
| 			Context("with no existing session", func() { | ||||
| 				BeforeEach(func() { | ||||
| 					err := ss.Save(response, request, session) | ||||
| 					Expect(err).ToNot(HaveOccurred()) | ||||
| 				}) | ||||
|  | ||||
| 				It("sets a `set-cookie` header in the response", func() { | ||||
| 					Expect(response.Header().Get("set-cookie")).ToNot(BeEmpty()) | ||||
| 				}) | ||||
|  | ||||
| 				It("Ensures the session CreatedAt is not zero", func() { | ||||
| 					Expect(session.CreatedAt.IsZero()).To(BeFalse()) | ||||
| 				}) | ||||
| 			}) | ||||
|  | ||||
| 			Context("with a broken session", func() { | ||||
| 				BeforeEach(func() { | ||||
| 					By("Using a valid cookie with a different providers session encoding") | ||||
| 					broken := "BrokenSessionFromADifferentSessionImplementation" | ||||
| 					value := encryption.SignedValue(cookieOpts.Secret, cookieOpts.Name, []byte(broken), time.Now()) | ||||
| 					cookie := cookiesapi.MakeCookieFromOptions(request, cookieOpts.Name, value, cookieOpts, cookieOpts.Expire, time.Now()) | ||||
| 					request.AddCookie(cookie) | ||||
|  | ||||
| 					err := ss.Save(response, request, session) | ||||
| 					Expect(err).ToNot(HaveOccurred()) | ||||
| 				}) | ||||
|  | ||||
| 				It("sets a `set-cookie` header in the response", func() { | ||||
| 					Expect(response.Header().Get("set-cookie")).ToNot(BeEmpty()) | ||||
| 				}) | ||||
|  | ||||
| 				It("Ensures the session CreatedAt is not zero", func() { | ||||
| 					Expect(session.CreatedAt.IsZero()).To(BeFalse()) | ||||
| 				}) | ||||
| 			}) | ||||
|  | ||||
| 			Context("with an expired saved session", func() { | ||||
| 				var err error | ||||
| 				BeforeEach(func() { | ||||
| 					By("saving a session") | ||||
| 					req := httptest.NewRequest("GET", "http://example.com/", nil) | ||||
| 					saveResp := httptest.NewRecorder() | ||||
| 					err = ss.Save(saveResp, req, session) | ||||
| 					Expect(err).ToNot(HaveOccurred()) | ||||
|  | ||||
| 					By("and clearing the session") | ||||
| 					for _, c := range saveResp.Result().Cookies() { | ||||
| 						request.AddCookie(c) | ||||
| 					} | ||||
| 					clearResp := httptest.NewRecorder() | ||||
| 					err = ss.Clear(clearResp, request) | ||||
| 					Expect(err).ToNot(HaveOccurred()) | ||||
|  | ||||
| 					By("then saving a request with the cleared session") | ||||
| 					err = ss.Save(response, request, session) | ||||
| 				}) | ||||
|  | ||||
| 				It("no error should occur", func() { | ||||
| 					Expect(err).ToNot(HaveOccurred()) | ||||
| 				}) | ||||
| 			}) | ||||
|  | ||||
| 			CheckCookieOptions() | ||||
| 		}) | ||||
|  | ||||
| 		Context("when Clear is called", func() { | ||||
| 			BeforeEach(func() { | ||||
| 				req := httptest.NewRequest("GET", "http://example.com/", nil) | ||||
| 				saveResp := httptest.NewRecorder() | ||||
| 				err := ss.Save(saveResp, req, session) | ||||
| 				Expect(err).ToNot(HaveOccurred()) | ||||
|  | ||||
| 				for _, c := range saveResp.Result().Cookies() { | ||||
| 					request.AddCookie(c) | ||||
| 				} | ||||
| 				err = ss.Clear(response, request) | ||||
| 				Expect(err).ToNot(HaveOccurred()) | ||||
| 			}) | ||||
|  | ||||
| 			It("sets a `set-cookie` header in the response", func() { | ||||
| 				Expect(response.Header().Get("Set-Cookie")).ToNot(BeEmpty()) | ||||
| 			}) | ||||
|  | ||||
| 			CheckCookieOptions() | ||||
| 		}) | ||||
|  | ||||
| 		Context("when Load is called", func() { | ||||
| 			LoadSessionTests := func() { | ||||
| 				var loadedSession *sessionsapi.SessionState | ||||
| 				BeforeEach(func() { | ||||
| 					var err error | ||||
| 					loadedSession, err = ss.Load(request) | ||||
| 					Expect(err).ToNot(HaveOccurred()) | ||||
| 				}) | ||||
|  | ||||
| 				It("loads a session equal to the original session", func() { | ||||
| 					if cookieOpts.Secret == "" { | ||||
| 						// Only Email and User stored in session when encrypted | ||||
| 						Expect(loadedSession.Email).To(Equal(session.Email)) | ||||
| 						Expect(loadedSession.User).To(Equal(session.User)) | ||||
| 					} else { | ||||
| 						// All fields stored in session if encrypted | ||||
|  | ||||
| 						// Can't compare time.Time using Equal() so remove ExpiresOn from sessions | ||||
| 						l := *loadedSession | ||||
| 						l.CreatedAt = nil | ||||
| 						l.ExpiresOn = nil | ||||
| 						s := *session | ||||
| 						s.CreatedAt = nil | ||||
| 						s.ExpiresOn = nil | ||||
| 						Expect(l).To(Equal(s)) | ||||
|  | ||||
| 						// Compare time.Time separately | ||||
| 						Expect(loadedSession.CreatedAt.Equal(*session.CreatedAt)).To(BeTrue()) | ||||
| 						Expect(loadedSession.ExpiresOn.Equal(*session.ExpiresOn)).To(BeTrue()) | ||||
| 					} | ||||
| 				}) | ||||
| 			} | ||||
|  | ||||
| 			BeforeEach(func() { | ||||
| 				req := httptest.NewRequest("GET", "http://example.com/", nil) | ||||
| 				resp := httptest.NewRecorder() | ||||
| 				err := ss.Save(resp, req, session) | ||||
| 				Expect(err).ToNot(HaveOccurred()) | ||||
|  | ||||
| 				for _, cookie := range resp.Result().Cookies() { | ||||
| 					request.AddCookie(cookie) | ||||
| 				} | ||||
| 			}) | ||||
|  | ||||
| 			Context("before the refresh period", func() { | ||||
| 				LoadSessionTests() | ||||
| 			}) | ||||
|  | ||||
| 			// Test TTLs and cleanup of persistent session storage | ||||
| 			// For non-persistent we rely on the browser cookie lifecycle | ||||
| 			if persistent { | ||||
| 				Context("after the refresh period, but before the cookie expire period", func() { | ||||
| 					BeforeEach(func() { | ||||
| 						switch ss.(type) { | ||||
| 						case *redis.SessionStore: | ||||
| 							mr.FastForward(cookieOpts.Refresh + time.Minute) | ||||
| 						} | ||||
| 					}) | ||||
|  | ||||
| 					LoadSessionTests() | ||||
| 				}) | ||||
|  | ||||
| 				Context("after the cookie expire period", func() { | ||||
| 					var loadedSession *sessionsapi.SessionState | ||||
| 					var err error | ||||
|  | ||||
| 					BeforeEach(func() { | ||||
| 						switch ss.(type) { | ||||
| 						case *redis.SessionStore: | ||||
| 							mr.FastForward(cookieOpts.Expire + time.Minute) | ||||
| 						} | ||||
|  | ||||
| 						loadedSession, err = ss.Load(request) | ||||
| 						Expect(err).To(HaveOccurred()) | ||||
| 					}) | ||||
|  | ||||
| 					It("returns an error loading the session", func() { | ||||
| 						Expect(err).To(HaveOccurred()) | ||||
| 					}) | ||||
|  | ||||
| 					It("returns an empty session", func() { | ||||
| 						Expect(loadedSession).To(BeNil()) | ||||
| 					}) | ||||
| 				}) | ||||
| 			} | ||||
| 		}) | ||||
|  | ||||
| 		if persistent { | ||||
| 			PersistentSessionStoreTests() | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	RunSessionTests := func(persistent bool) { | ||||
| 		Context("with default options", func() { | ||||
| 			BeforeEach(func() { | ||||
| 				var err error | ||||
| 				ss, err = sessions.NewSessionStore(opts, cookieOpts) | ||||
| 				Expect(err).ToNot(HaveOccurred()) | ||||
| 			}) | ||||
|  | ||||
| 			SessionStoreInterfaceTests(persistent) | ||||
| 		}) | ||||
|  | ||||
| 		Context("with non-default options", func() { | ||||
| 			BeforeEach(func() { | ||||
| 				cookieOpts = &options.CookieOptions{ | ||||
| 					Name:     "_cookie_name", | ||||
| 					Path:     "/path", | ||||
| 					Expire:   time.Duration(72) * time.Hour, | ||||
| 					Refresh:  time.Duration(2) * time.Hour, | ||||
| 					Secure:   false, | ||||
| 					HTTPOnly: false, | ||||
| 					Domains:  []string{"example.com"}, | ||||
| 					SameSite: "strict", | ||||
| 				} | ||||
|  | ||||
| 				// A secret is required but not defaulted | ||||
| 				secret := make([]byte, 32) | ||||
| 				_, err := rand.Read(secret) | ||||
| 				Expect(err).ToNot(HaveOccurred()) | ||||
| 				cookieOpts.Secret = base64.URLEncoding.EncodeToString(secret) | ||||
|  | ||||
| 				ss, err = sessions.NewSessionStore(opts, cookieOpts) | ||||
| 				Expect(err).ToNot(HaveOccurred()) | ||||
| 			}) | ||||
|  | ||||
| 			SessionStoreInterfaceTests(persistent) | ||||
| 		}) | ||||
| 	} | ||||
|  | ||||
| 	BeforeEach(func() { | ||||
| 		ss = nil | ||||
| 		opts = &options.SessionOptions{} | ||||
|  | ||||
| 		// A secret is required to create a Cipher, validation ensures it is the correct | ||||
| @@ -388,19 +46,6 @@ var _ = Describe("NewSessionStore", func() { | ||||
| 			HTTPOnly: true, | ||||
| 			SameSite: "", | ||||
| 		} | ||||
|  | ||||
| 		expires := time.Now().Add(1 * time.Hour) | ||||
| 		session = &sessionsapi.SessionState{ | ||||
| 			AccessToken:  "AccessToken", | ||||
| 			IDToken:      "IDToken", | ||||
| 			ExpiresOn:    &expires, | ||||
| 			RefreshToken: "RefreshToken", | ||||
| 			Email:        "john.doe@example.com", | ||||
| 			User:         "john.doe", | ||||
| 		} | ||||
|  | ||||
| 		request = httptest.NewRequest("GET", "http://example.com/", nil) | ||||
| 		response = httptest.NewRecorder() | ||||
| 	}) | ||||
|  | ||||
| 	Context("with type 'cookie'", func() { | ||||
| @@ -413,36 +58,12 @@ var _ = Describe("NewSessionStore", func() { | ||||
| 			Expect(err).NotTo(HaveOccurred()) | ||||
| 			Expect(ss).To(BeAssignableToTypeOf(&sessionscookie.SessionStore{})) | ||||
| 		}) | ||||
|  | ||||
| 		Context("the cookie.SessionStore", func() { | ||||
| 			RunSessionTests(false) | ||||
| 		}) | ||||
|  | ||||
| 		Context("with an invalid cookie secret", func() { | ||||
| 			BeforeEach(func() { | ||||
| 				cookieOpts.Secret = "invalid" | ||||
| 			}) | ||||
|  | ||||
| 			It("returns an error", func() { | ||||
| 				ss, err := sessions.NewSessionStore(opts, cookieOpts) | ||||
| 				Expect(err).To(HaveOccurred()) | ||||
| 				Expect(err.Error()).To(Equal("error initialising cipher: crypto/aes: invalid key size 7")) | ||||
| 				Expect(ss).To(BeNil()) | ||||
| 			}) | ||||
| 		}) | ||||
| 	}) | ||||
|  | ||||
| 	Context("with type 'redis'", func() { | ||||
| 		BeforeEach(func() { | ||||
| 			var err error | ||||
| 			mr, err = miniredis.Run() | ||||
| 			Expect(err).ToNot(HaveOccurred()) | ||||
| 			opts.Type = options.RedisSessionStoreType | ||||
| 			opts.Redis.ConnectionURL = "redis://" + mr.Addr() | ||||
| 		}) | ||||
|  | ||||
| 		AfterEach(func() { | ||||
| 			mr.Close() | ||||
| 			opts.Redis.ConnectionURL = "redis://" | ||||
| 		}) | ||||
|  | ||||
| 		It("creates a redis.SessionStore", func() { | ||||
| @@ -450,23 +71,6 @@ var _ = Describe("NewSessionStore", func() { | ||||
| 			Expect(err).NotTo(HaveOccurred()) | ||||
| 			Expect(ss).To(BeAssignableToTypeOf(&redis.SessionStore{})) | ||||
| 		}) | ||||
|  | ||||
| 		Context("the redis.SessionStore", func() { | ||||
| 			RunSessionTests(true) | ||||
| 		}) | ||||
|  | ||||
| 		Context("with an invalid cookie secret", func() { | ||||
| 			BeforeEach(func() { | ||||
| 				cookieOpts.Secret = "invalid" | ||||
| 			}) | ||||
|  | ||||
| 			It("returns an error", func() { | ||||
| 				ss, err := sessions.NewSessionStore(opts, cookieOpts) | ||||
| 				Expect(err).To(HaveOccurred()) | ||||
| 				Expect(err.Error()).To(Equal("error initialising cipher: crypto/aes: invalid key size 7")) | ||||
| 				Expect(ss).To(BeNil()) | ||||
| 			}) | ||||
| 		}) | ||||
| 	}) | ||||
|  | ||||
| 	Context("with an invalid type", func() { | ||||
|   | ||||
							
								
								
									
										435
									
								
								pkg/sessions/tests/session_store_tests.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										435
									
								
								pkg/sessions/tests/session_store_tests.go
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,435 @@ | ||||
| package tests | ||||
|  | ||||
| import ( | ||||
| 	"crypto/rand" | ||||
| 	"net/http" | ||||
| 	"net/http/httptest" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| 	"time" | ||||
|  | ||||
| 	"github.com/oauth2-proxy/oauth2-proxy/pkg/apis/options" | ||||
| 	sessionsapi "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/sessions" | ||||
| 	cookiesapi "github.com/oauth2-proxy/oauth2-proxy/pkg/cookies" | ||||
| 	"github.com/oauth2-proxy/oauth2-proxy/pkg/encryption" | ||||
| 	. "github.com/onsi/ginkgo" | ||||
| 	. "github.com/onsi/gomega" | ||||
| ) | ||||
|  | ||||
| // testInput is passed to test function as a pointer. | ||||
| // This allows BeforeEach blocks to initialise and use these values after | ||||
| // Ginkgo has unpacked the tests. | ||||
| // Interfaces have to be wrapped in closures otherwise nil pointers are thrown. | ||||
| type testInput struct { | ||||
| 	cookieOpts            *options.CookieOptions | ||||
| 	ss                    sessionStoreFunc | ||||
| 	session               *sessionsapi.SessionState | ||||
| 	request               *http.Request | ||||
| 	response              *httptest.ResponseRecorder | ||||
| 	persistentFastForward PersistentStoreFastForwardFunc | ||||
| } | ||||
|  | ||||
| // sessionStoreFunc is used in testInput to wrap the SessionStore interface. | ||||
| type sessionStoreFunc func() sessionsapi.SessionStore | ||||
|  | ||||
| // PersistentStoreFastForwardFunc is used to adjust the time of the persistent | ||||
| // store to fast forward expiry of sessions. | ||||
| type PersistentStoreFastForwardFunc func(time.Duration) error | ||||
|  | ||||
| // NewSessionStoreFunc allows any session store implementation to configure their | ||||
| // own session store before each test. | ||||
| type NewSessionStoreFunc func(sessionOpts *options.SessionOptions, cookieOpts *options.CookieOptions) (sessionsapi.SessionStore, error) | ||||
|  | ||||
| func RunSessionStoreTests(newSS NewSessionStoreFunc, persistentFastForward PersistentStoreFastForwardFunc) { | ||||
| 	Describe("Session Store Suite", func() { | ||||
| 		var opts *options.SessionOptions | ||||
| 		var ss sessionsapi.SessionStore | ||||
| 		var input testInput | ||||
| 		var cookieSecret []byte | ||||
|  | ||||
| 		getSessionStore := func() sessionsapi.SessionStore { | ||||
| 			return ss | ||||
| 		} | ||||
|  | ||||
| 		BeforeEach(func() { | ||||
| 			ss = nil | ||||
| 			opts = &options.SessionOptions{} | ||||
|  | ||||
| 			// A secret is required to create a Cipher, validation ensures it is the correct | ||||
| 			// length before a session store is initialised. | ||||
| 			cookieSecret = make([]byte, 32) | ||||
| 			_, err := rand.Read(cookieSecret) | ||||
| 			Expect(err).ToNot(HaveOccurred()) | ||||
|  | ||||
| 			// Set default options in CookieOptions | ||||
| 			cookieOpts := &options.CookieOptions{ | ||||
| 				Name:     "_oauth2_proxy", | ||||
| 				Path:     "/", | ||||
| 				Expire:   time.Duration(168) * time.Hour, | ||||
| 				Refresh:  time.Duration(1) * time.Hour, | ||||
| 				Secure:   true, | ||||
| 				HTTPOnly: true, | ||||
| 				SameSite: "", | ||||
| 				Secret:   string(cookieSecret), | ||||
| 			} | ||||
|  | ||||
| 			expires := time.Now().Add(1 * time.Hour) | ||||
| 			session := &sessionsapi.SessionState{ | ||||
| 				AccessToken:  "AccessToken", | ||||
| 				IDToken:      "IDToken", | ||||
| 				ExpiresOn:    &expires, | ||||
| 				RefreshToken: "RefreshToken", | ||||
| 				Email:        "john.doe@example.com", | ||||
| 				User:         "john.doe", | ||||
| 			} | ||||
|  | ||||
| 			request := httptest.NewRequest("GET", "http://example.com/", nil) | ||||
| 			response := httptest.NewRecorder() | ||||
|  | ||||
| 			input = testInput{ | ||||
| 				cookieOpts:            cookieOpts, | ||||
| 				ss:                    getSessionStore, | ||||
| 				session:               session, | ||||
| 				request:               request, | ||||
| 				response:              response, | ||||
| 				persistentFastForward: persistentFastForward, | ||||
| 			} | ||||
| 		}) | ||||
|  | ||||
| 		Context("with default options", func() { | ||||
| 			BeforeEach(func() { | ||||
| 				var err error | ||||
| 				ss, err = newSS(opts, input.cookieOpts) | ||||
| 				Expect(err).ToNot(HaveOccurred()) | ||||
| 			}) | ||||
|  | ||||
| 			SessionStoreInterfaceTests(&input) | ||||
| 			if persistentFastForward != nil { | ||||
| 				PersistentSessionStoreInterfaceTests(&input) | ||||
| 			} | ||||
| 		}) | ||||
|  | ||||
| 		Context("with non-default options", func() { | ||||
| 			BeforeEach(func() { | ||||
| 				input.cookieOpts = &options.CookieOptions{ | ||||
| 					Name:     "_cookie_name", | ||||
| 					Path:     "/path", | ||||
| 					Expire:   time.Duration(72) * time.Hour, | ||||
| 					Refresh:  time.Duration(2) * time.Hour, | ||||
| 					Secure:   false, | ||||
| 					HTTPOnly: false, | ||||
| 					Domains:  []string{"example.com"}, | ||||
| 					SameSite: "strict", | ||||
| 					Secret:   string(cookieSecret), | ||||
| 				} | ||||
|  | ||||
| 				var err error | ||||
| 				ss, err = newSS(opts, input.cookieOpts) | ||||
| 				Expect(err).ToNot(HaveOccurred()) | ||||
| 			}) | ||||
|  | ||||
| 			SessionStoreInterfaceTests(&input) | ||||
| 			if persistentFastForward != nil { | ||||
| 				PersistentSessionStoreInterfaceTests(&input) | ||||
| 			} | ||||
| 		}) | ||||
|  | ||||
| 		Context("with an invalid cookie secret", func() { | ||||
| 			BeforeEach(func() { | ||||
| 				input.cookieOpts.Secret = "invalid" | ||||
| 			}) | ||||
|  | ||||
| 			It("returns an error when initialising the session store", func() { | ||||
| 				ss, err := newSS(opts, input.cookieOpts) | ||||
| 				Expect(err).To(MatchError("error initialising cipher: crypto/aes: invalid key size 7")) | ||||
| 				Expect(ss).To(BeNil()) | ||||
| 			}) | ||||
| 		}) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func CheckCookieOptions(in *testInput) { | ||||
| 	Context("the cookies returned", func() { | ||||
| 		var cookies []*http.Cookie | ||||
| 		BeforeEach(func() { | ||||
| 			cookies = in.response.Result().Cookies() | ||||
| 		}) | ||||
|  | ||||
| 		It("have the correct name set", func() { | ||||
| 			if len(cookies) == 1 { | ||||
| 				Expect(cookies[0].Name).To(Equal(in.cookieOpts.Name)) | ||||
| 			} else { | ||||
| 				for _, cookie := range cookies { | ||||
| 					Expect(cookie.Name).To(ContainSubstring(in.cookieOpts.Name)) | ||||
| 				} | ||||
| 			} | ||||
| 		}) | ||||
|  | ||||
| 		It("have the correct path set", func() { | ||||
| 			for _, cookie := range cookies { | ||||
| 				Expect(cookie.Path).To(Equal(in.cookieOpts.Path)) | ||||
| 			} | ||||
| 		}) | ||||
|  | ||||
| 		It("have the correct domain set", func() { | ||||
| 			for _, cookie := range cookies { | ||||
| 				specifiedDomain := "" | ||||
| 				if len(in.cookieOpts.Domains) > 0 { | ||||
| 					specifiedDomain = in.cookieOpts.Domains[0] | ||||
| 				} | ||||
| 				Expect(cookie.Domain).To(Equal(specifiedDomain)) | ||||
| 			} | ||||
| 		}) | ||||
|  | ||||
| 		It("have the correct HTTPOnly set", func() { | ||||
| 			for _, cookie := range cookies { | ||||
| 				Expect(cookie.HttpOnly).To(Equal(in.cookieOpts.HTTPOnly)) | ||||
| 			} | ||||
| 		}) | ||||
|  | ||||
| 		It("have the correct secure set", func() { | ||||
| 			for _, cookie := range cookies { | ||||
| 				Expect(cookie.Secure).To(Equal(in.cookieOpts.Secure)) | ||||
| 			} | ||||
| 		}) | ||||
|  | ||||
| 		It("have the correct SameSite set", func() { | ||||
| 			for _, cookie := range cookies { | ||||
| 				Expect(cookie.SameSite).To(Equal(cookiesapi.ParseSameSite(in.cookieOpts.SameSite))) | ||||
| 			} | ||||
| 		}) | ||||
|  | ||||
| 		It("have a signature timestamp matching session.CreatedAt", func() { | ||||
| 			for _, cookie := range cookies { | ||||
| 				if cookie.Value != "" { | ||||
| 					parts := strings.Split(cookie.Value, "|") | ||||
| 					Expect(parts).To(HaveLen(3)) | ||||
| 					Expect(parts[1]).To(Equal(strconv.Itoa(int(in.session.CreatedAt.Unix())))) | ||||
| 				} | ||||
| 			} | ||||
| 		}) | ||||
|  | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func PersistentSessionStoreInterfaceTests(in *testInput) { | ||||
| 	// Check that a stale cookie can't load an already cleared session | ||||
| 	Context("when Clear is called on a persistent store", func() { | ||||
| 		var resultCookies []*http.Cookie | ||||
|  | ||||
| 		BeforeEach(func() { | ||||
| 			req := httptest.NewRequest("GET", "http://example.com/", nil) | ||||
| 			saveResp := httptest.NewRecorder() | ||||
| 			err := in.ss().Save(saveResp, req, in.session) | ||||
| 			Expect(err).ToNot(HaveOccurred()) | ||||
|  | ||||
| 			resultCookies = saveResp.Result().Cookies() | ||||
| 			for _, c := range resultCookies { | ||||
| 				in.request.AddCookie(c) | ||||
| 			} | ||||
| 			err = in.ss().Clear(in.response, in.request) | ||||
| 			Expect(err).ToNot(HaveOccurred()) | ||||
| 		}) | ||||
|  | ||||
| 		Context("attempting to Load", func() { | ||||
| 			var loadedAfterClear *sessionsapi.SessionState | ||||
| 			var loadErr error | ||||
|  | ||||
| 			BeforeEach(func() { | ||||
| 				loadReq := httptest.NewRequest("GET", "http://example.com/", nil) | ||||
| 				for _, c := range resultCookies { | ||||
| 					loadReq.AddCookie(c) | ||||
| 				} | ||||
|  | ||||
| 				loadedAfterClear, loadErr = in.ss().Load(loadReq) | ||||
| 			}) | ||||
|  | ||||
| 			It("returns an empty session", func() { | ||||
| 				Expect(loadedAfterClear).To(BeNil()) | ||||
| 			}) | ||||
|  | ||||
| 			It("returns an error", func() { | ||||
| 				Expect(loadErr).To(HaveOccurred()) | ||||
| 			}) | ||||
| 		}) | ||||
|  | ||||
| 		CheckCookieOptions(in) | ||||
| 	}) | ||||
|  | ||||
| 	// Test TTLs and cleanup of persistent session storage | ||||
| 	// For non-persistent we rely on the browser cookie lifecycle | ||||
| 	Context("when Load is called on a persistent store", func() { | ||||
| 		BeforeEach(func() { | ||||
| 			req := httptest.NewRequest("GET", "http://example.com/", nil) | ||||
| 			resp := httptest.NewRecorder() | ||||
| 			err := in.ss().Save(resp, req, in.session) | ||||
| 			Expect(err).ToNot(HaveOccurred()) | ||||
|  | ||||
| 			for _, cookie := range resp.Result().Cookies() { | ||||
| 				in.request.AddCookie(cookie) | ||||
| 			} | ||||
| 		}) | ||||
|  | ||||
| 		Context("after the refresh period, but before the cookie expire period", func() { | ||||
| 			BeforeEach(func() { | ||||
| 				Expect(in.persistentFastForward(in.cookieOpts.Refresh + time.Minute)).To(Succeed()) | ||||
| 			}) | ||||
|  | ||||
| 			LoadSessionTests(in) | ||||
| 		}) | ||||
|  | ||||
| 		Context("after the cookie expire period", func() { | ||||
| 			var loadedSession *sessionsapi.SessionState | ||||
| 			var err error | ||||
|  | ||||
| 			BeforeEach(func() { | ||||
| 				Expect(in.persistentFastForward(in.cookieOpts.Expire + time.Minute)).To(Succeed()) | ||||
|  | ||||
| 				loadedSession, err = in.ss().Load(in.request) | ||||
| 				Expect(err).To(HaveOccurred()) | ||||
| 			}) | ||||
|  | ||||
| 			It("returns an error loading the session", func() { | ||||
| 				Expect(err).To(HaveOccurred()) | ||||
| 			}) | ||||
|  | ||||
| 			It("returns an empty session", func() { | ||||
| 				Expect(loadedSession).To(BeNil()) | ||||
| 			}) | ||||
| 		}) | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func SessionStoreInterfaceTests(in *testInput) { | ||||
| 	Context("when Save is called", func() { | ||||
| 		Context("with no existing session", func() { | ||||
| 			BeforeEach(func() { | ||||
| 				err := in.ss().Save(in.response, in.request, in.session) | ||||
| 				Expect(err).ToNot(HaveOccurred()) | ||||
| 			}) | ||||
|  | ||||
| 			It("sets a `set-cookie` header in the response", func() { | ||||
| 				Expect(in.response.Header().Get("set-cookie")).ToNot(BeEmpty()) | ||||
| 			}) | ||||
|  | ||||
| 			It("Ensures the session CreatedAt is not zero", func() { | ||||
| 				Expect(in.session.CreatedAt.IsZero()).To(BeFalse()) | ||||
| 			}) | ||||
|  | ||||
| 			CheckCookieOptions(in) | ||||
| 		}) | ||||
|  | ||||
| 		Context("with a broken session", func() { | ||||
| 			BeforeEach(func() { | ||||
| 				By("Using a valid cookie with a different providers session encoding") | ||||
| 				broken := "BrokenSessionFromADifferentSessionImplementation" | ||||
| 				value := encryption.SignedValue(in.cookieOpts.Secret, in.cookieOpts.Name, []byte(broken), time.Now()) | ||||
| 				cookie := cookiesapi.MakeCookieFromOptions(in.request, in.cookieOpts.Name, value, in.cookieOpts, in.cookieOpts.Expire, time.Now()) | ||||
| 				in.request.AddCookie(cookie) | ||||
|  | ||||
| 				err := in.ss().Save(in.response, in.request, in.session) | ||||
| 				Expect(err).ToNot(HaveOccurred()) | ||||
| 			}) | ||||
|  | ||||
| 			It("sets a `set-cookie` header in the response", func() { | ||||
| 				Expect(in.response.Header().Get("set-cookie")).ToNot(BeEmpty()) | ||||
| 			}) | ||||
|  | ||||
| 			It("Ensures the session CreatedAt is not zero", func() { | ||||
| 				Expect(in.session.CreatedAt.IsZero()).To(BeFalse()) | ||||
| 			}) | ||||
|  | ||||
| 			CheckCookieOptions(in) | ||||
| 		}) | ||||
|  | ||||
| 		Context("with an expired saved session", func() { | ||||
| 			var err error | ||||
| 			BeforeEach(func() { | ||||
| 				By("saving a session") | ||||
| 				req := httptest.NewRequest("GET", "http://example.com/", nil) | ||||
| 				saveResp := httptest.NewRecorder() | ||||
| 				err = in.ss().Save(saveResp, req, in.session) | ||||
| 				Expect(err).ToNot(HaveOccurred()) | ||||
|  | ||||
| 				By("and clearing the session") | ||||
| 				for _, c := range saveResp.Result().Cookies() { | ||||
| 					in.request.AddCookie(c) | ||||
| 				} | ||||
| 				clearResp := httptest.NewRecorder() | ||||
| 				err = in.ss().Clear(clearResp, in.request) | ||||
| 				Expect(err).ToNot(HaveOccurred()) | ||||
|  | ||||
| 				By("then saving a request with the cleared session") | ||||
| 				err = in.ss().Save(in.response, in.request, in.session) | ||||
| 			}) | ||||
|  | ||||
| 			It("no error should occur", func() { | ||||
| 				Expect(err).ToNot(HaveOccurred()) | ||||
| 			}) | ||||
| 		}) | ||||
| 	}) | ||||
|  | ||||
| 	Context("when Clear is called", func() { | ||||
| 		BeforeEach(func() { | ||||
| 			req := httptest.NewRequest("GET", "http://example.com/", nil) | ||||
| 			saveResp := httptest.NewRecorder() | ||||
| 			err := in.ss().Save(saveResp, req, in.session) | ||||
| 			Expect(err).ToNot(HaveOccurred()) | ||||
|  | ||||
| 			for _, c := range saveResp.Result().Cookies() { | ||||
| 				in.request.AddCookie(c) | ||||
| 			} | ||||
| 			err = in.ss().Clear(in.response, in.request) | ||||
| 			Expect(err).ToNot(HaveOccurred()) | ||||
| 		}) | ||||
|  | ||||
| 		It("sets a `set-cookie` header in the response", func() { | ||||
| 			Expect(in.response.Header().Get("Set-Cookie")).ToNot(BeEmpty()) | ||||
| 		}) | ||||
|  | ||||
| 		CheckCookieOptions(in) | ||||
| 	}) | ||||
|  | ||||
| 	Context("when Load is called", func() { | ||||
| 		BeforeEach(func() { | ||||
| 			req := httptest.NewRequest("GET", "http://example.com/", nil) | ||||
| 			resp := httptest.NewRecorder() | ||||
| 			err := in.ss().Save(resp, req, in.session) | ||||
| 			Expect(err).ToNot(HaveOccurred()) | ||||
|  | ||||
| 			for _, cookie := range resp.Result().Cookies() { | ||||
| 				in.request.AddCookie(cookie) | ||||
| 			} | ||||
| 		}) | ||||
|  | ||||
| 		Context("before the refresh period", func() { | ||||
| 			LoadSessionTests(in) | ||||
| 		}) | ||||
|  | ||||
| 	}) | ||||
| } | ||||
|  | ||||
| func LoadSessionTests(in *testInput) { | ||||
| 	var loadedSession *sessionsapi.SessionState | ||||
| 	BeforeEach(func() { | ||||
| 		var err error | ||||
| 		loadedSession, err = in.ss().Load(in.request) | ||||
| 		Expect(err).ToNot(HaveOccurred()) | ||||
| 	}) | ||||
|  | ||||
| 	It("loads a session equal to the original session", func() { | ||||
| 		// Can't compare time.Time using Equal() so remove ExpiresOn from sessions | ||||
| 		l := *loadedSession | ||||
| 		l.CreatedAt = nil | ||||
| 		l.ExpiresOn = nil | ||||
| 		s := *in.session | ||||
| 		s.CreatedAt = nil | ||||
| 		s.ExpiresOn = nil | ||||
| 		Expect(l).To(Equal(s)) | ||||
|  | ||||
| 		// Compare time.Time separately | ||||
| 		Expect(loadedSession.CreatedAt.Equal(*in.session.CreatedAt)).To(BeTrue()) | ||||
| 		Expect(loadedSession.ExpiresOn.Equal(*in.session.ExpiresOn)).To(BeTrue()) | ||||
|  | ||||
| 	}) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user