Marco A. 2691dae2b6
feat: App API v2 (#10077)
# Which Problems Are Solved

This PR *partially* addresses #9450 . Specifically, it implements the
resource based API for the apps. APIs for app keys ARE not part of this
PR.

# How the Problems Are Solved

- `CreateApplication`, `PatchApplication` (update) and
`RegenerateClientSecret` endpoints are now unique for all app types:
API, SAML and OIDC apps.
  - All new endpoints have integration tests
  - All new endpoints are using permission checks V2

# Additional Changes

- The `ListApplications` endpoint allows to do sorting (see protobuf for
details) and filtering by app type (see protobuf).
- SAML and OIDC update endpoint can now receive requests for partial
updates

# Additional Context

Partially addresses #9450
2025-06-27 17:25:44 +02:00

150 lines
3.7 KiB
Go

package convert
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/zitadel/zitadel/internal/domain"
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
app "github.com/zitadel/zitadel/pkg/grpc/app/v2beta"
)
func TestCreateAPIApplicationRequestToDomain(t *testing.T) {
t.Parallel()
tests := []struct {
name string
appName string
projectID string
appID string
req *app.CreateAPIApplicationRequest
want *domain.APIApp
}{
{
name: "basic auth method",
appName: "my-app",
projectID: "proj-1",
appID: "someID",
req: &app.CreateAPIApplicationRequest{
AuthMethodType: app.APIAuthMethodType_API_AUTH_METHOD_TYPE_BASIC,
},
want: &domain.APIApp{
ObjectRoot: models.ObjectRoot{AggregateID: "proj-1"},
AppName: "my-app",
AuthMethodType: domain.APIAuthMethodTypeBasic,
AppID: "someID",
},
},
{
name: "private key jwt",
appName: "jwt-app",
projectID: "proj-2",
req: &app.CreateAPIApplicationRequest{
AuthMethodType: app.APIAuthMethodType_API_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT,
},
want: &domain.APIApp{
ObjectRoot: models.ObjectRoot{AggregateID: "proj-2"},
AppName: "jwt-app",
AuthMethodType: domain.APIAuthMethodTypePrivateKeyJWT,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
// When
got := CreateAPIApplicationRequestToDomain(tt.appName, tt.projectID, tt.appID, tt.req)
// Then
assert.Equal(t, tt.want, got)
})
}
}
func TestUpdateAPIApplicationConfigurationRequestToDomain(t *testing.T) {
t.Parallel()
tests := []struct {
name string
appID string
projectID string
req *app.UpdateAPIApplicationConfigurationRequest
want *domain.APIApp
}{
{
name: "basic auth method",
appID: "app-1",
projectID: "proj-1",
req: &app.UpdateAPIApplicationConfigurationRequest{
AuthMethodType: app.APIAuthMethodType_API_AUTH_METHOD_TYPE_BASIC,
},
want: &domain.APIApp{
ObjectRoot: models.ObjectRoot{AggregateID: "proj-1"},
AppID: "app-1",
AuthMethodType: domain.APIAuthMethodTypeBasic,
},
},
{
name: "private key jwt",
appID: "app-2",
projectID: "proj-2",
req: &app.UpdateAPIApplicationConfigurationRequest{
AuthMethodType: app.APIAuthMethodType_API_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT,
},
want: &domain.APIApp{
ObjectRoot: models.ObjectRoot{AggregateID: "proj-2"},
AppID: "app-2",
AuthMethodType: domain.APIAuthMethodTypePrivateKeyJWT,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
// When
got := UpdateAPIApplicationConfigurationRequestToDomain(tt.appID, tt.projectID, tt.req)
// Then
assert.Equal(t, tt.want, got)
})
}
}
func Test_apiAuthMethodTypeToPb(t *testing.T) {
t.Parallel()
tt := []struct {
name string
methodType domain.APIAuthMethodType
expectedResult app.APIAuthMethodType
}{
{
name: "basic auth method",
methodType: domain.APIAuthMethodTypeBasic,
expectedResult: app.APIAuthMethodType_API_AUTH_METHOD_TYPE_BASIC,
},
{
name: "private key jwt",
methodType: domain.APIAuthMethodTypePrivateKeyJWT,
expectedResult: app.APIAuthMethodType_API_AUTH_METHOD_TYPE_PRIVATE_KEY_JWT,
},
{
name: "unknown auth method defaults to basic",
expectedResult: app.APIAuthMethodType_API_AUTH_METHOD_TYPE_BASIC,
},
}
for _, tc := range tt {
t.Run(tc.name, func(t *testing.T) {
t.Parallel()
// When
res := apiAuthMethodTypeToPb(tc.methodType)
// Then
assert.Equal(t, tc.expectedResult, res)
})
}
}