Add trust center files
Signed-off-by: Sacha Al Himdani <sacha@getprobo.com>
This commit is contained in:
@@ -74,6 +74,7 @@ type (
|
||||
Frameworks *FrameworkService
|
||||
TrustCenterAccesses *TrustCenterAccessService
|
||||
TrustCenterReferences *TrustCenterReferenceService
|
||||
TrustCenterFiles *TrustCenterFileService
|
||||
Reports *ReportService
|
||||
Organizations *OrganizationService
|
||||
SlackMessages *SlackMessageService
|
||||
@@ -136,6 +137,7 @@ func (s *Service) WithTenant(tenantID gid.TenantID) *TenantService {
|
||||
tenantService.Frameworks = &FrameworkService{svc: tenantService}
|
||||
tenantService.TrustCenterAccesses = &TrustCenterAccessService{svc: tenantService, auth: s.auth, logger: s.logger}
|
||||
tenantService.TrustCenterReferences = &TrustCenterReferenceService{svc: tenantService}
|
||||
tenantService.TrustCenterFiles = &TrustCenterFileService{svc: tenantService}
|
||||
tenantService.Reports = &ReportService{svc: tenantService}
|
||||
tenantService.Organizations = &OrganizationService{svc: tenantService}
|
||||
tenantService.SlackMessages = &SlackMessageService{svc: tenantService, slackClient: slackClient}
|
||||
|
||||
@@ -51,9 +51,17 @@ type (
|
||||
Granted bool
|
||||
}
|
||||
|
||||
SlackMessageFile struct {
|
||||
ID string
|
||||
Name string
|
||||
Category string
|
||||
Granted bool
|
||||
}
|
||||
|
||||
SlackMessageMetadata struct {
|
||||
Documents []SlackMessageDocument
|
||||
Reports []SlackMessageReport
|
||||
Files []SlackMessageFile
|
||||
}
|
||||
)
|
||||
|
||||
@@ -61,6 +69,7 @@ func (m SlackMessageMetadata) toMap() map[string]any {
|
||||
return map[string]any{
|
||||
"documents": m.Documents,
|
||||
"reports": m.Reports,
|
||||
"files": m.Files,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,10 +95,10 @@ func (s *Service) GetInitialSlackMessageByChannelAndTS(
|
||||
return &slackMessage, nil
|
||||
}
|
||||
|
||||
func (s *SlackMessageService) GetSlackMessageMetadataByID(
|
||||
func (s *SlackMessageService) GetSlackMessageDocumentIDs(
|
||||
ctx context.Context,
|
||||
slackMessageID gid.GID,
|
||||
) (documentIDs []gid.GID, reportIDs []gid.GID, err error) {
|
||||
) (documentIDs []gid.GID, reportIDs []gid.GID, fileIDs []gid.GID, err error) {
|
||||
var slackMessage coredata.SlackMessage
|
||||
|
||||
err = s.svc.pg.WithConn(ctx, func(conn pg.Conn) error {
|
||||
@@ -101,52 +110,14 @@ func (s *SlackMessageService) GetSlackMessageMetadataByID(
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
documents, ok := slackMessage.Metadata["documents"].([]any)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("invalid documents metadata")
|
||||
}
|
||||
documentIDs = extractIDsFromMetadata(slackMessage.Metadata, "documents")
|
||||
reportIDs = extractIDsFromMetadata(slackMessage.Metadata, "reports")
|
||||
fileIDs = extractIDsFromMetadata(slackMessage.Metadata, "files")
|
||||
|
||||
for _, docAny := range documents {
|
||||
doc, ok := docAny.(map[string]any)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
idStr, ok := doc["ID"].(string)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
docID, err := gid.ParseGID(idStr)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
documentIDs = append(documentIDs, docID)
|
||||
}
|
||||
|
||||
reports, ok := slackMessage.Metadata["reports"].([]any)
|
||||
if !ok {
|
||||
return nil, nil, fmt.Errorf("invalid reports metadata")
|
||||
}
|
||||
|
||||
for _, repAny := range reports {
|
||||
rep, ok := repAny.(map[string]any)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
idStr, ok := rep["ID"].(string)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
repID, err := gid.ParseGID(idStr)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
reportIDs = append(reportIDs, repID)
|
||||
}
|
||||
|
||||
return documentIDs, reportIDs, nil
|
||||
return documentIDs, reportIDs, fileIDs, nil
|
||||
}
|
||||
|
||||
func (s *SlackMessageService) UpdateSlackAccessMessage(
|
||||
@@ -171,7 +142,7 @@ func (s *SlackMessageService) UpdateSlackAccessMessage(
|
||||
return fmt.Errorf("cannot load trust center access: %w", err)
|
||||
}
|
||||
|
||||
documents, reports, err := s.loadDocumentsAndReportsFromAccesses(ctx, tx, trustCenterAccess.ID)
|
||||
documents, reports, files, err := s.loadDocumentsReportsAndFilesFromAccesses(ctx, tx, trustCenterAccess.ID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -185,6 +156,7 @@ func (s *SlackMessageService) UpdateSlackAccessMessage(
|
||||
trustCenter.OrganizationID,
|
||||
documents,
|
||||
reports,
|
||||
files,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -193,6 +165,7 @@ func (s *SlackMessageService) UpdateSlackAccessMessage(
|
||||
metadata := SlackMessageMetadata{
|
||||
Documents: documents,
|
||||
Reports: reports,
|
||||
Files: files,
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
@@ -261,9 +234,9 @@ func (s *SlackMessageService) QueueSlackNotification(
|
||||
return fmt.Errorf("no slack connector found for organization")
|
||||
}
|
||||
|
||||
documents, reports, err := s.loadDocumentsAndReportsFromAccesses(ctx, tx, trustCenterAccess.ID)
|
||||
documents, reports, files, err := s.loadDocumentsReportsAndFilesFromAccesses(ctx, tx, trustCenterAccess.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load documents and reports: %w", err)
|
||||
return fmt.Errorf("cannot load documents, reports and files: %w", err)
|
||||
}
|
||||
|
||||
slackMessageID := gid.New(s.svc.scope.GetTenantID(), coredata.SlackMessageEntityType)
|
||||
@@ -275,6 +248,7 @@ func (s *SlackMessageService) QueueSlackNotification(
|
||||
trustCenter.OrganizationID,
|
||||
documents,
|
||||
reports,
|
||||
files,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot build access request message: %w", err)
|
||||
@@ -283,6 +257,7 @@ func (s *SlackMessageService) QueueSlackNotification(
|
||||
metadata := SlackMessageMetadata{
|
||||
Documents: documents,
|
||||
Reports: reports,
|
||||
Files: files,
|
||||
}
|
||||
|
||||
now := time.Now()
|
||||
@@ -334,28 +309,30 @@ func (s *SlackMessageService) QueueSlackNotification(
|
||||
})
|
||||
}
|
||||
|
||||
func (s *SlackMessageService) loadDocumentsAndReportsFromAccesses(
|
||||
func (s *SlackMessageService) loadDocumentsReportsAndFilesFromAccesses(
|
||||
ctx context.Context,
|
||||
conn pg.Conn,
|
||||
trustCenterAccessID gid.GID,
|
||||
) (
|
||||
documents []SlackMessageDocument,
|
||||
reports []SlackMessageReport,
|
||||
files []SlackMessageFile,
|
||||
err error,
|
||||
) {
|
||||
documents = []SlackMessageDocument{}
|
||||
reports = []SlackMessageReport{}
|
||||
files = []SlackMessageFile{}
|
||||
|
||||
var accesses coredata.TrustCenterDocumentAccesses
|
||||
if err := accesses.LoadAllByTrustCenterAccessID(ctx, conn, s.svc.scope, trustCenterAccessID); err != nil {
|
||||
return nil, nil, fmt.Errorf("cannot load trust center document accesses: %w", err)
|
||||
return nil, nil, nil, fmt.Errorf("cannot load trust center document accesses: %w", err)
|
||||
}
|
||||
|
||||
for _, access := range accesses {
|
||||
if access.DocumentID != nil {
|
||||
doc := &coredata.Document{}
|
||||
if err := doc.LoadByID(ctx, conn, s.svc.scope, *access.DocumentID); err != nil {
|
||||
return nil, nil, fmt.Errorf("cannot load document: %w", err)
|
||||
return nil, nil, nil, fmt.Errorf("cannot load document: %w", err)
|
||||
}
|
||||
documents = append(documents, SlackMessageDocument{
|
||||
ID: access.DocumentID.String(),
|
||||
@@ -367,17 +344,17 @@ func (s *SlackMessageService) loadDocumentsAndReportsFromAccesses(
|
||||
if access.ReportID != nil {
|
||||
rep := &coredata.Report{}
|
||||
if err := rep.LoadByID(ctx, conn, s.svc.scope, *access.ReportID); err != nil {
|
||||
return nil, nil, fmt.Errorf("cannot load report: %w", err)
|
||||
return nil, nil, nil, fmt.Errorf("cannot load report: %w", err)
|
||||
}
|
||||
|
||||
audit := &coredata.Audit{}
|
||||
if err := audit.LoadByReportID(ctx, conn, s.svc.scope, *access.ReportID); err != nil {
|
||||
return nil, nil, fmt.Errorf("cannot load audit: %w", err)
|
||||
return nil, nil, nil, fmt.Errorf("cannot load audit: %w", err)
|
||||
}
|
||||
|
||||
framework := &coredata.Framework{}
|
||||
if err := framework.LoadByID(ctx, conn, s.svc.scope, audit.FrameworkID); err != nil {
|
||||
return nil, nil, fmt.Errorf("cannot load framework: %w", err)
|
||||
return nil, nil, nil, fmt.Errorf("cannot load framework: %w", err)
|
||||
}
|
||||
|
||||
label := framework.Name
|
||||
@@ -391,9 +368,22 @@ func (s *SlackMessageService) loadDocumentsAndReportsFromAccesses(
|
||||
Granted: access.Active,
|
||||
})
|
||||
}
|
||||
|
||||
if access.TrustCenterFileID != nil {
|
||||
file := &coredata.TrustCenterFile{}
|
||||
if err := file.LoadByID(ctx, conn, s.svc.scope, *access.TrustCenterFileID); err != nil {
|
||||
return nil, nil, nil, fmt.Errorf("cannot load trust center file: %w", err)
|
||||
}
|
||||
files = append(files, SlackMessageFile{
|
||||
ID: access.TrustCenterFileID.String(),
|
||||
Name: file.Name,
|
||||
Category: file.Category,
|
||||
Granted: access.Active,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
return documents, reports, nil
|
||||
return documents, reports, files, nil
|
||||
}
|
||||
|
||||
func (s *SlackMessageService) buildAccessRequestMessage(
|
||||
@@ -403,9 +393,11 @@ func (s *SlackMessageService) buildAccessRequestMessage(
|
||||
organizationID gid.GID,
|
||||
documents []SlackMessageDocument,
|
||||
reports []SlackMessageReport,
|
||||
files []SlackMessageFile,
|
||||
) (map[string]any, error) {
|
||||
var documentIDs []string
|
||||
var reportIDs []string
|
||||
var fileIDs []string
|
||||
|
||||
for _, doc := range documents {
|
||||
documentIDs = append(documentIDs, doc.ID)
|
||||
@@ -413,6 +405,9 @@ func (s *SlackMessageService) buildAccessRequestMessage(
|
||||
for _, rep := range reports {
|
||||
reportIDs = append(reportIDs, rep.ID)
|
||||
}
|
||||
for _, file := range files {
|
||||
fileIDs = append(fileIDs, file.ID)
|
||||
}
|
||||
|
||||
templateData := struct {
|
||||
RequesterName string
|
||||
@@ -422,8 +417,10 @@ func (s *SlackMessageService) buildAccessRequestMessage(
|
||||
SlackMessageID string
|
||||
DocumentIDs []string
|
||||
ReportIDs []string
|
||||
FileIDs []string
|
||||
Documents []SlackMessageDocument
|
||||
Reports []SlackMessageReport
|
||||
Files []SlackMessageFile
|
||||
}{
|
||||
RequesterName: requesterName,
|
||||
RequesterEmail: requesterEmail,
|
||||
@@ -432,8 +429,10 @@ func (s *SlackMessageService) buildAccessRequestMessage(
|
||||
SlackMessageID: slackMessageID.String(),
|
||||
DocumentIDs: documentIDs,
|
||||
ReportIDs: reportIDs,
|
||||
FileIDs: fileIDs,
|
||||
Documents: documents,
|
||||
Reports: reports,
|
||||
Files: files,
|
||||
}
|
||||
|
||||
var buf bytes.Buffer
|
||||
@@ -448,3 +447,30 @@ func (s *SlackMessageService) buildAccessRequestMessage(
|
||||
|
||||
return body, nil
|
||||
}
|
||||
|
||||
func extractIDsFromMetadata(metadata map[string]any, fieldName string) []gid.GID {
|
||||
ids := []gid.GID{}
|
||||
|
||||
items, ok := metadata[fieldName].([]any)
|
||||
if !ok || items == nil {
|
||||
return ids
|
||||
}
|
||||
|
||||
for _, itemAny := range items {
|
||||
item, ok := itemAny.(map[string]any)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
idStr, ok := item["ID"].(string)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
id, err := gid.ParseGID(idStr)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
ids = append(ids, id)
|
||||
}
|
||||
|
||||
return ids
|
||||
}
|
||||
|
||||
@@ -107,6 +107,40 @@
|
||||
"value": "{{.ID}}",
|
||||
"style": "primary"
|
||||
}{{end}}
|
||||
}{{end}}{{end}}{{if .Files}},
|
||||
{
|
||||
"type": "divider"
|
||||
},
|
||||
{
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": "*📎 Requested Files*"
|
||||
}
|
||||
}{{range .Files}},
|
||||
{
|
||||
"type": "section",
|
||||
"text": {
|
||||
"type": "mrkdwn",
|
||||
"text": "<https://{{$.Domain}}/organizations/{{$.OrganizationID}}/trust-center/files|{{jsonEscape .Name}}>{{if .Category}} ({{jsonEscape .Category}}){{end}}"
|
||||
},
|
||||
"accessory": {{if .Granted}}{
|
||||
"type": "button",
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": "✓ Granted"
|
||||
},
|
||||
"url": "https://{{$.Domain}}/organizations/{{$.OrganizationID}}/trust-center/access"
|
||||
}{{else}}{
|
||||
"type": "button",
|
||||
"text": {
|
||||
"type": "plain_text",
|
||||
"text": "Accept"
|
||||
},
|
||||
"action_id": "accept_file",
|
||||
"value": "{{.ID}}",
|
||||
"style": "primary"
|
||||
}{{end}}
|
||||
}{{end}}{{end}},
|
||||
{
|
||||
"type": "context",
|
||||
|
||||
@@ -67,11 +67,12 @@ type (
|
||||
}
|
||||
|
||||
TrustCenterAccessRequest struct {
|
||||
TrustCenterID gid.GID
|
||||
Email string
|
||||
Name *string
|
||||
DocumentIDs []gid.GID
|
||||
ReportIDs []gid.GID
|
||||
TrustCenterID gid.GID
|
||||
Email string
|
||||
Name *string
|
||||
DocumentIDs []gid.GID
|
||||
ReportIDs []gid.GID
|
||||
TrustCenterFileIDs []gid.GID
|
||||
}
|
||||
)
|
||||
|
||||
@@ -145,6 +146,20 @@ func (s TrustCenterAccessService) Request(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
trustCenterFileIDs := req.TrustCenterFileIDs
|
||||
if req.TrustCenterFileIDs == nil {
|
||||
var allTrustCenterFiles coredata.TrustCenterFiles
|
||||
|
||||
if err := allTrustCenterFiles.LoadAllByOrganizationID(ctx, tx, s.svc.scope, organizationID); err != nil {
|
||||
return fmt.Errorf("cannot list trust center files: %w", err)
|
||||
}
|
||||
|
||||
for _, file := range allTrustCenterFiles {
|
||||
trustCenterFileIDs = append(trustCenterFileIDs, file.ID)
|
||||
}
|
||||
}
|
||||
|
||||
existingAccess := &coredata.TrustCenterAccess{}
|
||||
err := existingAccess.LoadByTrustCenterIDAndEmail(ctx, tx, s.svc.scope, req.TrustCenterID, req.Email)
|
||||
|
||||
@@ -186,9 +201,10 @@ func (s TrustCenterAccessService) Request(
|
||||
return fmt.Errorf("cannot load existing access records: %w", err)
|
||||
}
|
||||
|
||||
existingDocumentIDs, existingReportIDs := extractExistingIDs(existingAccesses)
|
||||
existingDocumentIDs, existingReportIDs, existingTrustCenterFileIDs := extractExistingIDs(existingAccesses)
|
||||
newDocumentIDs := filterExistingIDs(documentIDs, existingDocumentIDs)
|
||||
newReportIDs := filterExistingIDs(reportIDs, existingReportIDs)
|
||||
newTrustCenterFileIDs := filterExistingIDs(trustCenterFileIDs, existingTrustCenterFileIDs)
|
||||
|
||||
var accesses coredata.TrustCenterDocumentAccesses
|
||||
|
||||
@@ -200,6 +216,10 @@ func (s TrustCenterAccessService) Request(
|
||||
return fmt.Errorf("cannot bulk insert trust center report accesses: %w", err)
|
||||
}
|
||||
|
||||
if err := accesses.BulkInsertTrustCenterFileAccesses(ctx, tx, s.svc.scope, access.ID, newTrustCenterFileIDs, now); err != nil {
|
||||
return fmt.Errorf("cannot bulk insert trust center file accesses: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
@@ -335,12 +355,48 @@ func (s TrustCenterAccessService) LoadReportAccess(
|
||||
return reportAccess, nil
|
||||
}
|
||||
|
||||
func (s TrustCenterAccessService) LoadTrustCenterFileAccess(
|
||||
ctx context.Context,
|
||||
trustCenterID gid.GID,
|
||||
email string,
|
||||
trustCenterFileID gid.GID,
|
||||
) (*coredata.TrustCenterDocumentAccess, error) {
|
||||
var fileAccess *coredata.TrustCenterDocumentAccess
|
||||
|
||||
err := s.svc.pg.WithConn(ctx, func(conn pg.Conn) error {
|
||||
access := &coredata.TrustCenterAccess{}
|
||||
err := access.LoadByTrustCenterIDAndEmail(ctx, conn, s.svc.scope, trustCenterID, email)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load trust center access: %w", err)
|
||||
}
|
||||
|
||||
if !access.Active {
|
||||
return fmt.Errorf("trust center access is not active")
|
||||
}
|
||||
|
||||
fileAccess = &coredata.TrustCenterDocumentAccess{}
|
||||
err = fileAccess.LoadByTrustCenterAccessIDAndTrustCenterFileID(ctx, conn, s.svc.scope, access.ID, trustCenterFileID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load trust center file access: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return fileAccess, nil
|
||||
}
|
||||
|
||||
func (s *TrustCenterAccessService) AcceptByIDs(
|
||||
ctx context.Context,
|
||||
organizationID gid.GID,
|
||||
email string,
|
||||
documentIDs []gid.GID,
|
||||
reportIDs []gid.GID,
|
||||
fileIDs []gid.GID,
|
||||
) error {
|
||||
return s.svc.pg.WithTx(ctx, func(tx pg.Conn) error {
|
||||
trustCenter := &coredata.TrustCenter{}
|
||||
@@ -366,6 +422,11 @@ func (s *TrustCenterAccessService) AcceptByIDs(
|
||||
return fmt.Errorf("cannot activate report accesses: %w", err)
|
||||
}
|
||||
}
|
||||
if len(fileIDs) > 0 {
|
||||
if err := coredata.ActivateByTrustCenterFileIDs(ctx, tx, s.svc.scope, access.ID, fileIDs, now); err != nil {
|
||||
return fmt.Errorf("cannot activate trust center file accesses: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
if wasInactive {
|
||||
access.Active = true
|
||||
@@ -470,9 +531,10 @@ func (s *TrustCenterAccessService) sendTrustCenterAccessEmail(
|
||||
return nil
|
||||
}
|
||||
|
||||
func extractExistingIDs(accesses coredata.TrustCenterDocumentAccesses) ([]gid.GID, []gid.GID) {
|
||||
func extractExistingIDs(accesses coredata.TrustCenterDocumentAccesses) ([]gid.GID, []gid.GID, []gid.GID) {
|
||||
var documentIDs []gid.GID
|
||||
var reportIDs []gid.GID
|
||||
var trustCenterFileIDs []gid.GID
|
||||
|
||||
for _, access := range accesses {
|
||||
if access.DocumentID != nil {
|
||||
@@ -481,9 +543,12 @@ func extractExistingIDs(accesses coredata.TrustCenterDocumentAccesses) ([]gid.GI
|
||||
if access.ReportID != nil {
|
||||
reportIDs = append(reportIDs, *access.ReportID)
|
||||
}
|
||||
if access.TrustCenterFileID != nil {
|
||||
trustCenterFileIDs = append(trustCenterFileIDs, *access.TrustCenterFileID)
|
||||
}
|
||||
}
|
||||
|
||||
return documentIDs, reportIDs
|
||||
return documentIDs, reportIDs, trustCenterFileIDs
|
||||
}
|
||||
|
||||
func filterExistingIDs(allIDs []gid.GID, existingIDs []gid.GID) []gid.GID {
|
||||
|
||||
150
pkg/trust/trust_center_file_service.go
Normal file
150
pkg/trust/trust_center_file_service.go
Normal file
@@ -0,0 +1,150 @@
|
||||
// Copyright (c) 2025 Probo Inc <hello@getprobo.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 trust
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/aws/aws-sdk-go-v2/aws"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/getprobo/probo/pkg/coredata"
|
||||
"github.com/getprobo/probo/pkg/gid"
|
||||
"github.com/getprobo/probo/pkg/page"
|
||||
"github.com/getprobo/probo/pkg/watermarkpdf"
|
||||
"go.gearno.de/kit/pg"
|
||||
)
|
||||
|
||||
type TrustCenterFileService struct {
|
||||
svc *TenantService
|
||||
}
|
||||
|
||||
func (s *TrustCenterFileService) Get(
|
||||
ctx context.Context,
|
||||
trustCenterFileID gid.GID,
|
||||
) (*coredata.TrustCenterFile, error) {
|
||||
trustCenterFile := &coredata.TrustCenterFile{}
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
err := trustCenterFile.LoadByID(ctx, conn, s.svc.scope, trustCenterFileID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load trust center file: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return trustCenterFile, nil
|
||||
}
|
||||
|
||||
func (s *TrustCenterFileService) ListForOrganizationId(
|
||||
ctx context.Context,
|
||||
organizationID gid.GID,
|
||||
cursor *page.Cursor[coredata.TrustCenterFileOrderField],
|
||||
) (*page.Page[*coredata.TrustCenterFile, coredata.TrustCenterFileOrderField], error) {
|
||||
var trustCenterFiles coredata.TrustCenterFiles
|
||||
|
||||
err := s.svc.pg.WithConn(
|
||||
ctx,
|
||||
func(conn pg.Conn) error {
|
||||
err := trustCenterFiles.LoadByOrganizationID(ctx, conn, s.svc.scope, organizationID, cursor)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load trust center files: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return page.NewPage(trustCenterFiles, cursor), nil
|
||||
}
|
||||
|
||||
func (s *TrustCenterFileService) ExportFile(
|
||||
ctx context.Context,
|
||||
trustCenterFileID gid.GID,
|
||||
email string,
|
||||
) ([]byte, error) {
|
||||
pdfData, err := s.exportFileData(ctx, trustCenterFileID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot export trust center file: %w", err)
|
||||
}
|
||||
|
||||
watermarkedPDF, err := watermarkpdf.AddConfidentialWithTimestamp(pdfData, email)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot add watermark to PDF: %w", err)
|
||||
}
|
||||
|
||||
return watermarkedPDF, nil
|
||||
}
|
||||
|
||||
func (s *TrustCenterFileService) ExportFileWithoutWatermark(
|
||||
ctx context.Context,
|
||||
trustCenterFileID gid.GID,
|
||||
) ([]byte, error) {
|
||||
return s.exportFileData(ctx, trustCenterFileID)
|
||||
}
|
||||
|
||||
func (s *TrustCenterFileService) exportFileData(
|
||||
ctx context.Context,
|
||||
trustCenterFileID gid.GID,
|
||||
) ([]byte, error) {
|
||||
var trustCenterFile *coredata.TrustCenterFile
|
||||
var file *coredata.File
|
||||
|
||||
err := s.svc.pg.WithConn(ctx, func(conn pg.Conn) error {
|
||||
trustCenterFile = &coredata.TrustCenterFile{}
|
||||
if err := trustCenterFile.LoadByID(ctx, conn, s.svc.scope, trustCenterFileID); err != nil {
|
||||
return fmt.Errorf("cannot load trust center file: %w", err)
|
||||
}
|
||||
|
||||
file = &coredata.File{}
|
||||
if err := file.LoadByID(ctx, conn, s.svc.scope, trustCenterFile.FileID); err != nil {
|
||||
return fmt.Errorf("cannot load file: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result, err := s.svc.s3.GetObject(ctx, &s3.GetObjectInput{
|
||||
Bucket: aws.String(s.svc.bucket),
|
||||
Key: aws.String(file.FileKey),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot download file from S3: %w", err)
|
||||
}
|
||||
defer result.Body.Close()
|
||||
|
||||
fileData, err := io.ReadAll(result.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot read file data: %w", err)
|
||||
}
|
||||
|
||||
return fileData, nil
|
||||
}
|
||||
Reference in New Issue
Block a user