chore: upgrade to oidc v2 release (#5437)

* chore: upgrade to oidc v2 release

* fix tests

* fix build errors after rebase

* pin oidc v2.1.0

* pin oidc v2.1.1 (include bugfix)

* pin oidc v2.1.2 (include bugfix)

* pin oidc v2.2.1 (bugfix)

include fix zitadel/oidc#349

* fix: refresh token handling

* simplify cognitive complexity

* fix: handle error

---------

Co-authored-by: Livio Spring <livio.a@gmail.com>
This commit is contained in:
Tim Möhlmann 2023-03-28 14:28:56 +03:00 committed by GitHub
parent 542271b467
commit 25c3c17986
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 362 additions and 249 deletions

17
go.mod
View File

@ -23,7 +23,7 @@ require (
github.com/go-ldap/ldap/v3 v3.4.4 github.com/go-ldap/ldap/v3 v3.4.4
github.com/golang/glog v1.0.0 github.com/golang/glog v1.0.0
github.com/golang/mock v1.6.0 github.com/golang/mock v1.6.0
github.com/golang/protobuf v1.5.2 github.com/golang/protobuf v1.5.3
github.com/gorilla/csrf v1.7.1 github.com/gorilla/csrf v1.7.1
github.com/gorilla/mux v1.8.0 github.com/gorilla/mux v1.8.0
github.com/gorilla/schema v1.2.0 github.com/gorilla/schema v1.2.0
@ -57,7 +57,7 @@ require (
github.com/superseriousbusiness/exifremove v0.0.0-20210330092427-6acd27eac203 github.com/superseriousbusiness/exifremove v0.0.0-20210330092427-6acd27eac203
github.com/ttacon/libphonenumber v1.2.1 github.com/ttacon/libphonenumber v1.2.1
github.com/zitadel/logging v0.3.4 github.com/zitadel/logging v0.3.4
github.com/zitadel/oidc/v2 v2.0.0-dynamic-issuer.9 github.com/zitadel/oidc/v2 v2.2.1
github.com/zitadel/saml v0.0.10 github.com/zitadel/saml v0.0.10
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.27.0 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.27.0
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.27.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.27.0
@ -70,16 +70,16 @@ require (
go.opentelemetry.io/otel/sdk/export/metric v0.25.0 go.opentelemetry.io/otel/sdk/export/metric v0.25.0
go.opentelemetry.io/otel/sdk/metric v0.25.0 go.opentelemetry.io/otel/sdk/metric v0.25.0
go.opentelemetry.io/otel/trace v1.11.2 go.opentelemetry.io/otel/trace v1.11.2
golang.org/x/crypto v0.6.0 golang.org/x/crypto v0.7.0
golang.org/x/net v0.7.0 golang.org/x/net v0.8.0
golang.org/x/oauth2 v0.5.0 golang.org/x/oauth2 v0.6.0
golang.org/x/sync v0.1.0 golang.org/x/sync v0.1.0
golang.org/x/text v0.7.0 golang.org/x/text v0.8.0
golang.org/x/tools v0.6.0 golang.org/x/tools v0.6.0
google.golang.org/api v0.110.0 google.golang.org/api v0.110.0
google.golang.org/genproto v0.0.0-20230221151758-ace64dc21148 google.golang.org/genproto v0.0.0-20230221151758-ace64dc21148
google.golang.org/grpc v1.53.0 google.golang.org/grpc v1.53.0
google.golang.org/protobuf v1.28.1 google.golang.org/protobuf v1.29.1
gopkg.in/square/go-jose.v2 v2.6.0 gopkg.in/square/go-jose.v2 v2.6.0
sigs.k8s.io/yaml v1.3.0 sigs.k8s.io/yaml v1.3.0
) )
@ -90,6 +90,7 @@ require (
github.com/go-logr/logr v1.2.3 // indirect github.com/go-logr/logr v1.2.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect
github.com/klauspost/cpuid/v2 v2.2.3 // indirect github.com/klauspost/cpuid/v2 v2.2.3 // indirect
github.com/muhlemmer/gu v0.3.1 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect github.com/pelletier/go-toml/v2 v2.0.6 // indirect
go.uber.org/atomic v1.10.0 // indirect go.uber.org/atomic v1.10.0 // indirect
go.uber.org/multierr v1.8.0 // indirect go.uber.org/multierr v1.8.0 // indirect
@ -192,7 +193,7 @@ require (
go.opentelemetry.io/otel/internal/metric v0.25.0 // indirect go.opentelemetry.io/otel/internal/metric v0.25.0 // indirect
go.opentelemetry.io/proto/otlp v0.15.0 // indirect go.opentelemetry.io/proto/otlp v0.15.0 // indirect
golang.org/x/mod v0.8.0 // indirect golang.org/x/mod v0.8.0 // indirect
golang.org/x/sys v0.5.0 // indirect golang.org/x/sys v0.6.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
google.golang.org/appengine v1.6.7 // indirect google.golang.org/appengine v1.6.7 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect

39
go.sum
View File

@ -34,7 +34,6 @@ cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4g
cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ=
cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY= cloud.google.com/go/compute v1.18.0 h1:FEigFqoDbys2cvFkZ9Fjq4gnHBP55anJ0yQyau2f9oY=
cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs= cloud.google.com/go/compute v1.18.0/go.mod h1:1X7yHxec2Ga+Ss6jPyjxRxpu2uu7PLgsOVXvgU0yacs=
cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE=
@ -463,8 +462,9 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM= github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg=
github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
@ -488,11 +488,9 @@ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM= github.com/google/go-github/v28 v28.1.1/go.mod h1:bsqJWQX05omyWVmc00nEUql9mhQyv38lDZ8kPZcQVoM=
github.com/google/go-github/v31 v31.0.0/go.mod h1:NQPZol8/1sMoWYGN2yaALIBytu17gAWfhbweiEed3pM=
github.com/google/go-licenses v0.0.0-20210329231322-ce1d9163b77d/go.mod h1:+TYOmkVoJOpwnS0wfdsJCV9CoD5nJYsHoFk/0CrTK4M= github.com/google/go-licenses v0.0.0-20210329231322-ce1d9163b77d/go.mod h1:+TYOmkVoJOpwnS0wfdsJCV9CoD5nJYsHoFk/0CrTK4M=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/go-replayers/grpcreplay v0.1.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= github.com/google/go-replayers/grpcreplay v0.1.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE=
@ -690,6 +688,7 @@ github.com/jarcoal/httpmock v1.0.5/go.mod h1:ATjnClrvW/3tijVmpL/va5Z3aAyGvqU3gCT
github.com/jarcoal/jpath v0.0.0-20140328210829-f76b8b2dbf52 h1:jny9eqYPwkG8IVy7foUoRjQmFLcArCSz+uPsL6KS0HQ= github.com/jarcoal/jpath v0.0.0-20140328210829-f76b8b2dbf52 h1:jny9eqYPwkG8IVy7foUoRjQmFLcArCSz+uPsL6KS0HQ=
github.com/jarcoal/jpath v0.0.0-20140328210829-f76b8b2dbf52/go.mod h1:RDZ+4PR3mDOtTpVbI0qBE+rdhmtIrtbssiNn38/1OWA= github.com/jarcoal/jpath v0.0.0-20140328210829-f76b8b2dbf52/go.mod h1:RDZ+4PR3mDOtTpVbI0qBE+rdhmtIrtbssiNn38/1OWA=
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jeremija/gosubmit v0.2.7 h1:At0OhGCFGPXyjPYAsCchoBUhE099pcBXmsb4iZqROIc=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/jhump/protoreflect v1.6.1/go.mod h1:RZQ/lnuN+zqeRVpQigTwO6o0AJUkxbnSnpuG7toUTG4= github.com/jhump/protoreflect v1.6.1/go.mod h1:RZQ/lnuN+zqeRVpQigTwO6o0AJUkxbnSnpuG7toUTG4=
github.com/jhump/protoreflect v1.8.2/go.mod h1:7GcYQDdMU/O/BBrl/cX6PNHpXh6cenjd8pneu5yW7Tg= github.com/jhump/protoreflect v1.8.2/go.mod h1:7GcYQDdMU/O/BBrl/cX6PNHpXh6cenjd8pneu5yW7Tg=
@ -863,6 +862,8 @@ github.com/muesli/gamut v0.3.1 h1:8hozovcrDBWLLAwuOXC+UDyO0/uNroIdXAmY/lQOMHo=
github.com/muesli/gamut v0.3.1/go.mod h1:BED0DN21PXU1YaYNwaTmX9700SRHPcWWd6Llj0zsz5k= github.com/muesli/gamut v0.3.1/go.mod h1:BED0DN21PXU1YaYNwaTmX9700SRHPcWWd6Llj0zsz5k=
github.com/muesli/kmeans v0.3.1 h1:KshLQ8wAETfLWOJKMuDCVYHnafddSa1kwGh/IypGIzY= github.com/muesli/kmeans v0.3.1 h1:KshLQ8wAETfLWOJKMuDCVYHnafddSa1kwGh/IypGIzY=
github.com/muesli/kmeans v0.3.1/go.mod h1:8/OvJW7cHc1BpRf8URb43m+vR105DDe+Kj1WcFXYDqc= github.com/muesli/kmeans v0.3.1/go.mod h1:8/OvJW7cHc1BpRf8URb43m+vR105DDe+Kj1WcFXYDqc=
github.com/muhlemmer/gu v0.3.1 h1:7EAqmFrW7n3hETvuAdmFmn4hS8W+z3LgKtrnow+YzNM=
github.com/muhlemmer/gu v0.3.1/go.mod h1:YHtHR+gxM+bKEIIs7Hmi9sPT3ZDUvTN/i88wQpZkrdM=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
@ -880,7 +881,6 @@ github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32 h1:W6apQkHrMkS0Muv8G/TipAy
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms= github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
github.com/nicksnyder/go-i18n/v2 v2.2.1 h1:aOzRCdwsJuoExfZhoiXHy4bjruwCMdt5otbYojM/PaA= github.com/nicksnyder/go-i18n/v2 v2.2.1 h1:aOzRCdwsJuoExfZhoiXHy4bjruwCMdt5otbYojM/PaA=
github.com/nicksnyder/go-i18n/v2 v2.2.1/go.mod h1:fF2++lPHlo+/kPaj3nB0uxtPwzlPm+BlgwGX7MkeGj0= github.com/nicksnyder/go-i18n/v2 v2.2.1/go.mod h1:fF2++lPHlo+/kPaj3nB0uxtPwzlPm+BlgwGX7MkeGj0=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
github.com/nishanths/predeclared v0.0.0-20200524104333-86fad755b4d3/go.mod h1:nt3d53pc1VYcphSCIaYAJtnPYnr3Zyn8fMq2wvPGPso= github.com/nishanths/predeclared v0.0.0-20200524104333-86fad755b4d3/go.mod h1:nt3d53pc1VYcphSCIaYAJtnPYnr3Zyn8fMq2wvPGPso=
github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs= github.com/oklog/oklog v0.3.2/go.mod h1:FCV+B7mhrz4o+ueLpx+KqkyXRGMWOYEvfiXtdGtbWGs=
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
@ -1141,8 +1141,8 @@ github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5t
github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= github.com/zenazn/goji v0.9.0/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q=
github.com/zitadel/logging v0.3.4 h1:9hZsTjMMTE3X2LUi0xcF9Q9EdLo+FAezeu52ireBbHM= github.com/zitadel/logging v0.3.4 h1:9hZsTjMMTE3X2LUi0xcF9Q9EdLo+FAezeu52ireBbHM=
github.com/zitadel/logging v0.3.4/go.mod h1:aPpLQhE+v6ocNK0TWrBrd363hZ95KcI17Q1ixAQwZF0= github.com/zitadel/logging v0.3.4/go.mod h1:aPpLQhE+v6ocNK0TWrBrd363hZ95KcI17Q1ixAQwZF0=
github.com/zitadel/oidc/v2 v2.0.0-dynamic-issuer.9 h1:P7xbgv2501rsW8E0Uj804LMBrabVuZYcstqoFVmgWjA= github.com/zitadel/oidc/v2 v2.2.1 h1:3uaN7ERsP031MZqhqUNVyLlGB7seel/YJ0CUryjIGSQ=
github.com/zitadel/oidc/v2 v2.0.0-dynamic-issuer.9/go.mod h1:2jHMP6o/WK0EmcNJkz+FSpjeqcCuQG9YqqqzKZkfgIE= github.com/zitadel/oidc/v2 v2.2.1/go.mod h1:tGkj9lQk6KVj5hsM89XPadvi6I06666sMy3KtykvSFM=
github.com/zitadel/saml v0.0.10 h1:cyKd78Vat9vz55S74lggJrXMSqbAPsnJDrPFTPScNYY= github.com/zitadel/saml v0.0.10 h1:cyKd78Vat9vz55S74lggJrXMSqbAPsnJDrPFTPScNYY=
github.com/zitadel/saml v0.0.10/go.mod h1:Hze1/zRN9j1uh7U+89vweP/OwLNO8BLHg3zU1Jtycdg= github.com/zitadel/saml v0.0.10/go.mod h1:Hze1/zRN9j1uh7U+89vweP/OwLNO8BLHg3zU1Jtycdg=
github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0= github.com/ziutek/mymysql v1.5.4/go.mod h1:LMSpPZ6DbqWFxNCHW77HeMg9I646SAhApZ/wKdgO/C0=
@ -1257,8 +1257,9 @@ golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5y
golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220517005047-85d78b3ac167/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.0.0-20220824171710-5757bc0c5503/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= golang.org/x/crypto v0.0.0-20220824171710-5757bc0c5503/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc=
golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58=
golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
@ -1358,11 +1359,10 @@ golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qx
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE= golang.org/x/net v0.4.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181106182150-f42d05182288/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-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@ -1381,9 +1381,8 @@ golang.org/x/oauth2 v0.0.0-20210427180440-81ed05c6b58c/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
golang.org/x/oauth2 v0.3.0/go.mod h1:rQrIauxkUhJ6CuwEXwymO2/eh4xz2ZWF1nBkcxS+tGk= golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw=
golang.org/x/oauth2 v0.5.0 h1:HuArIo48skDwlrvM3sEdHXElYslAMsf3KwRkkW4MC4s= golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw=
golang.org/x/oauth2 v0.5.0/go.mod h1:9/XBHVqLaWO3/BRHs5jbpYCnOZVjj5V0ndyaAM7KB4I=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -1480,8 +1479,9 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
@ -1498,8 +1498,9 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= 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/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@ -1726,14 +1727,12 @@ google.golang.org/protobuf v1.25.1-0.20200805231151-a709e31e5d12/go.mod h1:9JNX7
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.29.1 h1:7QBf+IK2gx70Ap/hDsOmam3GE0v9HicjfEdAxE62UoM=
google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= google.golang.org/protobuf v1.29.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= 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 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw= gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=

View File

@ -92,7 +92,7 @@ func (s *SystemAPIUser) readKey() (*rsa.PublicKey, error) {
return crypto.BytesToPublicKey(s.KeyData) return crypto.BytesToPublicKey(s.KeyData)
} }
func (s *systemJWTStorage) GetKeyByIDAndUserID(_ context.Context, _, userID string) (*jose.JSONWebKey, error) { func (s *systemJWTStorage) GetKeyByIDAndClientID(_ context.Context, _, userID string) (*jose.JSONWebKey, error) {
cachedKey, ok := s.cachedKeys[userID] cachedKey, ok := s.cachedKeys[userID]
if ok { if ok {
return &jose.JSONWebKey{KeyID: userID, Key: cachedKey}, nil return &jose.JSONWebKey{KeyID: userID, Key: cachedKey}, nil

View File

@ -143,7 +143,7 @@ func getInfoFromRequest(req op.TokenRequest) (string, string, string, time.Time,
} }
func (o *OPStorage) TokenRequestByRefreshToken(ctx context.Context, refreshToken string) (op.RefreshTokenRequest, error) { func (o *OPStorage) TokenRequestByRefreshToken(ctx context.Context, refreshToken string) (op.RefreshTokenRequest, error) {
tokenView, err := o.repo.RefreshTokenByID(ctx, refreshToken) tokenView, err := o.repo.RefreshTokenByToken(ctx, refreshToken)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -175,7 +175,7 @@ func (o *OPStorage) TerminateSession(ctx context.Context, userID, clientID strin
} }
func (o *OPStorage) RevokeToken(ctx context.Context, token, userID, clientID string) *oidc.Error { func (o *OPStorage) RevokeToken(ctx context.Context, token, userID, clientID string) *oidc.Error {
refreshToken, err := o.repo.RefreshTokenByID(ctx, token) refreshToken, err := o.repo.RefreshTokenByID(ctx, token, userID)
if err == nil { if err == nil {
if refreshToken.ClientID != clientID { if refreshToken.ClientID != clientID {
return oidc.ErrInvalidClient().WithDescription("token was not issued for this client") return oidc.ErrInvalidClient().WithDescription("token was not issued for this client")
@ -203,6 +203,17 @@ func (o *OPStorage) RevokeToken(ctx context.Context, token, userID, clientID str
return oidc.ErrServerError().WithParent(err) return oidc.ErrServerError().WithParent(err)
} }
func (o *OPStorage) GetRefreshTokenInfo(ctx context.Context, clientID string, token string) (userID string, tokenID string, err error) {
refreshToken, err := o.repo.RefreshTokenByToken(ctx, token)
if err != nil {
return "", "", op.ErrInvalidRefreshToken
}
if refreshToken.ClientID != clientID {
return "", "", oidc.ErrInvalidClient().WithDescription("token was not issued for this client")
}
return refreshToken.UserID, refreshToken.ID, nil
}
func (o *OPStorage) assertProjectRoleScopes(ctx context.Context, clientID string, scopes []string) ([]string, error) { func (o *OPStorage) assertProjectRoleScopes(ctx context.Context, clientID string, scopes []string) ([]string, error) {
for _, scope := range scopes { for _, scope := range scopes {
if strings.HasPrefix(scope, ScopeProjectRolePrefix) { if strings.HasPrefix(scope, ScopeProjectRolePrefix) {

View File

@ -67,7 +67,7 @@ func (o *OPStorage) GetClientByClientID(ctx context.Context, id string) (_ op.Cl
return ClientFromBusiness(client, o.defaultLoginURL, accessTokenLifetime, idTokenLifetime, allowedScopes) return ClientFromBusiness(client, o.defaultLoginURL, accessTokenLifetime, idTokenLifetime, allowedScopes)
} }
func (o *OPStorage) GetKeyByIDAndUserID(ctx context.Context, keyID, userID string) (_ *jose.JSONWebKey, err error) { func (o *OPStorage) GetKeyByIDAndClientID(ctx context.Context, keyID, userID string) (_ *jose.JSONWebKey, err error) {
return o.GetKeyByIDAndIssuer(ctx, keyID, userID) return o.GetKeyByIDAndIssuer(ctx, keyID, userID)
} }
@ -114,7 +114,7 @@ func (o *OPStorage) AuthorizeClientIDSecret(ctx context.Context, id string, secr
return o.command.VerifyAPIClientSecret(ctx, app.ProjectID, app.ID, secret) return o.command.VerifyAPIClientSecret(ctx, app.ProjectID, app.ID, secret)
} }
func (o *OPStorage) SetUserinfoFromToken(ctx context.Context, userInfo oidc.UserInfoSetter, tokenID, subject, origin string) (err error) { func (o *OPStorage) SetUserinfoFromToken(ctx context.Context, userInfo *oidc.UserInfo, tokenID, subject, origin string) (err error) {
ctx, span := tracing.NewSpan(ctx) ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }() defer func() { span.EndWithError(err) }()
token, err := o.repo.TokenByIDs(ctx, subject, tokenID) token, err := o.repo.TokenByIDs(ctx, subject, tokenID)
@ -133,7 +133,7 @@ func (o *OPStorage) SetUserinfoFromToken(ctx context.Context, userInfo oidc.User
return o.setUserinfo(ctx, userInfo, token.UserID, token.ApplicationID, token.Scopes) return o.setUserinfo(ctx, userInfo, token.UserID, token.ApplicationID, token.Scopes)
} }
func (o *OPStorage) SetUserinfoFromScopes(ctx context.Context, userInfo oidc.UserInfoSetter, userID, applicationID string, scopes []string) (err error) { func (o *OPStorage) SetUserinfoFromScopes(ctx context.Context, userInfo *oidc.UserInfo, userID, applicationID string, scopes []string) (err error) {
ctx, span := tracing.NewSpan(ctx) ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }() defer func() { span.EndWithError(err) }()
if applicationID != "" { if applicationID != "" {
@ -151,7 +151,7 @@ func (o *OPStorage) SetUserinfoFromScopes(ctx context.Context, userInfo oidc.Use
return o.setUserinfo(ctx, userInfo, userID, applicationID, scopes) return o.setUserinfo(ctx, userInfo, userID, applicationID, scopes)
} }
func (o *OPStorage) SetIntrospectionFromToken(ctx context.Context, introspection oidc.IntrospectionResponse, tokenID, subject, clientID string) error { func (o *OPStorage) SetIntrospectionFromToken(ctx context.Context, introspection *oidc.IntrospectionResponse, tokenID, subject, clientID string) error {
token, err := o.repo.TokenByIDs(ctx, subject, tokenID) token, err := o.repo.TokenByIDs(ctx, subject, tokenID)
if err != nil { if err != nil {
return errors.ThrowPermissionDenied(nil, "OIDC-Dsfb2", "token is not valid or has expired") return errors.ThrowPermissionDenied(nil, "OIDC-Dsfb2", "token is not valid or has expired")
@ -168,19 +168,21 @@ func (o *OPStorage) SetIntrospectionFromToken(ctx context.Context, introspection
} }
for _, aud := range token.Audience { for _, aud := range token.Audience {
if aud == clientID || aud == projectID { if aud == clientID || aud == projectID {
err := o.setUserinfo(ctx, introspection, token.UserID, clientID, token.Scopes) userInfo := new(oidc.UserInfo)
err := o.setUserinfo(ctx, userInfo, subject, clientID, token.Scopes)
if err != nil { if err != nil {
return err return err
} }
introspection.SetScopes(token.Scopes) introspection.SetUserInfo(userInfo)
introspection.SetClientID(token.ApplicationID) introspection.Scope = token.Scopes
introspection.SetTokenType(oidc.BearerToken) introspection.ClientID = token.ApplicationID
introspection.SetExpiration(token.Expiration) introspection.TokenType = oidc.BearerToken
introspection.SetIssuedAt(token.CreationDate) introspection.Expiration = oidc.FromTime(token.Expiration)
introspection.SetNotBefore(token.CreationDate) introspection.IssuedAt = oidc.FromTime(token.CreationDate)
introspection.SetAudience(token.Audience) introspection.NotBefore = oidc.FromTime(token.CreationDate)
introspection.SetIssuer(op.IssuerFromContext(ctx)) introspection.Audience = token.Audience
introspection.SetJWTID(token.ID) introspection.Issuer = op.IssuerFromContext(ctx)
introspection.JWTID = token.ID
return nil return nil
} }
} }
@ -252,7 +254,7 @@ func (o *OPStorage) checkOrgScopes(ctx context.Context, user *query.User, scopes
return scopes, nil return scopes, nil
} }
func (o *OPStorage) setUserinfo(ctx context.Context, userInfo oidc.UserInfoSetter, userID, applicationID string, scopes []string) (err error) { func (o *OPStorage) setUserinfo(ctx context.Context, userInfo *oidc.UserInfo, userID, applicationID string, scopes []string) (err error) {
ctx, span := tracing.NewSpan(ctx) ctx, span := tracing.NewSpan(ctx)
defer func() { span.EndWithError(err) }() defer func() { span.EndWithError(err) }()
user, err := o.query.GetUserByID(ctx, true, userID, false) user, err := o.query.GetUserByID(ctx, true, userID, false)
@ -263,50 +265,23 @@ func (o *OPStorage) setUserinfo(ctx context.Context, userInfo oidc.UserInfoSette
for _, scope := range scopes { for _, scope := range scopes {
switch scope { switch scope {
case oidc.ScopeOpenID: case oidc.ScopeOpenID:
userInfo.SetSubject(user.ID) userInfo.Subject = user.ID
case oidc.ScopeEmail: case oidc.ScopeEmail:
if user.Human == nil { setUserInfoEmail(userInfo, user)
continue
}
userInfo.SetEmail(string(user.Human.Email), user.Human.IsEmailVerified)
case oidc.ScopeProfile: case oidc.ScopeProfile:
userInfo.SetPreferredUsername(user.PreferredLoginName) o.setUserInfoProfile(ctx, userInfo, user)
userInfo.SetUpdatedAt(user.ChangeDate)
if user.Human != nil {
userInfo.SetName(user.Human.DisplayName)
userInfo.SetFamilyName(user.Human.LastName)
userInfo.SetGivenName(user.Human.FirstName)
userInfo.SetNickname(user.Human.NickName)
userInfo.SetGender(getGender(user.Human.Gender))
userInfo.SetLocale(user.Human.PreferredLanguage)
userInfo.SetPicture(domain.AvatarURL(o.assetAPIPrefix(ctx), user.ResourceOwner, user.Human.AvatarKey))
} else {
userInfo.SetName(user.Machine.Name)
}
case oidc.ScopePhone: case oidc.ScopePhone:
if user.Human == nil { setUserInfoPhone(userInfo, user)
continue
}
userInfo.SetPhone(string(user.Human.Phone), user.Human.IsPhoneVerified)
case oidc.ScopeAddress: case oidc.ScopeAddress:
//TODO: handle address for human users as soon as implemented //TODO: handle address for human users as soon as implemented
case ScopeUserMetaData: case ScopeUserMetaData:
userMetaData, err := o.assertUserMetaData(ctx, userID) if err := o.setUserInfoMetadata(ctx, userInfo, userID); err != nil {
if err != nil {
return err return err
} }
if len(userMetaData) > 0 {
userInfo.AppendClaims(ClaimUserMetaData, userMetaData)
}
case ScopeResourceOwner: case ScopeResourceOwner:
resourceOwnerClaims, err := o.assertUserResourceOwner(ctx, userID) if err := o.setUserInfoResourceOwner(ctx, userInfo, userID); err != nil {
if err != nil {
return err return err
} }
for claim, value := range resourceOwnerClaims {
userInfo.AppendClaims(claim, value)
}
default: default:
if strings.HasPrefix(scope, ScopeProjectRolePrefix) { if strings.HasPrefix(scope, ScopeProjectRolePrefix) {
roles = append(roles, strings.TrimPrefix(scope, ScopeProjectRolePrefix)) roles = append(roles, strings.TrimPrefix(scope, ScopeProjectRolePrefix))
@ -316,13 +291,9 @@ func (o *OPStorage) setUserinfo(ctx context.Context, userInfo oidc.UserInfoSette
} }
if strings.HasPrefix(scope, domain.OrgIDScope) { if strings.HasPrefix(scope, domain.OrgIDScope) {
userInfo.AppendClaims(domain.OrgIDClaim, strings.TrimPrefix(scope, domain.OrgIDScope)) userInfo.AppendClaims(domain.OrgIDClaim, strings.TrimPrefix(scope, domain.OrgIDScope))
resourceOwnerClaims, err := o.assertUserResourceOwner(ctx, userID) if err := o.setUserInfoResourceOwner(ctx, userInfo, userID); err != nil {
if err != nil {
return err return err
} }
for claim, value := range resourceOwnerClaims {
userInfo.AppendClaims(claim, value)
}
} }
} }
} }
@ -339,7 +310,64 @@ func (o *OPStorage) setUserinfo(ctx context.Context, userInfo oidc.UserInfoSette
return o.userinfoFlows(ctx, user.ResourceOwner, userGrants, userInfo) return o.userinfoFlows(ctx, user.ResourceOwner, userGrants, userInfo)
} }
func (o *OPStorage) userinfoFlows(ctx context.Context, resourceOwner string, userGrants *query.UserGrants, userInfo oidc.UserInfoSetter) error { func (o *OPStorage) setUserInfoProfile(ctx context.Context, userInfo *oidc.UserInfo, user *query.User) {
userInfo.PreferredUsername = user.PreferredLoginName
userInfo.UpdatedAt = oidc.FromTime(user.ChangeDate)
if user.Machine != nil {
userInfo.Name = user.Machine.Name
return
}
userInfo.Name = user.Human.DisplayName
userInfo.FamilyName = user.Human.LastName
userInfo.GivenName = user.Human.FirstName
userInfo.Nickname = user.Human.NickName
userInfo.Gender = getGender(user.Human.Gender)
userInfo.Locale = oidc.NewLocale(user.Human.PreferredLanguage)
userInfo.Picture = domain.AvatarURL(o.assetAPIPrefix(ctx), user.ResourceOwner, user.Human.AvatarKey)
}
func setUserInfoEmail(userInfo *oidc.UserInfo, user *query.User) {
if user.Human == nil {
return
}
userInfo.UserInfoEmail = oidc.UserInfoEmail{
Email: string(user.Human.Email),
EmailVerified: oidc.Bool(user.Human.IsEmailVerified)}
}
func setUserInfoPhone(userInfo *oidc.UserInfo, user *query.User) {
if user.Human == nil {
return
}
userInfo.UserInfoPhone = oidc.UserInfoPhone{
PhoneNumber: string(user.Human.Phone),
PhoneNumberVerified: user.Human.IsPhoneVerified,
}
}
func (o *OPStorage) setUserInfoMetadata(ctx context.Context, userInfo *oidc.UserInfo, userID string) error {
userMetaData, err := o.assertUserMetaData(ctx, userID)
if err != nil {
return err
}
if len(userMetaData) > 0 {
userInfo.AppendClaims(ClaimUserMetaData, userMetaData)
}
return nil
}
func (o *OPStorage) setUserInfoResourceOwner(ctx context.Context, userInfo *oidc.UserInfo, userID string) error {
resourceOwnerClaims, err := o.assertUserResourceOwner(ctx, userID)
if err != nil {
return err
}
for claim, value := range resourceOwnerClaims {
userInfo.AppendClaims(claim, value)
}
return nil
}
func (o *OPStorage) userinfoFlows(ctx context.Context, resourceOwner string, userGrants *query.UserGrants, userInfo *oidc.UserInfo) error {
queriedActions, err := o.query.GetActiveActionsByFlowAndTriggerType(ctx, domain.FlowTypeCustomiseToken, domain.TriggerTypePreUserinfoCreation, resourceOwner, false) queriedActions, err := o.query.GetActiveActionsByFlowAndTriggerType(ctx, domain.FlowTypeCustomiseToken, domain.TriggerTypePreUserinfoCreation, resourceOwner, false)
if err != nil { if err != nil {
return err return err
@ -350,7 +378,7 @@ func (o *OPStorage) userinfoFlows(ctx context.Context, resourceOwner string, use
actions.SetFields("claims", userinfoClaims(userInfo)), actions.SetFields("claims", userinfoClaims(userInfo)),
actions.SetFields("getUser", func(c *actions.FieldConfig) interface{} { actions.SetFields("getUser", func(c *actions.FieldConfig) interface{} {
return func(call goja.FunctionCall) goja.Value { return func(call goja.FunctionCall) goja.Value {
user, err := o.query.GetUserByID(ctx, true, userInfo.GetSubject(), false) user, err := o.query.GetUserByID(ctx, true, userInfo.Subject, false)
if err != nil { if err != nil {
panic(err) panic(err)
} }
@ -368,7 +396,7 @@ func (o *OPStorage) userinfoFlows(ctx context.Context, resourceOwner string, use
metadata, err := o.query.SearchUserMetadata( metadata, err := o.query.SearchUserMetadata(
ctx, ctx,
true, true,
userInfo.GetSubject(), userInfo.Subject,
&query.UserMetadataSearchQueries{Queries: []query.SearchQuery{resourceOwnerQuery}}, &query.UserMetadataSearchQueries{Queries: []query.SearchQuery{resourceOwnerQuery}},
false, false,
) )
@ -394,7 +422,7 @@ func (o *OPStorage) userinfoFlows(ctx context.Context, resourceOwner string, use
actions.SetFields("v1", actions.SetFields("v1",
actions.SetFields("userinfo", actions.SetFields("userinfo",
actions.SetFields("setClaim", func(key string, value interface{}) { actions.SetFields("setClaim", func(key string, value interface{}) {
if userInfo.GetClaim(key) == nil { if userInfo.Claims[key] == nil {
userInfo.AppendClaims(key, value) userInfo.AppendClaims(key, value)
return return
} }
@ -406,7 +434,7 @@ func (o *OPStorage) userinfoFlows(ctx context.Context, resourceOwner string, use
), ),
actions.SetFields("claims", actions.SetFields("claims",
actions.SetFields("setClaim", func(key string, value interface{}) { actions.SetFields("setClaim", func(key string, value interface{}) {
if userInfo.GetClaim(key) == nil { if userInfo.Claims[key] == nil {
userInfo.AppendClaims(key, value) userInfo.AppendClaims(key, value)
return return
} }
@ -434,7 +462,7 @@ func (o *OPStorage) userinfoFlows(ctx context.Context, resourceOwner string, use
Key: key, Key: key,
Value: value, Value: value,
} }
if _, err = o.command.SetUserMetadata(ctx, metadata, userInfo.GetSubject(), resourceOwner); err != nil { if _, err = o.command.SetUserMetadata(ctx, metadata, userInfo.Subject, resourceOwner); err != nil {
logging.WithError(err).Info("unable to set md in action") logging.WithError(err).Info("unable to set md in action")
panic(err) panic(err)
} }
@ -729,7 +757,7 @@ func appendClaim(claims map[string]interface{}, claim string, value interface{})
return claims return claims
} }
func userinfoClaims(userInfo oidc.UserInfoSetter) func(c *actions.FieldConfig) interface{} { func userinfoClaims(userInfo *oidc.UserInfo) func(c *actions.FieldConfig) interface{} {
return func(c *actions.FieldConfig) interface{} { return func(c *actions.FieldConfig) interface{} {
marshalled, err := json.Marshal(userInfo) marshalled, err := json.Marshal(userInfo)
if err != nil { if err != nil {

View File

@ -84,7 +84,6 @@ func NewProvider(ctx context.Context, config Config, defaultLogoutRedirectURI st
return nil, caos_errs.ThrowInternal(err, "OIDC-D3gq1", "cannot create options: %w") return nil, caos_errs.ThrowInternal(err, "OIDC-D3gq1", "cannot create options: %w")
} }
provider, err := op.NewDynamicOpenIDProvider( provider, err := op.NewDynamicOpenIDProvider(
ctx,
"", "",
opConfig, opConfig,
storage, storage,

View File

@ -18,7 +18,7 @@ import (
func (l *Login) runPostExternalAuthenticationActions( func (l *Login) runPostExternalAuthenticationActions(
user *domain.ExternalUser, user *domain.ExternalUser,
tokens *oidc.Tokens, tokens *oidc.Tokens[*oidc.IDTokenClaims],
authRequest *domain.AuthRequest, authRequest *domain.AuthRequest,
httpRequest *http.Request, httpRequest *http.Request,
idpUser idp.User, idpUser idp.User,
@ -347,7 +347,7 @@ func (l *Login) runPostCreationActions(
return object.UserGrantsToDomain(userID, mutableUserGrants.UserGrants), err return object.UserGrantsToDomain(userID, mutableUserGrants.UserGrants), err
} }
func tokenCtxFields(tokens *oidc.Tokens) []actions.FieldOption { func tokenCtxFields(tokens *oidc.Tokens[*oidc.IDTokenClaims]) []actions.FieldOption {
var accessToken, idToken string var accessToken, idToken string
getClaim := func(claim string) interface{} { getClaim := func(claim string) interface{} {
return nil return nil
@ -367,7 +367,7 @@ func tokenCtxFields(tokens *oidc.Tokens) []actions.FieldOption {
idToken = tokens.IDToken idToken = tokens.IDToken
if tokens.IDTokenClaims != nil { if tokens.IDTokenClaims != nil {
getClaim = func(claim string) interface{} { getClaim = func(claim string) interface{} {
return tokens.IDTokenClaims.GetClaim(claim) return tokens.IDTokenClaims.Claims[claim]
} }
claimsJSON = func() (string, error) { claimsJSON = func() (string, error) {
c, err := json.Marshal(tokens.IDTokenClaims) c, err := json.Marshal(tokens.IDTokenClaims)

View File

@ -837,7 +837,7 @@ func (l *Login) appendUserGrants(ctx context.Context, userGrants []*domain.UserG
return nil return nil
} }
func (l *Login) externalAuthFailed(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, tokens *oidc.Tokens, user idp.User, err error) { func (l *Login) externalAuthFailed(w http.ResponseWriter, r *http.Request, authReq *domain.AuthRequest, tokens *oidc.Tokens[*oidc.IDTokenClaims], user idp.User, err error) {
if _, actionErr := l.runPostExternalAuthenticationActions(&domain.ExternalUser{}, tokens, authReq, r, user, err); actionErr != nil { if _, actionErr := l.runPostExternalAuthenticationActions(&domain.ExternalUser{}, tokens, authReq, r, user, err); actionErr != nil {
logging.WithError(err).Error("both external user authentication and action post authentication failed") logging.WithError(err).Error("both external user authentication and action post authentication failed")
} }
@ -845,7 +845,7 @@ func (l *Login) externalAuthFailed(w http.ResponseWriter, r *http.Request, authR
} }
// tokens extracts the oidc.Tokens for backwards compatibility of PostExternalAuthenticationActions // tokens extracts the oidc.Tokens for backwards compatibility of PostExternalAuthenticationActions
func tokens(session idp.Session) *oidc.Tokens { func tokens(session idp.Session) *oidc.Tokens[*oidc.IDTokenClaims] {
switch s := session.(type) { switch s := session.(type) {
case *openid.Session: case *openid.Session:
return s.Tokens return s.Tokens

View File

@ -81,7 +81,7 @@ func (l *Login) handleJWTExtraction(w http.ResponseWriter, r *http.Request, auth
l.renderError(w, r, authReq, err) l.renderError(w, r, authReq, err)
return return
} }
session := &jwt.Session{Provider: provider, Tokens: &oidc.Tokens{IDToken: token, Token: &oauth2.Token{}}} session := &jwt.Session{Provider: provider, Tokens: &oidc.Tokens[*oidc.IDTokenClaims]{IDToken: token, Token: &oauth2.Token{}}}
user, err := session.FetchUser(r.Context()) user, err := session.FetchUser(r.Context())
if err != nil { if err != nil {
if _, actionErr := l.runPostExternalAuthenticationActions(new(domain.ExternalUser), tokens(session), authReq, r, user, err); actionErr != nil { if _, actionErr := l.runPostExternalAuthenticationActions(new(domain.ExternalUser), tokens(session), authReq, r, user, err); actionErr != nil {

View File

@ -26,11 +26,22 @@ type RefreshTokenRepo struct {
KeyAlgorithm crypto.EncryptionAlgorithm KeyAlgorithm crypto.EncryptionAlgorithm
} }
func (r *RefreshTokenRepo) RefreshTokenByID(ctx context.Context, refreshToken string) (*usr_model.RefreshTokenView, error) { func (r *RefreshTokenRepo) RefreshTokenByToken(ctx context.Context, refreshToken string) (*usr_model.RefreshTokenView, error) {
userID, tokenID, token, err := domain.FromRefreshToken(refreshToken, r.KeyAlgorithm) userID, tokenID, token, err := domain.FromRefreshToken(refreshToken, r.KeyAlgorithm)
if err != nil { if err != nil {
return nil, err return nil, err
} }
tokenView, err := r.RefreshTokenByID(ctx, tokenID, userID)
if err != nil {
return nil, err
}
if tokenView.Token != token {
return nil, errors.ThrowNotFound(nil, "EVENT-5Bm9s", "Errors.User.RefreshToken.Invalid")
}
return tokenView, nil
}
func (r *RefreshTokenRepo) RefreshTokenByID(ctx context.Context, tokenID, userID string) (*usr_model.RefreshTokenView, error) {
tokenView, viewErr := r.View.RefreshTokenByID(tokenID, authz.GetInstance(ctx).InstanceID()) tokenView, viewErr := r.View.RefreshTokenByID(tokenID, authz.GetInstance(ctx).InstanceID())
if viewErr != nil && !errors.IsNotFound(viewErr) { if viewErr != nil && !errors.IsNotFound(viewErr) {
return nil, viewErr return nil, viewErr
@ -57,7 +68,7 @@ func (r *RefreshTokenRepo) RefreshTokenByID(ctx context.Context, refreshToken st
return model.RefreshTokenViewToModel(&viewToken), nil return model.RefreshTokenViewToModel(&viewToken), nil
} }
} }
if !tokenView.Expiration.After(time.Now()) || tokenView.Token != token { if !tokenView.Expiration.After(time.Now()) {
return nil, errors.ThrowNotFound(nil, "EVENT-5Bm9s", "Errors.User.RefreshToken.Invalid") return nil, errors.ThrowNotFound(nil, "EVENT-5Bm9s", "Errors.User.RefreshToken.Invalid")
} }
return model.RefreshTokenViewToModel(tokenView), nil return model.RefreshTokenViewToModel(tokenView), nil

View File

@ -7,6 +7,7 @@ import (
) )
type RefreshTokenRepository interface { type RefreshTokenRepository interface {
RefreshTokenByID(ctx context.Context, refreshToken string) (*model.RefreshTokenView, error) RefreshTokenByID(ctx context.Context, tokenID, userID string) (*model.RefreshTokenView, error)
RefreshTokenByToken(ctx context.Context, refreshToken string) (*model.RefreshTokenView, error)
SearchMyRefreshTokens(ctx context.Context, userID string, request *model.RefreshTokenSearchRequest) (*model.RefreshTokenSearchResponse, error) SearchMyRefreshTokens(ctx context.Context, userID string, request *model.RefreshTokenSearchRequest) (*model.RefreshTokenSearchResponse, error)
} }

View File

@ -153,11 +153,11 @@ func (repo *TokenVerifierRepo) getTokenIDAndSubject(ctx context.Context, accessT
tokenIDSubject, err := repo.decryptAccessToken(accessToken) tokenIDSubject, err := repo.decryptAccessToken(accessToken)
if err != nil { if err != nil {
// if decryption did not work, it might be a JWT // if decryption did not work, it might be a JWT
accessTokenClaims, err := op.VerifyAccessToken(ctx, accessToken, repo.jwtTokenVerifier(ctx)) accessTokenClaims, err := op.VerifyAccessToken[*oidc.AccessTokenClaims](ctx, accessToken, repo.jwtTokenVerifier(ctx))
if err != nil { if err != nil {
return "", "", false return "", "", false
} }
return accessTokenClaims.GetTokenID(), accessTokenClaims.GetSubject(), true return accessTokenClaims.JWTID, accessTokenClaims.Subject, true
} }
splitToken := strings.Split(tokenIDSubject, ":") splitToken := strings.Split(tokenIDSubject, ":")
if len(splitToken) != 2 { if len(splitToken) != 2 {

View File

@ -30,7 +30,7 @@ func TestSession_FetchUser(t *testing.T) {
options []ProviderOptions options []ProviderOptions
authURL string authURL string
code string code string
tokens *oidc.Tokens tokens *oidc.Tokens[*oidc.IDTokenClaims]
} }
type want struct { type want struct {
err func(error) bool err func(error) bool
@ -87,7 +87,7 @@ func TestSession_FetchUser(t *testing.T) {
Reply(http.StatusInternalServerError) Reply(http.StatusInternalServerError)
}, },
authURL: "https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=openid+profile+email&state=testState", authURL: "https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=openid+profile+email&state=testState",
tokens: &oidc.Tokens{ tokens: &oidc.Tokens[*oidc.IDTokenClaims]{
Token: &oauth2.Token{ Token: &oauth2.Token{
AccessToken: "accessToken", AccessToken: "accessToken",
TokenType: oidc.BearerToken, TokenType: oidc.BearerToken,
@ -125,7 +125,7 @@ func TestSession_FetchUser(t *testing.T) {
JSON(userinfo()) JSON(userinfo())
}, },
authURL: "https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=openid+profile+email&state=testState", authURL: "https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=openid+profile+email&state=testState",
tokens: &oidc.Tokens{ tokens: &oidc.Tokens[*oidc.IDTokenClaims]{
Token: &oauth2.Token{ Token: &oauth2.Token{
AccessToken: "accessToken", AccessToken: "accessToken",
TokenType: oidc.BearerToken, TokenType: oidc.BearerToken,
@ -189,7 +189,7 @@ func TestSession_FetchUser(t *testing.T) {
JSON(userinfo()) JSON(userinfo())
}, },
authURL: "https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=openid+profile+email&state=testState", authURL: "https://login.microsoftonline.com/consumers/oauth2/v2.0/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=openid+profile+email&state=testState",
tokens: &oidc.Tokens{ tokens: &oidc.Tokens[*oidc.IDTokenClaims]{
Token: &oauth2.Token{ Token: &oauth2.Token{
AccessToken: "accessToken", AccessToken: "accessToken",
TokenType: oidc.BearerToken, TokenType: oidc.BearerToken,

View File

@ -27,7 +27,7 @@ func TestSession_FetchUser(t *testing.T) {
httpMock func() httpMock func()
authURL string authURL string
code string code string
tokens *oidc.Tokens tokens *oidc.Tokens[*oidc.IDTokenClaims]
scopes []string scopes []string
options []oauth.ProviderOpts options []oauth.ProviderOpts
} }
@ -93,7 +93,7 @@ func TestSession_FetchUser(t *testing.T) {
Reply(http.StatusInternalServerError) Reply(http.StatusInternalServerError)
}, },
authURL: "https://github.com/login/oauth/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&state=testState", authURL: "https://github.com/login/oauth/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&state=testState",
tokens: &oidc.Tokens{ tokens: &oidc.Tokens[*oidc.IDTokenClaims]{
Token: &oauth2.Token{ Token: &oauth2.Token{
AccessToken: "accessToken", AccessToken: "accessToken",
TokenType: oidc.BearerToken, TokenType: oidc.BearerToken,
@ -122,7 +122,7 @@ func TestSession_FetchUser(t *testing.T) {
JSON(userinfo()) JSON(userinfo())
}, },
authURL: "https://github.com/login/oauth/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&state=testState", authURL: "https://github.com/login/oauth/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&state=testState",
tokens: &oidc.Tokens{ tokens: &oidc.Tokens[*oidc.IDTokenClaims]{
Token: &oauth2.Token{ Token: &oauth2.Token{
AccessToken: "accessToken", AccessToken: "accessToken",
TokenType: oidc.BearerToken, TokenType: oidc.BearerToken,

View File

@ -27,7 +27,7 @@ func TestProvider_FetchUser(t *testing.T) {
httpMock func() httpMock func()
authURL string authURL string
code string code string
tokens *openid.Tokens tokens *openid.Tokens[*openid.IDTokenClaims]
options []oidc.ProviderOpts options []oidc.ProviderOpts
} }
type want struct { type want struct {
@ -85,7 +85,7 @@ func TestProvider_FetchUser(t *testing.T) {
JSON(userinfo()) JSON(userinfo())
}, },
authURL: "https://gitlab.com/oauth/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=openid&state=testState", authURL: "https://gitlab.com/oauth/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=openid&state=testState",
tokens: &openid.Tokens{ tokens: &openid.Tokens[*openid.IDTokenClaims]{
Token: &oauth2.Token{ Token: &oauth2.Token{
AccessToken: "accessToken", AccessToken: "accessToken",
TokenType: openid.BearerToken, TokenType: openid.BearerToken,
@ -122,7 +122,7 @@ func TestProvider_FetchUser(t *testing.T) {
JSON(userinfo()) JSON(userinfo())
}, },
authURL: "https://gitlab.com/oauth/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=openid&state=testState", authURL: "https://gitlab.com/oauth/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=openid&state=testState",
tokens: &openid.Tokens{ tokens: &openid.Tokens[*openid.IDTokenClaims]{
Token: &oauth2.Token{ Token: &oauth2.Token{
AccessToken: "accessToken", AccessToken: "accessToken",
TokenType: openid.BearerToken, TokenType: openid.BearerToken,
@ -200,18 +200,26 @@ func TestProvider_FetchUser(t *testing.T) {
} }
} }
func userinfo() openid.UserInfoSetter { func userinfo() *openid.UserInfo {
info := openid.NewUserInfo() return &openid.UserInfo{
info.SetSubject("sub") Subject: "sub",
info.SetGivenName("firstname") UserInfoProfile: openid.UserInfoProfile{
info.SetFamilyName("lastname") GivenName: "firstname",
info.SetName("firstname lastname") FamilyName: "lastname",
info.SetNickname("nickname") Name: "firstname lastname",
info.SetPreferredUsername("username") Nickname: "nickname",
info.SetEmail("email", true) PreferredUsername: "username",
info.SetPhone("phone", true) Locale: openid.NewLocale(language.English),
info.SetLocale(language.English) Picture: "picture",
info.SetPicture("picture") Profile: "profile",
info.SetProfile("profile") },
return info UserInfoEmail: openid.UserInfoEmail{
Email: "email",
EmailVerified: openid.Bool(true),
},
UserInfoPhone: openid.UserInfoPhone{
PhoneNumber: "phone",
PhoneNumberVerified: true,
},
}
} }

View File

@ -30,7 +30,7 @@ func New(clientID, clientSecret, redirectURI string, scopes []string, opts ...oi
}, nil }, nil
} }
var userMapper = func(info openid.UserInfo) idp.User { var userMapper = func(info *openid.UserInfo) idp.User {
return &User{oidc.DefaultMapper(info)} return &User{oidc.DefaultMapper(info)}
} }

View File

@ -27,7 +27,7 @@ func TestSession_FetchUser(t *testing.T) {
httpMock func() httpMock func()
authURL string authURL string
code string code string
tokens *openid.Tokens tokens *openid.Tokens[*openid.IDTokenClaims]
} }
type want struct { type want struct {
err error err error
@ -85,7 +85,7 @@ func TestSession_FetchUser(t *testing.T) {
JSON(userinfo()) JSON(userinfo())
}, },
authURL: "https://accounts.google.com/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=openid&state=testState", authURL: "https://accounts.google.com/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=openid&state=testState",
tokens: &openid.Tokens{ tokens: &openid.Tokens[*openid.IDTokenClaims]{
Token: &oauth2.Token{ Token: &oauth2.Token{
AccessToken: "accessToken", AccessToken: "accessToken",
TokenType: openid.BearerToken, TokenType: openid.BearerToken,
@ -122,7 +122,7 @@ func TestSession_FetchUser(t *testing.T) {
JSON(userinfo()) JSON(userinfo())
}, },
authURL: "https://accounts.google.com/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=openid&state=testState", authURL: "https://accounts.google.com/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=openid&state=testState",
tokens: &openid.Tokens{ tokens: &openid.Tokens[*openid.IDTokenClaims]{
Token: &oauth2.Token{ Token: &oauth2.Token{
AccessToken: "accessToken", AccessToken: "accessToken",
TokenType: openid.BearerToken, TokenType: openid.BearerToken,
@ -201,15 +201,22 @@ func TestSession_FetchUser(t *testing.T) {
} }
} }
func userinfo() openid.UserInfoSetter { func userinfo() *openid.UserInfo {
info := openid.NewUserInfo() return &openid.UserInfo{
info.SetSubject("sub") Subject: "sub",
info.SetGivenName("firstname") UserInfoProfile: openid.UserInfoProfile{
info.SetFamilyName("lastname") GivenName: "firstname",
info.SetName("firstname lastname") FamilyName: "lastname",
info.SetEmail("email", true) Name: "firstname lastname",
info.SetLocale(language.English) Locale: openid.NewLocale(language.English),
info.SetPicture("picture") Picture: "picture",
info.AppendClaims("hd", "hosted domain") },
return info UserInfoEmail: openid.UserInfoEmail{
Email: "email",
EmailVerified: openid.Bool(true),
},
Claims: map[string]any{
"hd": "hosted domain",
},
}
} }

View File

@ -27,7 +27,7 @@ var (
type Session struct { type Session struct {
*Provider *Provider
AuthURL string AuthURL string
Tokens *oidc.Tokens Tokens *oidc.Tokens[*oidc.IDTokenClaims]
} }
// GetAuthURL implements the [idp.Session] interface // GetAuthURL implements the [idp.Session] interface
@ -48,12 +48,12 @@ func (s *Session) FetchUser(ctx context.Context) (user idp.User, err error) {
return &User{s.Tokens.IDTokenClaims}, nil return &User{s.Tokens.IDTokenClaims}, nil
} }
func (s *Session) validateToken(ctx context.Context, token string) (oidc.IDTokenClaims, error) { func (s *Session) validateToken(ctx context.Context, token string) (*oidc.IDTokenClaims, error) {
logging.Debug("begin token validation") logging.Debug("begin token validation")
// TODO: be able to specify them in the template: https://github.com/zitadel/zitadel/issues/5322 // TODO: be able to specify them in the template: https://github.com/zitadel/zitadel/issues/5322
offset := 3 * time.Second offset := 3 * time.Second
maxAge := time.Hour maxAge := time.Hour
claims := oidc.EmptyIDTokenClaims() claims := new(oidc.IDTokenClaims)
payload, err := oidc.ParseToken(token, claims) payload, err := oidc.ParseToken(token, claims)
if err != nil { if err != nil {
return nil, fmt.Errorf("%w: malformed jwt payload: %v", ErrInvalidToken, err) return nil, fmt.Errorf("%w: malformed jwt payload: %v", ErrInvalidToken, err)
@ -84,45 +84,57 @@ func (s *Session) validateToken(ctx context.Context, token string) (oidc.IDToken
} }
type User struct { type User struct {
oidc.IDTokenClaims *oidc.IDTokenClaims
} }
func (u *User) GetID() string { func (u *User) GetID() string {
return u.IDTokenClaims.GetSubject() return u.Subject
} }
func (u *User) GetFirstName() string { func (u *User) GetFirstName() string {
return u.IDTokenClaims.GetGivenName() return u.GivenName
} }
func (u *User) GetLastName() string { func (u *User) GetLastName() string {
return u.IDTokenClaims.GetFamilyName() return u.FamilyName
} }
func (u *User) GetDisplayName() string { func (u *User) GetDisplayName() string {
return u.IDTokenClaims.GetName() return u.Name
} }
func (u *User) GetNickname() string { func (u *User) GetNickname() string {
return u.IDTokenClaims.GetNickname() return u.Nickname
} }
func (u *User) GetPhone() domain.PhoneNumber { func (u *User) GetPreferredUsername() string {
return domain.PhoneNumber(u.IDTokenClaims.GetPhoneNumber()) return u.PreferredUsername
}
func (u *User) IsPhoneVerified() bool {
return u.IDTokenClaims.IsPhoneNumberVerified()
}
func (u *User) GetPreferredLanguage() language.Tag {
return u.IDTokenClaims.GetLocale()
}
func (u *User) GetAvatarURL() string {
return u.IDTokenClaims.GetPicture()
} }
func (u *User) GetEmail() domain.EmailAddress { func (u *User) GetEmail() domain.EmailAddress {
return domain.EmailAddress(u.IDTokenClaims.GetEmail()) return domain.EmailAddress(u.Email)
}
func (u *User) IsEmailVerified() bool {
return bool(u.EmailVerified)
}
func (u *User) GetPhone() domain.PhoneNumber {
return domain.PhoneNumber(u.IDTokenClaims.PhoneNumber)
}
func (u *User) IsPhoneVerified() bool {
return u.PhoneNumberVerified
}
func (u *User) GetPreferredLanguage() language.Tag {
return u.Locale.Tag()
}
func (u *User) GetAvatarURL() string {
return u.Picture
}
func (u *User) GetProfile() string {
return u.Profile
} }

View File

@ -30,7 +30,7 @@ func TestSession_FetchUser(t *testing.T) {
encryptionAlg func(t *testing.T) crypto.EncryptionAlgorithm encryptionAlg func(t *testing.T) crypto.EncryptionAlgorithm
httpMock func(issuer string) httpMock func(issuer string)
authURL string authURL string
tokens *oidc.Tokens tokens *oidc.Tokens[*oidc.IDTokenClaims]
} }
type want struct { type want struct {
err func(error) bool err func(error) bool
@ -93,7 +93,7 @@ func TestSession_FetchUser(t *testing.T) {
JSON(keys(t)) JSON(keys(t))
}, },
authURL: "https://auth.com/jwt?authRequestID=testState", authURL: "https://auth.com/jwt?authRequestID=testState",
tokens: &oidc.Tokens{ tokens: &oidc.Tokens[*oidc.IDTokenClaims]{
Token: &oauth2.Token{}, Token: &oauth2.Token{},
IDToken: "invalidToken", IDToken: "invalidToken",
}, },
@ -121,26 +121,32 @@ func TestSession_FetchUser(t *testing.T) {
JSON(keys(t)) JSON(keys(t))
}, },
authURL: "https://auth.com/jwt?authRequestID=testState", authURL: "https://auth.com/jwt?authRequestID=testState",
tokens: &oidc.Tokens{ tokens: &oidc.Tokens[*oidc.IDTokenClaims]{
Token: &oauth2.Token{}, Token: &oauth2.Token{},
IDToken: idToken(t, "https://jwt.com"), IDToken: idToken(t, "https://jwt.com"),
IDTokenClaims: func() oidc.IDTokenClaims { IDTokenClaims: &oidc.IDTokenClaims{
claims := oidc.EmptyIDTokenClaims() TokenClaims: oidc.TokenClaims{
userinfo := oidc.NewUserInfo() Subject: "sub",
userinfo.SetSubject("sub") },
userinfo.SetPicture("picture") UserInfoProfile: oidc.UserInfoProfile{
userinfo.SetName("firstname lastname") Picture: "picture",
userinfo.SetEmail("email", true) Name: "firstname lastname",
userinfo.SetGivenName("firstname") GivenName: "firstname",
userinfo.SetFamilyName("lastname") FamilyName: "lastname",
userinfo.SetNickname("nickname") Nickname: "nickname",
userinfo.SetPreferredUsername("username") PreferredUsername: "username",
userinfo.SetProfile("profile") Profile: "profile",
userinfo.SetPhone("phone", true) Locale: oidc.NewLocale(language.English),
userinfo.SetLocale(language.English) },
claims.SetUserinfo(userinfo) UserInfoEmail: oidc.UserInfoEmail{
return claims Email: "email",
}(), EmailVerified: oidc.Bool(true),
},
UserInfoPhone: oidc.UserInfoPhone{
PhoneNumber: "phone",
PhoneNumberVerified: true,
},
},
}, },
}, },
want: want{ want: want{
@ -219,19 +225,25 @@ func idToken(t *testing.T, issuer string) string {
"clientID", "clientID",
0, 0,
) )
info := oidc.NewUserInfo() claims.UserInfoProfile = oidc.UserInfoProfile{
info.SetSubject("sub") GivenName: "firstname",
info.SetGivenName("firstname") FamilyName: "lastname",
info.SetFamilyName("lastname") Name: "firstname lastname",
info.SetName("firstname lastname") Nickname: "nickname",
info.SetNickname("nickname") PreferredUsername: "username",
info.SetPreferredUsername("username") Locale: oidc.NewLocale(language.English),
info.SetEmail("email", true) Picture: "picture",
info.SetPhone("phone", true) Profile: "profile",
info.SetLocale(language.English) }
info.SetPicture("picture") claims.UserInfoEmail = oidc.UserInfoEmail{
info.SetProfile("profile") Email: "email",
claims.SetUserinfo(info) EmailVerified: oidc.Bool(true),
}
claims.UserInfoPhone = oidc.UserInfoPhone{
PhoneNumber: "phone",
PhoneNumberVerified: true,
}
privateKey, err := crypto.BytesToPrivateKey([]byte(`-----BEGIN RSA PRIVATE KEY----- privateKey, err := crypto.BytesToPrivateKey([]byte(`-----BEGIN RSA PRIVATE KEY-----
MIIEpAIBAAKCAQEAs38btwb3c7r0tMaQpGvBmY+mPwMU/LpfuPoC0k2t4RsKp0fv MIIEpAIBAAKCAQEAs38btwb3c7r0tMaQpGvBmY+mPwMU/LpfuPoC0k2t4RsKp0fv
40SMl50CRrHgk395wch8PMPYbl3+8TtYAJuyrFALIj3Ff1UcKIk0hOH5DDsfh7/q 40SMl50CRrHgk395wch8PMPYbl3+8TtYAJuyrFALIj3Ff1UcKIk0hOH5DDsfh7/q

View File

@ -20,7 +20,7 @@ var _ idp.Session = (*Session)(nil)
type Session struct { type Session struct {
AuthURL string AuthURL string
Code string Code string
Tokens *oidc.Tokens Tokens *oidc.Tokens[*oidc.IDTokenClaims]
Provider *Provider Provider *Provider
} }
@ -55,7 +55,7 @@ func (s *Session) authorize(ctx context.Context) (err error) {
if s.Code == "" { if s.Code == "" {
return ErrCodeMissing return ErrCodeMissing
} }
s.Tokens, err = rp.CodeExchange(ctx, s.Code, s.Provider.RelyingParty) s.Tokens, err = rp.CodeExchange[*oidc.IDTokenClaims](ctx, s.Code, s.Provider.RelyingParty)
if err != nil { if err != nil {
return err return err
} }

View File

@ -26,7 +26,7 @@ func TestProvider_FetchUser(t *testing.T) {
userMapper func() idp.User userMapper func() idp.User
authURL string authURL string
code string code string
tokens *oidc.Tokens tokens *oidc.Tokens[*oidc.IDTokenClaims]
} }
type want struct { type want struct {
err func(error) bool err func(error) bool
@ -97,7 +97,7 @@ func TestProvider_FetchUser(t *testing.T) {
return NewUserMapper("userID") return NewUserMapper("userID")
}, },
authURL: "https://oauth2.com/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=user&state=testState", authURL: "https://oauth2.com/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=user&state=testState",
tokens: &oidc.Tokens{ tokens: &oidc.Tokens[*oidc.IDTokenClaims]{
Token: &oauth2.Token{ Token: &oauth2.Token{
AccessToken: "accessToken", AccessToken: "accessToken",
TokenType: oidc.BearerToken, TokenType: oidc.BearerToken,
@ -137,7 +137,7 @@ func TestProvider_FetchUser(t *testing.T) {
return NewUserMapper("userID") return NewUserMapper("userID")
}, },
authURL: "https://issuer.com/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=user&state=testState", authURL: "https://issuer.com/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=user&state=testState",
tokens: &oidc.Tokens{ tokens: &oidc.Tokens[*oidc.IDTokenClaims]{
Token: &oauth2.Token{ Token: &oauth2.Token{
AccessToken: "accessToken", AccessToken: "accessToken",
TokenType: oidc.BearerToken, TokenType: oidc.BearerToken,

View File

@ -21,7 +21,7 @@ type Provider struct {
isAutoCreation bool isAutoCreation bool
isAutoUpdate bool isAutoUpdate bool
useIDToken bool useIDToken bool
userInfoMapper func(info oidc.UserInfo) idp.User userInfoMapper func(info *oidc.UserInfo) idp.User
authOptions []rp.AuthURLOpt authOptions []rp.AuthURLOpt
} }
@ -77,9 +77,9 @@ func WithSelectAccount() ProviderOpts {
} }
} }
type UserInfoMapper func(info oidc.UserInfo) idp.User type UserInfoMapper func(info *oidc.UserInfo) idp.User
var DefaultMapper UserInfoMapper = func(info oidc.UserInfo) idp.User { var DefaultMapper UserInfoMapper = func(info *oidc.UserInfo) idp.User {
return NewUser(info) return NewUser(info)
} }

View File

@ -21,7 +21,7 @@ func TestProvider_BeginAuth(t *testing.T) {
clientSecret string clientSecret string
redirectURI string redirectURI string
scopes []string scopes []string
userMapper func(info oidc.UserInfo) idp.User userMapper func(info *oidc.UserInfo) idp.User
httpMock func(issuer string) httpMock func(issuer string)
opts []ProviderOpts opts []ProviderOpts
} }
@ -82,7 +82,7 @@ func TestProvider_Options(t *testing.T) {
clientSecret string clientSecret string
redirectURI string redirectURI string
scopes []string scopes []string
userMapper func(info oidc.UserInfo) idp.User userMapper func(info *oidc.UserInfo) idp.User
opts []ProviderOpts opts []ProviderOpts
httpMock func(issuer string) httpMock func(issuer string)
} }

View File

@ -21,7 +21,7 @@ type Session struct {
Provider *Provider Provider *Provider
AuthURL string AuthURL string
Code string Code string
Tokens *oidc.Tokens Tokens *oidc.Tokens[*oidc.IDTokenClaims]
} }
// GetAuthURL implements the [idp.Session] interface. // GetAuthURL implements the [idp.Session] interface.
@ -48,7 +48,7 @@ func (s *Session) FetchUser(ctx context.Context) (user idp.User, err error) {
return nil, err return nil, err
} }
if s.Provider.useIDToken { if s.Provider.useIDToken {
info = s.Tokens.IDTokenClaims info = s.Tokens.IDTokenClaims.GetUserInfo()
} }
u := s.Provider.userInfoMapper(info) u := s.Provider.userInfoMapper(info)
return u, nil return u, nil
@ -58,50 +58,66 @@ func (s *Session) authorize(ctx context.Context) (err error) {
if s.Code == "" { if s.Code == "" {
return ErrCodeMissing return ErrCodeMissing
} }
s.Tokens, err = rp.CodeExchange(ctx, s.Code, s.Provider.RelyingParty) s.Tokens, err = rp.CodeExchange[*oidc.IDTokenClaims](ctx, s.Code, s.Provider.RelyingParty)
return err return err
} }
func NewUser(info oidc.UserInfo) *User { func NewUser(info *oidc.UserInfo) *User {
return &User{UserInfo: info} return &User{UserInfo: info}
} }
type User struct { type User struct {
oidc.UserInfo *oidc.UserInfo
} }
func (u *User) GetID() string { func (u *User) GetID() string {
return u.GetSubject() return u.Subject
} }
func (u *User) GetFirstName() string { func (u *User) GetFirstName() string {
return u.GetGivenName() return u.GivenName
} }
func (u *User) GetLastName() string { func (u *User) GetLastName() string {
return u.GetFamilyName() return u.FamilyName
} }
func (u *User) GetDisplayName() string { func (u *User) GetDisplayName() string {
return u.GetName() return u.Name
} }
func (u *User) GetPhone() domain.PhoneNumber { func (u *User) GetNickname() string {
return domain.PhoneNumber(u.GetPhoneNumber()) return u.Nickname
} }
func (u *User) IsPhoneVerified() bool { func (u *User) GetPreferredUsername() string {
return u.IsPhoneNumberVerified() return u.PreferredUsername
}
func (u *User) GetPreferredLanguage() language.Tag {
return u.GetLocale()
}
func (u *User) GetAvatarURL() string {
return u.GetPicture()
} }
func (u *User) GetEmail() domain.EmailAddress { func (u *User) GetEmail() domain.EmailAddress {
return domain.EmailAddress(u.UserInfo.GetEmail()) return domain.EmailAddress(u.UserInfo.Email)
}
func (u *User) IsEmailVerified() bool {
return bool(u.EmailVerified)
}
func (u *User) GetPhone() domain.PhoneNumber {
return domain.PhoneNumber(u.PhoneNumber)
}
func (u *User) IsPhoneVerified() bool {
return u.PhoneNumberVerified
}
func (u *User) GetPreferredLanguage() language.Tag {
return u.Locale.Tag()
}
func (u *User) GetAvatarURL() string {
return u.Picture
}
func (u *User) GetProfile() string {
return u.Profile
} }

View File

@ -29,11 +29,11 @@ func TestSession_FetchUser(t *testing.T) {
clientSecret string clientSecret string
redirectURI string redirectURI string
scopes []string scopes []string
userMapper func(oidc.UserInfo) idp.User userMapper func(*oidc.UserInfo) idp.User
httpMock func(issuer string) httpMock func(issuer string)
authURL string authURL string
code string code string
tokens *oidc.Tokens tokens *oidc.Tokens[*oidc.IDTokenClaims]
} }
type want struct { type want struct {
err error err error
@ -114,7 +114,7 @@ func TestSession_FetchUser(t *testing.T) {
JSON(userinfo()) JSON(userinfo())
}, },
authURL: "https://issuer.com/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=openid&state=testState", authURL: "https://issuer.com/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=openid&state=testState",
tokens: &oidc.Tokens{ tokens: &oidc.Tokens[*oidc.IDTokenClaims]{
Token: &oauth2.Token{ Token: &oauth2.Token{
AccessToken: "accessToken", AccessToken: "accessToken",
TokenType: oidc.BearerToken, TokenType: oidc.BearerToken,
@ -163,7 +163,7 @@ func TestSession_FetchUser(t *testing.T) {
JSON(userinfo()) JSON(userinfo())
}, },
authURL: "https://issuer.com/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=openid&state=testState", authURL: "https://issuer.com/authorize?client_id=clientID&redirect_uri=redirectURI&response_type=code&scope=openid&state=testState",
tokens: &oidc.Tokens{ tokens: &oidc.Tokens[*oidc.IDTokenClaims]{
Token: &oauth2.Token{ Token: &oauth2.Token{
AccessToken: "accessToken", AccessToken: "accessToken",
TokenType: oidc.BearerToken, TokenType: oidc.BearerToken,
@ -294,20 +294,28 @@ func TestSession_FetchUser(t *testing.T) {
} }
} }
func userinfo() oidc.UserInfoSetter { func userinfo() *oidc.UserInfo {
info := oidc.NewUserInfo() return &oidc.UserInfo{
info.SetSubject("sub") Subject: "sub",
info.SetGivenName("firstname") UserInfoProfile: oidc.UserInfoProfile{
info.SetFamilyName("lastname") GivenName: "firstname",
info.SetName("firstname lastname") FamilyName: "lastname",
info.SetNickname("nickname") Name: "firstname lastname",
info.SetPreferredUsername("username") Nickname: "nickname",
info.SetEmail("email", true) PreferredUsername: "username",
info.SetPhone("phone", true) Locale: oidc.NewLocale(language.English),
info.SetLocale(language.English) Picture: "picture",
info.SetPicture("picture") Profile: "profile",
info.SetProfile("profile") },
return info UserInfoEmail: oidc.UserInfoEmail{
Email: "email",
EmailVerified: oidc.Bool(true),
},
UserInfoPhone: oidc.UserInfoPhone{
PhoneNumber: "phone",
PhoneNumberVerified: true,
},
}
} }
func tokenResponse(t *testing.T, issuer string) *oidc.AccessTokenResponse { func tokenResponse(t *testing.T, issuer string) *oidc.AccessTokenResponse {