Flatten compliance portal package layout
Remove the root complianceportal package and the resolver facade that existed only to break an IAM import cycle. Admin policies, domain URL helpers, and actions live under management; visitor OAuth metadata, brand URLs, and public read paths live under visitor. Drop the duplicate trust API magic-link mutations now that Connect handles portal auth, and stop IAM from owning compliance page email branding. Signed-off-by: Bryan Frimin <bryan@probo.com>
This commit is contained in:
46
pkg/complianceportal/visitor/brand.go
Normal file
46
pkg/complianceportal/visitor/brand.go
Normal file
@@ -0,0 +1,46 @@
|
||||
// Copyright (c) 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 visitor
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
const (
|
||||
BrandLogoPath = "/brand/logo"
|
||||
BrandDarkLogoPath = "/brand/dark-logo"
|
||||
)
|
||||
|
||||
func BrandLogoURL(portalBaseURL string) (string, error) {
|
||||
return brandAssetURL(portalBaseURL, BrandLogoPath)
|
||||
}
|
||||
|
||||
func BrandDarkLogoURL(portalBaseURL string) (string, error) {
|
||||
return brandAssetURL(portalBaseURL, BrandDarkLogoPath)
|
||||
}
|
||||
|
||||
func brandAssetURL(portalBaseURL string, path string) (string, error) {
|
||||
parsed, err := url.Parse(portalBaseURL)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("cannot parse portal base URL: %w", err)
|
||||
}
|
||||
|
||||
parsed.Path = path
|
||||
parsed.RawQuery = ""
|
||||
parsed.Fragment = ""
|
||||
|
||||
return parsed.String(), nil
|
||||
}
|
||||
117
pkg/complianceportal/visitor/cimd.go
Normal file
117
pkg/complianceportal/visitor/cimd.go
Normal file
@@ -0,0 +1,117 @@
|
||||
// Copyright (c) 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 visitor
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/iam/oauth2"
|
||||
)
|
||||
|
||||
const (
|
||||
VisitorOAuthScope = "openid profile email"
|
||||
CIMDMetadataPath = "/.well-known/oauth-client-metadata"
|
||||
OAuthCallbackPath = "/callback"
|
||||
)
|
||||
|
||||
func CIMDClientIDURL(portalBaseURL string) (string, error) {
|
||||
parsed, err := url.Parse(portalBaseURL)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
parsed.Path = CIMDMetadataPath
|
||||
parsed.RawQuery = ""
|
||||
parsed.Fragment = ""
|
||||
|
||||
return parsed.String(), nil
|
||||
}
|
||||
|
||||
func OAuthCallbackURL(portalBaseURL string) (string, error) {
|
||||
parsed, err := url.Parse(portalBaseURL)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
parsed.Path = OAuthCallbackPath
|
||||
parsed.RawQuery = ""
|
||||
parsed.Fragment = ""
|
||||
|
||||
return parsed.String(), nil
|
||||
}
|
||||
|
||||
func PortalRootURL(rawURL string) (string, error) {
|
||||
parsed, err := url.Parse(rawURL)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("cannot parse portal URL: %w", err)
|
||||
}
|
||||
|
||||
parsed.Path = ""
|
||||
parsed.RawQuery = ""
|
||||
parsed.Fragment = ""
|
||||
|
||||
return parsed.String(), nil
|
||||
}
|
||||
|
||||
func PortalBaseURLFromCIMDClientID(clientIDURL string) (string, error) {
|
||||
portalURL, err := PortalRootURL(clientIDURL)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("cannot parse cimd client_id URL: %w", err)
|
||||
}
|
||||
|
||||
return portalURL, nil
|
||||
}
|
||||
|
||||
func BuildClientMetadataDocument(
|
||||
portal *coredata.TrustCenter,
|
||||
portalBaseURL string,
|
||||
) (oauth2.ClientMetadataDocument, error) {
|
||||
clientID, err := CIMDClientIDURL(portalBaseURL)
|
||||
if err != nil {
|
||||
return oauth2.ClientMetadataDocument{}, fmt.Errorf("cannot build cimd client_id URL: %w", err)
|
||||
}
|
||||
|
||||
redirectURI, err := OAuthCallbackURL(portalBaseURL)
|
||||
if err != nil {
|
||||
return oauth2.ClientMetadataDocument{}, fmt.Errorf("cannot build oauth callback URL: %w", err)
|
||||
}
|
||||
|
||||
portalRootURL, err := PortalRootURL(portalBaseURL)
|
||||
if err != nil {
|
||||
return oauth2.ClientMetadataDocument{}, fmt.Errorf("cannot build cimd client_uri URL: %w", err)
|
||||
}
|
||||
|
||||
doc := oauth2.ClientMetadataDocument{
|
||||
ClientID: clientID,
|
||||
ClientName: portal.Title,
|
||||
ClientURI: portalRootURL,
|
||||
RedirectURIs: []string{redirectURI},
|
||||
TokenEndpointAuthMethod: "none",
|
||||
GrantTypes: []string{"authorization_code", "refresh_token"},
|
||||
ResponseTypes: []string{"code"},
|
||||
Scope: VisitorOAuthScope,
|
||||
}
|
||||
|
||||
if portal.LogoFileID != nil {
|
||||
logoURI, err := BrandLogoURL(portalBaseURL)
|
||||
if err == nil {
|
||||
doc.LogoURI = logoURI
|
||||
}
|
||||
}
|
||||
|
||||
return doc, nil
|
||||
}
|
||||
98
pkg/complianceportal/visitor/cimd_test.go
Normal file
98
pkg/complianceportal/visitor/cimd_test.go
Normal file
@@ -0,0 +1,98 @@
|
||||
// Copyright (c) 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 visitor
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/gid"
|
||||
)
|
||||
|
||||
func TestCIMDClientIDURL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
clientID, err := CIMDClientIDURL("https://acme.example.com/overview")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "https://acme.example.com/.well-known/oauth-client-metadata", clientID)
|
||||
}
|
||||
|
||||
func TestOAuthCallbackURL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
callbackURL, err := OAuthCallbackURL("https://acme.example.com/")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "https://acme.example.com/callback", callbackURL)
|
||||
}
|
||||
|
||||
func TestPortalBaseURLFromCIMDClientID(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
baseURL, err := PortalBaseURLFromCIMDClientID(
|
||||
"https://acme.example.com/.well-known/oauth-client-metadata",
|
||||
)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "https://acme.example.com", baseURL)
|
||||
}
|
||||
|
||||
func TestBrandLogoURL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logoURL, err := BrandLogoURL("https://acme.example.com/page")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "https://acme.example.com/brand/logo", logoURL)
|
||||
|
||||
darkLogoURL, err := BrandDarkLogoURL("https://acme.example.com/")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "https://acme.example.com/brand/dark-logo", darkLogoURL)
|
||||
}
|
||||
|
||||
func TestBuildClientMetadataDocument(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
websiteURL := "https://www.acme.com"
|
||||
portal := &coredata.TrustCenter{
|
||||
Title: "Acme Compliance Page",
|
||||
WebsiteURL: &websiteURL,
|
||||
}
|
||||
|
||||
doc, err := BuildClientMetadataDocument(
|
||||
portal,
|
||||
"https://acme.example.com/.well-known/oauth-client-metadata",
|
||||
)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "https://acme.example.com/.well-known/oauth-client-metadata", doc.ClientID)
|
||||
assert.Equal(t, "Acme Compliance Page", doc.ClientName)
|
||||
assert.Equal(t, []string{"https://acme.example.com/callback"}, doc.RedirectURIs)
|
||||
assert.Equal(t, "https://acme.example.com", doc.ClientURI)
|
||||
assert.Equal(t, VisitorOAuthScope, doc.Scope)
|
||||
assert.Empty(t, doc.LogoURI)
|
||||
}
|
||||
|
||||
func TestBuildClientMetadataDocument_LogoURIUsesBrandLogoEndpoint(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
logoFileID := gid.MustParseGID("WR-qMrB5AAEAGQAAAZ9mIO8B8vDFQ-i3")
|
||||
portal := &coredata.TrustCenter{
|
||||
Title: "Acme Compliance Page",
|
||||
LogoFileID: &logoFileID,
|
||||
}
|
||||
|
||||
doc, err := BuildClientMetadataDocument(portal, "https://acme.example.com")
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, "https://acme.example.com/brand/logo", doc.LogoURI)
|
||||
}
|
||||
@@ -58,7 +58,7 @@ func (s *Service) GetComplianceFramework(
|
||||
func (s *Service) ListComplianceFrameworksByPortalID(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
trustCenterID gid.GID,
|
||||
compliancePageID gid.GID,
|
||||
cursor *page.Cursor[coredata.ComplianceFrameworkOrderField],
|
||||
) (*page.Page[*coredata.ComplianceFramework, coredata.ComplianceFrameworkOrderField], error) {
|
||||
var complianceFrameworks coredata.ComplianceFrameworks
|
||||
@@ -66,7 +66,7 @@ func (s *Service) ListComplianceFrameworksByPortalID(
|
||||
err := s.pg.WithConn(
|
||||
ctx,
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
err := complianceFrameworks.LoadByTrustCenterID(ctx, conn, scope, trustCenterID, cursor)
|
||||
err := complianceFrameworks.LoadByTrustCenterID(ctx, conn, scope, compliancePageID, cursor)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load compliance frameworks: %w", err)
|
||||
}
|
||||
|
||||
@@ -122,40 +122,40 @@ type (
|
||||
func (s *Service) RenderCompliancePageMarkdown(
|
||||
ctx context.Context,
|
||||
w io.Writer,
|
||||
trustCenterID gid.GID,
|
||||
compliancePageID gid.GID,
|
||||
scope coredata.Scoper,
|
||||
) error {
|
||||
org, err := s.GetPortalOrganization(ctx, trustCenterID)
|
||||
org, err := s.GetPortalOrganization(ctx, compliancePageID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load organization for compliance page: %w", err)
|
||||
}
|
||||
|
||||
trustCenter, err := s.GetPortalByID(ctx, trustCenterID)
|
||||
compliancePage, err := s.GetPortalByID(ctx, compliancePageID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load trust center for compliance page: %w", err)
|
||||
return fmt.Errorf("cannot load compliance page: %w", err)
|
||||
}
|
||||
|
||||
data := &compliancePageData{
|
||||
OrgName: org.Name,
|
||||
}
|
||||
|
||||
if trustCenter.Description != nil && *trustCenter.Description != "" {
|
||||
data.Description = *trustCenter.Description
|
||||
if compliancePage.Description != nil && *compliancePage.Description != "" {
|
||||
data.Description = *compliancePage.Description
|
||||
}
|
||||
|
||||
if trustCenter.WebsiteURL != nil && *trustCenter.WebsiteURL != "" {
|
||||
data.Details = append(data.Details, compliancePageDetail{Label: "Website", Value: *trustCenter.WebsiteURL})
|
||||
if compliancePage.WebsiteURL != nil && *compliancePage.WebsiteURL != "" {
|
||||
data.Details = append(data.Details, compliancePageDetail{Label: "Website", Value: *compliancePage.WebsiteURL})
|
||||
}
|
||||
|
||||
if trustCenter.Email != nil && *trustCenter.Email != "" {
|
||||
data.Details = append(data.Details, compliancePageDetail{Label: "Email", Value: *trustCenter.Email})
|
||||
if compliancePage.Email != nil && *compliancePage.Email != "" {
|
||||
data.Details = append(data.Details, compliancePageDetail{Label: "Email", Value: *compliancePage.Email})
|
||||
}
|
||||
|
||||
if trustCenter.HeadquarterAddress != nil && *trustCenter.HeadquarterAddress != "" {
|
||||
data.Details = append(data.Details, compliancePageDetail{Label: "Headquarters", Value: *trustCenter.HeadquarterAddress})
|
||||
if compliancePage.HeadquarterAddress != nil && *compliancePage.HeadquarterAddress != "" {
|
||||
data.Details = append(data.Details, compliancePageDetail{Label: "Headquarters", Value: *compliancePage.HeadquarterAddress})
|
||||
}
|
||||
|
||||
data.Frameworks, err = s.fetchComplianceFrameworks(ctx, scope, trustCenterID)
|
||||
data.Frameworks, err = s.fetchComplianceFrameworks(ctx, scope, compliancePageID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot fetch compliance frameworks: %w", err)
|
||||
}
|
||||
@@ -175,12 +175,12 @@ func (s *Service) RenderCompliancePageMarkdown(
|
||||
return fmt.Errorf("cannot fetch thirdParties: %w", err)
|
||||
}
|
||||
|
||||
data.References, err = s.fetchReferences(ctx, scope, trustCenterID)
|
||||
data.References, err = s.fetchReferences(ctx, scope, compliancePageID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot fetch references: %w", err)
|
||||
}
|
||||
|
||||
data.CustomLinks, err = s.fetchCustomLinks(ctx, scope, trustCenterID)
|
||||
data.CustomLinks, err = s.fetchCustomLinks(ctx, scope, compliancePageID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot fetch external links: %w", err)
|
||||
}
|
||||
@@ -207,11 +207,11 @@ type (
|
||||
func (s *Service) RenderSitemap(
|
||||
ctx context.Context,
|
||||
w io.Writer,
|
||||
trustCenterID gid.GID,
|
||||
compliancePageID gid.GID,
|
||||
scope coredata.Scoper,
|
||||
baseURL string,
|
||||
) error {
|
||||
org, err := s.GetPortalOrganization(ctx, trustCenterID)
|
||||
org, err := s.GetPortalOrganization(ctx, compliancePageID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load organization for sitemap: %w", err)
|
||||
}
|
||||
@@ -322,7 +322,7 @@ func (s *Service) fetchDocumentIDs(
|
||||
coredata.NewTrustCenterFileFilter(),
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot list trust center files: %w", err)
|
||||
return nil, fmt.Errorf("cannot list compliance page files: %w", err)
|
||||
}
|
||||
|
||||
for _, file := range result.Data {
|
||||
@@ -401,7 +401,7 @@ func (s *Service) fetchDocumentIDs(
|
||||
func (s *Service) fetchComplianceFrameworks(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
trustCenterID gid.GID,
|
||||
compliancePageID gid.GID,
|
||||
) ([]compliancePageFramework, error) {
|
||||
var frameworks []compliancePageFramework
|
||||
|
||||
@@ -417,7 +417,7 @@ func (s *Service) fetchComplianceFrameworks(
|
||||
},
|
||||
)
|
||||
|
||||
result, err := s.ListComplianceFrameworksByPortalID(ctx, scope, trustCenterID, cursor)
|
||||
result, err := s.ListComplianceFrameworksByPortalID(ctx, scope, compliancePageID, cursor)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot list compliance frameworks: %w", err)
|
||||
}
|
||||
@@ -621,7 +621,7 @@ func (s *Service) fetchThirdParties(
|
||||
func (s *Service) fetchReferences(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
trustCenterID gid.GID,
|
||||
compliancePageID gid.GID,
|
||||
) ([]compliancePageReference, error) {
|
||||
var refs []compliancePageReference
|
||||
|
||||
@@ -637,7 +637,7 @@ func (s *Service) fetchReferences(
|
||||
},
|
||||
)
|
||||
|
||||
result, err := s.ListPortalReferencesForPortalID(ctx, scope, trustCenterID, cursor)
|
||||
result, err := s.ListPortalReferencesForPortalID(ctx, scope, compliancePageID, cursor)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot list references: %w", err)
|
||||
}
|
||||
@@ -669,7 +669,7 @@ func (s *Service) fetchReferences(
|
||||
func (s *Service) fetchCustomLinks(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
trustCenterID gid.GID,
|
||||
compliancePageID gid.GID,
|
||||
) ([]compliancePageCustomLink, error) {
|
||||
var links []compliancePageCustomLink
|
||||
|
||||
@@ -685,7 +685,7 @@ func (s *Service) fetchCustomLinks(
|
||||
},
|
||||
)
|
||||
|
||||
result, err := s.ListCustomLinksForPortalID(ctx, scope, trustCenterID, cursor)
|
||||
result, err := s.ListCustomLinksForPortalID(ctx, scope, compliancePageID, cursor)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot list custom links: %w", err)
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import (
|
||||
func (s *Service) ListCustomLinksForPortalID(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
trustCenterID gid.GID,
|
||||
compliancePageID gid.GID,
|
||||
cursor *page.Cursor[coredata.ComplianceCustomLinkOrderField],
|
||||
) (*page.Page[*coredata.ComplianceCustomLink, coredata.ComplianceCustomLinkOrderField], error) {
|
||||
var links coredata.ComplianceCustomLinks
|
||||
@@ -41,7 +41,7 @@ func (s *Service) ListCustomLinksForPortalID(
|
||||
err := s.pg.WithConn(
|
||||
ctx,
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
err := links.LoadByTrustCenterID(ctx, conn, scope, trustCenterID, cursor)
|
||||
err := links.LoadByTrustCenterID(ctx, conn, scope, compliancePageID, cursor)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load custom links: %w", err)
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ func (s *Service) exportDocumentPDFData(
|
||||
}
|
||||
|
||||
if document.TrustCenterVisibility == coredata.TrustCenterVisibilityNone {
|
||||
return fmt.Errorf("document not visible on trust center")
|
||||
return fmt.Errorf("document not visible on compliance page")
|
||||
}
|
||||
|
||||
if err := version.LoadLatestPublishedVersion(ctx, conn, scope, documentID); err != nil {
|
||||
|
||||
@@ -23,17 +23,17 @@ package visitor
|
||||
import "errors"
|
||||
|
||||
var (
|
||||
ErrOAuthStateNotFound = errors.New("oauth state not found")
|
||||
ErrOAuthStateExpired = errors.New("oauth state expired")
|
||||
ErrPageNotFound = errors.New("page not found")
|
||||
ErrMembershipNotFound = errors.New("membership not found")
|
||||
ErrUserNotFound = errors.New("user not found")
|
||||
ErrUserInactive = errors.New("user inactive")
|
||||
ErrDocumentAccessNotFound = errors.New("document access not found")
|
||||
ErrNDAFileNotFound = errors.New("NDA file not found")
|
||||
ErrDocumentNotFound = errors.New("document not found")
|
||||
ErrDocumentNotVisible = errors.New("document not visible")
|
||||
ErrReportNotFound = errors.New("report not found")
|
||||
ErrTrustCenterFileNotFound = errors.New("trust center file not found")
|
||||
ErrTrustCenterFileNotVisible = errors.New("trust center file not visible")
|
||||
ErrOAuthStateNotFound = errors.New("oauth state not found")
|
||||
ErrOAuthStateExpired = errors.New("oauth state expired")
|
||||
ErrPageNotFound = errors.New("page not found")
|
||||
ErrMembershipNotFound = errors.New("membership not found")
|
||||
ErrUserNotFound = errors.New("user not found")
|
||||
ErrUserInactive = errors.New("user inactive")
|
||||
ErrDocumentAccessNotFound = errors.New("document access not found")
|
||||
ErrNDAFileNotFound = errors.New("NDA file not found")
|
||||
ErrDocumentNotFound = errors.New("document not found")
|
||||
ErrDocumentNotVisible = errors.New("document not visible")
|
||||
ErrReportNotFound = errors.New("report not found")
|
||||
ErrPortalFileNotFound = errors.New("portal file not found")
|
||||
ErrPortalFileNotVisible = errors.New("portal file not visible")
|
||||
)
|
||||
|
||||
@@ -60,9 +60,9 @@ func (s *Service) RequestPortalAccess(
|
||||
err := s.pg.WithTx(
|
||||
ctx,
|
||||
func(ctx context.Context, tx pg.Tx) error {
|
||||
trustCenter := &coredata.TrustCenter{}
|
||||
if err := trustCenter.LoadByID(ctx, tx, scope, req.TrustCenterID); err != nil {
|
||||
return fmt.Errorf("cannot load trust center: %w", err)
|
||||
compliancePage := &coredata.TrustCenter{}
|
||||
if err := compliancePage.LoadByID(ctx, tx, scope, req.TrustCenterID); err != nil {
|
||||
return fmt.Errorf("cannot load compliance page: %w", err)
|
||||
}
|
||||
|
||||
access = &coredata.TrustCenterAccess{}
|
||||
@@ -70,7 +70,7 @@ func (s *Service) RequestPortalAccess(
|
||||
return fmt.Errorf("cannot load compliance page membership: %w", err)
|
||||
}
|
||||
|
||||
organizationID := trustCenter.OrganizationID
|
||||
organizationID := compliancePage.OrganizationID
|
||||
|
||||
documentIDs := req.DocumentIDs
|
||||
if req.DocumentIDs == nil {
|
||||
@@ -145,7 +145,7 @@ func (s *Service) RequestPortalAccess(
|
||||
func(ctx context.Context, cursor *page.Cursor[coredata.TrustCenterFileOrderField]) ([]*coredata.TrustCenterFile, error) {
|
||||
var batch coredata.TrustCenterFiles
|
||||
if err := batch.LoadByOrganizationID(ctx, tx, scope, organizationID, cursor, filter); err != nil {
|
||||
return nil, fmt.Errorf("cannot list trust center files: %w", err)
|
||||
return nil, fmt.Errorf("cannot list compliance page files: %w", err)
|
||||
}
|
||||
|
||||
return batch, nil
|
||||
@@ -196,7 +196,7 @@ func (s *Service) RequestPortalAccess(
|
||||
coredata.TrustCenterDocumentAccessStatusRequested,
|
||||
now,
|
||||
); err != nil {
|
||||
return fmt.Errorf("cannot bulk insert trust center document accesses: %w", err)
|
||||
return fmt.Errorf("cannot bulk insert compliance page document accesses: %w", err)
|
||||
}
|
||||
|
||||
if err := accesses.BulkInsertReportFileAccesses(
|
||||
@@ -209,7 +209,7 @@ func (s *Service) RequestPortalAccess(
|
||||
coredata.TrustCenterDocumentAccessStatusRequested,
|
||||
now,
|
||||
); err != nil {
|
||||
return fmt.Errorf("cannot bulk insert trust center report accesses: %w", err)
|
||||
return fmt.Errorf("cannot bulk insert compliance page report accesses: %w", err)
|
||||
}
|
||||
|
||||
if err := accesses.BulkInsertTrustCenterFileAccesses(
|
||||
@@ -222,7 +222,7 @@ func (s *Service) RequestPortalAccess(
|
||||
coredata.TrustCenterDocumentAccessStatusRequested,
|
||||
now,
|
||||
); err != nil {
|
||||
return fmt.Errorf("cannot bulk insert trust center file accesses: %w", err)
|
||||
return fmt.Errorf("cannot bulk insert compliance page file accesses: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -242,7 +242,7 @@ func (s *Service) RequestPortalAccess(
|
||||
func (s *Service) GetPortalAccess(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
trustCenterID gid.GID,
|
||||
compliancePageID gid.GID,
|
||||
identityID gid.GID,
|
||||
) (coredata.TrustCenterAccess, error) {
|
||||
var access coredata.TrustCenterAccess
|
||||
@@ -250,7 +250,7 @@ func (s *Service) GetPortalAccess(
|
||||
err := s.pg.WithConn(
|
||||
ctx,
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
return access.LoadByTrustCenterIDAndIdentityID(ctx, conn, scope, trustCenterID, identityID)
|
||||
return access.LoadByTrustCenterIDAndIdentityID(ctx, conn, scope, compliancePageID, identityID)
|
||||
},
|
||||
)
|
||||
|
||||
@@ -260,7 +260,7 @@ func (s *Service) GetPortalAccess(
|
||||
func (s *Service) GetPortalDocumentAccess(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
trustCenterID gid.GID,
|
||||
compliancePageID gid.GID,
|
||||
identityID gid.GID,
|
||||
documentID gid.GID,
|
||||
) (*coredata.TrustCenterDocumentAccess, error) {
|
||||
@@ -271,13 +271,13 @@ func (s *Service) GetPortalDocumentAccess(
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
access := &coredata.TrustCenterAccess{}
|
||||
|
||||
err := access.LoadByTrustCenterIDAndIdentityID(ctx, conn, scope, trustCenterID, identityID)
|
||||
err := access.LoadByTrustCenterIDAndIdentityID(ctx, conn, scope, compliancePageID, identityID)
|
||||
if err != nil {
|
||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||
return ErrMembershipNotFound
|
||||
}
|
||||
|
||||
return fmt.Errorf("cannot load trust center access: %w", err)
|
||||
return fmt.Errorf("cannot load compliance page access: %w", err)
|
||||
}
|
||||
|
||||
profile := &coredata.MembershipProfile{}
|
||||
@@ -315,7 +315,7 @@ func (s *Service) GetPortalDocumentAccess(
|
||||
func (s *Service) GetPortalReportFileAccess(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
trustCenterID gid.GID,
|
||||
compliancePageID gid.GID,
|
||||
identityID gid.GID,
|
||||
reportFileID gid.GID,
|
||||
) (*coredata.TrustCenterDocumentAccess, error) {
|
||||
@@ -326,13 +326,13 @@ func (s *Service) GetPortalReportFileAccess(
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
access := &coredata.TrustCenterAccess{}
|
||||
|
||||
err := access.LoadByTrustCenterIDAndIdentityID(ctx, conn, scope, trustCenterID, identityID)
|
||||
err := access.LoadByTrustCenterIDAndIdentityID(ctx, conn, scope, compliancePageID, identityID)
|
||||
if err != nil {
|
||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||
return ErrMembershipNotFound
|
||||
}
|
||||
|
||||
return fmt.Errorf("cannot load trust center access: %w", err)
|
||||
return fmt.Errorf("cannot load compliance page access: %w", err)
|
||||
}
|
||||
|
||||
profile := &coredata.MembershipProfile{}
|
||||
@@ -370,7 +370,7 @@ func (s *Service) GetPortalReportFileAccess(
|
||||
func (s *Service) GetPortalFileAccess(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
trustCenterID gid.GID,
|
||||
compliancePageID gid.GID,
|
||||
identityID gid.GID,
|
||||
trustCenterFileID gid.GID,
|
||||
) (*coredata.TrustCenterDocumentAccess, error) {
|
||||
@@ -381,13 +381,13 @@ func (s *Service) GetPortalFileAccess(
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
access := &coredata.TrustCenterAccess{}
|
||||
|
||||
err := access.LoadByTrustCenterIDAndIdentityID(ctx, conn, scope, trustCenterID, identityID)
|
||||
err := access.LoadByTrustCenterIDAndIdentityID(ctx, conn, scope, compliancePageID, identityID)
|
||||
if err != nil {
|
||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||
return ErrMembershipNotFound
|
||||
}
|
||||
|
||||
return fmt.Errorf("cannot load trust center access: %w", err)
|
||||
return fmt.Errorf("cannot load compliance page access: %w", err)
|
||||
}
|
||||
|
||||
profile := &coredata.MembershipProfile{}
|
||||
@@ -409,7 +409,7 @@ func (s *Service) GetPortalFileAccess(
|
||||
return ErrDocumentAccessNotFound
|
||||
}
|
||||
|
||||
return fmt.Errorf("cannot load trust center file access: %w", err)
|
||||
return fmt.Errorf("cannot load compliance page file access: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -434,9 +434,9 @@ func (s *Service) GrantPortalAccessByIDs(
|
||||
return s.pg.WithTx(
|
||||
ctx,
|
||||
func(ctx context.Context, tx pg.Tx) error {
|
||||
trustCenter := &coredata.TrustCenter{}
|
||||
if err := trustCenter.LoadByOrganizationID(ctx, tx, scope, organizationID); err != nil {
|
||||
return fmt.Errorf("cannot load trust center: %w", err)
|
||||
compliancePage := &coredata.TrustCenter{}
|
||||
if err := compliancePage.LoadByOrganizationID(ctx, tx, scope, organizationID); err != nil {
|
||||
return fmt.Errorf("cannot load compliance page: %w", err)
|
||||
}
|
||||
|
||||
identity := &coredata.Identity{}
|
||||
@@ -445,8 +445,8 @@ func (s *Service) GrantPortalAccessByIDs(
|
||||
}
|
||||
|
||||
access := &coredata.TrustCenterAccess{}
|
||||
if err := access.LoadByTrustCenterIDAndIdentityID(ctx, tx, scope, trustCenter.ID, identity.ID); err != nil {
|
||||
return fmt.Errorf("cannot load trust center access: %w", err)
|
||||
if err := access.LoadByTrustCenterIDAndIdentityID(ctx, tx, scope, compliancePage.ID, identity.ID); err != nil {
|
||||
return fmt.Errorf("cannot load compliance page access: %w", err)
|
||||
}
|
||||
|
||||
profile := &coredata.MembershipProfile{}
|
||||
@@ -477,7 +477,7 @@ func (s *Service) GrantPortalAccessByIDs(
|
||||
|
||||
if len(fileIDs) > 0 {
|
||||
if err := coredata.GrantByTrustCenterFileIDs(ctx, tx, scope, access.ID, fileIDs, now); err != nil {
|
||||
return fmt.Errorf("cannot grant trust center file accesses: %w", err)
|
||||
return fmt.Errorf("cannot grant compliance page file accesses: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -515,7 +515,7 @@ func (s *Service) sendPortalAccessEmail(
|
||||
access.UpdatedAt = now
|
||||
|
||||
if err := access.Update(ctx, tx, scope); err != nil {
|
||||
return fmt.Errorf("cannot update trust center access with expiration: %w", err)
|
||||
return fmt.Errorf("cannot update compliance page access with expiration: %w", err)
|
||||
}
|
||||
|
||||
emailPresenterCfg, err := s.GetPortalEmailPresenterConfig(ctx, scope, access.TrustCenterID)
|
||||
@@ -527,7 +527,7 @@ func (s *Service) sendPortalAccessEmail(
|
||||
|
||||
subject, textBody, htmlBody, err := emailPresenter.RenderTrustCenterAccess(ctx, organization.Name)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot render trust center access email: %w", err)
|
||||
return fmt.Errorf("cannot render compliance page access email: %w", err)
|
||||
}
|
||||
|
||||
accessEmail := coredata.NewEmail(
|
||||
@@ -560,9 +560,9 @@ func (s *Service) RejectOrRevokePortalAccessByIDs(
|
||||
return s.pg.WithTx(
|
||||
ctx,
|
||||
func(ctx context.Context, tx pg.Tx) error {
|
||||
trustCenter := &coredata.TrustCenter{}
|
||||
if err := trustCenter.LoadByOrganizationID(ctx, tx, scope, organizationID); err != nil {
|
||||
return fmt.Errorf("cannot load trust center: %w", err)
|
||||
compliancePage := &coredata.TrustCenter{}
|
||||
if err := compliancePage.LoadByOrganizationID(ctx, tx, scope, organizationID); err != nil {
|
||||
return fmt.Errorf("cannot load compliance page: %w", err)
|
||||
}
|
||||
|
||||
identity := &coredata.Identity{}
|
||||
@@ -571,8 +571,8 @@ func (s *Service) RejectOrRevokePortalAccessByIDs(
|
||||
}
|
||||
|
||||
access := &coredata.TrustCenterAccess{}
|
||||
if err := access.LoadByTrustCenterIDAndIdentityID(ctx, tx, scope, trustCenter.ID, identity.ID); err != nil {
|
||||
return fmt.Errorf("cannot load trust center access: %w", err)
|
||||
if err := access.LoadByTrustCenterIDAndIdentityID(ctx, tx, scope, compliancePage.ID, identity.ID); err != nil {
|
||||
return fmt.Errorf("cannot load compliance page access: %w", err)
|
||||
}
|
||||
|
||||
profile := &coredata.MembershipProfile{}
|
||||
@@ -603,7 +603,7 @@ func (s *Service) RejectOrRevokePortalAccessByIDs(
|
||||
shouldSendEmail = true
|
||||
|
||||
if err := coredata.RejectOrRevokeByTrustCenterFileIDs(ctx, tx, scope, access.ID, fileIDs, now); err != nil {
|
||||
return fmt.Errorf("cannot reject/revoke trust center file accesses: %w", err)
|
||||
return fmt.Errorf("cannot reject/revoke compliance page file accesses: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -681,7 +681,7 @@ func (s *Service) sendPortalDocumentAccessRejectedEmail(
|
||||
organization.Name,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot render trust center documents access rejected email: %w", err)
|
||||
return fmt.Errorf("cannot render compliance page documents access rejected email: %w", err)
|
||||
}
|
||||
|
||||
accessEmail := coredata.NewEmail(
|
||||
|
||||
@@ -47,7 +47,7 @@ func (s *Service) GetPortalFile(
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
err := trustCenterFile.LoadByID(ctx, conn, scope, trustCenterFileID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load trust center file: %w", err)
|
||||
return fmt.Errorf("cannot load compliance page file: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -58,11 +58,11 @@ func (s *Service) GetPortalFile(
|
||||
}
|
||||
|
||||
if trustCenterFile.OrganizationID != organizationID {
|
||||
return nil, ErrTrustCenterFileNotFound
|
||||
return nil, ErrPortalFileNotFound
|
||||
}
|
||||
|
||||
if trustCenterFile.TrustCenterVisibility == coredata.TrustCenterVisibilityNone {
|
||||
return nil, ErrTrustCenterFileNotVisible
|
||||
return nil, ErrPortalFileNotVisible
|
||||
}
|
||||
|
||||
return trustCenterFile, nil
|
||||
@@ -82,7 +82,7 @@ func (s *Service) ListPortalFilesForOrganizationID(
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
err := trustCenterFiles.LoadByOrganizationID(ctx, conn, scope, organizationID, cursor, filter)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load trust center files: %w", err)
|
||||
return fmt.Errorf("cannot load compliance page files: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -103,7 +103,7 @@ func (s *Service) ExportPortalFile(
|
||||
) ([]byte, string, error) {
|
||||
fileData, mimeType, err := s.exportPortalFileData(ctx, scope, trustCenterFileID)
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("cannot export trust center file: %w", err)
|
||||
return nil, "", fmt.Errorf("cannot export compliance page file: %w", err)
|
||||
}
|
||||
|
||||
if mimeType == "application/pdf" {
|
||||
@@ -141,7 +141,7 @@ func (s *Service) exportPortalFileData(
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
trustCenterFile = &coredata.TrustCenterFile{}
|
||||
if err := trustCenterFile.LoadByID(ctx, conn, scope, trustCenterFileID); err != nil {
|
||||
return fmt.Errorf("cannot load trust center file: %w", err)
|
||||
return fmt.Errorf("cannot load compliance page file: %w", err)
|
||||
}
|
||||
|
||||
file = &coredata.File{}
|
||||
|
||||
@@ -33,7 +33,7 @@ import (
|
||||
func (s *Service) ListPortalReferencesForPortalID(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
trustCenterID gid.GID,
|
||||
compliancePageID gid.GID,
|
||||
cursor *page.Cursor[coredata.TrustCenterReferenceOrderField],
|
||||
) (*page.Page[*coredata.TrustCenterReference, coredata.TrustCenterReferenceOrderField], error) {
|
||||
var references coredata.TrustCenterReferences
|
||||
@@ -43,9 +43,9 @@ func (s *Service) ListPortalReferencesForPortalID(
|
||||
ctx,
|
||||
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
err := references.LoadByTrustCenterID(ctx, conn, scope, trustCenterID, cursor)
|
||||
err := references.LoadByTrustCenterID(ctx, conn, scope, compliancePageID, cursor)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load trust center references: %w", err)
|
||||
return fmt.Errorf("cannot load compliance page references: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -72,7 +72,7 @@ func (s *Service) GeneratePortalReferenceLogoURL(
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("cannot load trust center reference: %w", err)
|
||||
return "", fmt.Errorf("cannot load compliance page reference: %w", err)
|
||||
}
|
||||
|
||||
file, err := s.fileManager.GetPublicFile(ctx, reference.LogoFileID)
|
||||
@@ -95,7 +95,7 @@ func (s *Service) GetPortalReference(
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
err := reference.LoadByID(ctx, conn, scope, referenceID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load trust center reference: %w", err)
|
||||
return fmt.Errorf("cannot load compliance page reference: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -28,7 +28,6 @@ import (
|
||||
|
||||
"go.gearno.de/kit/pg"
|
||||
"go.probo.inc/probo/packages/emails"
|
||||
"go.probo.inc/probo/pkg/complianceportal"
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/gid"
|
||||
)
|
||||
@@ -36,26 +35,26 @@ import (
|
||||
func (s *Service) GetPortal(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
trustCenterID gid.GID,
|
||||
compliancePageID gid.GID,
|
||||
) (*coredata.TrustCenter, error) {
|
||||
var trustCenter *coredata.TrustCenter
|
||||
var compliancePage *coredata.TrustCenter
|
||||
|
||||
err := s.pg.WithConn(
|
||||
ctx,
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
trustCenter = &coredata.TrustCenter{}
|
||||
if err := trustCenter.LoadByID(ctx, conn, scope, trustCenterID); err != nil {
|
||||
return fmt.Errorf("cannot load trust center: %w", err)
|
||||
compliancePage = &coredata.TrustCenter{}
|
||||
if err := compliancePage.LoadByID(ctx, conn, scope, compliancePageID); err != nil {
|
||||
return fmt.Errorf("cannot load compliance page: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot load trust center: %w", err)
|
||||
return nil, fmt.Errorf("cannot load compliance page: %w", err)
|
||||
}
|
||||
|
||||
return trustCenter, nil
|
||||
return compliancePage, nil
|
||||
}
|
||||
|
||||
func (s *Service) GetPortalByOrganizationID(
|
||||
@@ -63,14 +62,14 @@ func (s *Service) GetPortalByOrganizationID(
|
||||
scope coredata.Scoper,
|
||||
organizationID gid.GID,
|
||||
) (*coredata.TrustCenter, error) {
|
||||
trustCenter := &coredata.TrustCenter{}
|
||||
compliancePage := &coredata.TrustCenter{}
|
||||
|
||||
err := s.pg.WithConn(
|
||||
ctx,
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
err := trustCenter.LoadByOrganizationID(ctx, conn, scope, organizationID)
|
||||
err := compliancePage.LoadByOrganizationID(ctx, conn, scope, organizationID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load trust center: %w", err)
|
||||
return fmt.Errorf("cannot load compliance page: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -80,30 +79,30 @@ func (s *Service) GetPortalByOrganizationID(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return trustCenter, nil
|
||||
return compliancePage, nil
|
||||
}
|
||||
|
||||
func (s *Service) GetPortalNDAFile(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
trustCenterID gid.GID,
|
||||
compliancePageID gid.GID,
|
||||
) (*coredata.File, error) {
|
||||
var file *coredata.File
|
||||
|
||||
err := s.pg.WithConn(
|
||||
ctx,
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
trustCenter := &coredata.TrustCenter{}
|
||||
if err := trustCenter.LoadByID(ctx, conn, scope, trustCenterID); err != nil {
|
||||
return fmt.Errorf("cannot load trust center: %w", err)
|
||||
compliancePage := &coredata.TrustCenter{}
|
||||
if err := compliancePage.LoadByID(ctx, conn, scope, compliancePageID); err != nil {
|
||||
return fmt.Errorf("cannot load compliance page: %w", err)
|
||||
}
|
||||
|
||||
if trustCenter.NonDisclosureAgreementFileID == nil {
|
||||
if compliancePage.NonDisclosureAgreementFileID == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
file = &coredata.File{}
|
||||
if err := file.LoadByID(ctx, conn, scope, *trustCenter.NonDisclosureAgreementFileID); err != nil {
|
||||
if err := file.LoadByID(ctx, conn, scope, *compliancePage.NonDisclosureAgreementFileID); err != nil {
|
||||
return fmt.Errorf("cannot load file: %w", err)
|
||||
}
|
||||
|
||||
@@ -120,7 +119,7 @@ func (s *Service) GetPortalNDAFile(
|
||||
func (s *Service) GeneratePortalNDAFileURL(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
trustCenterID gid.GID,
|
||||
compliancePageID gid.GID,
|
||||
expiresIn time.Duration,
|
||||
) (string, error) {
|
||||
var file *coredata.File
|
||||
@@ -128,17 +127,17 @@ func (s *Service) GeneratePortalNDAFileURL(
|
||||
err := s.pg.WithConn(
|
||||
ctx,
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
trustCenter := &coredata.TrustCenter{}
|
||||
if err := trustCenter.LoadByID(ctx, conn, scope, trustCenterID); err != nil {
|
||||
return fmt.Errorf("cannot load trust center: %w", err)
|
||||
compliancePage := &coredata.TrustCenter{}
|
||||
if err := compliancePage.LoadByID(ctx, conn, scope, compliancePageID); err != nil {
|
||||
return fmt.Errorf("cannot load compliance page: %w", err)
|
||||
}
|
||||
|
||||
if trustCenter.NonDisclosureAgreementFileID == nil {
|
||||
if compliancePage.NonDisclosureAgreementFileID == nil {
|
||||
return fmt.Errorf("no NDA file found")
|
||||
}
|
||||
|
||||
file = &coredata.File{}
|
||||
if err := file.LoadByID(ctx, conn, scope, *trustCenter.NonDisclosureAgreementFileID); err != nil {
|
||||
if err := file.LoadByID(ctx, conn, scope, *compliancePage.NonDisclosureAgreementFileID); err != nil {
|
||||
return fmt.Errorf("cannot load file: %w", err)
|
||||
}
|
||||
|
||||
@@ -281,12 +280,11 @@ func (s *Service) GetPortalEmailPresenterConfig(
|
||||
return fmt.Errorf("cannot load organization: %w", err)
|
||||
}
|
||||
|
||||
publicURL, err := complianceportal.PublicURLForTrustCenter(
|
||||
publicURL, err := s.management.PublicURLForCompliancePage(
|
||||
ctx,
|
||||
conn,
|
||||
scope,
|
||||
compliancePage,
|
||||
s.baseDomain,
|
||||
)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot resolve compliance page URL: %w", err)
|
||||
@@ -327,24 +325,24 @@ func (s *Service) GetPortalEmailPresenterConfig(
|
||||
func (s *Service) GetPortalMailingList(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
trustCenterID gid.GID,
|
||||
compliancePageID gid.GID,
|
||||
) (*coredata.MailingList, error) {
|
||||
var mailingList *coredata.MailingList
|
||||
|
||||
err := s.pg.WithConn(
|
||||
ctx,
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
trustCenter := &coredata.TrustCenter{}
|
||||
if err := trustCenter.LoadByID(ctx, conn, scope, trustCenterID); err != nil {
|
||||
return fmt.Errorf("cannot load trust center: %w", err)
|
||||
compliancePage := &coredata.TrustCenter{}
|
||||
if err := compliancePage.LoadByID(ctx, conn, scope, compliancePageID); err != nil {
|
||||
return fmt.Errorf("cannot load compliance page: %w", err)
|
||||
}
|
||||
|
||||
if trustCenter.MailingListID == nil {
|
||||
if compliancePage.MailingListID == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
mailingList = &coredata.MailingList{}
|
||||
if err := mailingList.LoadByID(ctx, conn, scope, *trustCenter.MailingListID); err != nil {
|
||||
if err := mailingList.LoadByID(ctx, conn, scope, *compliancePage.MailingListID); err != nil {
|
||||
return fmt.Errorf("cannot load mailing list: %w", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ import (
|
||||
"go.gearno.de/kit/log"
|
||||
"go.gearno.de/kit/pg"
|
||||
"go.probo.inc/probo/packages/emails"
|
||||
"go.probo.inc/probo/pkg/complianceportal"
|
||||
"go.probo.inc/probo/pkg/complianceportal/management"
|
||||
"go.probo.inc/probo/pkg/coredata"
|
||||
"go.probo.inc/probo/pkg/esign"
|
||||
"go.probo.inc/probo/pkg/filemanager"
|
||||
@@ -45,7 +45,7 @@ const NDAConsentText = "By clicking \"Review and sign\", I consent to sign this
|
||||
|
||||
type (
|
||||
// Service is the visitor-facing compliance portal service. It exposes the
|
||||
// public read operations for the trust center and its related resources as
|
||||
// public read operations for the compliance page and its related resources as
|
||||
// methods on a single type.
|
||||
Service struct {
|
||||
pg *pg.Client
|
||||
@@ -61,6 +61,7 @@ type (
|
||||
logger *log.Logger
|
||||
slack *slack.Service
|
||||
resourceAlias *resourcealias.Service
|
||||
management *management.Service
|
||||
}
|
||||
)
|
||||
|
||||
@@ -78,6 +79,7 @@ func NewService(
|
||||
logger *log.Logger,
|
||||
slack *slack.Service,
|
||||
resourceAliasSvc *resourcealias.Service,
|
||||
managementSvc *management.Service,
|
||||
) *Service {
|
||||
svc := &Service{
|
||||
pg: pgClient,
|
||||
@@ -93,6 +95,7 @@ func NewService(
|
||||
logger: logger,
|
||||
slack: slack,
|
||||
resourceAlias: resourceAliasSvc,
|
||||
management: managementSvc,
|
||||
}
|
||||
|
||||
return svc
|
||||
@@ -102,18 +105,18 @@ func (s *Service) GetPortalByID(
|
||||
ctx context.Context,
|
||||
id gid.GID,
|
||||
) (*coredata.TrustCenter, error) {
|
||||
trustCenter := &coredata.TrustCenter{}
|
||||
compliancePage := &coredata.TrustCenter{}
|
||||
|
||||
err := s.pg.WithConn(
|
||||
ctx,
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
err := trustCenter.LoadByID(ctx, conn, coredata.NewNoScope(), id)
|
||||
err := compliancePage.LoadByID(ctx, conn, coredata.NewNoScope(), id)
|
||||
if err != nil {
|
||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||
return ErrPageNotFound
|
||||
}
|
||||
|
||||
return fmt.Errorf("cannot load trust center: %w", err)
|
||||
return fmt.Errorf("cannot load compliance page: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -123,25 +126,25 @@ func (s *Service) GetPortalByID(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return trustCenter, nil
|
||||
return compliancePage, nil
|
||||
}
|
||||
|
||||
func (s *Service) GetPortalBySlug(
|
||||
ctx context.Context,
|
||||
slug string,
|
||||
) (*coredata.TrustCenter, error) {
|
||||
trustCenter := &coredata.TrustCenter{}
|
||||
compliancePage := &coredata.TrustCenter{}
|
||||
|
||||
err := s.pg.WithConn(
|
||||
ctx,
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
err := trustCenter.LoadBySlug(ctx, conn, slug)
|
||||
err := compliancePage.LoadBySlug(ctx, conn, slug)
|
||||
if err != nil {
|
||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||
return ErrPageNotFound
|
||||
}
|
||||
|
||||
return fmt.Errorf("cannot load trust center: %w", err)
|
||||
return fmt.Errorf("cannot load compliance page: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -151,25 +154,25 @@ func (s *Service) GetPortalBySlug(
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return trustCenter, nil
|
||||
return compliancePage, nil
|
||||
}
|
||||
|
||||
// GetEffectiveCanonicalHost returns the host a compliance page should be
|
||||
// served under. It prefers the primary domain when its certificate is active,
|
||||
// and otherwise falls back to the managed probopage subdomain. An empty string
|
||||
// is returned when no serving host can be determined.
|
||||
func (s *Service) GetPortalEffectiveCanonicalHost(ctx context.Context, trustCenterID gid.GID) (string, error) {
|
||||
func (s *Service) GetPortalEffectiveCanonicalHost(ctx context.Context, compliancePageID gid.GID) (string, error) {
|
||||
var host string
|
||||
|
||||
err := s.pg.WithConn(
|
||||
ctx,
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
trustCenter := &coredata.TrustCenter{}
|
||||
if err := trustCenter.LoadByID(ctx, conn, coredata.NewNoScope(), trustCenterID); err != nil {
|
||||
return fmt.Errorf("cannot load trust center: %w", err)
|
||||
compliancePage := &coredata.TrustCenter{}
|
||||
if err := compliancePage.LoadByID(ctx, conn, coredata.NewNoScope(), compliancePageID); err != nil {
|
||||
return fmt.Errorf("cannot load compliance page: %w", err)
|
||||
}
|
||||
|
||||
domain, err := complianceportal.EffectiveDomainForTrustCenter(ctx, conn, coredata.NewNoScope(), trustCenter)
|
||||
domain, err := s.management.EffectiveDomainForCompliancePage(ctx, conn, coredata.NewNoScope(), compliancePage)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -189,7 +192,7 @@ func (s *Service) GetPortalEffectiveCanonicalHost(ctx context.Context, trustCent
|
||||
}
|
||||
|
||||
func (s *Service) GetPortalByDomainName(ctx context.Context, domain string) (*coredata.TrustCenter, error) {
|
||||
trustCenter := &coredata.TrustCenter{}
|
||||
compliancePage := &coredata.TrustCenter{}
|
||||
|
||||
err := s.pg.WithConn(
|
||||
ctx,
|
||||
@@ -203,13 +206,13 @@ func (s *Service) GetPortalByDomainName(ctx context.Context, domain string) (*co
|
||||
return fmt.Errorf("cannot load custom domain: %w", err)
|
||||
}
|
||||
|
||||
trustCenter = &coredata.TrustCenter{}
|
||||
if err := trustCenter.LoadByDomainID(ctx, conn, customDomain.ID); err != nil {
|
||||
compliancePage = &coredata.TrustCenter{}
|
||||
if err := compliancePage.LoadByDomainID(ctx, conn, customDomain.ID); err != nil {
|
||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||
return ErrPageNotFound
|
||||
}
|
||||
|
||||
return fmt.Errorf("cannot load trust center: %w", err)
|
||||
return fmt.Errorf("cannot load compliance page: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -219,37 +222,37 @@ func (s *Service) GetPortalByDomainName(ctx context.Context, domain string) (*co
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return trustCenter, err
|
||||
return compliancePage, err
|
||||
}
|
||||
|
||||
// GetPortalEmailPresenterConfigByOrganizationID resolves the emails.PresenterConfig for
|
||||
// the trust center that belongs to the given organization. This is used by the
|
||||
// the compliance page that belongs to the given organization. This is used by the
|
||||
// esign certificate worker which needs per-org branding at render time.
|
||||
func (s *Service) GetPortalEmailPresenterConfigByOrganizationID(ctx context.Context, orgID gid.GID) (emails.PresenterConfig, error) {
|
||||
var trustCenter coredata.TrustCenter
|
||||
var compliancePage coredata.TrustCenter
|
||||
|
||||
scope := coredata.NewScopeFromObjectID(orgID)
|
||||
|
||||
err := s.pg.WithConn(
|
||||
ctx,
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
return trustCenter.LoadByOrganizationID(ctx, conn, scope, orgID)
|
||||
return compliancePage.LoadByOrganizationID(ctx, conn, scope, orgID)
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return emails.PresenterConfig{}, fmt.Errorf("cannot load trust center for org %s: %w", orgID, err)
|
||||
return emails.PresenterConfig{}, fmt.Errorf("cannot load compliance page for org %s: %w", orgID, err)
|
||||
}
|
||||
|
||||
return s.GetPortalEmailPresenterConfig(ctx, scope, trustCenter.ID)
|
||||
return s.GetPortalEmailPresenterConfig(ctx, scope, compliancePage.ID)
|
||||
}
|
||||
|
||||
func (s *Service) GetPortalOrganization(
|
||||
ctx context.Context,
|
||||
trustCenterID gid.GID,
|
||||
compliancePageID gid.GID,
|
||||
) (*coredata.Organization, error) {
|
||||
trustCenter, err := s.GetPortalByID(ctx, trustCenterID)
|
||||
compliancePage, err := s.GetPortalByID(ctx, compliancePageID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot load trust center: %w", err)
|
||||
return nil, fmt.Errorf("cannot load compliance page: %w", err)
|
||||
}
|
||||
|
||||
org := &coredata.Organization{}
|
||||
@@ -257,7 +260,7 @@ func (s *Service) GetPortalOrganization(
|
||||
err = s.pg.WithConn(
|
||||
ctx,
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
return org.LoadByID(ctx, conn, coredata.NewNoScope(), trustCenter.OrganizationID)
|
||||
return org.LoadByID(ctx, conn, coredata.NewNoScope(), compliancePage.OrganizationID)
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
@@ -305,17 +308,17 @@ func (s *Service) GetPortalNDAFileByID(
|
||||
err := s.pg.WithConn(
|
||||
ctx,
|
||||
func(ctx context.Context, conn pg.Querier) error {
|
||||
trustCenter := &coredata.TrustCenter{}
|
||||
if err := trustCenter.LoadByID(ctx, conn, scope, compliancePageID); err != nil {
|
||||
return fmt.Errorf("cannot load trust center: %w", err)
|
||||
compliancePage := &coredata.TrustCenter{}
|
||||
if err := compliancePage.LoadByID(ctx, conn, scope, compliancePageID); err != nil {
|
||||
return fmt.Errorf("cannot load compliance page: %w", err)
|
||||
}
|
||||
|
||||
if trustCenter.NonDisclosureAgreementFileID == nil {
|
||||
if compliancePage.NonDisclosureAgreementFileID == nil {
|
||||
return ErrNDAFileNotFound
|
||||
}
|
||||
|
||||
file = &coredata.File{}
|
||||
if err := file.LoadByID(ctx, conn, scope, *trustCenter.NonDisclosureAgreementFileID); err != nil {
|
||||
if err := file.LoadByID(ctx, conn, scope, *compliancePage.NonDisclosureAgreementFileID); err != nil {
|
||||
if errors.Is(err, coredata.ErrResourceNotFound) {
|
||||
return ErrNDAFileNotFound
|
||||
}
|
||||
@@ -349,7 +352,7 @@ func (s *Service) ProvisionPortalMember(
|
||||
func(ctx context.Context, tx pg.Tx) error {
|
||||
compliancePage := &coredata.TrustCenter{}
|
||||
if err := compliancePage.LoadByID(ctx, tx, scope, compliancePageID); err != nil {
|
||||
return fmt.Errorf("cannot load trust center: %w", err)
|
||||
return fmt.Errorf("cannot load compliance page: %w", err)
|
||||
}
|
||||
|
||||
identity := &coredata.Identity{}
|
||||
@@ -360,7 +363,7 @@ func (s *Service) ProvisionPortalMember(
|
||||
access = &coredata.TrustCenterAccess{}
|
||||
if err := access.LoadByTrustCenterIDAndIdentityID(ctx, tx, scope, compliancePageID, identityID); err != nil {
|
||||
if !errors.Is(err, coredata.ErrResourceNotFound) {
|
||||
return fmt.Errorf("cannot load trust center access: %w", err)
|
||||
return fmt.Errorf("cannot load compliance page access: %w", err)
|
||||
}
|
||||
|
||||
access = &coredata.TrustCenterAccess{
|
||||
@@ -399,7 +402,7 @@ func (s *Service) ProvisionPortalMember(
|
||||
}
|
||||
|
||||
if err := access.Insert(ctx, tx, scope); err != nil {
|
||||
return fmt.Errorf("cannot insert trust center access: %w", err)
|
||||
return fmt.Errorf("cannot insert compliance page access: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ func (s *Service) ListThirdPartiesForOrganizationID(
|
||||
return page.NewPage(thirdParties, cursor), nil
|
||||
}
|
||||
|
||||
func (s *Service) ListDistinctTrustCenterCategoriesForOrganizationID(
|
||||
func (s *Service) ListDistinctPortalCategoriesForOrganizationID(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
organizationID gid.GID,
|
||||
@@ -116,7 +116,7 @@ func (s *Service) ListDistinctTrustCenterCategoriesForOrganizationID(
|
||||
return categories, nil
|
||||
}
|
||||
|
||||
func (s *Service) ListDistinctTrustCenterCountriesForOrganizationID(
|
||||
func (s *Service) ListDistinctPortalCountriesForOrganizationID(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
organizationID gid.GID,
|
||||
@@ -148,7 +148,7 @@ func (s *Service) ListDistinctTrustCenterCountriesForOrganizationID(
|
||||
func (s *Service) CountThirdPartiesForPortalID(
|
||||
ctx context.Context,
|
||||
scope coredata.Scoper,
|
||||
trustCenterID gid.GID,
|
||||
compliancePageID gid.GID,
|
||||
filter *coredata.ThirdPartyFilter,
|
||||
) (int, error) {
|
||||
if filter == nil {
|
||||
@@ -161,14 +161,14 @@ func (s *Service) CountThirdPartiesForPortalID(
|
||||
err := s.pg.WithConn(
|
||||
ctx,
|
||||
func(ctx context.Context, conn pg.Querier) (err error) {
|
||||
trustCenter, err := s.GetPortal(ctx, scope, trustCenterID)
|
||||
compliancePage, err := s.GetPortal(ctx, scope, compliancePageID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot load trust center: %w", err)
|
||||
return fmt.Errorf("cannot load compliance page: %w", err)
|
||||
}
|
||||
|
||||
thirdParties := &coredata.ThirdParties{}
|
||||
|
||||
count, err = thirdParties.CountByOrganizationID(ctx, conn, scope, trustCenter.OrganizationID, filter)
|
||||
count, err = thirdParties.CountByOrganizationID(ctx, conn, scope, compliancePage.OrganizationID, filter)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cannot count thirdParties: %w", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user