Expose alias field and set/remove mutations in console API
Adds an alias field to Document, Audit, and TrustCenterFile types. Introduces setTrustCenterAlias and removeTrustCenterAlias mutations with proper authorization and error handling. Signed-off-by: Bryan Frimin <bryan@probo.com>
This commit is contained in:
@@ -173,6 +173,16 @@ func (r *auditResolver) Findings(ctx context.Context, obj *types.Audit, first *i
|
||||
return types.NewFindingConnection(p, r, obj.ID, filter), nil
|
||||
}
|
||||
|
||||
// Alias is the resolver for the alias field.
|
||||
func (r *auditResolver) Alias(ctx context.Context, obj *types.Audit) (*string, error) {
|
||||
scope, err := r.authorize(ctx, obj.ID, probo.ActionAuditGet)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r.probo.TrustCenterAliases.GetByResourceID(ctx, scope, obj.ID)
|
||||
}
|
||||
|
||||
// Permission is the resolver for the permission field.
|
||||
func (r *auditResolver) Permission(ctx context.Context, obj *types.Audit, action string) (bool, error) {
|
||||
return r.Resolver.Permission(ctx, obj, action)
|
||||
|
||||
@@ -27,6 +27,16 @@ import (
|
||||
"go.probo.inc/probo/pkg/validator"
|
||||
)
|
||||
|
||||
// Alias is the resolver for the alias field.
|
||||
func (r *documentResolver) Alias(ctx context.Context, obj *types.Document) (*string, error) {
|
||||
scope, err := r.authorize(ctx, obj.ID, probo.ActionDocumentGet)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r.probo.TrustCenterAliases.GetByResourceID(ctx, scope, obj.ID)
|
||||
}
|
||||
|
||||
// Organization is the resolver for the organization field.
|
||||
func (r *documentResolver) Organization(ctx context.Context, obj *types.Document) (*types.Organization, error) {
|
||||
if _, err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil {
|
||||
|
||||
@@ -41,3 +41,6 @@ models:
|
||||
EmailAddr:
|
||||
model:
|
||||
- "go.probo.inc/probo/pkg/server/gqlutils/types/mail.AddrScalar"
|
||||
TrustCenterAlias:
|
||||
model:
|
||||
- "go.probo.inc/probo/pkg/server/api/console/v1/types.TrustCenterAlias"
|
||||
|
||||
@@ -173,6 +173,7 @@ type Audit implements Node {
|
||||
): FindingConnection @goField(forceResolver: true)
|
||||
|
||||
trustCenterVisibility: TrustCenterVisibility!
|
||||
alias: String @goField(forceResolver: true)
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
|
||||
|
||||
@@ -269,6 +269,7 @@ type Document implements Node {
|
||||
currentPublishedMajor: Int
|
||||
currentPublishedMinor: Int
|
||||
trustCenterVisibility: TrustCenterVisibility!
|
||||
alias: String @goField(forceResolver: true)
|
||||
organization: Organization! @goField(forceResolver: true)
|
||||
|
||||
versions(
|
||||
|
||||
@@ -444,6 +444,7 @@ type TrustCenterFile implements Node {
|
||||
category: String!
|
||||
file: File! @goField(forceResolver: true)
|
||||
trustCenterVisibility: TrustCenterVisibility!
|
||||
alias: String @goField(forceResolver: true)
|
||||
createdAt: Datetime!
|
||||
updatedAt: Datetime!
|
||||
organization: Organization! @goField(forceResolver: true)
|
||||
@@ -549,6 +550,12 @@ extend type Mutation {
|
||||
deleteCustomDomain(
|
||||
input: DeleteCustomDomainInput!
|
||||
): DeleteCustomDomainPayload!
|
||||
setTrustCenterAlias(
|
||||
input: SetTrustCenterAliasInput!
|
||||
): SetTrustCenterAliasPayload!
|
||||
removeTrustCenterAlias(
|
||||
input: RemoveTrustCenterAliasInput!
|
||||
): RemoveTrustCenterAliasPayload!
|
||||
}
|
||||
|
||||
input UpdateTrustCenterInput {
|
||||
@@ -758,3 +765,26 @@ type CreateCustomDomainPayload {
|
||||
type DeleteCustomDomainPayload {
|
||||
deletedCustomDomainId: ID!
|
||||
}
|
||||
|
||||
input SetTrustCenterAliasInput {
|
||||
resourceId: ID!
|
||||
alias: String!
|
||||
}
|
||||
|
||||
input RemoveTrustCenterAliasInput {
|
||||
resourceId: ID!
|
||||
}
|
||||
|
||||
type TrustCenterAlias {
|
||||
resourceId: ID!
|
||||
alias: String!
|
||||
organization: Organization! @goField(forceResolver: true)
|
||||
}
|
||||
|
||||
type SetTrustCenterAliasPayload {
|
||||
alias: TrustCenterAlias!
|
||||
}
|
||||
|
||||
type RemoveTrustCenterAliasPayload {
|
||||
deletedResourceId: ID!
|
||||
}
|
||||
|
||||
@@ -688,6 +688,75 @@ func (r *mutationResolver) DeleteCustomDomain(ctx context.Context, input types.D
|
||||
}, nil
|
||||
}
|
||||
|
||||
// SetTrustCenterAlias is the resolver for the setTrustCenterAlias field.
|
||||
func (r *mutationResolver) SetTrustCenterAlias(ctx context.Context, input types.SetTrustCenterAliasInput) (*types.SetTrustCenterAliasPayload, error) {
|
||||
scope, err := r.authorize(ctx, input.ResourceID, probo.ActionTrustCenterAliasSet)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
alias, err := r.probo.TrustCenterAliases.Create(
|
||||
ctx,
|
||||
scope,
|
||||
probo.CreateTrustCenterAliasRequest{
|
||||
ResourceID: input.ResourceID,
|
||||
Alias: input.Alias,
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
if errors.Is(err, coredata.ErrResourceAlreadyExists) {
|
||||
return nil, gqlutils.Conflict(ctx, err)
|
||||
}
|
||||
|
||||
if validationErrors, ok := errors.AsType[validator.ValidationErrors](err); ok {
|
||||
return nil, gqlutils.InvalidValidationErrors(ctx, validationErrors)
|
||||
}
|
||||
|
||||
if _, ok := errors.AsType[*probo.ErrTrustCenterAliasAuditReportMissing](err); ok {
|
||||
return nil, gqlutils.Invalid(ctx, err)
|
||||
}
|
||||
|
||||
if _, ok := errors.AsType[*probo.ErrTrustCenterAliasResourceInvalid](err); ok {
|
||||
return nil, gqlutils.Invalid(ctx, err)
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot set trust center alias", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.SetTrustCenterAliasPayload{
|
||||
Alias: types.NewTrustCenterAlias(input.ResourceID, alias),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// RemoveTrustCenterAlias is the resolver for the removeTrustCenterAlias field.
|
||||
func (r *mutationResolver) RemoveTrustCenterAlias(ctx context.Context, input types.RemoveTrustCenterAliasInput) (*types.RemoveTrustCenterAliasPayload, error) {
|
||||
scope, err := r.authorize(ctx, input.ResourceID, probo.ActionTrustCenterAliasRemove)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = r.probo.TrustCenterAliases.Remove(ctx, scope, input.ResourceID)
|
||||
if err != nil {
|
||||
if _, ok := errors.AsType[*probo.ErrTrustCenterAliasAuditReportMissing](err); ok {
|
||||
return nil, gqlutils.Invalid(ctx, err)
|
||||
}
|
||||
|
||||
if _, ok := errors.AsType[*probo.ErrTrustCenterAliasResourceInvalid](err); ok {
|
||||
return nil, gqlutils.Invalid(ctx, err)
|
||||
}
|
||||
|
||||
r.logger.ErrorCtx(ctx, "cannot remove trust center alias", log.Error(err))
|
||||
|
||||
return nil, gqlutils.Internal(ctx)
|
||||
}
|
||||
|
||||
return &types.RemoveTrustCenterAliasPayload{
|
||||
DeletedResourceID: input.ResourceID,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Logo is the resolver for the logo field.
|
||||
func (r *trustCenterResolver) Logo(ctx context.Context, obj *types.TrustCenter) (*types.File, error) {
|
||||
if _, err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterGet); err != nil {
|
||||
@@ -1016,6 +1085,27 @@ func (r *trustCenterAccessResolver) Permission(ctx context.Context, obj *types.T
|
||||
return r.Resolver.Permission(ctx, obj, action)
|
||||
}
|
||||
|
||||
// Organization is the resolver for the organization field.
|
||||
func (r *trustCenterAliasResolver) Organization(ctx context.Context, obj *types.TrustCenterAlias) (*types.Organization, error) {
|
||||
scope, err := r.authorize(ctx, obj.OrganizationID, probo.ActionOrganizationGet)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
organization, err := r.probo.Organizations.Get(ctx, scope, obj.OrganizationID)
|
||||
if err != nil {
|
||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||
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
|
||||
}
|
||||
|
||||
// Document is the resolver for the document field.
|
||||
func (r *trustCenterDocumentAccessResolver) Document(ctx context.Context, obj *types.TrustCenterDocumentAccess) (*types.Document, error) {
|
||||
scope, err := r.authorize(ctx, obj.ID, probo.ActionDocumentGet)
|
||||
@@ -1137,6 +1227,16 @@ func (r *trustCenterFileResolver) File(ctx context.Context, obj *types.TrustCent
|
||||
return r.loadFile(ctx, obj.File.ID)
|
||||
}
|
||||
|
||||
// Alias is the resolver for the alias field.
|
||||
func (r *trustCenterFileResolver) Alias(ctx context.Context, obj *types.TrustCenterFile) (*string, error) {
|
||||
scope, err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterFileGet)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r.probo.TrustCenterAliases.GetByResourceID(ctx, scope, obj.ID)
|
||||
}
|
||||
|
||||
// Organization is the resolver for the organization field.
|
||||
func (r *trustCenterFileResolver) Organization(ctx context.Context, obj *types.TrustCenterFile) (*types.Organization, error) {
|
||||
scope, err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet)
|
||||
@@ -1236,6 +1336,11 @@ func (r *Resolver) TrustCenterAccess() schema.TrustCenterAccessResolver {
|
||||
return &trustCenterAccessResolver{r}
|
||||
}
|
||||
|
||||
// TrustCenterAlias returns schema.TrustCenterAliasResolver implementation.
|
||||
func (r *Resolver) TrustCenterAlias() schema.TrustCenterAliasResolver {
|
||||
return &trustCenterAliasResolver{r}
|
||||
}
|
||||
|
||||
// TrustCenterDocumentAccess returns schema.TrustCenterDocumentAccessResolver implementation.
|
||||
func (r *Resolver) TrustCenterDocumentAccess() schema.TrustCenterDocumentAccessResolver {
|
||||
return &trustCenterDocumentAccessResolver{r}
|
||||
@@ -1271,6 +1376,7 @@ type complianceFrameworkResolver struct{ *Resolver }
|
||||
type customDomainResolver struct{ *Resolver }
|
||||
type trustCenterResolver struct{ *Resolver }
|
||||
type trustCenterAccessResolver struct{ *Resolver }
|
||||
type trustCenterAliasResolver struct{ *Resolver }
|
||||
type trustCenterDocumentAccessResolver struct{ *Resolver }
|
||||
type trustCenterDocumentAccessConnectionResolver struct{ *Resolver }
|
||||
type trustCenterFileResolver struct{ *Resolver }
|
||||
|
||||
34
pkg/server/api/console/v1/types/trust_center_alias.go
Normal file
34
pkg/server/api/console/v1/types/trust_center_alias.go
Normal file
@@ -0,0 +1,34 @@
|
||||
// Copyright (c) 2025-2026 Probo Inc <hello@probo.com>.
|
||||
//
|
||||
// Permission to use, copy, modify, and/or distribute this software for any
|
||||
// purpose with or without fee is hereby granted, provided that the above
|
||||
// copyright notice and this permission notice appear in all copies.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
||||
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
||||
// AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
||||
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
||||
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
||||
// OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
||||
// PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
package types
|
||||
|
||||
import (
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/gid"
|
||||
)
|
||||
|
||||
type TrustCenterAlias struct {
|
||||
ResourceID gid.GID `json:"resourceId"`
|
||||
Alias string `json:"alias"`
|
||||
OrganizationID gid.GID `json:"-"`
|
||||
}
|
||||
|
||||
func NewTrustCenterAlias(resourceID gid.GID, alias *coredata.TrustCenterAlias) *TrustCenterAlias {
|
||||
return &TrustCenterAlias{
|
||||
ResourceID: resourceID,
|
||||
Alias: alias.Alias,
|
||||
OrganizationID: alias.OrganizationID,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user