mirror of
https://github.com/zitadel/zitadel.git
synced 2025-12-23 17:46:44 +00:00
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())
|
||
|
|
}
|
||
|
|
})
|
||
|
|
}
|
||
|
|
|
||
|
|
}
|