Merge pull request #869 from grnhse/streamline-provider-naming
Streamline Provider Interface & Bearer Session Handlers
This commit is contained in:
		
						commit
						f6ae15e8c3
					
				|  | @ -43,11 +43,12 @@ | |||
| 
 | ||||
| ## Changes since v6.1.1 | ||||
| 
 | ||||
| - [#925](https://github.com/oauth2-proxy/oauth2-rpoxy/pull/925) Fix basic auth legacy header conversion (@JoelSpeed) | ||||
| - [#916](https://github.com/oauth2-proxy/oauth2-rpoxy/pull/916) Add AlphaOptions struct to prepare for alpha config loading (@JoelSpeed) | ||||
| - [#925](https://github.com/oauth2-proxy/oauth2-proxy/pull/925) Fix basic auth legacy header conversion (@JoelSpeed) | ||||
| - [#916](https://github.com/oauth2-proxy/oauth2-proxy/pull/916) Add AlphaOptions struct to prepare for alpha config loading (@JoelSpeed) | ||||
| - [#923](https://github.com/oauth2-proxy/oauth2-proxy/pull/923) Support TLS 1.3 (@aajisaka) | ||||
| - [#918](https://github.com/oauth2-proxy/oauth2-proxy/pull/918) Fix log header output (@JoelSpeed) | ||||
| - [#911](https://github.com/oauth2-proxy/oauth2-proxy/pull/911) Validate provider type on startup. | ||||
| - [#869](https://github.com/oauth2-proxy/oauth2-proxy/pull/869) Streamline provider interface method names and signatures (@NickMeves) | ||||
| - [#906](https://github.com/oauth2-proxy/oauth2-proxy/pull/906) Set up v6.1.x versioned documentation as default documentation (@JoelSpeed) | ||||
| - [#905](https://github.com/oauth2-proxy/oauth2-proxy/pull/905) Remove v5 legacy sessions support (@NickMeves) | ||||
| - [#904](https://github.com/oauth2-proxy/oauth2-proxy/pull/904) Set `skip-auth-strip-headers` to `true` by default (@NickMeves) | ||||
|  |  | |||
							
								
								
									
										7
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										7
									
								
								go.mod
								
								
								
								
							|  | @ -19,15 +19,16 @@ require ( | |||
| 	github.com/onsi/gomega v1.10.2 | ||||
| 	github.com/pierrec/lz4 v2.5.2+incompatible | ||||
| 	github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect | ||||
| 	github.com/spf13/pflag v1.0.3 | ||||
| 	github.com/spf13/pflag v1.0.5 | ||||
| 	github.com/spf13/viper v1.6.3 | ||||
| 	github.com/stretchr/testify v1.6.1 | ||||
| 	github.com/vmihailenco/msgpack/v4 v4.3.11 | ||||
| 	github.com/yhat/wsutil v0.0.0-20170731153501-1d66fa95c997 | ||||
| 	golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 | ||||
| 	golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 | ||||
| 	golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 | ||||
| 	golang.org/x/net v0.0.0-20200707034311-ab3426394381 | ||||
| 	golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d | ||||
| 	google.golang.org/api v0.20.0 | ||||
| 	gopkg.in/natefinch/lumberjack.v2 v2.0.0 | ||||
| 	gopkg.in/square/go-jose.v2 v2.4.1 | ||||
| 	k8s.io/apimachinery v0.19.3 | ||||
| ) | ||||
|  |  | |||
							
								
								
									
										69
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										69
									
								
								go.sum
								
								
								
								
							|  | @ -8,7 +8,10 @@ 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/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= | ||||
| github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= | ||||
| github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= | ||||
| github.com/PuerkitoBio/urlesc v0.0.0-20160726150825-5bd2802263f2/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= | ||||
| 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/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc= | ||||
|  | @ -48,36 +51,52 @@ github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZm | |||
| github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= | ||||
| github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= | ||||
| github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= | ||||
| github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM= | ||||
| github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= | ||||
| github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= | ||||
| github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= | ||||
| github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= | ||||
| github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= | ||||
| github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= | ||||
| github.com/frankban/quicktest v1.10.0 h1:Gfh+GAJZOAoKZsIZeZbdn2JF10kN1XHNvjsvQK8gVkE= | ||||
| github.com/frankban/quicktest v1.10.0/go.mod h1:ui7WezCLWMWxVWr1GETZY3smRy0G4KWq9vcPtJmFl7Y= | ||||
| github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= | ||||
| github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= | ||||
| github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= | ||||
| github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= | ||||
| github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= | ||||
| github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= | ||||
| github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= | ||||
| github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= | ||||
| github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= | ||||
| github.com/go-logr/logr v0.2.0/go.mod h1:z6/tIYblkpsD+a4lm/fGIIU9mZ+XfAiaFtq7xTgseGU= | ||||
| github.com/go-openapi/jsonpointer v0.0.0-20160704185906-46af16f9f7b1/go.mod h1:+35s3my2LFTysnkMfxsJBAMHj/DoqoB9knIWoYG/Vk0= | ||||
| github.com/go-openapi/jsonreference v0.0.0-20160704190145-13c6e3589ad9/go.mod h1:W3Z9FmVs9qj+KR4zFKmDPGiLdk1D9Rlm7cyMvf57TTg= | ||||
| github.com/go-openapi/spec v0.0.0-20160808142527-6aced65f8501/go.mod h1:J8+jY1nAiCcj+friV/PDoE1/3eeccG9LYBs0tYvLOWc= | ||||
| github.com/go-openapi/swag v0.0.0-20160704191624-1d0bd113de87/go.mod h1:DXUve3Dpr1UfpPtxFw+EFuQ41HhCWZfha5jSVRG7C7I= | ||||
| github.com/go-redis/redis/v8 v8.2.3 h1:eNesND+DWt/sjQOtPFxAbQkTIXaXX00qNLxjVWkZ70k= | ||||
| github.com/go-redis/redis/v8 v8.2.3/go.mod h1:ysgGY09J/QeDYbu3HikWEIPCwaeOkuNoTgKayTEaEOw= | ||||
| github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= | ||||
| github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= | ||||
| github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= | ||||
| github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= | ||||
| github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= | ||||
| github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= | ||||
| github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= | ||||
| github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= | ||||
| github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= | ||||
| github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= | ||||
| github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||
| github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||
| github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= | ||||
| github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= | ||||
| github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= | ||||
| github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= | ||||
| github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= | ||||
| github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= | ||||
| github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= | ||||
| github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= | ||||
| github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= | ||||
| github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= | ||||
| github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= | ||||
| github.com/gomodule/redigo v1.7.1-0.20190322064113-39e2c31b7ca3/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= | ||||
|  | @ -92,6 +111,7 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ | |||
| github.com/google/go-cmp v0.5.1 h1:JFrFEBb2xKufg6XkJsJr+WbKb4FQlURi5RUcBveYu9k= | ||||
| github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= | ||||
| github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= | ||||
| github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= | ||||
| github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= | ||||
| github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= | ||||
|  | @ -99,6 +119,7 @@ github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+ | |||
| github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= | ||||
| github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM= | ||||
| github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= | ||||
| github.com/googleapis/gnostic v0.4.1/go.mod h1:LRhVm6pbyptWbWbuZ38d1eyptfvIytN3ir6b65WBswg= | ||||
| github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= | ||||
| github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= | ||||
| github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= | ||||
|  | @ -112,7 +133,9 @@ github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= | |||
| github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= | ||||
| github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= | ||||
| github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= | ||||
| github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= | ||||
| github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= | ||||
| github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= | ||||
| github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= | ||||
| github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= | ||||
| github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= | ||||
|  | @ -120,6 +143,7 @@ github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7V | |||
| github.com/justinas/alice v1.2.0 h1:+MHSA/vccVCF4Uq37S42jwlkvI2Xzl7zTPCN5BnZNVo= | ||||
| github.com/justinas/alice v1.2.0/go.mod h1:fN5HRH/reO/zrUflLfTN43t3vXvKzvZIENsNEe7i7qA= | ||||
| github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= | ||||
| github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= | ||||
| github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= | ||||
| github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= | ||||
| github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= | ||||
|  | @ -131,6 +155,7 @@ 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/mailru/easyjson v0.0.0-20160728113105-d5b7844b561a/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= | ||||
| 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= | ||||
|  | @ -139,16 +164,23 @@ github.com/mbland/hmacauth v0.0.0-20170912233209-44256dfd4bfa/go.mod h1:8vxFeeg+ | |||
| 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= | ||||
| github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= | ||||
| github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= | ||||
| github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= | ||||
| github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= | ||||
| github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= | ||||
| github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= | ||||
| github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= | ||||
| github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= | ||||
| github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= | ||||
| github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= | ||||
| github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= | ||||
| github.com/onsi/ginkgo v1.11.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= | ||||
| github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= | ||||
| github.com/onsi/ginkgo v1.14.1 h1:jMU0WaQrP0a/YAEq8eJmJKjBoMs+pClEr1vDMlM/Do4= | ||||
| github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= | ||||
| github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= | ||||
| 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.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= | ||||
| github.com/onsi/gomega v1.10.2 h1:aY/nuoWlKJud2J6U0E3NWsjlg+0GtwXxgEqthRdzlcs= | ||||
|  | @ -158,6 +190,7 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 | |||
| github.com/pierrec/lz4 v2.5.2+incompatible h1:WCjObylUIOlKy/+7Abdn34TLIkXiA4UWUMhxq9m9ZXI= | ||||
| github.com/pierrec/lz4 v2.5.2+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= | ||||
| github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | ||||
| github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= | ||||
| github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= | ||||
| github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= | ||||
| github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 h1:J9b7z+QKAmPf4YLrFg6oQUotqHQeUNWwkvo7jZp1GLU= | ||||
|  | @ -186,14 +219,18 @@ github.com/spf13/cast v1.3.0 h1:oget//CVOEoFewqQxwr0Ej5yjygnqGkvggSE/gB35Q8= | |||
| github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= | ||||
| github.com/spf13/jwalterweatherman v1.0.0 h1:XHEdyB+EcvlqZamSM4ZOMGlc93t6AcsBEu9Gc1vn7yk= | ||||
| github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= | ||||
| github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= | ||||
| github.com/spf13/pflag v1.0.3 h1:zPAT6CGy6wXeQ7NtTnaTerfKOsV6V6F8agHXFiazDkg= | ||||
| github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= | ||||
| github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= | ||||
| github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= | ||||
| github.com/spf13/viper v1.6.3 h1:pDDu1OyEDTKzpJwdq4TiuLyMsUgRa/BT5cn5O62NoHs= | ||||
| github.com/spf13/viper v1.6.3/go.mod h1:jUMtyi0/lB5yZH/FjyGAoH7IMNrIhlBf6pXZmbMDvzw= | ||||
| github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||
| github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= | ||||
| github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= | ||||
| github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= | ||||
| github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= | ||||
| github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= | ||||
| github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= | ||||
| github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= | ||||
|  | @ -223,6 +260,8 @@ go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= | |||
| golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= | ||||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2 h1:VklqNMn3ovrHsnt90PveolxSbWFaJdECFbxSq0Mqo2M= | ||||
| golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= | ||||
| golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= | ||||
| golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= | ||||
| golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= | ||||
| golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= | ||||
| golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= | ||||
|  | @ -237,12 +276,16 @@ golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73r | |||
| golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= | ||||
| golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||||
| golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= | ||||
| 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-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= | ||||
| golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= | ||||
| golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= | ||||
| golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7 h1:AeiKBIuRw3UomYXSbLy0Mc2dDLfdtbT/IVn4keq83P0= | ||||
| golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= | ||||
| golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU= | ||||
| golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= | ||||
| golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= | ||||
| golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= | ||||
| golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= | ||||
|  | @ -260,6 +303,7 @@ golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5h | |||
| golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| golang.org/x/sys v0.0.0-20190204203706-41f3e6584952/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= | ||||
| golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
|  | @ -267,14 +311,20 @@ golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7w | |||
| golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20200519105757-fe76b779f299 h1:DYfZAGf2WMFjMxbgTjaC+2HC7NkNAQs+6Q8b9WEB/F4= | ||||
| golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4 h1:5/PjkGUjvEU5Gl6BxmvKRPpqo2uNMv4rcHBMwzk/st8= | ||||
| golang.org/x/sys v0.0.0-20200622214017-ed371f2e16b4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= | ||||
| golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= | ||||
| golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs= | ||||
| golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= | ||||
| golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= | ||||
| golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= | ||||
| golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= | ||||
| golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= | ||||
| golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= | ||||
| golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= | ||||
| golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= | ||||
|  | @ -296,6 +346,8 @@ google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRn | |||
| google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= | ||||
| google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55 h1:gSJIx1SDwno+2ElGhA4+qG2zF97qiUzTM+rQ0klBOcE= | ||||
| google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= | ||||
| google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= | ||||
| google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= | ||||
| google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= | ||||
| google.golang.org/grpc v1.21.0/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= | ||||
| google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= | ||||
|  | @ -306,13 +358,20 @@ google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ | |||
| google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= | ||||
| google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= | ||||
| google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= | ||||
| google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= | ||||
| google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= | ||||
| google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= | ||||
| google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= | ||||
| google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA= | ||||
| google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= | ||||
| gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= | ||||
| gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= | ||||
| gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY= | ||||
| 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/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= | ||||
| gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= | ||||
| gopkg.in/ini.v1 v1.51.0 h1:AQvPpx3LzTDM0AjnIRlVFwFFGC+npRopjZxLJj6gdno= | ||||
| gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= | ||||
| gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8= | ||||
|  | @ -326,6 +385,7 @@ gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bl | |||
| gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= | ||||
| gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= | ||||
| gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= | ||||
|  | @ -333,3 +393,12 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C | |||
| 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= | ||||
| k8s.io/apimachinery v0.19.3 h1:bpIQXlKjB4cB/oNpnNnV+BybGPR7iP5oYpsOTEJ4hgc= | ||||
| k8s.io/apimachinery v0.19.3/go.mod h1:DnPGDnARWFvYa3pMHgSxtbZb7gpzzAZ1pTfaUNDVlmA= | ||||
| k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= | ||||
| k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE= | ||||
| k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y= | ||||
| k8s.io/kube-openapi v0.0.0-20200805222855-6aeccd4b50c6/go.mod h1:UuqjUnNftUyPE5H64/qeyjQoUZhGpeFDVdxjTeEVN2o= | ||||
| sigs.k8s.io/structured-merge-diff/v4 v4.0.1/go.mod h1:bJZC9H9iH24zzfZ/41RGcq60oK1F7G282QMXDPYydCw= | ||||
| sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o= | ||||
| sigs.k8s.io/yaml v1.2.0/go.mod h1:yfXDCHCao9+ENCvLSE62v9VSji2MKu5jeNfTrofGhJc= | ||||
|  |  | |||
							
								
								
									
										112
									
								
								oauthproxy.go
								
								
								
								
							
							
						
						
									
										112
									
								
								oauthproxy.go
								
								
								
								
							|  | @ -13,7 +13,6 @@ import ( | |||
| 	"strings" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/coreos/go-oidc" | ||||
| 	"github.com/justinas/alice" | ||||
| 	ipapi "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/ip" | ||||
| 	middlewareapi "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/middleware" | ||||
|  | @ -78,36 +77,34 @@ type OAuthProxy struct { | |||
| 	AuthOnlyPath      string | ||||
| 	UserInfoPath      string | ||||
| 
 | ||||
| 	allowedRoutes           []allowedRoute | ||||
| 	redirectURL             *url.URL // the url to receive requests at
 | ||||
| 	whitelistDomains        []string | ||||
| 	provider                providers.Provider | ||||
| 	providerNameOverride    string | ||||
| 	sessionStore            sessionsapi.SessionStore | ||||
| 	ProxyPrefix             string | ||||
| 	SignInMessage           string | ||||
| 	basicAuthValidator      basic.Validator | ||||
| 	displayHtpasswdForm     bool | ||||
| 	serveMux                http.Handler | ||||
| 	SetXAuthRequest         bool | ||||
| 	PassBasicAuth           bool | ||||
| 	SetBasicAuth            bool | ||||
| 	SkipProviderButton      bool | ||||
| 	PassUserHeaders         bool | ||||
| 	BasicAuthPassword       string | ||||
| 	PassAccessToken         bool | ||||
| 	SetAuthorization        bool | ||||
| 	PassAuthorization       bool | ||||
| 	PreferEmailToUser       bool | ||||
| 	skipAuthPreflight       bool | ||||
| 	skipJwtBearerTokens     bool | ||||
| 	mainJwtBearerVerifier   *oidc.IDTokenVerifier | ||||
| 	extraJwtBearerVerifiers []*oidc.IDTokenVerifier | ||||
| 	templates               *template.Template | ||||
| 	realClientIPParser      ipapi.RealClientIPParser | ||||
| 	trustedIPs              *ip.NetSet | ||||
| 	Banner                  string | ||||
| 	Footer                  string | ||||
| 	allowedRoutes        []allowedRoute | ||||
| 	redirectURL          *url.URL // the url to receive requests at
 | ||||
| 	whitelistDomains     []string | ||||
| 	provider             providers.Provider | ||||
| 	providerNameOverride string | ||||
| 	sessionStore         sessionsapi.SessionStore | ||||
| 	ProxyPrefix          string | ||||
| 	SignInMessage        string | ||||
| 	basicAuthValidator   basic.Validator | ||||
| 	displayHtpasswdForm  bool | ||||
| 	serveMux             http.Handler | ||||
| 	SetXAuthRequest      bool | ||||
| 	PassBasicAuth        bool | ||||
| 	SetBasicAuth         bool | ||||
| 	SkipProviderButton   bool | ||||
| 	PassUserHeaders      bool | ||||
| 	BasicAuthPassword    string | ||||
| 	PassAccessToken      bool | ||||
| 	SetAuthorization     bool | ||||
| 	PassAuthorization    bool | ||||
| 	PreferEmailToUser    bool | ||||
| 	skipAuthPreflight    bool | ||||
| 	skipJwtBearerTokens  bool | ||||
| 	templates            *template.Template | ||||
| 	realClientIPParser   ipapi.RealClientIPParser | ||||
| 	trustedIPs           *ip.NetSet | ||||
| 	Banner               string | ||||
| 	Footer               string | ||||
| 
 | ||||
| 	sessionChain alice.Chain | ||||
| 	headersChain alice.Chain | ||||
|  | @ -202,25 +199,23 @@ func NewOAuthProxy(opts *options.Options, validator func(string) bool) (*OAuthPr | |||
| 		AuthOnlyPath:      fmt.Sprintf("%s/auth", opts.ProxyPrefix), | ||||
| 		UserInfoPath:      fmt.Sprintf("%s/userinfo", opts.ProxyPrefix), | ||||
| 
 | ||||
| 		ProxyPrefix:             opts.ProxyPrefix, | ||||
| 		provider:                opts.GetProvider(), | ||||
| 		providerNameOverride:    opts.ProviderName, | ||||
| 		sessionStore:            sessionStore, | ||||
| 		serveMux:                upstreamProxy, | ||||
| 		redirectURL:             redirectURL, | ||||
| 		allowedRoutes:           allowedRoutes, | ||||
| 		whitelistDomains:        opts.WhitelistDomains, | ||||
| 		skipAuthPreflight:       opts.SkipAuthPreflight, | ||||
| 		skipJwtBearerTokens:     opts.SkipJwtBearerTokens, | ||||
| 		mainJwtBearerVerifier:   opts.GetOIDCVerifier(), | ||||
| 		extraJwtBearerVerifiers: opts.GetJWTBearerVerifiers(), | ||||
| 		realClientIPParser:      opts.GetRealClientIPParser(), | ||||
| 		SkipProviderButton:      opts.SkipProviderButton, | ||||
| 		templates:               templates, | ||||
| 		trustedIPs:              trustedIPs, | ||||
| 		Banner:                  opts.Banner, | ||||
| 		Footer:                  opts.Footer, | ||||
| 		SignInMessage:           buildSignInMessage(opts), | ||||
| 		ProxyPrefix:          opts.ProxyPrefix, | ||||
| 		provider:             opts.GetProvider(), | ||||
| 		providerNameOverride: opts.ProviderName, | ||||
| 		sessionStore:         sessionStore, | ||||
| 		serveMux:             upstreamProxy, | ||||
| 		redirectURL:          redirectURL, | ||||
| 		allowedRoutes:        allowedRoutes, | ||||
| 		whitelistDomains:     opts.WhitelistDomains, | ||||
| 		skipAuthPreflight:    opts.SkipAuthPreflight, | ||||
| 		skipJwtBearerTokens:  opts.SkipJwtBearerTokens, | ||||
| 		realClientIPParser:   opts.GetRealClientIPParser(), | ||||
| 		SkipProviderButton:   opts.SkipProviderButton, | ||||
| 		templates:            templates, | ||||
| 		trustedIPs:           trustedIPs, | ||||
| 		Banner:               opts.Banner, | ||||
| 		Footer:               opts.Footer, | ||||
| 		SignInMessage:        buildSignInMessage(opts), | ||||
| 
 | ||||
| 		basicAuthValidator:  basicAuthValidator, | ||||
| 		displayHtpasswdForm: basicAuthValidator != nil && opts.DisplayHtpasswdForm, | ||||
|  | @ -266,18 +261,13 @@ func buildSessionChain(opts *options.Options, sessionStore sessionsapi.SessionSt | |||
| 	chain := alice.New() | ||||
| 
 | ||||
| 	if opts.SkipJwtBearerTokens { | ||||
| 		sessionLoaders := []middlewareapi.TokenToSessionLoader{} | ||||
| 		if opts.GetOIDCVerifier() != nil { | ||||
| 			sessionLoaders = append(sessionLoaders, middlewareapi.TokenToSessionLoader{ | ||||
| 				Verifier:       opts.GetOIDCVerifier(), | ||||
| 				TokenToSession: opts.GetProvider().CreateSessionStateFromBearerToken, | ||||
| 			}) | ||||
| 		sessionLoaders := []middlewareapi.TokenToSessionFunc{ | ||||
| 			opts.GetProvider().CreateSessionFromToken, | ||||
| 		} | ||||
| 
 | ||||
| 		for _, verifier := range opts.GetJWTBearerVerifiers() { | ||||
| 			sessionLoaders = append(sessionLoaders, middlewareapi.TokenToSessionLoader{ | ||||
| 				Verifier: verifier, | ||||
| 			}) | ||||
| 			sessionLoaders = append(sessionLoaders, | ||||
| 				middlewareapi.CreateTokenToSessionFunc(verifier.Verify)) | ||||
| 		} | ||||
| 
 | ||||
| 		chain = chain.Append(middleware.NewJwtSessionLoader(sessionLoaders)) | ||||
|  | @ -291,7 +281,7 @@ func buildSessionChain(opts *options.Options, sessionStore sessionsapi.SessionSt | |||
| 		SessionStore:           sessionStore, | ||||
| 		RefreshPeriod:          opts.Cookie.Refresh, | ||||
| 		RefreshSessionIfNeeded: opts.GetProvider().RefreshSessionIfNeeded, | ||||
| 		ValidateSessionState:   opts.GetProvider().ValidateSessionState, | ||||
| 		ValidateSessionState:   opts.GetProvider().ValidateSession, | ||||
| 	})) | ||||
| 
 | ||||
| 	return chain | ||||
|  | @ -416,7 +406,7 @@ func (p *OAuthProxy) enrichSessionState(ctx context.Context, s *sessionsapi.Sess | |||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return p.provider.EnrichSessionState(ctx, s) | ||||
| 	return p.provider.EnrichSession(ctx, s) | ||||
| } | ||||
| 
 | ||||
| // MakeCSRFCookie creates a cookie for CSRF
 | ||||
|  |  | |||
|  | @ -400,7 +400,7 @@ func (tp *TestProvider) GetEmailAddress(_ context.Context, _ *sessions.SessionSt | |||
| 	return tp.EmailAddress, nil | ||||
| } | ||||
| 
 | ||||
| func (tp *TestProvider) ValidateSessionState(_ context.Context, _ *sessions.SessionState) bool { | ||||
| func (tp *TestProvider) ValidateSession(_ context.Context, _ *sessions.SessionState) bool { | ||||
| 	return tp.ValidToken | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -2,23 +2,57 @@ package middleware | |||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 	"fmt" | ||||
| 
 | ||||
| 	"github.com/coreos/go-oidc" | ||||
| 	sessionsapi "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions" | ||||
| ) | ||||
| 
 | ||||
| // TokenToSessionFunc takes a rawIDToken and an idToken and converts it into a
 | ||||
| // SessionState.
 | ||||
| type TokenToSessionFunc func(ctx context.Context, rawIDToken string, idToken *oidc.IDToken) (*sessionsapi.SessionState, error) | ||||
| // TokenToSessionFunc takes a raw ID Token and converts it into a SessionState.
 | ||||
| type TokenToSessionFunc func(ctx context.Context, token string) (*sessionsapi.SessionState, error) | ||||
| 
 | ||||
| // TokenToSessionLoader pairs a token verifier with the correct converter function
 | ||||
| // to convert the ID Token to a SessionState.
 | ||||
| type TokenToSessionLoader struct { | ||||
| 	// Verfier is used to verify that the ID Token was signed by the claimed issuer
 | ||||
| 	// and that the token has not been tampered with.
 | ||||
| 	Verifier *oidc.IDTokenVerifier | ||||
| // VerifyFunc takes a raw bearer token and verifies it returning the converted
 | ||||
| // oidc.IDToken representation of the token.
 | ||||
| type VerifyFunc func(ctx context.Context, token string) (*oidc.IDToken, error) | ||||
| 
 | ||||
| 	// TokenToSession converts a rawIDToken and an idToken to a SessionState.
 | ||||
| 	// (Optional) If not set a default basic implementation is used.
 | ||||
| 	TokenToSession TokenToSessionFunc | ||||
| // CreateTokenToSessionFunc provides a handler that is a default implementation
 | ||||
| // for converting a JWT into a session.
 | ||||
| func CreateTokenToSessionFunc(verify VerifyFunc) TokenToSessionFunc { | ||||
| 	return func(ctx context.Context, token string) (*sessionsapi.SessionState, error) { | ||||
| 		var claims struct { | ||||
| 			Subject           string `json:"sub"` | ||||
| 			Email             string `json:"email"` | ||||
| 			Verified          *bool  `json:"email_verified"` | ||||
| 			PreferredUsername string `json:"preferred_username"` | ||||
| 		} | ||||
| 
 | ||||
| 		idToken, err := verify(ctx, token) | ||||
| 		if err != nil { | ||||
| 			return nil, err | ||||
| 		} | ||||
| 
 | ||||
| 		if err := idToken.Claims(&claims); err != nil { | ||||
| 			return nil, fmt.Errorf("failed to parse bearer token claims: %v", err) | ||||
| 		} | ||||
| 
 | ||||
| 		if claims.Email == "" { | ||||
| 			claims.Email = claims.Subject | ||||
| 		} | ||||
| 
 | ||||
| 		if claims.Verified != nil && !*claims.Verified { | ||||
| 			return nil, fmt.Errorf("email in id_token (%s) isn't verified", claims.Email) | ||||
| 		} | ||||
| 
 | ||||
| 		newSession := &sessionsapi.SessionState{ | ||||
| 			Email:             claims.Email, | ||||
| 			User:              claims.Subject, | ||||
| 			PreferredUsername: claims.PreferredUsername, | ||||
| 			AccessToken:       token, | ||||
| 			IDToken:           token, | ||||
| 			RefreshToken:      "", | ||||
| 			ExpiresOn:         &idToken.Expiry, | ||||
| 		} | ||||
| 
 | ||||
| 		return newSession, nil | ||||
| 	} | ||||
| } | ||||
|  |  | |||
|  | @ -1,30 +1,21 @@ | |||
| package middleware | ||||
| 
 | ||||
| import ( | ||||
| 	"context" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"regexp" | ||||
| 
 | ||||
| 	"github.com/coreos/go-oidc" | ||||
| 	"github.com/justinas/alice" | ||||
| 	middlewareapi "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/middleware" | ||||
| 	sessionsapi "github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions" | ||||
| 	"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/logger" | ||||
| 	k8serrors "k8s.io/apimachinery/pkg/util/errors" | ||||
| ) | ||||
| 
 | ||||
| const jwtRegexFormat = `^eyJ[a-zA-Z0-9_-]*\.eyJ[a-zA-Z0-9_-]*\.[a-zA-Z0-9_-]+$` | ||||
| 
 | ||||
| func NewJwtSessionLoader(sessionLoaders []middlewareapi.TokenToSessionLoader) alice.Constructor { | ||||
| 	for i, loader := range sessionLoaders { | ||||
| 		if loader.TokenToSession == nil { | ||||
| 			sessionLoaders[i] = middlewareapi.TokenToSessionLoader{ | ||||
| 				Verifier:       loader.Verifier, | ||||
| 				TokenToSession: createSessionStateFromBearerToken, | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| const jwtRegexFormat = `^ey[IJ][a-zA-Z0-9_-]*\.ey[IJ][a-zA-Z0-9_-]*\.[a-zA-Z0-9_-]+$` | ||||
| 
 | ||||
| func NewJwtSessionLoader(sessionLoaders []middlewareapi.TokenToSessionFunc) alice.Constructor { | ||||
| 	js := &jwtSessionLoader{ | ||||
| 		jwtRegex:       regexp.MustCompile(jwtRegexFormat), | ||||
| 		sessionLoaders: sessionLoaders, | ||||
|  | @ -36,7 +27,7 @@ func NewJwtSessionLoader(sessionLoaders []middlewareapi.TokenToSessionLoader) al | |||
| // Authorization headers.
 | ||||
| type jwtSessionLoader struct { | ||||
| 	jwtRegex       *regexp.Regexp | ||||
| 	sessionLoaders []middlewareapi.TokenToSessionLoader | ||||
| 	sessionLoaders []middlewareapi.TokenToSessionFunc | ||||
| } | ||||
| 
 | ||||
| // loadSession attempts to load a session from a JWT stored in an Authorization
 | ||||
|  | @ -75,24 +66,27 @@ func (j *jwtSessionLoader) getJwtSession(req *http.Request) (*sessionsapi.Sessio | |||
| 		return nil, nil | ||||
| 	} | ||||
| 
 | ||||
| 	rawBearerToken, err := j.findBearerTokenFromHeader(auth) | ||||
| 	token, err := j.findTokenFromHeader(auth) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	// This leading error message only occurs if all session loaders fail
 | ||||
| 	errs := []error{errors.New("unable to verify bearer token")} | ||||
| 	for _, loader := range j.sessionLoaders { | ||||
| 		bearerToken, err := loader.Verifier.Verify(req.Context(), rawBearerToken) | ||||
| 		if err == nil { | ||||
| 			// The token was verified, convert it to a session
 | ||||
| 			return loader.TokenToSession(req.Context(), rawBearerToken, bearerToken) | ||||
| 		session, err := loader(req.Context(), token) | ||||
| 		if err != nil { | ||||
| 			errs = append(errs, err) | ||||
| 			continue | ||||
| 		} | ||||
| 		return session, nil | ||||
| 	} | ||||
| 
 | ||||
| 	return nil, fmt.Errorf("unable to verify jwt token: %q", req.Header.Get("Authorization")) | ||||
| 	return nil, k8serrors.NewAggregate(errs) | ||||
| } | ||||
| 
 | ||||
| // findBearerTokenFromHeader finds a valid JWT token from the Authorization header of a given request.
 | ||||
| func (j *jwtSessionLoader) findBearerTokenFromHeader(header string) (string, error) { | ||||
| // findTokenFromHeader finds a valid JWT token from the Authorization header of a given request.
 | ||||
| func (j *jwtSessionLoader) findTokenFromHeader(header string) (string, error) { | ||||
| 	tokenType, token, err := splitAuthHeader(header) | ||||
| 	if err != nil { | ||||
| 		return "", err | ||||
|  | @ -132,38 +126,3 @@ func (j *jwtSessionLoader) getBasicToken(token string) (string, error) { | |||
| 
 | ||||
| 	return "", fmt.Errorf("invalid basic auth token found in authorization header") | ||||
| } | ||||
| 
 | ||||
| // createSessionStateFromBearerToken is a default implementation for converting
 | ||||
| // a JWT into a session state.
 | ||||
| func createSessionStateFromBearerToken(ctx context.Context, rawIDToken string, idToken *oidc.IDToken) (*sessionsapi.SessionState, error) { | ||||
| 	var claims struct { | ||||
| 		Subject           string `json:"sub"` | ||||
| 		Email             string `json:"email"` | ||||
| 		Verified          *bool  `json:"email_verified"` | ||||
| 		PreferredUsername string `json:"preferred_username"` | ||||
| 	} | ||||
| 
 | ||||
| 	if err := idToken.Claims(&claims); err != nil { | ||||
| 		return nil, fmt.Errorf("failed to parse bearer token claims: %v", err) | ||||
| 	} | ||||
| 
 | ||||
| 	if claims.Email == "" { | ||||
| 		claims.Email = claims.Subject | ||||
| 	} | ||||
| 
 | ||||
| 	if claims.Verified != nil && !*claims.Verified { | ||||
| 		return nil, fmt.Errorf("email in id_token (%s) isn't verified", claims.Email) | ||||
| 	} | ||||
| 
 | ||||
| 	newSession := &sessionsapi.SessionState{ | ||||
| 		Email:             claims.Email, | ||||
| 		User:              claims.Subject, | ||||
| 		PreferredUsername: claims.PreferredUsername, | ||||
| 		AccessToken:       rawIDToken, | ||||
| 		IDToken:           rawIDToken, | ||||
| 		RefreshToken:      "", | ||||
| 		ExpiresOn:         &idToken.Expiry, | ||||
| 	} | ||||
| 
 | ||||
| 	return newSession, nil | ||||
| } | ||||
|  |  | |||
|  | @ -20,12 +20,13 @@ import ( | |||
| 	. "github.com/onsi/ginkgo" | ||||
| 	. "github.com/onsi/ginkgo/extensions/table" | ||||
| 	. "github.com/onsi/gomega" | ||||
| 	k8serrors "k8s.io/apimachinery/pkg/util/errors" | ||||
| ) | ||||
| 
 | ||||
| type noOpKeySet struct { | ||||
| } | ||||
| 
 | ||||
| func (noOpKeySet) VerifySignature(ctx context.Context, jwt string) (payload []byte, err error) { | ||||
| func (noOpKeySet) VerifySignature(_ context.Context, jwt string) (payload []byte, err error) { | ||||
| 	splitStrings := strings.Split(jwt, ".") | ||||
| 	payloadString := splitStrings[1] | ||||
| 	return base64.RawURLEncoding.DecodeString(payloadString) | ||||
|  | @ -73,13 +74,18 @@ Nnc3a3lGVWFCNUMxQnNJcnJMTWxka1dFaHluYmI4Ongtb2F1dGgtYmFzaWM=` | |||
| 	const validToken = "eyJfoobar.eyJfoobar.12345asdf" | ||||
| 
 | ||||
| 	Context("JwtSessionLoader", func() { | ||||
| 		var verifier *oidc.IDTokenVerifier | ||||
| 		var verifier middlewareapi.VerifyFunc | ||||
| 		const nonVerifiedToken = validToken | ||||
| 
 | ||||
| 		BeforeEach(func() { | ||||
| 			keyset := noOpKeySet{} | ||||
| 			verifier = oidc.NewVerifier("https://issuer.example.com", keyset, | ||||
| 				&oidc.Config{ClientID: "https://test.myapp.com", SkipExpiryCheck: true}) | ||||
| 			verifier = oidc.NewVerifier( | ||||
| 				"https://issuer.example.com", | ||||
| 				noOpKeySet{}, | ||||
| 				&oidc.Config{ | ||||
| 					ClientID:        "https://test.myapp.com", | ||||
| 					SkipExpiryCheck: true, | ||||
| 				}, | ||||
| 			).Verify | ||||
| 		}) | ||||
| 
 | ||||
| 		type jwtSessionLoaderTableInput struct { | ||||
|  | @ -102,10 +108,8 @@ Nnc3a3lGVWFCNUMxQnNJcnJMTWxka1dFaHluYmI4Ongtb2F1dGgtYmFzaWM=` | |||
| 
 | ||||
| 				rw := httptest.NewRecorder() | ||||
| 
 | ||||
| 				sessionLoaders := []middlewareapi.TokenToSessionLoader{ | ||||
| 					{ | ||||
| 						Verifier: verifier, | ||||
| 					}, | ||||
| 				sessionLoaders := []middlewareapi.TokenToSessionFunc{ | ||||
| 					middlewareapi.CreateTokenToSessionFunc(verifier), | ||||
| 				} | ||||
| 
 | ||||
| 				// Create the handler with a next handler that will capture the session
 | ||||
|  | @ -167,17 +171,19 @@ Nnc3a3lGVWFCNUMxQnNJcnJMTWxka1dFaHluYmI4Ongtb2F1dGgtYmFzaWM=` | |||
| 		const nonVerifiedToken = validToken | ||||
| 
 | ||||
| 		BeforeEach(func() { | ||||
| 			keyset := noOpKeySet{} | ||||
| 			verifier := oidc.NewVerifier("https://issuer.example.com", keyset, | ||||
| 				&oidc.Config{ClientID: "https://test.myapp.com", SkipExpiryCheck: true}) | ||||
| 			verifier := oidc.NewVerifier( | ||||
| 				"https://issuer.example.com", | ||||
| 				noOpKeySet{}, | ||||
| 				&oidc.Config{ | ||||
| 					ClientID:        "https://test.myapp.com", | ||||
| 					SkipExpiryCheck: true, | ||||
| 				}, | ||||
| 			).Verify | ||||
| 
 | ||||
| 			j = &jwtSessionLoader{ | ||||
| 				jwtRegex: regexp.MustCompile(jwtRegexFormat), | ||||
| 				sessionLoaders: []middlewareapi.TokenToSessionLoader{ | ||||
| 					{ | ||||
| 						Verifier:       verifier, | ||||
| 						TokenToSession: createSessionStateFromBearerToken, | ||||
| 					}, | ||||
| 				sessionLoaders: []middlewareapi.TokenToSessionFunc{ | ||||
| 					middlewareapi.CreateTokenToSessionFunc(verifier), | ||||
| 				}, | ||||
| 			} | ||||
| 		}) | ||||
|  | @ -218,8 +224,11 @@ Nnc3a3lGVWFCNUMxQnNJcnJMTWxka1dFaHluYmI4Ongtb2F1dGgtYmFzaWM=` | |||
| 			}), | ||||
| 			Entry("Bearer <nonVerifiedToken>", getJWTSessionTableInput{ | ||||
| 				authorizationHeader: fmt.Sprintf("Bearer %s", nonVerifiedToken), | ||||
| 				expectedErr:         errors.New("unable to verify jwt token: \"Bearer eyJfoobar.eyJfoobar.12345asdf\""), | ||||
| 				expectedSession:     nil, | ||||
| 				expectedErr: k8serrors.NewAggregate([]error{ | ||||
| 					errors.New("unable to verify bearer token"), | ||||
| 					errors.New("oidc: malformed jwt: illegal base64 data at input byte 8"), | ||||
| 				}), | ||||
| 				expectedSession: nil, | ||||
| 			}), | ||||
| 			Entry("Bearer <verifiedToken>", getJWTSessionTableInput{ | ||||
| 				authorizationHeader: fmt.Sprintf("Bearer %s", verifiedToken), | ||||
|  | @ -228,8 +237,11 @@ Nnc3a3lGVWFCNUMxQnNJcnJMTWxka1dFaHluYmI4Ongtb2F1dGgtYmFzaWM=` | |||
| 			}), | ||||
| 			Entry("Basic Base64(<nonVerifiedToken>:) (No password)", getJWTSessionTableInput{ | ||||
| 				authorizationHeader: "Basic ZXlKZm9vYmFyLmV5SmZvb2Jhci4xMjM0NWFzZGY6", | ||||
| 				expectedErr:         errors.New("unable to verify jwt token: \"Basic ZXlKZm9vYmFyLmV5SmZvb2Jhci4xMjM0NWFzZGY6\""), | ||||
| 				expectedSession:     nil, | ||||
| 				expectedErr: k8serrors.NewAggregate([]error{ | ||||
| 					errors.New("unable to verify bearer token"), | ||||
| 					errors.New("oidc: malformed jwt: illegal base64 data at input byte 8"), | ||||
| 				}), | ||||
| 				expectedSession: nil, | ||||
| 			}), | ||||
| 			Entry("Basic Base64(<verifiedToken>:x-oauth-basic) (Sentinel password)", getJWTSessionTableInput{ | ||||
| 				authorizationHeader: fmt.Sprintf("Basic %s", verifiedTokenXOAuthBasicBase64), | ||||
|  | @ -239,7 +251,7 @@ Nnc3a3lGVWFCNUMxQnNJcnJMTWxka1dFaHluYmI4Ongtb2F1dGgtYmFzaWM=` | |||
| 		) | ||||
| 	}) | ||||
| 
 | ||||
| 	Context("findBearerTokenFromHeader", func() { | ||||
| 	Context("findTokenFromHeader", func() { | ||||
| 		var j *jwtSessionLoader | ||||
| 
 | ||||
| 		BeforeEach(func() { | ||||
|  | @ -256,7 +268,7 @@ Nnc3a3lGVWFCNUMxQnNJcnJMTWxka1dFaHluYmI4Ongtb2F1dGgtYmFzaWM=` | |||
| 
 | ||||
| 		DescribeTable("with a header", | ||||
| 			func(in findBearerTokenFromHeaderTableInput) { | ||||
| 				token, err := j.findBearerTokenFromHeader(in.header) | ||||
| 				token, err := j.findTokenFromHeader(in.header) | ||||
| 				if in.expectedErr != nil { | ||||
| 					Expect(err).To(MatchError(in.expectedErr)) | ||||
| 				} else { | ||||
|  | @ -381,7 +393,7 @@ Nnc3a3lGVWFCNUMxQnNJcnJMTWxka1dFaHluYmI4Ongtb2F1dGgtYmFzaWM=` | |||
| 		) | ||||
| 	}) | ||||
| 
 | ||||
| 	Context("createSessionStateFromBearerToken", func() { | ||||
| 	Context("CreateTokenToSessionFunc", func() { | ||||
| 		ctx := context.Background() | ||||
| 		expiresFuture := time.Now().Add(time.Duration(5) * time.Minute) | ||||
| 		verified := true | ||||
|  | @ -393,7 +405,7 @@ Nnc3a3lGVWFCNUMxQnNJcnJMTWxka1dFaHluYmI4Ongtb2F1dGgtYmFzaWM=` | |||
| 			jwt.StandardClaims | ||||
| 		} | ||||
| 
 | ||||
| 		type createSessionStateTableInput struct { | ||||
| 		type tokenToSessionTableInput struct { | ||||
| 			idToken         idTokenClaims | ||||
| 			expectedErr     error | ||||
| 			expectedUser    string | ||||
|  | @ -402,12 +414,19 @@ Nnc3a3lGVWFCNUMxQnNJcnJMTWxka1dFaHluYmI4Ongtb2F1dGgtYmFzaWM=` | |||
| 		} | ||||
| 
 | ||||
| 		DescribeTable("when creating a session from an IDToken", | ||||
| 			func(in createSessionStateTableInput) { | ||||
| 				verifier := oidc.NewVerifier( | ||||
| 					"https://issuer.example.com", | ||||
| 					noOpKeySet{}, | ||||
| 					&oidc.Config{ClientID: "asdf1234"}, | ||||
| 				) | ||||
| 			func(in tokenToSessionTableInput) { | ||||
| 				verifier := func(ctx context.Context, token string) (*oidc.IDToken, error) { | ||||
| 					oidcVerifier := oidc.NewVerifier( | ||||
| 						"https://issuer.example.com", | ||||
| 						noOpKeySet{}, | ||||
| 						&oidc.Config{ClientID: "asdf1234"}, | ||||
| 					) | ||||
| 
 | ||||
| 					idToken, err := oidcVerifier.Verify(ctx, token) | ||||
| 					Expect(err).ToNot(HaveOccurred()) | ||||
| 
 | ||||
| 					return idToken, nil | ||||
| 				} | ||||
| 
 | ||||
| 				key, err := rsa.GenerateKey(rand.Reader, 2048) | ||||
| 				Expect(err).ToNot(HaveOccurred()) | ||||
|  | @ -415,11 +434,7 @@ Nnc3a3lGVWFCNUMxQnNJcnJMTWxka1dFaHluYmI4Ongtb2F1dGgtYmFzaWM=` | |||
| 				rawIDToken, err := jwt.NewWithClaims(jwt.SigningMethodRS256, in.idToken).SignedString(key) | ||||
| 				Expect(err).ToNot(HaveOccurred()) | ||||
| 
 | ||||
| 				// Pass to a dummy Verifier to get an oidc.IDToken from the rawIDToken for our actual test below
 | ||||
| 				idToken, err := verifier.Verify(context.Background(), rawIDToken) | ||||
| 				Expect(err).ToNot(HaveOccurred()) | ||||
| 
 | ||||
| 				session, err := createSessionStateFromBearerToken(ctx, rawIDToken, idToken) | ||||
| 				session, err := middlewareapi.CreateTokenToSessionFunc(verifier)(ctx, rawIDToken) | ||||
| 				if in.expectedErr != nil { | ||||
| 					Expect(err).To(MatchError(in.expectedErr)) | ||||
| 					Expect(session).To(BeNil()) | ||||
|  | @ -435,7 +450,7 @@ Nnc3a3lGVWFCNUMxQnNJcnJMTWxka1dFaHluYmI4Ongtb2F1dGgtYmFzaWM=` | |||
| 				Expect(session.RefreshToken).To(BeEmpty()) | ||||
| 				Expect(session.PreferredUsername).To(BeEmpty()) | ||||
| 			}, | ||||
| 			Entry("with no email", createSessionStateTableInput{ | ||||
| 			Entry("with no email", tokenToSessionTableInput{ | ||||
| 				idToken: idTokenClaims{ | ||||
| 					StandardClaims: jwt.StandardClaims{ | ||||
| 						Audience:  "asdf1234", | ||||
|  | @ -452,7 +467,7 @@ Nnc3a3lGVWFCNUMxQnNJcnJMTWxka1dFaHluYmI4Ongtb2F1dGgtYmFzaWM=` | |||
| 				expectedEmail:   "123456789", | ||||
| 				expectedExpires: &expiresFuture, | ||||
| 			}), | ||||
| 			Entry("with a verified email", createSessionStateTableInput{ | ||||
| 			Entry("with a verified email", tokenToSessionTableInput{ | ||||
| 				idToken: idTokenClaims{ | ||||
| 					StandardClaims: jwt.StandardClaims{ | ||||
| 						Audience:  "asdf1234", | ||||
|  | @ -471,7 +486,7 @@ Nnc3a3lGVWFCNUMxQnNJcnJMTWxka1dFaHluYmI4Ongtb2F1dGgtYmFzaWM=` | |||
| 				expectedEmail:   "foo@example.com", | ||||
| 				expectedExpires: &expiresFuture, | ||||
| 			}), | ||||
| 			Entry("with a non-verified email", createSessionStateTableInput{ | ||||
| 			Entry("with a non-verified email", tokenToSessionTableInput{ | ||||
| 				idToken: idTokenClaims{ | ||||
| 					StandardClaims: jwt.StandardClaims{ | ||||
| 						Audience:  "asdf1234", | ||||
|  |  | |||
|  | @ -233,6 +233,9 @@ func parseProviderInfo(o *options.Options, msgs []string) []string { | |||
| 	p.ValidateURL, msgs = parseURL(o.ValidateURL, "validate", msgs) | ||||
| 	p.ProtectedResource, msgs = parseURL(o.ProtectedResource, "resource", msgs) | ||||
| 
 | ||||
| 	// Make the OIDC Verifier accessible to all providers that can support it
 | ||||
| 	p.Verifier = o.GetOIDCVerifier() | ||||
| 
 | ||||
| 	p.SetAllowedGroups(o.AllowedGroups) | ||||
| 
 | ||||
| 	provider := providers.New(o.ProviderType, p) | ||||
|  | @ -273,18 +276,14 @@ func parseProviderInfo(o *options.Options, msgs []string) []string { | |||
| 		p.AllowUnverifiedEmail = o.InsecureOIDCAllowUnverifiedEmail | ||||
| 		p.UserIDClaim = o.UserIDClaim | ||||
| 		p.GroupsClaim = o.OIDCGroupsClaim | ||||
| 		if o.GetOIDCVerifier() == nil { | ||||
| 		if p.Verifier == nil { | ||||
| 			msgs = append(msgs, "oidc provider requires an oidc issuer URL") | ||||
| 		} else { | ||||
| 			p.Verifier = o.GetOIDCVerifier() | ||||
| 		} | ||||
| 	case *providers.GitLabProvider: | ||||
| 		p.AllowUnverifiedEmail = o.InsecureOIDCAllowUnverifiedEmail | ||||
| 		p.Groups = o.GitLabGroup | ||||
| 
 | ||||
| 		if o.GetOIDCVerifier() != nil { | ||||
| 			p.Verifier = o.GetOIDCVerifier() | ||||
| 		} else { | ||||
| 		if p.Verifier == nil { | ||||
| 			// Initialize with default verifier for gitlab.com
 | ||||
| 			ctx := context.Background() | ||||
| 
 | ||||
|  |  | |||
|  | @ -83,6 +83,6 @@ func (p *DigitalOceanProvider) GetEmailAddress(ctx context.Context, s *sessions. | |||
| } | ||||
| 
 | ||||
| // ValidateSessionState validates the AccessToken
 | ||||
| func (p *DigitalOceanProvider) ValidateSessionState(ctx context.Context, s *sessions.SessionState) bool { | ||||
| func (p *DigitalOceanProvider) ValidateSession(ctx context.Context, s *sessions.SessionState) bool { | ||||
| 	return validateToken(ctx, p, s.AccessToken, makeOIDCHeader(s.AccessToken)) | ||||
| } | ||||
|  |  | |||
|  | @ -89,6 +89,6 @@ func (p *FacebookProvider) GetEmailAddress(ctx context.Context, s *sessions.Sess | |||
| } | ||||
| 
 | ||||
| // ValidateSessionState validates the AccessToken
 | ||||
| func (p *FacebookProvider) ValidateSessionState(ctx context.Context, s *sessions.SessionState) bool { | ||||
| func (p *FacebookProvider) ValidateSession(ctx context.Context, s *sessions.SessionState) bool { | ||||
| 	return validateToken(ctx, p, s.AccessToken, makeOIDCHeader(s.AccessToken)) | ||||
| } | ||||
|  |  | |||
|  | @ -103,7 +103,7 @@ func (p *GitHubProvider) SetUsers(users []string) { | |||
| } | ||||
| 
 | ||||
| // EnrichSessionState updates the User & Email after the initial Redeem
 | ||||
| func (p *GitHubProvider) EnrichSessionState(ctx context.Context, s *sessions.SessionState) error { | ||||
| func (p *GitHubProvider) EnrichSession(ctx context.Context, s *sessions.SessionState) error { | ||||
| 	err := p.getEmail(ctx, s) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
|  | @ -112,7 +112,7 @@ func (p *GitHubProvider) EnrichSessionState(ctx context.Context, s *sessions.Ses | |||
| } | ||||
| 
 | ||||
| // ValidateSessionState validates the AccessToken
 | ||||
| func (p *GitHubProvider) ValidateSessionState(ctx context.Context, s *sessions.SessionState) bool { | ||||
| func (p *GitHubProvider) ValidateSession(ctx context.Context, s *sessions.SessionState) bool { | ||||
| 	return validateToken(ctx, p, s.AccessToken, makeGitHubHeader(s.AccessToken)) | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -188,13 +188,13 @@ func (p *GitLabProvider) createSessionState(ctx context.Context, token *oauth2.T | |||
| } | ||||
| 
 | ||||
| // ValidateSessionState checks that the session's IDToken is still valid
 | ||||
| func (p *GitLabProvider) ValidateSessionState(ctx context.Context, s *sessions.SessionState) bool { | ||||
| func (p *GitLabProvider) ValidateSession(ctx context.Context, s *sessions.SessionState) bool { | ||||
| 	_, err := p.Verifier.Verify(ctx, s.IDToken) | ||||
| 	return err == nil | ||||
| } | ||||
| 
 | ||||
| // GetEmailAddress returns the Account email address
 | ||||
| func (p *GitLabProvider) EnrichSessionState(ctx context.Context, s *sessions.SessionState) error { | ||||
| func (p *GitLabProvider) EnrichSession(ctx context.Context, s *sessions.SessionState) error { | ||||
| 	// Retrieve user info
 | ||||
| 	userInfo, err := p.getUserInfo(ctx, s) | ||||
| 	if err != nil { | ||||
|  |  | |||
|  | @ -64,7 +64,7 @@ func TestGitLabProviderBadToken(t *testing.T) { | |||
| 	p := testGitLabProvider(bURL.Host) | ||||
| 
 | ||||
| 	session := &sessions.SessionState{AccessToken: "unexpected_gitlab_access_token"} | ||||
| 	err := p.EnrichSessionState(context.Background(), session) | ||||
| 	err := p.EnrichSession(context.Background(), session) | ||||
| 	assert.Error(t, err) | ||||
| } | ||||
| 
 | ||||
|  | @ -76,7 +76,7 @@ func TestGitLabProviderUnverifiedEmailDenied(t *testing.T) { | |||
| 	p := testGitLabProvider(bURL.Host) | ||||
| 
 | ||||
| 	session := &sessions.SessionState{AccessToken: "gitlab_access_token"} | ||||
| 	err := p.EnrichSessionState(context.Background(), session) | ||||
| 	err := p.EnrichSession(context.Background(), session) | ||||
| 	assert.Error(t, err) | ||||
| } | ||||
| 
 | ||||
|  | @ -89,7 +89,7 @@ func TestGitLabProviderUnverifiedEmailAllowed(t *testing.T) { | |||
| 	p.AllowUnverifiedEmail = true | ||||
| 
 | ||||
| 	session := &sessions.SessionState{AccessToken: "gitlab_access_token"} | ||||
| 	err := p.EnrichSessionState(context.Background(), session) | ||||
| 	err := p.EnrichSession(context.Background(), session) | ||||
| 	assert.NoError(t, err) | ||||
| 	assert.Equal(t, "foo@bar.com", session.Email) | ||||
| } | ||||
|  | @ -103,7 +103,7 @@ func TestGitLabProviderUsername(t *testing.T) { | |||
| 	p.AllowUnverifiedEmail = true | ||||
| 
 | ||||
| 	session := &sessions.SessionState{AccessToken: "gitlab_access_token"} | ||||
| 	err := p.EnrichSessionState(context.Background(), session) | ||||
| 	err := p.EnrichSession(context.Background(), session) | ||||
| 	assert.NoError(t, err) | ||||
| 	assert.Equal(t, "FooBar", session.User) | ||||
| } | ||||
|  | @ -118,7 +118,7 @@ func TestGitLabProviderGroupMembershipValid(t *testing.T) { | |||
| 	p.Groups = []string{"foo"} | ||||
| 
 | ||||
| 	session := &sessions.SessionState{AccessToken: "gitlab_access_token"} | ||||
| 	err := p.EnrichSessionState(context.Background(), session) | ||||
| 	err := p.EnrichSession(context.Background(), session) | ||||
| 	assert.NoError(t, err) | ||||
| 	assert.Equal(t, "FooBar", session.User) | ||||
| } | ||||
|  | @ -133,6 +133,6 @@ func TestGitLabProviderGroupMembershipMissing(t *testing.T) { | |||
| 	p.Groups = []string{"baz"} | ||||
| 
 | ||||
| 	session := &sessions.SessionState{AccessToken: "gitlab_access_token"} | ||||
| 	err := p.EnrichSessionState(context.Background(), session) | ||||
| 	err := p.EnrichSession(context.Background(), session) | ||||
| 	assert.Error(t, err) | ||||
| } | ||||
|  |  | |||
|  | @ -179,7 +179,7 @@ func (p *GoogleProvider) Redeem(ctx context.Context, redirectURL, code string) ( | |||
| 
 | ||||
| // EnrichSessionState checks the listed Google Groups configured and adds any
 | ||||
| // that the user is a member of to session.Groups.
 | ||||
| func (p *GoogleProvider) EnrichSessionState(ctx context.Context, s *sessions.SessionState) error { | ||||
| func (p *GoogleProvider) EnrichSession(ctx context.Context, s *sessions.SessionState) error { | ||||
| 	// TODO (@NickMeves) - Move to pure EnrichSessionState logic and stop
 | ||||
| 	// reusing legacy `groupValidator`.
 | ||||
| 	//
 | ||||
|  |  | |||
|  | @ -32,7 +32,7 @@ func (tp *ValidateSessionStateTestProvider) GetEmailAddress(ctx context.Context, | |||
| 
 | ||||
| // Note that we're testing the internal validateToken() used to implement
 | ||||
| // several Provider's ValidateSessionState() implementations
 | ||||
| func (tp *ValidateSessionStateTestProvider) ValidateSessionState(ctx context.Context, s *sessions.SessionState) bool { | ||||
| func (tp *ValidateSessionStateTestProvider) ValidateSession(ctx context.Context, s *sessions.SessionState) bool { | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -94,6 +94,6 @@ func (p *LinkedInProvider) GetEmailAddress(ctx context.Context, s *sessions.Sess | |||
| } | ||||
| 
 | ||||
| // ValidateSessionState validates the AccessToken
 | ||||
| func (p *LinkedInProvider) ValidateSessionState(ctx context.Context, s *sessions.SessionState) bool { | ||||
| func (p *LinkedInProvider) ValidateSession(ctx context.Context, s *sessions.SessionState) bool { | ||||
| 	return validateToken(ctx, p, s.AccessToken, makeLinkedInHeader(s.AccessToken)) | ||||
| } | ||||
|  |  | |||
|  | @ -22,7 +22,6 @@ const emailClaim = "email" | |||
| type OIDCProvider struct { | ||||
| 	*ProviderData | ||||
| 
 | ||||
| 	Verifier             *oidc.IDTokenVerifier | ||||
| 	AllowUnverifiedEmail bool | ||||
| 	UserIDClaim          string | ||||
| 	GroupsClaim          string | ||||
|  | @ -175,14 +174,19 @@ func (p *OIDCProvider) createSessionState(ctx context.Context, token *oauth2.Tok | |||
| 	return newSession, nil | ||||
| } | ||||
| 
 | ||||
| func (p *OIDCProvider) CreateSessionStateFromBearerToken(ctx context.Context, rawIDToken string, idToken *oidc.IDToken) (*sessions.SessionState, error) { | ||||
| func (p *OIDCProvider) CreateSessionFromToken(ctx context.Context, token string) (*sessions.SessionState, error) { | ||||
| 	idToken, err := p.Verifier.Verify(ctx, token) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	newSession, err := p.createSessionStateInternal(ctx, idToken, nil) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	newSession.AccessToken = rawIDToken | ||||
| 	newSession.IDToken = rawIDToken | ||||
| 	newSession.AccessToken = token | ||||
| 	newSession.IDToken = token | ||||
| 	newSession.RefreshToken = "" | ||||
| 	newSession.ExpiresOn = &idToken.Expiry | ||||
| 
 | ||||
|  | @ -221,7 +225,7 @@ func (p *OIDCProvider) createSessionStateInternal(ctx context.Context, idToken * | |||
| } | ||||
| 
 | ||||
| // ValidateSessionState checks that the session's IDToken is still valid
 | ||||
| func (p *OIDCProvider) ValidateSessionState(ctx context.Context, s *sessions.SessionState) bool { | ||||
| func (p *OIDCProvider) ValidateSession(ctx context.Context, s *sessions.SessionState) bool { | ||||
| 	_, err := p.Verifier.Verify(ctx, s.IDToken) | ||||
| 	return err == nil | ||||
| } | ||||
|  |  | |||
|  | @ -144,16 +144,17 @@ func newOIDCProvider(serverURL *url.URL) *OIDCProvider { | |||
| 			Scheme: serverURL.Scheme, | ||||
| 			Host:   serverURL.Host, | ||||
| 			Path:   "/api"}, | ||||
| 		Scope: "openid profile offline_access"} | ||||
| 
 | ||||
| 	p := &OIDCProvider{ | ||||
| 		ProviderData: providerData, | ||||
| 		Scope: "openid profile offline_access", | ||||
| 		Verifier: oidc.NewVerifier( | ||||
| 			"https://issuer.example.com", | ||||
| 			fakeKeySetStub{}, | ||||
| 			&oidc.Config{ClientID: clientID}, | ||||
| 		), | ||||
| 		UserIDClaim: "email", | ||||
| 	} | ||||
| 
 | ||||
| 	p := &OIDCProvider{ | ||||
| 		ProviderData: providerData, | ||||
| 		UserIDClaim:  "email", | ||||
| 	} | ||||
| 
 | ||||
| 	return p | ||||
|  | @ -298,7 +299,7 @@ func TestOIDCProviderRefreshSessionIfNeededWithIdToken(t *testing.T) { | |||
| 	assert.Equal(t, refreshToken, existingSession.RefreshToken) | ||||
| } | ||||
| 
 | ||||
| func TestCreateSessionStateFromBearerToken(t *testing.T) { | ||||
| func TestOIDCProviderCreateSessionFromToken(t *testing.T) { | ||||
| 	const profileURLEmail = "janed@me.com" | ||||
| 
 | ||||
| 	testCases := map[string]struct { | ||||
|  | @ -347,14 +348,7 @@ func TestCreateSessionStateFromBearerToken(t *testing.T) { | |||
| 			rawIDToken, err := newSignedTestIDToken(tc.IDToken) | ||||
| 			assert.NoError(t, err) | ||||
| 
 | ||||
| 			keyset := fakeKeySetStub{} | ||||
| 			verifier := oidc.NewVerifier("https://issuer.example.com", keyset, | ||||
| 				&oidc.Config{ClientID: "https://test.myapp.com", SkipExpiryCheck: true}) | ||||
| 
 | ||||
| 			idToken, err := verifier.Verify(context.Background(), rawIDToken) | ||||
| 			assert.NoError(t, err) | ||||
| 
 | ||||
| 			ss, err := provider.CreateSessionStateFromBearerToken(context.Background(), rawIDToken, idToken) | ||||
| 			ss, err := provider.CreateSessionFromToken(context.Background(), rawIDToken) | ||||
| 			assert.NoError(t, err) | ||||
| 
 | ||||
| 			assert.Equal(t, tc.ExpectedUser, ss.User) | ||||
|  |  | |||
|  | @ -5,6 +5,7 @@ import ( | |||
| 	"io/ioutil" | ||||
| 	"net/url" | ||||
| 
 | ||||
| 	"github.com/coreos/go-oidc" | ||||
| 	"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/logger" | ||||
| ) | ||||
| 
 | ||||
|  | @ -26,6 +27,7 @@ type ProviderData struct { | |||
| 	ClientSecretFile string | ||||
| 	Scope            string | ||||
| 	Prompt           string | ||||
| 	Verifier         *oidc.IDTokenVerifier | ||||
| 
 | ||||
| 	// Universal Group authorization data structure
 | ||||
| 	// any provider can set to consume
 | ||||
|  |  | |||
|  | @ -8,8 +8,7 @@ import ( | |||
| 	"net/url" | ||||
| 	"time" | ||||
| 
 | ||||
| 	"github.com/coreos/go-oidc" | ||||
| 
 | ||||
| 	"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/middleware" | ||||
| 	"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions" | ||||
| 	"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/requests" | ||||
| ) | ||||
|  | @ -94,7 +93,7 @@ func (p *ProviderData) GetEmailAddress(_ context.Context, _ *sessions.SessionSta | |||
| 
 | ||||
| // EnrichSessionState is called after Redeem to allow providers to enrich session fields
 | ||||
| // such as User, Email, Groups with provider specific API calls.
 | ||||
| func (p *ProviderData) EnrichSessionState(_ context.Context, _ *sessions.SessionState) error { | ||||
| func (p *ProviderData) EnrichSession(_ context.Context, _ *sessions.SessionState) error { | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
|  | @ -115,7 +114,7 @@ func (p *ProviderData) Authorize(_ context.Context, s *sessions.SessionState) (b | |||
| } | ||||
| 
 | ||||
| // ValidateSessionState validates the AccessToken
 | ||||
| func (p *ProviderData) ValidateSessionState(ctx context.Context, s *sessions.SessionState) bool { | ||||
| func (p *ProviderData) ValidateSession(ctx context.Context, s *sessions.SessionState) bool { | ||||
| 	return validateToken(ctx, p, s.AccessToken, nil) | ||||
| } | ||||
| 
 | ||||
|  | @ -125,8 +124,10 @@ func (p *ProviderData) RefreshSessionIfNeeded(_ context.Context, _ *sessions.Ses | |||
| 	return false, nil | ||||
| } | ||||
| 
 | ||||
| // CreateSessionStateFromBearerToken should be implemented to allow providers
 | ||||
| // to convert ID tokens into sessions
 | ||||
| func (p *ProviderData) CreateSessionStateFromBearerToken(_ context.Context, _ string, _ *oidc.IDToken) (*sessions.SessionState, error) { | ||||
| // CreateSessionFromToken converts Bearer IDTokens into sessions
 | ||||
| func (p *ProviderData) CreateSessionFromToken(ctx context.Context, token string) (*sessions.SessionState, error) { | ||||
| 	if p.Verifier != nil { | ||||
| 		return middleware.CreateTokenToSessionFunc(p.Verifier.Verify)(ctx, token) | ||||
| 	} | ||||
| 	return nil, ErrNotImplemented | ||||
| } | ||||
|  |  | |||
|  | @ -49,10 +49,13 @@ func TestAcrValuesConfigured(t *testing.T) { | |||
| 	assert.Contains(t, result, "acr_values=testValue") | ||||
| } | ||||
| 
 | ||||
| func TestEnrichSessionState(t *testing.T) { | ||||
| func TestProviderDataEnrichSession(t *testing.T) { | ||||
| 	g := NewWithT(t) | ||||
| 	p := &ProviderData{} | ||||
| 	s := &sessions.SessionState{} | ||||
| 	assert.NoError(t, p.EnrichSessionState(context.Background(), s)) | ||||
| 
 | ||||
| 	err := p.EnrichSession(context.Background(), s) | ||||
| 	g.Expect(err).ToNot(HaveOccurred()) | ||||
| } | ||||
| 
 | ||||
| func TestProviderDataAuthorize(t *testing.T) { | ||||
|  |  | |||
|  | @ -3,7 +3,6 @@ package providers | |||
| import ( | ||||
| 	"context" | ||||
| 
 | ||||
| 	"github.com/coreos/go-oidc" | ||||
| 	"github.com/oauth2-proxy/oauth2-proxy/v7/pkg/apis/sessions" | ||||
| ) | ||||
| 
 | ||||
|  | @ -13,12 +12,12 @@ type Provider interface { | |||
| 	// DEPRECATED: Migrate to EnrichSessionState
 | ||||
| 	GetEmailAddress(ctx context.Context, s *sessions.SessionState) (string, error) | ||||
| 	Redeem(ctx context.Context, redirectURI, code string) (*sessions.SessionState, error) | ||||
| 	EnrichSessionState(ctx context.Context, s *sessions.SessionState) error | ||||
| 	EnrichSession(ctx context.Context, s *sessions.SessionState) error | ||||
| 	Authorize(ctx context.Context, s *sessions.SessionState) (bool, error) | ||||
| 	ValidateSessionState(ctx context.Context, s *sessions.SessionState) bool | ||||
| 	ValidateSession(ctx context.Context, s *sessions.SessionState) bool | ||||
| 	GetLoginURL(redirectURI, finalRedirect string) string | ||||
| 	RefreshSessionIfNeeded(ctx context.Context, s *sessions.SessionState) (bool, error) | ||||
| 	CreateSessionStateFromBearerToken(ctx context.Context, rawIDToken string, idToken *oidc.IDToken) (*sessions.SessionState, error) | ||||
| 	CreateSessionFromToken(ctx context.Context, token string) (*sessions.SessionState, error) | ||||
| } | ||||
| 
 | ||||
| // New provides a new Provider based on the configured provider string
 | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue