mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-02 14:12:27 +00:00
# Which Problems Are Solved As part of our efforts to simplify the structure and versions of our APIs, were moving all existing v2beta endpoints to v2 and deprecate them. They will be removed in Zitadel V5. # How the Problems Are Solved - This PR moves app v2beta service and its endpoints to a corresponding to application v2 version. The v2beta service and endpoints are deprecated. - The comments and have been improved and, where not already done, moved from swagger annotations to proto. - All required fields have been marked with (google.api.field_behavior) = REQUIRED and validation rules have been added where missing. - Name ID of the application always `application_id`, previously was also `id` and `app_id`. - Get rid of all `app` abbreviations and name it `application` including the service name, `AppState` -> `ApplicationState` and `AppSorting` -> `ApplicationSorting` - Updated `CreateApplicationRequest`: - renamed `creation_request_type` to `application_type` and all its options to `XY_configuration` instead of `XY_request` - `RegenerateClientSecret` - renamed method to `GenerateClientSecret` - removed `app_type` from request - `ListApplicationRequest`: - removed required `project_id` and provided it as a filter - Type `ApplicationNameQuery` has been renamed to `ApplicationNameFilter` as its usage in the request - Renamed all fields and types from `config` to `configuration` - Updated `DeleteApplicationKeyRequest` - removed `organization_id` - Updated `GetApplicationKeyRequest`: - removed `project_id`, `application_id` and `organization_id`` - Updated `ListApplicationKeysRequest`: - removed oneOf `resource_id` and moved the options into filters - Name ID of the application key always `key_id`. - removed unnecessary package prefixed (`zitadel.application.v2`) - formatted using `buf` # Additional Changes None # Additional Context - part of https://github.com/zitadel/zitadel/issues/10772 - requires backport to v4.x
1429 lines
52 KiB
Go
1429 lines
52 KiB
Go
//go:build integration
|
|
|
|
package app_test
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"google.golang.org/grpc/codes"
|
|
"google.golang.org/grpc/status"
|
|
|
|
"github.com/zitadel/zitadel/internal/integration"
|
|
"github.com/zitadel/zitadel/pkg/grpc/application/v2"
|
|
org "github.com/zitadel/zitadel/pkg/grpc/org/v2beta"
|
|
)
|
|
|
|
func TestCreateApplication(t *testing.T) {
|
|
p := instance.CreateProject(IAMOwnerCtx, t, instance.DefaultOrg.GetId(), integration.ProjectName(), false, false)
|
|
|
|
t.Parallel()
|
|
|
|
notExistingProjectID := integration.ID()
|
|
|
|
tt := []struct {
|
|
testName string
|
|
creationRequest *application.CreateApplicationRequest
|
|
inputCtx context.Context
|
|
|
|
expectedResponseType string
|
|
expectedErrorType codes.Code
|
|
}{
|
|
{
|
|
testName: "when project for API application creation is not found should return failed precondition error",
|
|
inputCtx: IAMOwnerCtx,
|
|
creationRequest: &application.CreateApplicationRequest{
|
|
ProjectId: notExistingProjectID,
|
|
Name: "App Name",
|
|
ApplicationType: &application.CreateApplicationRequest_ApiConfiguration{
|
|
ApiConfiguration: &application.CreateAPIApplicationRequest{
|
|
AuthMethodType: application.APIAuthMethodType_API_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT,
|
|
},
|
|
},
|
|
},
|
|
expectedErrorType: codes.FailedPrecondition,
|
|
},
|
|
{
|
|
testName: "when CreateAPIApp request is valid should create application and return no error",
|
|
inputCtx: IAMOwnerCtx,
|
|
creationRequest: &application.CreateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
Name: "App Name",
|
|
ApplicationType: &application.CreateApplicationRequest_ApiConfiguration{
|
|
ApiConfiguration: &application.CreateAPIApplicationRequest{
|
|
AuthMethodType: application.APIAuthMethodType_API_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT,
|
|
},
|
|
},
|
|
},
|
|
expectedResponseType: fmt.Sprintf("%T", &application.CreateApplicationResponse_ApiConfiguration{}),
|
|
},
|
|
{
|
|
testName: "when project for OIDC application creation is not found should return failed precondition error",
|
|
inputCtx: IAMOwnerCtx,
|
|
creationRequest: &application.CreateApplicationRequest{
|
|
ProjectId: notExistingProjectID,
|
|
Name: "App Name",
|
|
ApplicationType: &application.CreateApplicationRequest_OidcConfiguration{
|
|
OidcConfiguration: &application.CreateOIDCApplicationRequest{
|
|
RedirectUris: []string{"http://example.com"},
|
|
ResponseTypes: []application.OIDCResponseType{application.OIDCResponseType_OIDC_RESPONSE_TYPE_CODE},
|
|
GrantTypes: []application.OIDCGrantType{application.OIDCGrantType_OIDC_GRANT_TYPE_AUTHORIZATION_CODE},
|
|
ApplicationType: application.OIDCApplicationType_OIDC_APP_TYPE_WEB,
|
|
AuthMethodType: application.OIDCAuthMethodType_OIDC_AUTH_METHOD_TYPE_BASIC,
|
|
PostLogoutRedirectUris: []string{"http://example.com/home"},
|
|
Version: application.OIDCVersion_OIDC_VERSION_1_0,
|
|
AccessTokenType: application.OIDCTokenType_OIDC_TOKEN_TYPE_JWT,
|
|
BackChannelLogoutUri: "http://example.com/logout",
|
|
LoginVersion: &application.LoginVersion{
|
|
Version: &application.LoginVersion_LoginV2{
|
|
LoginV2: &application.LoginV2{
|
|
BaseUri: &baseURI,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
expectedErrorType: codes.FailedPrecondition,
|
|
},
|
|
{
|
|
testName: "when CreateOIDCApp request is valid should create application and return no error",
|
|
inputCtx: IAMOwnerCtx,
|
|
creationRequest: &application.CreateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
Name: integration.ApplicationName(),
|
|
ApplicationType: &application.CreateApplicationRequest_OidcConfiguration{
|
|
OidcConfiguration: &application.CreateOIDCApplicationRequest{
|
|
RedirectUris: []string{"http://example.com"},
|
|
ResponseTypes: []application.OIDCResponseType{application.OIDCResponseType_OIDC_RESPONSE_TYPE_CODE},
|
|
GrantTypes: []application.OIDCGrantType{application.OIDCGrantType_OIDC_GRANT_TYPE_AUTHORIZATION_CODE},
|
|
ApplicationType: application.OIDCApplicationType_OIDC_APP_TYPE_WEB,
|
|
AuthMethodType: application.OIDCAuthMethodType_OIDC_AUTH_METHOD_TYPE_BASIC,
|
|
PostLogoutRedirectUris: []string{"http://example.com/home"},
|
|
Version: application.OIDCVersion_OIDC_VERSION_1_0,
|
|
AccessTokenType: application.OIDCTokenType_OIDC_TOKEN_TYPE_JWT,
|
|
BackChannelLogoutUri: "http://example.com/logout",
|
|
LoginVersion: &application.LoginVersion{
|
|
Version: &application.LoginVersion_LoginV2{
|
|
LoginV2: &application.LoginV2{
|
|
BaseUri: &baseURI,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
|
|
expectedResponseType: fmt.Sprintf("%T", &application.CreateApplicationResponse_OidcConfiguration{}),
|
|
},
|
|
{
|
|
testName: "when project for SAML application creation is not found should return failed precondition error",
|
|
inputCtx: IAMOwnerCtx,
|
|
creationRequest: &application.CreateApplicationRequest{
|
|
ProjectId: notExistingProjectID,
|
|
Name: integration.ApplicationName(),
|
|
ApplicationType: &application.CreateApplicationRequest_SamlConfiguration{
|
|
SamlConfiguration: &application.CreateSAMLApplicationRequest{
|
|
Metadata: &application.CreateSAMLApplicationRequest_MetadataUrl{
|
|
MetadataUrl: "http://example.com/metas",
|
|
},
|
|
LoginVersion: &application.LoginVersion{
|
|
Version: &application.LoginVersion_LoginV2{
|
|
LoginV2: &application.LoginV2{
|
|
BaseUri: &baseURI,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
expectedErrorType: codes.FailedPrecondition,
|
|
},
|
|
{
|
|
testName: "when CreateSAMLApp request is valid should create application and return no error",
|
|
inputCtx: IAMOwnerCtx,
|
|
creationRequest: &application.CreateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
Name: integration.ApplicationName(),
|
|
ApplicationType: &application.CreateApplicationRequest_SamlConfiguration{
|
|
SamlConfiguration: &application.CreateSAMLApplicationRequest{
|
|
Metadata: &application.CreateSAMLApplicationRequest_MetadataXml{
|
|
MetadataXml: samlMetadataGen(integration.URL()),
|
|
},
|
|
LoginVersion: &application.LoginVersion{
|
|
Version: &application.LoginVersion_LoginV2{
|
|
LoginV2: &application.LoginV2{
|
|
BaseUri: &baseURI,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
expectedResponseType: fmt.Sprintf("%T", &application.CreateApplicationResponse_SamlConfiguration{}),
|
|
},
|
|
}
|
|
|
|
for _, tc := range tt {
|
|
t.Run(tc.testName, func(t *testing.T) {
|
|
t.Parallel()
|
|
res, err := instance.Client.ApplicationV2.CreateApplication(tc.inputCtx, tc.creationRequest)
|
|
|
|
require.Equal(t, tc.expectedErrorType, status.Code(err))
|
|
if tc.expectedErrorType == codes.OK {
|
|
resType := fmt.Sprintf("%T", res.GetApplicationType())
|
|
assert.Equal(t, tc.expectedResponseType, resType)
|
|
assert.NotZero(t, res.GetApplicationId())
|
|
assert.NotZero(t, res.GetCreationDate())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestCreateApplication_WithDifferentPermissions(t *testing.T) {
|
|
p, projectOwnerCtx := getProjectAndProjectContext(t, instance, IAMOwnerCtx)
|
|
|
|
t.Parallel()
|
|
|
|
tt := []struct {
|
|
testName string
|
|
creationRequest *application.CreateApplicationRequest
|
|
inputCtx context.Context
|
|
|
|
expectedResponseType string
|
|
expectedErrorType codes.Code
|
|
}{
|
|
// Login User with no project.application.write
|
|
{
|
|
testName: "when user has no project.application.write permission for API request should return permission error",
|
|
inputCtx: LoginUserCtx,
|
|
creationRequest: &application.CreateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
Name: integration.ApplicationName(),
|
|
ApplicationType: &application.CreateApplicationRequest_ApiConfiguration{
|
|
ApiConfiguration: &application.CreateAPIApplicationRequest{
|
|
AuthMethodType: application.APIAuthMethodType_API_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT,
|
|
},
|
|
},
|
|
},
|
|
expectedErrorType: codes.PermissionDenied,
|
|
},
|
|
{
|
|
testName: "when user has no project.application.write permission for OIDC request should return permission error",
|
|
inputCtx: LoginUserCtx,
|
|
creationRequest: &application.CreateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
Name: integration.ApplicationName(),
|
|
ApplicationType: &application.CreateApplicationRequest_OidcConfiguration{
|
|
OidcConfiguration: &application.CreateOIDCApplicationRequest{
|
|
RedirectUris: []string{"http://example.com"},
|
|
ResponseTypes: []application.OIDCResponseType{application.OIDCResponseType_OIDC_RESPONSE_TYPE_CODE},
|
|
GrantTypes: []application.OIDCGrantType{application.OIDCGrantType_OIDC_GRANT_TYPE_AUTHORIZATION_CODE},
|
|
ApplicationType: application.OIDCApplicationType_OIDC_APP_TYPE_WEB,
|
|
AuthMethodType: application.OIDCAuthMethodType_OIDC_AUTH_METHOD_TYPE_BASIC,
|
|
PostLogoutRedirectUris: []string{"http://example.com/home"},
|
|
Version: application.OIDCVersion_OIDC_VERSION_1_0,
|
|
AccessTokenType: application.OIDCTokenType_OIDC_TOKEN_TYPE_JWT,
|
|
BackChannelLogoutUri: "http://example.com/logout",
|
|
LoginVersion: &application.LoginVersion{
|
|
Version: &application.LoginVersion_LoginV2{
|
|
LoginV2: &application.LoginV2{
|
|
BaseUri: &baseURI,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
|
|
expectedErrorType: codes.PermissionDenied,
|
|
},
|
|
{
|
|
testName: "when user has no project.application.write permission for SAML request should return permission error",
|
|
inputCtx: LoginUserCtx,
|
|
creationRequest: &application.CreateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
Name: integration.ApplicationName(),
|
|
ApplicationType: &application.CreateApplicationRequest_SamlConfiguration{
|
|
SamlConfiguration: &application.CreateSAMLApplicationRequest{
|
|
Metadata: &application.CreateSAMLApplicationRequest_MetadataXml{
|
|
MetadataXml: samlMetadataGen(integration.URL()),
|
|
},
|
|
LoginVersion: &application.LoginVersion{
|
|
Version: &application.LoginVersion_LoginV2{
|
|
LoginV2: &application.LoginV2{
|
|
BaseUri: &baseURI,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
expectedErrorType: codes.PermissionDenied,
|
|
},
|
|
|
|
// OrgOwner with project.application.write permission
|
|
{
|
|
testName: "when user is OrgOwner API request should succeed",
|
|
inputCtx: OrgOwnerCtx,
|
|
creationRequest: &application.CreateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
Name: integration.ApplicationName(),
|
|
ApplicationType: &application.CreateApplicationRequest_ApiConfiguration{
|
|
ApiConfiguration: &application.CreateAPIApplicationRequest{
|
|
AuthMethodType: application.APIAuthMethodType_API_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT,
|
|
},
|
|
},
|
|
},
|
|
expectedResponseType: fmt.Sprintf("%T", &application.CreateApplicationResponse_ApiConfiguration{}),
|
|
},
|
|
{
|
|
testName: "when user is OrgOwner OIDC request should succeed",
|
|
inputCtx: OrgOwnerCtx,
|
|
creationRequest: &application.CreateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
Name: integration.ApplicationName(),
|
|
ApplicationType: &application.CreateApplicationRequest_OidcConfiguration{
|
|
OidcConfiguration: &application.CreateOIDCApplicationRequest{
|
|
RedirectUris: []string{"http://example.com"},
|
|
ResponseTypes: []application.OIDCResponseType{application.OIDCResponseType_OIDC_RESPONSE_TYPE_CODE},
|
|
GrantTypes: []application.OIDCGrantType{application.OIDCGrantType_OIDC_GRANT_TYPE_AUTHORIZATION_CODE},
|
|
ApplicationType: application.OIDCApplicationType_OIDC_APP_TYPE_WEB,
|
|
AuthMethodType: application.OIDCAuthMethodType_OIDC_AUTH_METHOD_TYPE_BASIC,
|
|
PostLogoutRedirectUris: []string{"http://example.com/home"},
|
|
Version: application.OIDCVersion_OIDC_VERSION_1_0,
|
|
AccessTokenType: application.OIDCTokenType_OIDC_TOKEN_TYPE_JWT,
|
|
BackChannelLogoutUri: "http://example.com/logout",
|
|
LoginVersion: &application.LoginVersion{
|
|
Version: &application.LoginVersion_LoginV2{
|
|
LoginV2: &application.LoginV2{
|
|
BaseUri: &baseURI,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
|
|
expectedResponseType: fmt.Sprintf("%T", &application.CreateApplicationResponse_OidcConfiguration{}),
|
|
},
|
|
{
|
|
testName: "when user is OrgOwner SAML request should succeed",
|
|
inputCtx: OrgOwnerCtx,
|
|
creationRequest: &application.CreateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
Name: integration.ApplicationName(),
|
|
ApplicationType: &application.CreateApplicationRequest_SamlConfiguration{
|
|
SamlConfiguration: &application.CreateSAMLApplicationRequest{
|
|
Metadata: &application.CreateSAMLApplicationRequest_MetadataXml{
|
|
MetadataXml: samlMetadataGen(integration.URL()),
|
|
},
|
|
LoginVersion: &application.LoginVersion{
|
|
Version: &application.LoginVersion_LoginV2{
|
|
LoginV2: &application.LoginV2{
|
|
BaseUri: &baseURI,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
expectedResponseType: fmt.Sprintf("%T", &application.CreateApplicationResponse_SamlConfiguration{}),
|
|
},
|
|
|
|
// Project owner with project.application.write permission
|
|
{
|
|
testName: "when user is ProjectOwner API request should succeed",
|
|
inputCtx: projectOwnerCtx,
|
|
creationRequest: &application.CreateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
Name: integration.ApplicationName(),
|
|
ApplicationType: &application.CreateApplicationRequest_ApiConfiguration{
|
|
ApiConfiguration: &application.CreateAPIApplicationRequest{
|
|
AuthMethodType: application.APIAuthMethodType_API_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT,
|
|
},
|
|
},
|
|
},
|
|
expectedResponseType: fmt.Sprintf("%T", &application.CreateApplicationResponse_ApiConfiguration{}),
|
|
},
|
|
{
|
|
testName: "when user is ProjectOwner OIDC request should succeed",
|
|
inputCtx: projectOwnerCtx,
|
|
creationRequest: &application.CreateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
Name: integration.ApplicationName(),
|
|
ApplicationType: &application.CreateApplicationRequest_OidcConfiguration{
|
|
OidcConfiguration: &application.CreateOIDCApplicationRequest{
|
|
RedirectUris: []string{"http://example.com"},
|
|
ResponseTypes: []application.OIDCResponseType{application.OIDCResponseType_OIDC_RESPONSE_TYPE_CODE},
|
|
GrantTypes: []application.OIDCGrantType{application.OIDCGrantType_OIDC_GRANT_TYPE_AUTHORIZATION_CODE},
|
|
ApplicationType: application.OIDCApplicationType_OIDC_APP_TYPE_WEB,
|
|
AuthMethodType: application.OIDCAuthMethodType_OIDC_AUTH_METHOD_TYPE_BASIC,
|
|
PostLogoutRedirectUris: []string{"http://example.com/home"},
|
|
Version: application.OIDCVersion_OIDC_VERSION_1_0,
|
|
AccessTokenType: application.OIDCTokenType_OIDC_TOKEN_TYPE_JWT,
|
|
BackChannelLogoutUri: "http://example.com/logout",
|
|
LoginVersion: &application.LoginVersion{
|
|
Version: &application.LoginVersion_LoginV2{
|
|
LoginV2: &application.LoginV2{
|
|
BaseUri: &baseURI,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
|
|
expectedResponseType: fmt.Sprintf("%T", &application.CreateApplicationResponse_OidcConfiguration{}),
|
|
},
|
|
{
|
|
testName: "when user is ProjectOwner SAML request should succeed",
|
|
inputCtx: projectOwnerCtx,
|
|
creationRequest: &application.CreateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
Name: integration.ApplicationName(),
|
|
ApplicationType: &application.CreateApplicationRequest_SamlConfiguration{
|
|
SamlConfiguration: &application.CreateSAMLApplicationRequest{
|
|
Metadata: &application.CreateSAMLApplicationRequest_MetadataXml{
|
|
MetadataXml: samlMetadataGen(integration.URL()),
|
|
},
|
|
LoginVersion: &application.LoginVersion{
|
|
Version: &application.LoginVersion_LoginV2{
|
|
LoginV2: &application.LoginV2{
|
|
BaseUri: &baseURI,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
expectedResponseType: fmt.Sprintf("%T", &application.CreateApplicationResponse_SamlConfiguration{}),
|
|
},
|
|
}
|
|
|
|
for _, tc := range tt {
|
|
t.Run(tc.testName, func(t *testing.T) {
|
|
t.Parallel()
|
|
res, err := instance.Client.ApplicationV2.CreateApplication(tc.inputCtx, tc.creationRequest)
|
|
|
|
require.Equal(t, tc.expectedErrorType, status.Code(err))
|
|
if tc.expectedErrorType == codes.OK {
|
|
resType := fmt.Sprintf("%T", res.GetApplicationType())
|
|
assert.Equal(t, tc.expectedResponseType, resType)
|
|
assert.NotZero(t, res.GetApplicationId())
|
|
assert.NotZero(t, res.GetCreationDate())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUpdateApplication(t *testing.T) {
|
|
orgNotInCtx := instance.CreateOrganization(IAMOwnerCtx, integration.OrganizationName(), integration.Email())
|
|
pNotInCtx := instance.CreateProject(IAMOwnerCtx, t, orgNotInCtx.GetOrganizationId(), integration.ApplicationName(), false, false)
|
|
|
|
p := instance.CreateProject(IAMOwnerCtx, t, instance.DefaultOrg.GetId(), integration.ProjectName(), false, false)
|
|
|
|
baseURI := "http://example.com"
|
|
|
|
t.Cleanup(func() {
|
|
instance.Client.OrgV2beta.DeleteOrganization(IAMOwnerCtx, &org.DeleteOrganizationRequest{
|
|
Id: orgNotInCtx.GetOrganizationId(),
|
|
})
|
|
})
|
|
|
|
reqForAppNameCreation := &application.CreateApplicationRequest_ApiConfiguration{
|
|
ApiConfiguration: &application.CreateAPIApplicationRequest{AuthMethodType: application.APIAuthMethodType_API_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT},
|
|
}
|
|
reqForAPIAppCreation := reqForAppNameCreation
|
|
|
|
reqForOIDCAppCreation := &application.CreateApplicationRequest_OidcConfiguration{
|
|
OidcConfiguration: &application.CreateOIDCApplicationRequest{
|
|
RedirectUris: []string{"http://example.com"},
|
|
ResponseTypes: []application.OIDCResponseType{application.OIDCResponseType_OIDC_RESPONSE_TYPE_CODE},
|
|
GrantTypes: []application.OIDCGrantType{application.OIDCGrantType_OIDC_GRANT_TYPE_AUTHORIZATION_CODE},
|
|
ApplicationType: application.OIDCApplicationType_OIDC_APP_TYPE_WEB,
|
|
AuthMethodType: application.OIDCAuthMethodType_OIDC_AUTH_METHOD_TYPE_BASIC,
|
|
PostLogoutRedirectUris: []string{"http://example.com/home"},
|
|
Version: application.OIDCVersion_OIDC_VERSION_1_0,
|
|
AccessTokenType: application.OIDCTokenType_OIDC_TOKEN_TYPE_JWT,
|
|
BackChannelLogoutUri: "http://example.com/logout",
|
|
LoginVersion: &application.LoginVersion{
|
|
Version: &application.LoginVersion_LoginV2{
|
|
LoginV2: &application.LoginV2{
|
|
BaseUri: &baseURI,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
samlMetas := samlMetadataGen(integration.URL())
|
|
reqForSAMLAppCreation := &application.CreateApplicationRequest_SamlConfiguration{
|
|
SamlConfiguration: &application.CreateSAMLApplicationRequest{
|
|
Metadata: &application.CreateSAMLApplicationRequest_MetadataXml{
|
|
MetadataXml: samlMetas,
|
|
},
|
|
LoginVersion: &application.LoginVersion{
|
|
Version: &application.LoginVersion_LoginV2{
|
|
LoginV2: &application.LoginV2{
|
|
BaseUri: &baseURI,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
appForNameChange, appNameChangeErr := instance.Client.ApplicationV2.CreateApplication(IAMOwnerCtx, &application.CreateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
Name: integration.ApplicationName(),
|
|
ApplicationType: reqForAppNameCreation,
|
|
})
|
|
require.Nil(t, appNameChangeErr)
|
|
|
|
appForAPIConfigChange, appAPIConfigChangeErr := instance.Client.ApplicationV2.CreateApplication(IAMOwnerCtx, &application.CreateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
Name: integration.ApplicationName(),
|
|
ApplicationType: reqForAPIAppCreation,
|
|
})
|
|
require.Nil(t, appAPIConfigChangeErr)
|
|
|
|
appForOIDCConfigChange, appOIDCConfigChangeErr := instance.Client.ApplicationV2.CreateApplication(IAMOwnerCtx, &application.CreateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
Name: integration.ApplicationName(),
|
|
ApplicationType: reqForOIDCAppCreation,
|
|
})
|
|
require.Nil(t, appOIDCConfigChangeErr)
|
|
|
|
appForSAMLConfigChange, appSAMLConfigChangeErr := instance.Client.ApplicationV2.CreateApplication(IAMOwnerCtx, &application.CreateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
Name: integration.ApplicationName(),
|
|
ApplicationType: reqForSAMLAppCreation,
|
|
})
|
|
require.Nil(t, appSAMLConfigChangeErr)
|
|
|
|
t.Parallel()
|
|
|
|
tt := []struct {
|
|
testName string
|
|
inputCtx context.Context
|
|
updateRequest *application.UpdateApplicationRequest
|
|
|
|
expectedErrorType codes.Code
|
|
}{
|
|
{
|
|
testName: "when application for application name change request is not found should return not found error",
|
|
inputCtx: IAMOwnerCtx,
|
|
updateRequest: &application.UpdateApplicationRequest{
|
|
ProjectId: pNotInCtx.GetId(),
|
|
ApplicationId: appForNameChange.GetApplicationId(),
|
|
Name: "New name",
|
|
},
|
|
expectedErrorType: codes.NotFound,
|
|
},
|
|
{
|
|
testName: "when request for application name change is valid should return updated timestamp",
|
|
inputCtx: IAMOwnerCtx,
|
|
updateRequest: &application.UpdateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appForNameChange.GetApplicationId(),
|
|
|
|
Name: "New name",
|
|
},
|
|
},
|
|
|
|
{
|
|
testName: "when application for API config change request is not found should return not found error",
|
|
inputCtx: IAMOwnerCtx,
|
|
updateRequest: &application.UpdateApplicationRequest{
|
|
ProjectId: pNotInCtx.GetId(),
|
|
ApplicationId: appForAPIConfigChange.GetApplicationId(),
|
|
ApplicationType: &application.UpdateApplicationRequest_ApiConfiguration{
|
|
ApiConfiguration: &application.UpdateAPIApplicationConfigurationRequest{
|
|
AuthMethodType: application.APIAuthMethodType_API_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT,
|
|
},
|
|
},
|
|
},
|
|
expectedErrorType: codes.NotFound,
|
|
},
|
|
{
|
|
testName: "when request for API config change is valid should return updated timestamp",
|
|
inputCtx: IAMOwnerCtx,
|
|
updateRequest: &application.UpdateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appForAPIConfigChange.GetApplicationId(),
|
|
ApplicationType: &application.UpdateApplicationRequest_ApiConfiguration{
|
|
ApiConfiguration: &application.UpdateAPIApplicationConfigurationRequest{
|
|
AuthMethodType: application.APIAuthMethodType_API_AUTH_METHOD_TYPE_BASIC,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
testName: "when application for OIDC config change request is not found should return not found error",
|
|
inputCtx: IAMOwnerCtx,
|
|
updateRequest: &application.UpdateApplicationRequest{
|
|
ProjectId: pNotInCtx.GetId(),
|
|
ApplicationId: appForOIDCConfigChange.GetApplicationId(),
|
|
ApplicationType: &application.UpdateApplicationRequest_OidcConfiguration{
|
|
OidcConfiguration: &application.UpdateOIDCApplicationConfigurationRequest{
|
|
PostLogoutRedirectUris: []string{"http://example.com/home2"},
|
|
},
|
|
},
|
|
},
|
|
expectedErrorType: codes.NotFound,
|
|
},
|
|
{
|
|
testName: "when request for OIDC config change is valid should return updated timestamp",
|
|
inputCtx: IAMOwnerCtx,
|
|
updateRequest: &application.UpdateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appForOIDCConfigChange.GetApplicationId(),
|
|
ApplicationType: &application.UpdateApplicationRequest_OidcConfiguration{
|
|
OidcConfiguration: &application.UpdateOIDCApplicationConfigurationRequest{
|
|
PostLogoutRedirectUris: []string{"http://example.com/home2"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
|
|
{
|
|
testName: "when application for SAML config change request is not found should return not found error",
|
|
inputCtx: IAMOwnerCtx,
|
|
updateRequest: &application.UpdateApplicationRequest{
|
|
ProjectId: pNotInCtx.GetId(),
|
|
ApplicationId: appForSAMLConfigChange.GetApplicationId(),
|
|
ApplicationType: &application.UpdateApplicationRequest_SamlConfiguration{
|
|
SamlConfiguration: &application.UpdateSAMLApplicationConfigurationRequest{
|
|
Metadata: &application.UpdateSAMLApplicationConfigurationRequest_MetadataXml{
|
|
MetadataXml: samlMetas,
|
|
},
|
|
LoginVersion: &application.LoginVersion{Version: &application.LoginVersion_LoginV1{LoginV1: &application.LoginV1{}}},
|
|
},
|
|
},
|
|
},
|
|
expectedErrorType: codes.NotFound,
|
|
},
|
|
{
|
|
testName: "when request for SAML config change is valid should return updated timestamp",
|
|
inputCtx: IAMOwnerCtx,
|
|
updateRequest: &application.UpdateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appForSAMLConfigChange.GetApplicationId(),
|
|
ApplicationType: &application.UpdateApplicationRequest_SamlConfiguration{
|
|
SamlConfiguration: &application.UpdateSAMLApplicationConfigurationRequest{
|
|
Metadata: &application.UpdateSAMLApplicationConfigurationRequest_MetadataXml{
|
|
MetadataXml: samlMetas,
|
|
},
|
|
LoginVersion: &application.LoginVersion{Version: &application.LoginVersion_LoginV1{LoginV1: &application.LoginV1{}}},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range tt {
|
|
t.Run(tc.testName, func(t *testing.T) {
|
|
t.Parallel()
|
|
res, err := instance.Client.ApplicationV2.UpdateApplication(tc.inputCtx, tc.updateRequest)
|
|
|
|
require.Equal(t, tc.expectedErrorType, status.Code(err))
|
|
if tc.expectedErrorType == codes.OK {
|
|
assert.NotZero(t, res.GetChangeDate())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUpdateApplication_WithDifferentPermissions(t *testing.T) {
|
|
baseURI := "http://example.com"
|
|
|
|
p, projectOwnerCtx := getProjectAndProjectContext(t, instance, IAMOwnerCtx)
|
|
|
|
reqForAppNameCreation := &application.CreateApplicationRequest_ApiConfiguration{
|
|
ApiConfiguration: &application.CreateAPIApplicationRequest{AuthMethodType: application.APIAuthMethodType_API_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT},
|
|
}
|
|
|
|
appForNameChange, appNameChangeErr := instance.Client.ApplicationV2.CreateApplication(IAMOwnerCtx, &application.CreateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
Name: integration.ApplicationName(),
|
|
ApplicationType: reqForAppNameCreation,
|
|
})
|
|
require.Nil(t, appNameChangeErr)
|
|
|
|
appForAPIConfigChangeForProjectOwner := createAPIApp(t, IAMOwnerCtx, instance, p.GetId())
|
|
appForAPIConfigChangeForOrgOwner := createAPIApp(t, IAMOwnerCtx, instance, p.GetId())
|
|
appForAPIConfigChangeForLoginUser := createAPIApp(t, IAMOwnerCtx, instance, p.GetId())
|
|
|
|
appForOIDCConfigChangeForProjectOwner := createOIDCApp(t, baseURI, p.GetId())
|
|
appForOIDCConfigChangeForOrgOwner := createOIDCApp(t, baseURI, p.GetId())
|
|
appForOIDCConfigChangeForLoginUser := createOIDCApp(t, baseURI, p.GetId())
|
|
|
|
samlMetasForProjectOwner, appForSAMLConfigChangeForProjectOwner := createSAMLApp(t, baseURI, p.GetId())
|
|
samlMetasForOrgOwner, appForSAMLConfigChangeForOrgOwner := createSAMLApp(t, baseURI, p.GetId())
|
|
samlMetasForLoginUser, appForSAMLConfigChangeForLoginUser := createSAMLApp(t, baseURI, p.GetId())
|
|
|
|
t.Parallel()
|
|
|
|
tt := []struct {
|
|
testName string
|
|
inputCtx context.Context
|
|
updateRequest *application.UpdateApplicationRequest
|
|
|
|
expectedErrorType codes.Code
|
|
}{
|
|
// ProjectOwner
|
|
{
|
|
testName: "when user is ProjectOwner application name request should succeed",
|
|
inputCtx: projectOwnerCtx,
|
|
updateRequest: &application.UpdateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appForNameChange.GetApplicationId(),
|
|
|
|
Name: integration.ApplicationName(),
|
|
},
|
|
},
|
|
{
|
|
testName: "when user is ProjectOwner API application request should succeed",
|
|
inputCtx: projectOwnerCtx,
|
|
updateRequest: &application.UpdateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appForAPIConfigChangeForProjectOwner.GetApplicationId(),
|
|
ApplicationType: &application.UpdateApplicationRequest_ApiConfiguration{
|
|
ApiConfiguration: &application.UpdateAPIApplicationConfigurationRequest{
|
|
AuthMethodType: application.APIAuthMethodType_API_AUTH_METHOD_TYPE_BASIC,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
testName: "when user is ProjectOwner OIDC application request should succeed",
|
|
inputCtx: projectOwnerCtx,
|
|
updateRequest: &application.UpdateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appForOIDCConfigChangeForProjectOwner.GetApplicationId(),
|
|
ApplicationType: &application.UpdateApplicationRequest_OidcConfiguration{
|
|
OidcConfiguration: &application.UpdateOIDCApplicationConfigurationRequest{
|
|
PostLogoutRedirectUris: []string{"http://example.com/home2"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
testName: "when user is ProjectOwner SAML request should succeed",
|
|
inputCtx: projectOwnerCtx,
|
|
updateRequest: &application.UpdateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appForSAMLConfigChangeForProjectOwner.GetApplicationId(),
|
|
ApplicationType: &application.UpdateApplicationRequest_SamlConfiguration{
|
|
SamlConfiguration: &application.UpdateSAMLApplicationConfigurationRequest{
|
|
Metadata: &application.UpdateSAMLApplicationConfigurationRequest_MetadataXml{
|
|
MetadataXml: samlMetasForProjectOwner,
|
|
},
|
|
LoginVersion: &application.LoginVersion{Version: &application.LoginVersion_LoginV1{LoginV1: &application.LoginV1{}}},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
|
|
// OrgOwner context
|
|
{
|
|
testName: "when user is OrgOwner application name request should succeed",
|
|
inputCtx: OrgOwnerCtx,
|
|
updateRequest: &application.UpdateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appForNameChange.GetApplicationId(),
|
|
|
|
Name: integration.ApplicationName(),
|
|
},
|
|
},
|
|
{
|
|
testName: "when user is OrgOwner API application request should succeed",
|
|
inputCtx: OrgOwnerCtx,
|
|
updateRequest: &application.UpdateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appForAPIConfigChangeForOrgOwner.GetApplicationId(),
|
|
ApplicationType: &application.UpdateApplicationRequest_ApiConfiguration{
|
|
ApiConfiguration: &application.UpdateAPIApplicationConfigurationRequest{
|
|
AuthMethodType: application.APIAuthMethodType_API_AUTH_METHOD_TYPE_BASIC,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
testName: "when user is OrgOwner OIDC application request should succeed",
|
|
inputCtx: OrgOwnerCtx,
|
|
updateRequest: &application.UpdateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appForOIDCConfigChangeForOrgOwner.GetApplicationId(),
|
|
ApplicationType: &application.UpdateApplicationRequest_OidcConfiguration{
|
|
OidcConfiguration: &application.UpdateOIDCApplicationConfigurationRequest{
|
|
PostLogoutRedirectUris: []string{"http://example.com/home2"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
{
|
|
testName: "when user is OrgOwner SAML request should succeed",
|
|
inputCtx: OrgOwnerCtx,
|
|
updateRequest: &application.UpdateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appForSAMLConfigChangeForOrgOwner.GetApplicationId(),
|
|
ApplicationType: &application.UpdateApplicationRequest_SamlConfiguration{
|
|
SamlConfiguration: &application.UpdateSAMLApplicationConfigurationRequest{
|
|
Metadata: &application.UpdateSAMLApplicationConfigurationRequest_MetadataXml{
|
|
MetadataXml: samlMetasForOrgOwner,
|
|
},
|
|
LoginVersion: &application.LoginVersion{Version: &application.LoginVersion_LoginV1{LoginV1: &application.LoginV1{}}},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
|
|
// LoginUser
|
|
{
|
|
testName: "when user has no project.application.write permission for application name change request should return permission error",
|
|
inputCtx: LoginUserCtx,
|
|
updateRequest: &application.UpdateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appForNameChange.GetApplicationId(),
|
|
|
|
Name: integration.ApplicationName(),
|
|
},
|
|
expectedErrorType: codes.PermissionDenied,
|
|
},
|
|
{
|
|
testName: "when user has no project.application.write permission for API request should return permission error",
|
|
inputCtx: LoginUserCtx,
|
|
updateRequest: &application.UpdateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appForAPIConfigChangeForLoginUser.GetApplicationId(),
|
|
ApplicationType: &application.UpdateApplicationRequest_ApiConfiguration{
|
|
ApiConfiguration: &application.UpdateAPIApplicationConfigurationRequest{
|
|
AuthMethodType: application.APIAuthMethodType_API_AUTH_METHOD_TYPE_BASIC,
|
|
},
|
|
},
|
|
},
|
|
expectedErrorType: codes.PermissionDenied,
|
|
},
|
|
{
|
|
testName: "when user has no project.application.write permission for OIDC request should return permission error",
|
|
inputCtx: LoginUserCtx,
|
|
updateRequest: &application.UpdateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appForOIDCConfigChangeForLoginUser.GetApplicationId(),
|
|
ApplicationType: &application.UpdateApplicationRequest_OidcConfiguration{
|
|
OidcConfiguration: &application.UpdateOIDCApplicationConfigurationRequest{
|
|
PostLogoutRedirectUris: []string{"http://example.com/home2"},
|
|
},
|
|
},
|
|
},
|
|
expectedErrorType: codes.PermissionDenied,
|
|
},
|
|
{
|
|
testName: "when user has no project.application.write permission for SAML request should return permission error",
|
|
inputCtx: LoginUserCtx,
|
|
updateRequest: &application.UpdateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appForSAMLConfigChangeForLoginUser.GetApplicationId(),
|
|
ApplicationType: &application.UpdateApplicationRequest_SamlConfiguration{
|
|
SamlConfiguration: &application.UpdateSAMLApplicationConfigurationRequest{
|
|
Metadata: &application.UpdateSAMLApplicationConfigurationRequest_MetadataXml{
|
|
MetadataXml: samlMetasForLoginUser,
|
|
},
|
|
LoginVersion: &application.LoginVersion{Version: &application.LoginVersion_LoginV1{LoginV1: &application.LoginV1{}}},
|
|
},
|
|
},
|
|
},
|
|
expectedErrorType: codes.PermissionDenied,
|
|
},
|
|
}
|
|
|
|
for _, tc := range tt {
|
|
t.Run(tc.testName, func(t *testing.T) {
|
|
t.Parallel()
|
|
res, err := instance.Client.ApplicationV2.UpdateApplication(tc.inputCtx, tc.updateRequest)
|
|
|
|
require.Equal(t, tc.expectedErrorType, status.Code(err))
|
|
if tc.expectedErrorType == codes.OK {
|
|
assert.NotZero(t, res.GetChangeDate())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDeleteApplication(t *testing.T) {
|
|
p := instance.CreateProject(IAMOwnerCtx, t, instance.DefaultOrg.GetId(), integration.ProjectName(), false, false)
|
|
|
|
reqForAppNameCreation := &application.CreateApplicationRequest_ApiConfiguration{
|
|
ApiConfiguration: &application.CreateAPIApplicationRequest{AuthMethodType: application.APIAuthMethodType_API_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT},
|
|
}
|
|
|
|
appToDelete, appNameChangeErr := instance.Client.ApplicationV2.CreateApplication(IAMOwnerCtx, &application.CreateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
Name: integration.ApplicationName(),
|
|
ApplicationType: reqForAppNameCreation,
|
|
})
|
|
require.Nil(t, appNameChangeErr)
|
|
|
|
t.Parallel()
|
|
tt := []struct {
|
|
testName string
|
|
deleteRequest *application.DeleteApplicationRequest
|
|
inputCtx context.Context
|
|
|
|
expectedErrorType codes.Code
|
|
}{
|
|
{
|
|
testName: "when application to delete is not found should return not found error",
|
|
inputCtx: IAMOwnerCtx,
|
|
deleteRequest: &application.DeleteApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: integration.ID(),
|
|
},
|
|
expectedErrorType: codes.NotFound,
|
|
},
|
|
{
|
|
testName: "when application to delete is found should return deletion time",
|
|
inputCtx: IAMOwnerCtx,
|
|
deleteRequest: &application.DeleteApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appToDelete.GetApplicationId(),
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range tt {
|
|
t.Run(tc.testName, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// When
|
|
res, err := instance.Client.ApplicationV2.DeleteApplication(tc.inputCtx, tc.deleteRequest)
|
|
|
|
// Then
|
|
require.Equal(t, tc.expectedErrorType, status.Code(err))
|
|
if tc.expectedErrorType == codes.OK {
|
|
assert.NotZero(t, res.GetDeletionDate())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDeleteApplication_WithDifferentPermissions(t *testing.T) {
|
|
p, projectOwnerCtx := getProjectAndProjectContext(t, instance, IAMOwnerCtx)
|
|
|
|
appToDeleteForLoginUser := createAPIApp(t, IAMOwnerCtx, instance, p.GetId())
|
|
appToDeleteForProjectOwner := createAPIApp(t, IAMOwnerCtx, instance, p.GetId())
|
|
appToDeleteForOrgOwner := createAPIApp(t, IAMOwnerCtx, instance, p.GetId())
|
|
|
|
t.Parallel()
|
|
tt := []struct {
|
|
testName string
|
|
deleteRequest *application.DeleteApplicationRequest
|
|
inputCtx context.Context
|
|
|
|
expectedErrorType codes.Code
|
|
}{
|
|
// Login User
|
|
{
|
|
testName: "when user has no project.application.delete permission for application delete request should return permission error",
|
|
inputCtx: LoginUserCtx,
|
|
deleteRequest: &application.DeleteApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appToDeleteForLoginUser.GetApplicationId(),
|
|
},
|
|
expectedErrorType: codes.PermissionDenied,
|
|
},
|
|
|
|
// Project Owner
|
|
{
|
|
testName: "when user is ProjectOwner delete application request should succeed",
|
|
inputCtx: projectOwnerCtx,
|
|
deleteRequest: &application.DeleteApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appToDeleteForProjectOwner.GetApplicationId(),
|
|
},
|
|
},
|
|
|
|
// Org Owner
|
|
{
|
|
testName: "when user is OrgOwner delete application request should succeed",
|
|
inputCtx: projectOwnerCtx,
|
|
deleteRequest: &application.DeleteApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appToDeleteForOrgOwner.GetApplicationId(),
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range tt {
|
|
t.Run(tc.testName, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// When
|
|
res, err := instance.Client.ApplicationV2.DeleteApplication(tc.inputCtx, tc.deleteRequest)
|
|
|
|
// Then
|
|
require.Equal(t, tc.expectedErrorType, status.Code(err))
|
|
if tc.expectedErrorType == codes.OK {
|
|
assert.NotZero(t, res.GetDeletionDate())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDeactivateApplication(t *testing.T) {
|
|
p := instance.CreateProject(IAMOwnerCtx, t, instance.DefaultOrg.GetId(), integration.ProjectName(), false, false)
|
|
|
|
reqForAppNameCreation := &application.CreateApplicationRequest_ApiConfiguration{
|
|
ApiConfiguration: &application.CreateAPIApplicationRequest{AuthMethodType: application.APIAuthMethodType_API_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT},
|
|
}
|
|
|
|
appToDeactivate, appCreateErr := instance.Client.ApplicationV2.CreateApplication(IAMOwnerCtx, &application.CreateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
Name: integration.ApplicationName(),
|
|
ApplicationType: reqForAppNameCreation,
|
|
})
|
|
require.NoError(t, appCreateErr)
|
|
|
|
t.Parallel()
|
|
|
|
tt := []struct {
|
|
testName string
|
|
inputCtx context.Context
|
|
deleteRequest *application.DeactivateApplicationRequest
|
|
|
|
expectedErrorType codes.Code
|
|
}{
|
|
{
|
|
testName: "when application to deactivate is not found should return not found error",
|
|
inputCtx: IAMOwnerCtx,
|
|
deleteRequest: &application.DeactivateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: integration.ID(),
|
|
},
|
|
expectedErrorType: codes.NotFound,
|
|
},
|
|
{
|
|
testName: "when application to deactivate is found should return deactivation time",
|
|
inputCtx: IAMOwnerCtx,
|
|
deleteRequest: &application.DeactivateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appToDeactivate.GetApplicationId(),
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range tt {
|
|
t.Run(tc.testName, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// When
|
|
res, err := instance.Client.ApplicationV2.DeactivateApplication(tc.inputCtx, tc.deleteRequest)
|
|
|
|
// Then
|
|
require.Equal(t, tc.expectedErrorType, status.Code(err))
|
|
if tc.expectedErrorType == codes.OK {
|
|
assert.NotZero(t, res.GetDeactivationDate())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestDeactivateApplication_WithDifferentPermissions(t *testing.T) {
|
|
p, projectOwnerCtx := getProjectAndProjectContext(t, instance, IAMOwnerCtx)
|
|
|
|
appToDeactivateForLoginUser := createAPIApp(t, IAMOwnerCtx, instance, p.GetId())
|
|
appToDeactivateForPrjectOwner := createAPIApp(t, IAMOwnerCtx, instance, p.GetId())
|
|
appToDeactivateForOrgOwner := createAPIApp(t, IAMOwnerCtx, instance, p.GetId())
|
|
|
|
t.Parallel()
|
|
|
|
tt := []struct {
|
|
testName string
|
|
inputCtx context.Context
|
|
deleteRequest *application.DeactivateApplicationRequest
|
|
|
|
expectedErrorType codes.Code
|
|
}{
|
|
// Login User
|
|
{
|
|
testName: "when user has no project.application.write permission for application deactivate request should return permission error",
|
|
inputCtx: IAMOwnerCtx,
|
|
deleteRequest: &application.DeactivateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appToDeactivateForLoginUser.GetApplicationId(),
|
|
},
|
|
},
|
|
|
|
// Project Owner
|
|
{
|
|
testName: "when user is ProjectOwner deactivate application request should succeed",
|
|
inputCtx: projectOwnerCtx,
|
|
deleteRequest: &application.DeactivateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appToDeactivateForPrjectOwner.GetApplicationId(),
|
|
},
|
|
},
|
|
|
|
// Org Owner
|
|
{
|
|
testName: "when user is OrgOwner deactivate application request should succeed",
|
|
inputCtx: OrgOwnerCtx,
|
|
deleteRequest: &application.DeactivateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appToDeactivateForOrgOwner.GetApplicationId(),
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range tt {
|
|
t.Run(tc.testName, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// When
|
|
res, err := instance.Client.ApplicationV2.DeactivateApplication(tc.inputCtx, tc.deleteRequest)
|
|
|
|
// Then
|
|
require.Equal(t, tc.expectedErrorType, status.Code(err))
|
|
if tc.expectedErrorType == codes.OK {
|
|
assert.NotZero(t, res.GetDeactivationDate())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestReactivateApplication(t *testing.T) {
|
|
p := instance.CreateProject(IAMOwnerCtx, t, instance.DefaultOrg.GetId(), integration.ProjectName(), false, false)
|
|
|
|
reqForAppNameCreation := &application.CreateApplicationRequest_ApiConfiguration{
|
|
ApiConfiguration: &application.CreateAPIApplicationRequest{AuthMethodType: application.APIAuthMethodType_API_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT},
|
|
}
|
|
|
|
appToReactivate, appCreateErr := instance.Client.ApplicationV2.CreateApplication(IAMOwnerCtx, &application.CreateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
Name: integration.ApplicationName(),
|
|
ApplicationType: reqForAppNameCreation,
|
|
})
|
|
require.Nil(t, appCreateErr)
|
|
|
|
_, appDeactivateErr := instance.Client.ApplicationV2.DeactivateApplication(IAMOwnerCtx, &application.DeactivateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appToReactivate.GetApplicationId(),
|
|
})
|
|
require.Nil(t, appDeactivateErr)
|
|
|
|
t.Parallel()
|
|
|
|
tt := []struct {
|
|
testName string
|
|
inputCtx context.Context
|
|
reactivateRequest *application.ReactivateApplicationRequest
|
|
|
|
expectedErrorType codes.Code
|
|
}{
|
|
{
|
|
testName: "when application to reactivate is not found should return not found error",
|
|
inputCtx: IAMOwnerCtx,
|
|
reactivateRequest: &application.ReactivateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: integration.ID(),
|
|
},
|
|
expectedErrorType: codes.NotFound,
|
|
},
|
|
{
|
|
testName: "when application to reactivate is found should return deactivation time",
|
|
inputCtx: IAMOwnerCtx,
|
|
reactivateRequest: &application.ReactivateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appToReactivate.GetApplicationId(),
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range tt {
|
|
t.Run(tc.testName, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// When
|
|
res, err := instance.Client.ApplicationV2.ReactivateApplication(tc.inputCtx, tc.reactivateRequest)
|
|
|
|
// Then
|
|
require.Equal(t, tc.expectedErrorType, status.Code(err))
|
|
if tc.expectedErrorType == codes.OK {
|
|
assert.NotZero(t, res.GetReactivationDate())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestReactivateApplication_WithDifferentPermissions(t *testing.T) {
|
|
p, projectOwnerCtx := getProjectAndProjectContext(t, instance, IAMOwnerCtx)
|
|
|
|
appToReactivateForLoginUser := createAPIApp(t, IAMOwnerCtx, instance, p.GetId())
|
|
deactivateApp(t, appToReactivateForLoginUser, p.GetId())
|
|
|
|
appToReactivateForProjectOwner := createAPIApp(t, IAMOwnerCtx, instance, p.GetId())
|
|
deactivateApp(t, appToReactivateForProjectOwner, p.GetId())
|
|
|
|
appToReactivateForOrgOwner := createAPIApp(t, IAMOwnerCtx, instance, p.GetId())
|
|
deactivateApp(t, appToReactivateForOrgOwner, p.GetId())
|
|
|
|
t.Parallel()
|
|
|
|
tt := []struct {
|
|
testName string
|
|
inputCtx context.Context
|
|
reactivateRequest *application.ReactivateApplicationRequest
|
|
|
|
expectedErrorType codes.Code
|
|
}{
|
|
// Login User
|
|
{
|
|
testName: "when user has no project.application.write permission for application reactivate request should return permission error",
|
|
inputCtx: LoginUserCtx,
|
|
reactivateRequest: &application.ReactivateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appToReactivateForLoginUser.GetApplicationId(),
|
|
},
|
|
expectedErrorType: codes.PermissionDenied,
|
|
},
|
|
|
|
// Project Owner
|
|
{
|
|
testName: "when user is ProjectOwner reactivate application request should succeed",
|
|
inputCtx: projectOwnerCtx,
|
|
reactivateRequest: &application.ReactivateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appToReactivateForProjectOwner.GetApplicationId(),
|
|
},
|
|
},
|
|
|
|
// Org Owner
|
|
{
|
|
testName: "when user is OrgOwner reactivate application request should succeed",
|
|
inputCtx: OrgOwnerCtx,
|
|
reactivateRequest: &application.ReactivateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: appToReactivateForOrgOwner.GetApplicationId(),
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range tt {
|
|
t.Run(tc.testName, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// When
|
|
res, err := instance.Client.ApplicationV2.ReactivateApplication(tc.inputCtx, tc.reactivateRequest)
|
|
|
|
// Then
|
|
require.Equal(t, tc.expectedErrorType, status.Code(err))
|
|
if tc.expectedErrorType == codes.OK {
|
|
assert.NotZero(t, res.GetReactivationDate())
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestRegenerateClientSecret(t *testing.T) {
|
|
p := instance.CreateProject(IAMOwnerCtx, t, instance.DefaultOrg.GetId(), integration.ProjectName(), false, false)
|
|
|
|
reqForApiAppCreation := &application.CreateApplicationRequest_ApiConfiguration{
|
|
ApiConfiguration: &application.CreateAPIApplicationRequest{AuthMethodType: application.APIAuthMethodType_API_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT},
|
|
}
|
|
|
|
apiAppToRegen, apiAppCreateErr := instance.Client.ApplicationV2.CreateApplication(IAMOwnerCtx, &application.CreateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
Name: integration.ApplicationName(),
|
|
ApplicationType: reqForApiAppCreation,
|
|
})
|
|
require.Nil(t, apiAppCreateErr)
|
|
|
|
reqForOIDCAppCreation := &application.CreateApplicationRequest_OidcConfiguration{
|
|
OidcConfiguration: &application.CreateOIDCApplicationRequest{
|
|
RedirectUris: []string{"http://example.com"},
|
|
ResponseTypes: []application.OIDCResponseType{application.OIDCResponseType_OIDC_RESPONSE_TYPE_CODE},
|
|
GrantTypes: []application.OIDCGrantType{application.OIDCGrantType_OIDC_GRANT_TYPE_AUTHORIZATION_CODE},
|
|
ApplicationType: application.OIDCApplicationType_OIDC_APP_TYPE_WEB,
|
|
AuthMethodType: application.OIDCAuthMethodType_OIDC_AUTH_METHOD_TYPE_BASIC,
|
|
PostLogoutRedirectUris: []string{"http://example.com/home"},
|
|
Version: application.OIDCVersion_OIDC_VERSION_1_0,
|
|
AccessTokenType: application.OIDCTokenType_OIDC_TOKEN_TYPE_JWT,
|
|
BackChannelLogoutUri: "http://example.com/logout",
|
|
LoginVersion: &application.LoginVersion{
|
|
Version: &application.LoginVersion_LoginV2{
|
|
LoginV2: &application.LoginV2{
|
|
BaseUri: &baseURI,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
oidcAppToRegen, oidcAppCreateErr := instance.Client.ApplicationV2.CreateApplication(IAMOwnerCtx, &application.CreateApplicationRequest{
|
|
ProjectId: p.GetId(),
|
|
Name: integration.ApplicationName(),
|
|
ApplicationType: reqForOIDCAppCreation,
|
|
})
|
|
require.Nil(t, oidcAppCreateErr)
|
|
|
|
t.Parallel()
|
|
|
|
tt := []struct {
|
|
testName string
|
|
inputCtx context.Context
|
|
generateRequest *application.GenerateClientSecretRequest
|
|
|
|
expectedErrorType codes.Code
|
|
oldSecret string
|
|
}{
|
|
{
|
|
testName: "when application to generate is not found should return not found error",
|
|
inputCtx: IAMOwnerCtx,
|
|
generateRequest: &application.GenerateClientSecretRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: integration.ID(),
|
|
},
|
|
expectedErrorType: codes.NotFound,
|
|
},
|
|
{
|
|
testName: "when API application to generate is found should return different secret",
|
|
inputCtx: IAMOwnerCtx,
|
|
generateRequest: &application.GenerateClientSecretRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: apiAppToRegen.GetApplicationId(),
|
|
},
|
|
oldSecret: apiAppToRegen.GetApiConfiguration().GetClientSecret(),
|
|
},
|
|
{
|
|
testName: "when OIDC application to generate is found should return different secret",
|
|
inputCtx: IAMOwnerCtx,
|
|
generateRequest: &application.GenerateClientSecretRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: oidcAppToRegen.GetApplicationId(),
|
|
},
|
|
oldSecret: oidcAppToRegen.GetOidcConfiguration().GetClientSecret(),
|
|
},
|
|
}
|
|
|
|
for _, tc := range tt {
|
|
t.Run(tc.testName, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// When
|
|
res, err := instance.Client.ApplicationV2.GenerateClientSecret(tc.inputCtx, tc.generateRequest)
|
|
|
|
// Then
|
|
require.Equal(t, tc.expectedErrorType, status.Code(err))
|
|
if tc.expectedErrorType == codes.OK {
|
|
assert.NotZero(t, res.GetCreationDate())
|
|
assert.NotEqual(t, tc.oldSecret, res.GetClientSecret())
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|
|
|
|
func TestRegenerateClientSecret_WithDifferentPermissions(t *testing.T) {
|
|
p, projectOwnerCtx := getProjectAndProjectContext(t, instance, IAMOwnerCtx)
|
|
|
|
apiAppToRegenForLoginUser := createAPIApp(t, IAMOwnerCtx, instance, p.GetId())
|
|
apiAppToRegenForProjectOwner := createAPIApp(t, IAMOwnerCtx, instance, p.GetId())
|
|
apiAppToRegenForOrgOwner := createAPIApp(t, IAMOwnerCtx, instance, p.GetId())
|
|
|
|
oidcAppToRegenForLoginUser := createOIDCApp(t, baseURI, p.GetId())
|
|
oidcAppToRegenForProjectOwner := createOIDCApp(t, baseURI, p.GetId())
|
|
oidcAppToRegenForOrgOwner := createOIDCApp(t, baseURI, p.GetId())
|
|
|
|
t.Parallel()
|
|
|
|
tt := []struct {
|
|
testName string
|
|
inputCtx context.Context
|
|
regenRequest *application.GenerateClientSecretRequest
|
|
|
|
expectedErrorType codes.Code
|
|
oldSecret string
|
|
}{
|
|
// Login user
|
|
{
|
|
testName: "when user has no project.application.write permission for API application secret regen request should return permission error",
|
|
inputCtx: LoginUserCtx,
|
|
regenRequest: &application.GenerateClientSecretRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: apiAppToRegenForLoginUser.GetApplicationId(),
|
|
},
|
|
expectedErrorType: codes.PermissionDenied,
|
|
},
|
|
{
|
|
testName: "when user has no project.application.write permission for OIDC application secret regen request should return permission error",
|
|
inputCtx: LoginUserCtx,
|
|
regenRequest: &application.GenerateClientSecretRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: oidcAppToRegenForLoginUser.GetApplicationId(),
|
|
},
|
|
expectedErrorType: codes.PermissionDenied,
|
|
},
|
|
|
|
// Project Owner
|
|
{
|
|
testName: "when user is ProjectOwner regen API application secret request should succeed",
|
|
inputCtx: projectOwnerCtx,
|
|
regenRequest: &application.GenerateClientSecretRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: apiAppToRegenForProjectOwner.GetApplicationId(),
|
|
},
|
|
oldSecret: apiAppToRegenForProjectOwner.GetApiConfiguration().GetClientSecret(),
|
|
},
|
|
{
|
|
testName: "when user is ProjectOwner regen OIDC application secret request should succeed",
|
|
inputCtx: projectOwnerCtx,
|
|
regenRequest: &application.GenerateClientSecretRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: oidcAppToRegenForProjectOwner.GetApplicationId(),
|
|
},
|
|
oldSecret: oidcAppToRegenForProjectOwner.GetOidcConfiguration().GetClientSecret(),
|
|
},
|
|
|
|
// Org Owner
|
|
{
|
|
testName: "when user is OrgOwner regen API application secret request should succeed",
|
|
inputCtx: OrgOwnerCtx,
|
|
regenRequest: &application.GenerateClientSecretRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: apiAppToRegenForOrgOwner.GetApplicationId(),
|
|
},
|
|
oldSecret: apiAppToRegenForOrgOwner.GetApiConfiguration().GetClientSecret(),
|
|
},
|
|
{
|
|
testName: "when user is OrgOwner regen OIDC application secret request should succeed",
|
|
inputCtx: OrgOwnerCtx,
|
|
regenRequest: &application.GenerateClientSecretRequest{
|
|
ProjectId: p.GetId(),
|
|
ApplicationId: oidcAppToRegenForOrgOwner.GetApplicationId(),
|
|
},
|
|
oldSecret: oidcAppToRegenForOrgOwner.GetOidcConfiguration().GetClientSecret(),
|
|
},
|
|
}
|
|
|
|
for _, tc := range tt {
|
|
t.Run(tc.testName, func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
// When
|
|
res, err := instance.Client.ApplicationV2.GenerateClientSecret(tc.inputCtx, tc.regenRequest)
|
|
|
|
// Then
|
|
require.Equal(t, tc.expectedErrorType, status.Code(err))
|
|
if tc.expectedErrorType == codes.OK {
|
|
assert.NotZero(t, res.GetCreationDate())
|
|
assert.NotEqual(t, tc.oldSecret, res.GetClientSecret())
|
|
}
|
|
})
|
|
}
|
|
|
|
}
|