mirror of
https://github.com/andwati/zitadel.git
synced 2026-10-18 05:52:51 +00:00
# Which Problems Are Solved This PR implements the endpoints listed in https://github.com/zitadel/zitadel/issues/10444 . # How the Problems Are Solved The implementation follows the same pattern as the Instance one. The `Add` and `Remove` are implementing the `Commander` interface, while `List` Domains endpoints are implementing the `Querier` interace. The PR adds also some forgotten calls to the relational logic for the Instance API. The commits are identifiable by the label `instance:` prepended to them. This is the complete list: bafce01b0 , 6fe7257ab , e27bc9c34 , 8133ede73 , fde667953 , a3e1135ed , ee1a6f9c1 # Additional Context - Closes #10444 --------- Co-authored-by: Elio Bischof <[email protected]> Co-authored-by: Lebogang Phoshoko <[email protected]> Co-authored-by: Wim Van Laer <[email protected]> Co-authored-by: Max Peintner <[email protected]> Co-authored-by: Gayathri Vijayan <[email protected]>
123 lines
4.0 KiB
Go
123 lines
4.0 KiB
Go
package domain
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/zitadel/zitadel/backend/v3/storage/database"
|
|
"github.com/zitadel/zitadel/internal/zerrors"
|
|
instance_v2 "github.com/zitadel/zitadel/pkg/grpc/instance/v2"
|
|
)
|
|
|
|
type ListInstancesQuery struct {
|
|
Request *instance_v2.ListInstancesRequest
|
|
|
|
toReturn []*Instance
|
|
}
|
|
|
|
// Result implements Querier.
|
|
func (l *ListInstancesQuery) Result() []*Instance {
|
|
return l.toReturn
|
|
}
|
|
|
|
var _ Querier[[]*Instance] = (*ListInstancesQuery)(nil)
|
|
|
|
func NewListInstancesCommand(inputRequest *instance_v2.ListInstancesRequest) *ListInstancesQuery {
|
|
return &ListInstancesQuery{
|
|
Request: inputRequest,
|
|
}
|
|
}
|
|
|
|
// Execute implements [Querier].
|
|
func (l *ListInstancesQuery) Execute(ctx context.Context, opts *InvokeOpts) (err error) {
|
|
instanceRepo := opts.instanceRepo.LoadDomains()
|
|
domainRepo := opts.instanceDomainRepo
|
|
|
|
sorting := l.Sorting(instanceRepo)
|
|
limit, offset := l.Pagination()
|
|
conds, err := l.conditions(instanceRepo, domainRepo)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
instances, err := instanceRepo.List(ctx, opts.DB(), conds, sorting, limit, offset)
|
|
if err != nil {
|
|
return zerrors.ThrowInternal(err, "DOM-AIRPxN", "Errors.Instance.List")
|
|
}
|
|
|
|
l.toReturn = instances
|
|
|
|
return nil
|
|
}
|
|
|
|
func (l *ListInstancesQuery) Pagination() (database.QueryOption, database.QueryOption) {
|
|
return database.WithLimit(l.Request.GetPagination().GetLimit()),
|
|
database.WithOffset(uint32(l.Request.GetPagination().GetOffset()))
|
|
}
|
|
|
|
func (l *ListInstancesQuery) conditions(instanceRepo InstanceRepository, domainRepo InstanceDomainRepository) (database.QueryOption, error) {
|
|
conditions := make([]database.Condition, len(l.Request.GetFilters()))
|
|
for i, query := range l.Request.GetFilters() {
|
|
switch assertedType := query.GetFilter().(type) {
|
|
case *instance_v2.Filter_CustomDomainsFilter:
|
|
domainConditions := make([]database.Condition, len(assertedType.CustomDomainsFilter.GetDomains()))
|
|
for j, domain := range assertedType.CustomDomainsFilter.GetDomains() {
|
|
domainConditions[j] = domainRepo.DomainCondition(database.TextOperationEqual, domain)
|
|
}
|
|
conditions[i] = instanceRepo.ExistsDomain(
|
|
database.Or(domainConditions...),
|
|
)
|
|
case *instance_v2.Filter_InIdsFilter:
|
|
idConditions := make([]database.Condition, len(assertedType.InIdsFilter.GetIds()))
|
|
for j, id := range assertedType.InIdsFilter.GetIds() {
|
|
idConditions[j] = instanceRepo.IDCondition(id)
|
|
}
|
|
conditions[i] = database.Or(idConditions...)
|
|
default:
|
|
return nil, zerrors.ThrowInvalidArgument(NewUnexpectedQueryTypeError(assertedType), "DOM-AU99kR", "List.Query.Invalid")
|
|
}
|
|
}
|
|
|
|
return database.WithCondition(database.And(conditions...)), nil
|
|
}
|
|
|
|
func (l *ListInstancesQuery) Sorting(instanceRepo InstanceRepository) database.QueryOption {
|
|
var sortingCol database.Column
|
|
|
|
switch l.Request.GetSortingColumn() {
|
|
case instance_v2.FieldName_FIELD_NAME_CREATION_DATE:
|
|
sortingCol = instanceRepo.CreatedAtColumn()
|
|
case instance_v2.FieldName_FIELD_NAME_ID:
|
|
sortingCol = instanceRepo.IDColumn()
|
|
case instance_v2.FieldName_FIELD_NAME_NAME:
|
|
sortingCol = instanceRepo.NameColumn()
|
|
case instance_v2.FieldName_FIELD_NAME_UNSPECIFIED:
|
|
fallthrough
|
|
default:
|
|
return func(opts *database.QueryOpts) {}
|
|
}
|
|
|
|
orderDirection := database.OrderDirectionDesc
|
|
if l.Request.GetPagination().GetAsc() {
|
|
orderDirection = database.OrderDirectionAsc
|
|
}
|
|
|
|
return database.WithOrderBy(orderDirection, sortingCol)
|
|
}
|
|
|
|
// String implements [Querier].
|
|
func (l *ListInstancesQuery) String() string {
|
|
return "ListInstancesCommand"
|
|
}
|
|
|
|
// Validate implements [Querier].
|
|
func (l *ListInstancesQuery) Validate(ctx context.Context, opts *InvokeOpts) (err error) {
|
|
// TODO(IAM-Marco): This is likely wrong, because it's checking the read permission of
|
|
// the instance in context. In here, instead we should probably loop through all retrieved
|
|
// instances and check their permissions.
|
|
if authZErr := opts.Permissions.CheckInstancePermission(ctx, InstanceReadPermission); authZErr != nil {
|
|
return zerrors.ThrowPermissionDenied(authZErr, "DOM-cuT6Ws", "Errors.PermissionDenied")
|
|
}
|
|
|
|
return nil
|
|
}
|