feat(oidc): optimize the userinfo endpoint (#7706)

* feat(oidc): optimize the userinfo endpoint

* store project ID in the access token

* query for projectID if not in token

* add scope based tests

* Revert "store project ID in the access token"

This reverts commit 5f0262f23988e7f62d415d0e4a02a705f6ad5197.

* query project role assertion

* use project role assertion setting to return roles

* workaround eventual consistency and handle PAT

* do not append empty project id
This commit is contained in:
Tim Möhlmann
2024-04-09 15:15:35 +02:00
committed by GitHub
parent c8e0b30e17
commit 6a51c4b0f5
25 changed files with 528 additions and 159 deletions
+14 -14
View File
@@ -39,23 +39,23 @@ const (
func TestMain(m *testing.M) {
os.Exit(func() int {
ctx, errCtx, cancel := integration.Contexts(10 * time.Minute)
ctx, _, cancel := integration.Contexts(10 * time.Minute)
defer cancel()
Tester = integration.NewTester(ctx)
defer Tester.Done()
CTX, _ = Tester.WithAuthorization(ctx, integration.OrgOwner), errCtx
CTX = Tester.WithAuthorization(ctx, integration.OrgOwner)
User = Tester.CreateHumanUser(CTX)
Tester.SetUserPassword(CTX, User.GetUserId(), integration.UserPassword, false)
Tester.RegisterUserPasskey(CTX, User.GetUserId())
CTXLOGIN, _ = Tester.WithAuthorization(ctx, integration.Login), errCtx
CTXLOGIN = Tester.WithAuthorization(ctx, integration.Login)
return m.Run()
}())
}
func Test_ZITADEL_API_missing_audience_scope(t *testing.T) {
clientID := createClient(t)
clientID, _ := createClient(t)
authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID)
sessionID, sessionToken, startTime, changeTime := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId())
linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{
@@ -84,7 +84,7 @@ func Test_ZITADEL_API_missing_audience_scope(t *testing.T) {
}
func Test_ZITADEL_API_missing_authentication(t *testing.T) {
clientID := createClient(t)
clientID, _ := createClient(t)
authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, zitadelAudienceScope)
createResp, err := Tester.Client.SessionV2.CreateSession(CTX, &session.CreateSessionRequest{
Checks: &session.Checks{
@@ -118,7 +118,7 @@ func Test_ZITADEL_API_missing_authentication(t *testing.T) {
}
func Test_ZITADEL_API_missing_mfa(t *testing.T) {
clientID := createClient(t)
clientID, _ := createClient(t)
authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, zitadelAudienceScope)
sessionID, sessionToken, startTime, changeTime := Tester.CreatePasswordSession(t, CTX, User.GetUserId(), integration.UserPassword)
linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{
@@ -146,7 +146,7 @@ func Test_ZITADEL_API_missing_mfa(t *testing.T) {
}
func Test_ZITADEL_API_success(t *testing.T) {
clientID := createClient(t)
clientID, _ := createClient(t)
authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, zitadelAudienceScope)
sessionID, sessionToken, startTime, changeTime := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId())
linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{
@@ -176,7 +176,7 @@ func Test_ZITADEL_API_success(t *testing.T) {
func Test_ZITADEL_API_glob_redirects(t *testing.T) {
const redirectURI = "https://my-org-1yfnjl2xj-my-app.vercel.app/api/auth/callback/zitadel"
clientID := createClientWithOpts(t, clientOpts{
clientID, _ := createClientWithOpts(t, clientOpts{
redirectURI: "https://my-org-*-my-app.vercel.app/api/auth/callback/zitadel",
logoutURI: "https://my-org-*-my-app.vercel.app/",
devMode: true,
@@ -209,7 +209,7 @@ func Test_ZITADEL_API_glob_redirects(t *testing.T) {
}
func Test_ZITADEL_API_inactive_access_token(t *testing.T) {
clientID := createClient(t)
clientID, _ := createClient(t)
authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess, zitadelAudienceScope)
sessionID, sessionToken, startTime, changeTime := Tester.CreateVerifiedWebAuthNSession(t, CTXLOGIN, User.GetUserId())
linkResp, err := Tester.Client.OIDCv2.CreateCallback(CTXLOGIN, &oidc_pb.CreateCallbackRequest{
@@ -249,7 +249,7 @@ func Test_ZITADEL_API_inactive_access_token(t *testing.T) {
}
func Test_ZITADEL_API_terminated_session(t *testing.T) {
clientID := createClient(t)
clientID, _ := createClient(t)
provider, err := Tester.CreateRelyingParty(CTX, clientID, redirectURI)
require.NoError(t, err)
authRequestID := createAuthRequest(t, clientID, redirectURI, oidc.ScopeOpenID, oidc.ScopeOfflineAccess, zitadelAudienceScope)
@@ -291,7 +291,7 @@ func Test_ZITADEL_API_terminated_session(t *testing.T) {
}
func Test_ZITADEL_API_terminated_session_user_disabled(t *testing.T) {
clientID := createClient(t)
clientID, _ := createClient(t)
tests := []struct {
name string
disable func(userID string) error
@@ -361,7 +361,7 @@ func Test_ZITADEL_API_terminated_session_user_disabled(t *testing.T) {
}
}
func createClient(t testing.TB) string {
func createClient(t testing.TB) (clientID, projectID string) {
return createClientWithOpts(t, clientOpts{
redirectURI: redirectURI,
logoutURI: logoutRedirectURI,
@@ -375,12 +375,12 @@ type clientOpts struct {
devMode bool
}
func createClientWithOpts(t testing.TB, opts clientOpts) string {
func createClientWithOpts(t testing.TB, opts clientOpts) (clientID, projectID string) {
project, err := Tester.CreateProject(CTX)
require.NoError(t, err)
app, err := Tester.CreateOIDCNativeClient(CTX, opts.redirectURI, opts.logoutURI, project.GetId(), opts.devMode)
require.NoError(t, err)
return app.GetClientId()
return app.GetClientId(), project.GetId()
}
func createImplicitClient(t testing.TB) string {