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
|
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.
|
// Permission is the resolver for the permission field.
|
||||||
func (r *auditResolver) Permission(ctx context.Context, obj *types.Audit, action string) (bool, error) {
|
func (r *auditResolver) Permission(ctx context.Context, obj *types.Audit, action string) (bool, error) {
|
||||||
return r.Resolver.Permission(ctx, obj, action)
|
return r.Resolver.Permission(ctx, obj, action)
|
||||||
|
|||||||
@@ -27,6 +27,16 @@ import (
|
|||||||
"go.probo.inc/probo/pkg/validator"
|
"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.
|
// Organization is the resolver for the organization field.
|
||||||
func (r *documentResolver) Organization(ctx context.Context, obj *types.Document) (*types.Organization, error) {
|
func (r *documentResolver) Organization(ctx context.Context, obj *types.Document) (*types.Organization, error) {
|
||||||
if _, err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil {
|
if _, err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet); err != nil {
|
||||||
|
|||||||
@@ -41,3 +41,6 @@ models:
|
|||||||
EmailAddr:
|
EmailAddr:
|
||||||
model:
|
model:
|
||||||
- "go.probo.inc/probo/pkg/server/gqlutils/types/mail.AddrScalar"
|
- "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)
|
): FindingConnection @goField(forceResolver: true)
|
||||||
|
|
||||||
trustCenterVisibility: TrustCenterVisibility!
|
trustCenterVisibility: TrustCenterVisibility!
|
||||||
|
alias: String @goField(forceResolver: true)
|
||||||
createdAt: Datetime!
|
createdAt: Datetime!
|
||||||
updatedAt: Datetime!
|
updatedAt: Datetime!
|
||||||
|
|
||||||
|
|||||||
@@ -269,6 +269,7 @@ type Document implements Node {
|
|||||||
currentPublishedMajor: Int
|
currentPublishedMajor: Int
|
||||||
currentPublishedMinor: Int
|
currentPublishedMinor: Int
|
||||||
trustCenterVisibility: TrustCenterVisibility!
|
trustCenterVisibility: TrustCenterVisibility!
|
||||||
|
alias: String @goField(forceResolver: true)
|
||||||
organization: Organization! @goField(forceResolver: true)
|
organization: Organization! @goField(forceResolver: true)
|
||||||
|
|
||||||
versions(
|
versions(
|
||||||
|
|||||||
@@ -444,6 +444,7 @@ type TrustCenterFile implements Node {
|
|||||||
category: String!
|
category: String!
|
||||||
file: File! @goField(forceResolver: true)
|
file: File! @goField(forceResolver: true)
|
||||||
trustCenterVisibility: TrustCenterVisibility!
|
trustCenterVisibility: TrustCenterVisibility!
|
||||||
|
alias: String @goField(forceResolver: true)
|
||||||
createdAt: Datetime!
|
createdAt: Datetime!
|
||||||
updatedAt: Datetime!
|
updatedAt: Datetime!
|
||||||
organization: Organization! @goField(forceResolver: true)
|
organization: Organization! @goField(forceResolver: true)
|
||||||
@@ -549,6 +550,12 @@ extend type Mutation {
|
|||||||
deleteCustomDomain(
|
deleteCustomDomain(
|
||||||
input: DeleteCustomDomainInput!
|
input: DeleteCustomDomainInput!
|
||||||
): DeleteCustomDomainPayload!
|
): DeleteCustomDomainPayload!
|
||||||
|
setTrustCenterAlias(
|
||||||
|
input: SetTrustCenterAliasInput!
|
||||||
|
): SetTrustCenterAliasPayload!
|
||||||
|
removeTrustCenterAlias(
|
||||||
|
input: RemoveTrustCenterAliasInput!
|
||||||
|
): RemoveTrustCenterAliasPayload!
|
||||||
}
|
}
|
||||||
|
|
||||||
input UpdateTrustCenterInput {
|
input UpdateTrustCenterInput {
|
||||||
@@ -758,3 +765,26 @@ type CreateCustomDomainPayload {
|
|||||||
type DeleteCustomDomainPayload {
|
type DeleteCustomDomainPayload {
|
||||||
deletedCustomDomainId: ID!
|
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
|
}, 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.
|
// Logo is the resolver for the logo field.
|
||||||
func (r *trustCenterResolver) Logo(ctx context.Context, obj *types.TrustCenter) (*types.File, error) {
|
func (r *trustCenterResolver) Logo(ctx context.Context, obj *types.TrustCenter) (*types.File, error) {
|
||||||
if _, err := r.authorize(ctx, obj.ID, probo.ActionTrustCenterGet); err != nil {
|
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)
|
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.
|
// Document is the resolver for the document field.
|
||||||
func (r *trustCenterDocumentAccessResolver) Document(ctx context.Context, obj *types.TrustCenterDocumentAccess) (*types.Document, error) {
|
func (r *trustCenterDocumentAccessResolver) Document(ctx context.Context, obj *types.TrustCenterDocumentAccess) (*types.Document, error) {
|
||||||
scope, err := r.authorize(ctx, obj.ID, probo.ActionDocumentGet)
|
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)
|
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.
|
// Organization is the resolver for the organization field.
|
||||||
func (r *trustCenterFileResolver) Organization(ctx context.Context, obj *types.TrustCenterFile) (*types.Organization, error) {
|
func (r *trustCenterFileResolver) Organization(ctx context.Context, obj *types.TrustCenterFile) (*types.Organization, error) {
|
||||||
scope, err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet)
|
scope, err := r.authorize(ctx, obj.ID, probo.ActionOrganizationGet)
|
||||||
@@ -1236,6 +1336,11 @@ func (r *Resolver) TrustCenterAccess() schema.TrustCenterAccessResolver {
|
|||||||
return &trustCenterAccessResolver{r}
|
return &trustCenterAccessResolver{r}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TrustCenterAlias returns schema.TrustCenterAliasResolver implementation.
|
||||||
|
func (r *Resolver) TrustCenterAlias() schema.TrustCenterAliasResolver {
|
||||||
|
return &trustCenterAliasResolver{r}
|
||||||
|
}
|
||||||
|
|
||||||
// TrustCenterDocumentAccess returns schema.TrustCenterDocumentAccessResolver implementation.
|
// TrustCenterDocumentAccess returns schema.TrustCenterDocumentAccessResolver implementation.
|
||||||
func (r *Resolver) TrustCenterDocumentAccess() schema.TrustCenterDocumentAccessResolver {
|
func (r *Resolver) TrustCenterDocumentAccess() schema.TrustCenterDocumentAccessResolver {
|
||||||
return &trustCenterDocumentAccessResolver{r}
|
return &trustCenterDocumentAccessResolver{r}
|
||||||
@@ -1271,6 +1376,7 @@ type complianceFrameworkResolver struct{ *Resolver }
|
|||||||
type customDomainResolver struct{ *Resolver }
|
type customDomainResolver struct{ *Resolver }
|
||||||
type trustCenterResolver struct{ *Resolver }
|
type trustCenterResolver struct{ *Resolver }
|
||||||
type trustCenterAccessResolver struct{ *Resolver }
|
type trustCenterAccessResolver struct{ *Resolver }
|
||||||
|
type trustCenterAliasResolver struct{ *Resolver }
|
||||||
type trustCenterDocumentAccessResolver struct{ *Resolver }
|
type trustCenterDocumentAccessResolver struct{ *Resolver }
|
||||||
type trustCenterDocumentAccessConnectionResolver struct{ *Resolver }
|
type trustCenterDocumentAccessConnectionResolver struct{ *Resolver }
|
||||||
type trustCenterFileResolver 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