package connect_v1 // This file will be automatically regenerated based on the schema, any resolver // implementations // will be copied through when generating and any unknown code will be moved to the end. // Code generated by github.com/99designs/gqlgen version v0.17.94 import ( "context" "errors" "go.gearno.de/kit/log" "go.probo.inc/probo/pkg/coredata" "go.probo.inc/probo/pkg/iam" "go.probo.inc/probo/pkg/page" "go.probo.inc/probo/pkg/server/api/authz" "go.probo.inc/probo/pkg/server/api/connect/v1/schema" "go.probo.inc/probo/pkg/server/api/connect/v1/types" "go.probo.inc/probo/pkg/server/gqlutils" "go.probo.inc/probo/pkg/server/gqlutils/types/cursor" ) // CreateUser is the resolver for the createUser field. func (r *mutationResolver) CreateUser(ctx context.Context, input types.CreateUserInput) (*types.CreateUserPayload, error) { scope, err := r.authorize( ctx, input.OrganizationID, iam.ActionMembershipProfileCreate, authz.WithAttr("target_role", input.Role.String()), ) if err != nil { return nil, err } profile, err := r.iam.OrganizationService.CreateUser( ctx, scope, &iam.CreateUserRequest{ OrganizationID: input.OrganizationID, EmailAddress: input.EmailAddress, Role: input.Role, FullName: input.FullName, AdditionalEmailAddresses: input.AdditionalEmailAddresses, Kind: input.Kind, Position: input.Position, ContractStartDate: gqlutils.UnwrapOmittable(input.ContractStartDate), ContractEndDate: gqlutils.UnwrapOmittable(input.ContractEndDate), }, ) if err != nil { if _, ok := errors.AsType[*iam.ErrUserAlreadyExists](err); ok { return nil, gqlutils.Conflict(ctx, err) } r.logger.ErrorCtx(ctx, "cannot create user", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.CreateUserPayload{ ProfileEdge: types.NewProfileEdge(profile, coredata.MembershipProfileOrderFieldCreatedAt), }, nil } // DeactivateUser is the resolver for the deactivateUser field. func (r *mutationResolver) DeactivateUser(ctx context.Context, input types.DeactivateUserInput) (*types.DeactivateUserPayload, error) { scope, err := r.authorize(ctx, input.ProfileID, iam.ActionMembershipProfileDeactivate) if err != nil { return nil, err } err = r.iam.OrganizationService.DeactivateUser(ctx, scope, input.OrganizationID, input.ProfileID) if err != nil { if _, ok := errors.AsType[*iam.ErrUserManagedBySCIM](err); ok { return nil, gqlutils.Conflictf(ctx, "user is managed by SCIM and cannot be deactivated") } if _, ok := errors.AsType[*iam.ErrLastActiveOwner](err); ok { return nil, gqlutils.Conflictf(ctx, "cannot deactivate last active owner") } r.logger.ErrorCtx(ctx, "cannot deactivate user", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.DeactivateUserPayload{ Success: true, }, nil } // UpdateUser is the resolver for the updateUser field. func (r *mutationResolver) UpdateUser(ctx context.Context, input types.UpdateUserInput) (*types.UpdateUserPayload, error) { if _, err := r.authorize(ctx, input.ID, iam.ActionMembershipProfileUpdate); err != nil { return nil, err } profile, err := r.iam.OrganizationService.UpdateUser( ctx, &iam.UpdateUserRequest{ ID: input.ID, FullName: input.FullName, AdditionalEmailAddresses: input.AdditionalEmailAddresses, Kind: input.Kind, Position: input.Position, ContractStartDate: gqlutils.UnwrapOmittable(input.ContractStartDate), ContractEndDate: gqlutils.UnwrapOmittable(input.ContractEndDate), }, ) if err != nil { r.logger.ErrorCtx(ctx, "cannot update profile", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.UpdateUserPayload{ Profile: types.NewProfile(profile), }, nil } // RemoveUser is the resolver for the removeUser field. func (r *mutationResolver) RemoveUser(ctx context.Context, input types.RemoveUserInput) (*types.RemoveUserPayload, error) { scope, err := r.authorize(ctx, input.ProfileID, iam.ActionMembershipDelete) if err != nil { return nil, err } err = r.iam.OrganizationService.RemoveUser(ctx, scope, input.OrganizationID, input.ProfileID) if err != nil { if _, ok := errors.AsType[*iam.ErrUserManagedBySCIM](err); ok { return nil, gqlutils.Conflictf(ctx, "user is managed by SCIM and cannot be removed") } if _, ok := errors.AsType[*iam.ErrLastActiveOwner](err); ok { return nil, gqlutils.Conflictf(ctx, "cannot remove last active owner") } if _, ok := errors.AsType[*iam.ErrProfileInUse](err); ok { return nil, gqlutils.Conflictf(ctx, "cannot remove person: referenced by other resources") } r.logger.ErrorCtx(ctx, "cannot remove user from organization", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &types.RemoveUserPayload{DeletedProfileID: input.ProfileID}, nil } // Identity is the resolver for the identity field. func (r *profileResolver) Identity(ctx context.Context, obj *types.Profile) (*types.Identity, error) { if _, err := r.authorize( ctx, obj.ID, iam.ActionMembershipProfileGet, authz.WithSkipAssumptionCheck(), ); err != nil { return nil, err } identity, err := r.iam.AccountService.GetIdentity(ctx, obj.Identity.ID) if err != nil { if _, ok := errors.AsType[*iam.ErrIdentityNotFound](err); ok { return nil, gqlutils.NotFound(ctx, err) } r.logger.ErrorCtx(ctx, "cannot get identity", log.Error(err)) return nil, gqlutils.Internal(ctx) } return types.NewIdentity(identity), nil } // Organization is the resolver for the organization field. func (r *profileResolver) Organization(ctx context.Context, obj *types.Profile) (*types.Organization, error) { if _, err := r.authorize(ctx, obj.Organization.ID, iam.ActionOrganizationGet, authz.WithSkipAssumptionCheck()); err != nil { return nil, err } organization, err := r.iam.OrganizationService.GetOrganization(ctx, obj.Organization.ID) if err != nil { if _, ok := errors.AsType[*iam.ErrOrganizationNotFound](err); ok { return nil, gqlutils.NotFound(ctx, err) } r.logger.ErrorCtx(ctx, "cannot get organization", log.Error(err)) return nil, gqlutils.Internal(ctx) } return types.NewOrganization(organization), nil } // Membership is the resolver for the membership field. func (r *profileResolver) Membership(ctx context.Context, obj *types.Profile) (*types.Membership, error) { if _, err := r.authorize(ctx, obj.ID, iam.ActionMembershipGet, authz.WithSkipAssumptionCheck()); err != nil { return nil, err } membership, err := r.iam.AccountService.GetMembershipForOrganization(ctx, obj.Identity.ID, obj.Organization.ID) if err != nil { if _, ok := errors.AsType[*iam.ErrMembershipNotFound](err); ok { return nil, gqlutils.NotFound(ctx, err) } r.logger.ErrorCtx(ctx, "cannot get membership", log.Error(err)) return nil, gqlutils.Internal(ctx) } return types.NewMembership(membership), nil } // PendingInvitations is the resolver for the pendingInvitations field. func (r *profileResolver) PendingInvitations(ctx context.Context, obj *types.Profile, first *int, after *page.CursorKey, last *int, before *page.CursorKey, orderBy *types.InvitationOrderBy) (*types.InvitationConnection, error) { if _, err := r.authorize(ctx, obj.ID, iam.ActionInvitationList); err != nil { return nil, err } pageOrderBy := page.OrderBy[coredata.InvitationOrderField]{ Field: coredata.InvitationOrderFieldCreatedAt, Direction: page.OrderDirectionDesc, } cursor := cursor.NewCursor(first, after, last, before, pageOrderBy) page, err := r.iam.AccountService.ListPendingInvitations(ctx, obj.ID, cursor) if err != nil { r.logger.ErrorCtx(ctx, "cannot list pending invitations", log.Error(err)) return nil, gqlutils.Internal(ctx) } return types.NewInvitationConnection(page, r, obj.ID, nil), nil } // Permission is the resolver for the permission field. func (r *profileResolver) Permission(ctx context.Context, obj *types.Profile, action string) (bool, error) { return r.Resolver.Permission(ctx, obj, action) } // TotalCount is the resolver for the totalCount field. func (r *profileConnectionResolver) TotalCount(ctx context.Context, obj *types.ProfileConnection) (*int, error) { switch obj.Resolver.(type) { case *identityResolver: count, err := r.iam.AccountService.CountProfiles(ctx, obj.ParentID, obj.Filters) if err != nil { r.logger.ErrorCtx(ctx, "cannot count profiles", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &count, nil case *organizationResolver: count, err := r.iam.OrganizationService.CountProfiles(ctx, obj.ParentID, obj.Filters) if err != nil { r.logger.ErrorCtx(ctx, "cannot count profiles", log.Error(err)) return nil, gqlutils.Internal(ctx) } return &count, nil } r.logger.ErrorCtx(ctx, "unsupported resolver", log.Any("resolver", obj.Resolver)) return nil, gqlutils.Internal(ctx) } // Profile returns schema.ProfileResolver implementation. func (r *Resolver) Profile() schema.ProfileResolver { return &profileResolver{r} } // ProfileConnection returns schema.ProfileConnectionResolver implementation. func (r *Resolver) ProfileConnection() schema.ProfileConnectionResolver { return &profileConnectionResolver{r} } type ( profileResolver struct{ *Resolver } profileConnectionResolver struct{ *Resolver } )