mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-18 13:52:51 +00:00
# Which Problems Are Solved There's currently no way to retrieve a project based on the client_id of an application. A developer would need to iterate through all projects and their applications to make the correlation. # How the Problems Are Solved - Added a possibility to filter for `client_id` and `entity_id` on the ListApplications endpoint. - Added the `project_id` on the `Application` response (used on the ListApplications endpoint). # Additional Changes None # Additional Context - closes #11340 - requires backport to v4.x
279 lines
9.8 KiB
Go
279 lines
9.8 KiB
Go
package convert
|
|
|
|
import (
|
|
"net/url"
|
|
"strings"
|
|
|
|
"github.com/muhlemmer/gu"
|
|
"google.golang.org/protobuf/types/known/timestamppb"
|
|
|
|
"github.com/zitadel/zitadel/internal/api/grpc/filter/v2"
|
|
"github.com/zitadel/zitadel/internal/config/systemdefaults"
|
|
"github.com/zitadel/zitadel/internal/domain"
|
|
"github.com/zitadel/zitadel/internal/eventstore/v1/models"
|
|
"github.com/zitadel/zitadel/internal/query"
|
|
"github.com/zitadel/zitadel/internal/zerrors"
|
|
"github.com/zitadel/zitadel/pkg/grpc/application/v2"
|
|
)
|
|
|
|
func AppToPb(queryApp *query.App) *application.Application {
|
|
if queryApp == nil {
|
|
return &application.Application{}
|
|
}
|
|
|
|
return &application.Application{
|
|
ApplicationId: queryApp.ID,
|
|
CreationDate: timestamppb.New(queryApp.CreationDate),
|
|
ChangeDate: timestamppb.New(queryApp.ChangeDate),
|
|
State: appStateToPb(queryApp.State),
|
|
Name: queryApp.Name,
|
|
Configuration: appConfigToPb(queryApp),
|
|
ProjectId: queryApp.ProjectID,
|
|
}
|
|
}
|
|
|
|
func AppsToPb(queryApps []*query.App) []*application.Application {
|
|
pbApps := make([]*application.Application, len(queryApps))
|
|
|
|
for i, queryApp := range queryApps {
|
|
pbApps[i] = AppToPb(queryApp)
|
|
}
|
|
|
|
return pbApps
|
|
}
|
|
|
|
func ListApplicationsRequestToModel(sysDefaults systemdefaults.SystemDefaults, req *application.ListApplicationsRequest) (*query.AppSearchQueries, error) {
|
|
offset, limit, asc, err := filter.PaginationPbToQuery(sysDefaults, req.GetPagination())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
queries, err := appQueriesToModel(req.GetFilters())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &query.AppSearchQueries{
|
|
SearchRequest: query.SearchRequest{
|
|
Offset: offset,
|
|
Limit: limit,
|
|
Asc: asc,
|
|
SortingColumn: appSortingToColumn(req.GetSortingColumn()),
|
|
},
|
|
|
|
Queries: queries,
|
|
}, nil
|
|
}
|
|
|
|
func appSortingToColumn(sortingCriteria application.ApplicationSorting) query.Column {
|
|
switch sortingCriteria {
|
|
case application.ApplicationSorting_APPLICATION_SORT_BY_CHANGE_DATE:
|
|
return query.AppColumnChangeDate
|
|
case application.ApplicationSorting_APPLICATION_SORT_BY_CREATION_DATE:
|
|
return query.AppColumnCreationDate
|
|
case application.ApplicationSorting_APPLICATION_SORT_BY_NAME:
|
|
return query.AppColumnName
|
|
case application.ApplicationSorting_APPLICATION_SORT_BY_STATE:
|
|
return query.AppColumnState
|
|
case application.ApplicationSorting_APPLICATION_SORT_BY_ID:
|
|
fallthrough
|
|
default:
|
|
return query.AppColumnID
|
|
}
|
|
}
|
|
|
|
func appStateToPb(state domain.AppState) application.ApplicationState {
|
|
switch state {
|
|
case domain.AppStateActive:
|
|
return application.ApplicationState_APPLICATION_STATE_ACTIVE
|
|
case domain.AppStateInactive:
|
|
return application.ApplicationState_APPLICATION_STATE_INACTIVE
|
|
case domain.AppStateRemoved:
|
|
return application.ApplicationState_APPLICATION_STATE_REMOVED
|
|
case domain.AppStateUnspecified:
|
|
fallthrough
|
|
default:
|
|
return application.ApplicationState_APPLICATION_STATE_UNSPECIFIED
|
|
}
|
|
}
|
|
|
|
func appConfigToPb(app *query.App) application.IsApplicationConfiguration {
|
|
if app.OIDCConfig != nil {
|
|
return appOIDCConfigToPb(app.OIDCConfig)
|
|
}
|
|
if app.SAMLConfig != nil {
|
|
return appSAMLConfigToPb(app.SAMLConfig)
|
|
}
|
|
return appAPIConfigToPb(app.APIConfig)
|
|
}
|
|
|
|
func loginVersionToDomain(version *application.LoginVersion) (*domain.LoginVersion, *string, error) {
|
|
switch v := version.GetVersion().(type) {
|
|
case nil:
|
|
return gu.Ptr(domain.LoginVersionUnspecified), gu.Ptr(""), nil
|
|
case *application.LoginVersion_LoginV1:
|
|
return gu.Ptr(domain.LoginVersion1), gu.Ptr(""), nil
|
|
case *application.LoginVersion_LoginV2:
|
|
_, err := url.Parse(v.LoginV2.GetBaseUri())
|
|
return gu.Ptr(domain.LoginVersion2), gu.Ptr(v.LoginV2.GetBaseUri()), err
|
|
default:
|
|
return gu.Ptr(domain.LoginVersionUnspecified), gu.Ptr(""), nil
|
|
}
|
|
}
|
|
|
|
func loginVersionToPb(version domain.LoginVersion, baseURI *string) *application.LoginVersion {
|
|
switch version {
|
|
case domain.LoginVersionUnspecified:
|
|
return nil
|
|
case domain.LoginVersion1:
|
|
return &application.LoginVersion{Version: &application.LoginVersion_LoginV1{LoginV1: &application.LoginV1{}}}
|
|
case domain.LoginVersion2:
|
|
return &application.LoginVersion{Version: &application.LoginVersion_LoginV2{LoginV2: &application.LoginV2{BaseUri: baseURI}}}
|
|
default:
|
|
return nil
|
|
}
|
|
}
|
|
|
|
func appQueriesToModel(filters []*application.ApplicationSearchFilter) (queries []query.SearchQuery, err error) {
|
|
queries = make([]query.SearchQuery, len(filters))
|
|
for i, f := range filters {
|
|
queries[i], err = applicationFilterToQuery(f)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return queries, nil
|
|
}
|
|
|
|
func applicationFilterToQuery(applicationFilter *application.ApplicationSearchFilter) (query.SearchQuery, error) {
|
|
switch q := applicationFilter.GetFilter().(type) {
|
|
case *application.ApplicationSearchFilter_ProjectIdFilter:
|
|
return query.NewAppProjectIDSearchQuery(q.ProjectIdFilter.GetProjectId())
|
|
case *application.ApplicationSearchFilter_NameFilter:
|
|
return query.NewAppNameSearchQuery(filter.TextMethodPbToQuery(q.NameFilter.GetMethod()), q.NameFilter.GetName())
|
|
case *application.ApplicationSearchFilter_StateFilter:
|
|
return query.NewAppStateSearchQuery(domain.AppState(q.StateFilter))
|
|
case *application.ApplicationSearchFilter_TypeFilter:
|
|
return applicationTypeFilterToQuery(q.TypeFilter)
|
|
case *application.ApplicationSearchFilter_ClientIdFilter:
|
|
return query.NewAppClientIDSearchQuery(strings.TrimSpace(q.ClientIdFilter.GetClientId()))
|
|
case *application.ApplicationSearchFilter_EntityIdFilter:
|
|
return query.NewAppSAMLEntityIDSearchQuery(strings.TrimSpace(q.EntityIdFilter.GetEntityId()))
|
|
default:
|
|
return nil, zerrors.ThrowInvalidArgument(nil, "CONV-z2mAGy", "List.Query.Invalid")
|
|
}
|
|
}
|
|
|
|
func applicationTypeFilterToQuery(t application.ApplicationType) (*query.NotNullQuery, error) {
|
|
switch t {
|
|
case application.ApplicationType_APPLICATION_TYPE_OIDC:
|
|
return query.NewNotNullQuery(query.AppOIDCConfigColumnAppID)
|
|
case application.ApplicationType_APPLICATION_TYPE_API:
|
|
return query.NewNotNullQuery(query.AppAPIConfigColumnAppID)
|
|
case application.ApplicationType_APPLICATION_TYPE_SAML:
|
|
return query.NewNotNullQuery(query.AppSAMLConfigColumnAppID)
|
|
case application.ApplicationType_APPLICATION_TYPE_UNSPECIFIED:
|
|
return nil, zerrors.ThrowInvalidArgument(nil, "CONV-Jke83s", "List.Query.Invalid")
|
|
default:
|
|
return nil, zerrors.ThrowInvalidArgument(nil, "CONV-Skj3q", "List.Query.Invalid")
|
|
}
|
|
}
|
|
|
|
func CreateAPIClientKeyRequestToDomain(key *application.CreateApplicationKeyRequest) *domain.ApplicationKey {
|
|
return &domain.ApplicationKey{
|
|
ObjectRoot: models.ObjectRoot{
|
|
AggregateID: strings.TrimSpace(key.GetProjectId()),
|
|
},
|
|
ExpirationDate: key.GetExpirationDate().AsTime(),
|
|
Type: domain.AuthNKeyTypeJSON,
|
|
ApplicationID: strings.TrimSpace(key.GetApplicationId()),
|
|
}
|
|
}
|
|
|
|
func ListApplicationKeysRequestToDomain(sysDefaults systemdefaults.SystemDefaults, req *application.ListApplicationKeysRequest) (*query.AuthNKeySearchQueries, error) {
|
|
var queries []query.SearchQuery
|
|
|
|
queries, err := ApplicationKeySearchQueriesToQuery(req.GetFilters())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
offset, limit, asc, err := filter.PaginationPbToQuery(sysDefaults, req.GetPagination())
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return &query.AuthNKeySearchQueries{
|
|
SearchRequest: query.SearchRequest{
|
|
Offset: offset,
|
|
Limit: limit,
|
|
Asc: asc,
|
|
SortingColumn: appKeysSortingToColumn(req.GetSortingColumn()),
|
|
},
|
|
|
|
Queries: queries,
|
|
}, nil
|
|
}
|
|
|
|
func ApplicationKeySearchQueriesToQuery(queries []*application.ApplicationKeySearchFilter) (_ []query.SearchQuery, err error) {
|
|
searchQueries := make([]query.SearchQuery, len(queries))
|
|
for i, query := range queries {
|
|
searchQueries[i], err = ApplicationKeySearchFilterToQuery(query)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
return searchQueries, nil
|
|
}
|
|
|
|
func ApplicationKeySearchFilterToQuery(searchQuery *application.ApplicationKeySearchFilter) (query.SearchQuery, error) {
|
|
switch f := searchQuery.GetFilter().(type) {
|
|
case *application.ApplicationKeySearchFilter_ApplicationIdFilter:
|
|
return query.NewAuthNKeyObjectIDQuery(strings.TrimSpace(f.ApplicationIdFilter.GetApplicationId()))
|
|
case *application.ApplicationKeySearchFilter_OrganizationIdFilter:
|
|
return query.NewAuthNKeyResourceOwnerQuery(strings.TrimSpace(f.OrganizationIdFilter.GetOrganizationId()))
|
|
case *application.ApplicationKeySearchFilter_ProjectIdFilter:
|
|
return query.NewAuthNKeyAggregateIDQuery(strings.TrimSpace(f.ProjectIdFilter.GetProjectId()))
|
|
default:
|
|
return nil, zerrors.ThrowInvalidArgument(nil, "CONV-t3ENme", "List.Query.Invalid")
|
|
}
|
|
}
|
|
|
|
func appKeysSortingToColumn(sortingCriteria application.ApplicationKeysSorting) query.Column {
|
|
switch sortingCriteria {
|
|
case application.ApplicationKeysSorting_APPLICATION_KEYS_SORT_BY_PROJECT_ID:
|
|
return query.AuthNKeyColumnAggregateID
|
|
case application.ApplicationKeysSorting_APPLICATION_KEYS_SORT_BY_CREATION_DATE:
|
|
return query.AuthNKeyColumnCreationDate
|
|
case application.ApplicationKeysSorting_APPLICATION_KEYS_SORT_BY_EXPIRATION:
|
|
return query.AuthNKeyColumnExpiration
|
|
case application.ApplicationKeysSorting_APPLICATION_KEYS_SORT_BY_ORGANIZATION_ID:
|
|
return query.AuthNKeyColumnResourceOwner
|
|
case application.ApplicationKeysSorting_APPLICATION_KEYS_SORT_BY_TYPE:
|
|
return query.AuthNKeyColumnType
|
|
case application.ApplicationKeysSorting_APPLICATION_KEYS_SORT_BY_APPLICATION_ID:
|
|
return query.AuthNKeyColumnObjectID
|
|
case application.ApplicationKeysSorting_APPLICATION_KEYS_SORT_BY_ID:
|
|
fallthrough
|
|
default:
|
|
return query.AuthNKeyColumnID
|
|
}
|
|
}
|
|
|
|
func ApplicationKeysToPb(keys []*query.AuthNKey) []*application.ApplicationKey {
|
|
pbAppKeys := make([]*application.ApplicationKey, len(keys))
|
|
|
|
for i, k := range keys {
|
|
pbKey := &application.ApplicationKey{
|
|
KeyId: k.ID,
|
|
ApplicationId: k.ApplicationID,
|
|
ProjectId: k.AggregateID,
|
|
CreationDate: timestamppb.New(k.CreationDate),
|
|
OrganizationId: k.ResourceOwner,
|
|
ExpirationDate: timestamppb.New(k.Expiration),
|
|
}
|
|
pbAppKeys[i] = pbKey
|
|
}
|
|
|
|
return pbAppKeys
|
|
}
|