diff --git a/README.md b/README.md index 58f2aca7..0a4b08ef 100644 --- a/README.md +++ b/README.md @@ -1273,9 +1273,10 @@ if err != nil { You can impersonate to another user The impersonator user must have the `impersonation` permission in order for this request to work. The response would be a refresh JWT of the impersonated user - +TenantID would be the tenant to set as DCT claim, in case set +customClaims - would be extra claims that are needed on the JWT ```go -refreshJWT, err := descopeClient.Management.JWT().Impersonate(context.Background(), "impersonator id", "login id", true) +refreshJWT, err := descopeClient.Management.JWT().Impersonate(context.Background(), "impersonator id", "login id", true, map[string]any{"k1":"v1"}, "T1") if err != nil { // handle error } diff --git a/descope/internal/mgmt/jwt.go b/descope/internal/mgmt/jwt.go index 0418f992..d32ff992 100644 --- a/descope/internal/mgmt/jwt.go +++ b/descope/internal/mgmt/jwt.go @@ -39,7 +39,7 @@ func (j *jwt) UpdateJWTWithCustomClaims(ctx context.Context, jwt string, customC return jRes.JWT, nil } -func (j *jwt) Impersonate(ctx context.Context, impersonatorID string, loginID string, validateConcent bool) (string, error) { +func (j *jwt) Impersonate(ctx context.Context, impersonatorID string, loginID string, validateConcent bool, customClaims map[string]any, tenantID string) (string, error) { if loginID == "" { return "", utils.NewInvalidArgumentError("loginID") } @@ -50,6 +50,8 @@ func (j *jwt) Impersonate(ctx context.Context, impersonatorID string, loginID st "loginId": loginID, "impersonatorId": impersonatorID, "validateConsent": validateConcent, + "customClaims": customClaims, + "selectedTenant": tenantID, } res, err := j.client.DoPostRequest(ctx, api.Routes.ManagementImpersonate(), req, nil, j.conf.ManagementKey) if err != nil { diff --git a/descope/internal/mgmt/jwt_test.go b/descope/internal/mgmt/jwt_test.go index acd665d7..870bb97d 100644 --- a/descope/internal/mgmt/jwt_test.go +++ b/descope/internal/mgmt/jwt_test.go @@ -59,9 +59,11 @@ func TestImpersonate(t *testing.T) { require.EqualValues(t, impID, req["impersonatorId"]) require.EqualValues(t, loginID, req["loginId"]) require.EqualValues(t, true, req["validateConsent"]) + require.EqualValues(t, "t1", req["selectedTenant"]) + require.EqualValues(t, map[string]any{"k1": "v1"}, req["customClaims"]) }, map[string]interface{}{"jwt": expectedJWT})) - jwtRes, err := mgmt.JWT().Impersonate(context.Background(), impID, loginID, true) + jwtRes, err := mgmt.JWT().Impersonate(context.Background(), impID, loginID, true, map[string]any{"k1": "v1"}, "t1") require.NoError(t, err) require.EqualValues(t, expectedJWT, jwtRes) } @@ -71,7 +73,7 @@ func TestImpersonateMissingLoginID(t *testing.T) { mgmt := newTestMgmt(nil, helpers.DoOk(func(_ *http.Request) { called = true })) - jwtRes, err := mgmt.JWT().Impersonate(context.Background(), "test", "", true) + jwtRes, err := mgmt.JWT().Impersonate(context.Background(), "test", "", true, map[string]any{"k1": "v1"}, "t1") require.Error(t, err) require.False(t, called) require.Empty(t, jwtRes) @@ -82,7 +84,7 @@ func TestImpersonateMissingImpersonator(t *testing.T) { mgmt := newTestMgmt(nil, helpers.DoOk(func(_ *http.Request) { called = true })) - jwtRes, err := mgmt.JWT().Impersonate(context.Background(), "", "test", true) + jwtRes, err := mgmt.JWT().Impersonate(context.Background(), "", "test", true, map[string]any{"k1": "v1"}, "t1") require.Error(t, err) require.False(t, called) require.Empty(t, jwtRes) diff --git a/descope/sdk/mgmt.go b/descope/sdk/mgmt.go index 1b5aef58..c0924fbf 100644 --- a/descope/sdk/mgmt.go +++ b/descope/sdk/mgmt.go @@ -560,7 +560,7 @@ type JWT interface { // Impersonate another user // The impersonator user must have `impersonation` permission in order for this request to work // The response would be a refresh JWT of the impersonated user - Impersonate(ctx context.Context, impersonatorID string, loginID string, validateConcent bool) (string, error) + Impersonate(ctx context.Context, impersonatorID string, loginID string, validateConcent bool, customClaims map[string]any, tenantID string) (string, error) } // Provides functions for managing permissions in a project. diff --git a/descope/tests/mocks/mgmt/managementmock.go b/descope/tests/mocks/mgmt/managementmock.go index 0874360f..bf99334b 100644 --- a/descope/tests/mocks/mgmt/managementmock.go +++ b/descope/tests/mocks/mgmt/managementmock.go @@ -93,7 +93,7 @@ type MockJWT struct { UpdateJWTWithCustomClaimsResponse string UpdateJWTWithCustomClaimsError error - ImpersonateAssert func(impersonatorID string, loginID string, validateConcent bool) + ImpersonateAssert func(impersonatorID string, loginID string, validateConcent bool, customClaims map[string]any, tenantID string) ImpersonateResponse string ImpersonateError error } @@ -105,9 +105,9 @@ func (m *MockJWT) UpdateJWTWithCustomClaims(_ context.Context, jwt string, custo return m.UpdateJWTWithCustomClaimsResponse, m.UpdateJWTWithCustomClaimsError } -func (m *MockJWT) Impersonate(_ context.Context, impersonatorID string, loginID string, validateConcent bool) (string, error) { +func (m *MockJWT) Impersonate(_ context.Context, impersonatorID string, loginID string, validateConcent bool, customClaims map[string]any, tenantID string) (string, error) { if m.ImpersonateAssert != nil { - m.ImpersonateAssert(impersonatorID, loginID, validateConcent) + m.ImpersonateAssert(impersonatorID, loginID, validateConcent, customClaims, tenantID) } return m.ImpersonateResponse, m.ImpersonateError }