@@ -34,6 +34,7 @@ type (
|
|||||||
EmailAddress string `db:"email_address"`
|
EmailAddress string `db:"email_address"`
|
||||||
HashedPassword []byte `db:"hashed_password"`
|
HashedPassword []byte `db:"hashed_password"`
|
||||||
FullName string `db:"fullname"`
|
FullName string `db:"fullname"`
|
||||||
|
EmailAddressVerified bool `db:"email_address_verified"`
|
||||||
CreatedAt time.Time `db:"created_at"`
|
CreatedAt time.Time `db:"created_at"`
|
||||||
UpdatedAt time.Time `db:"updated_at"`
|
UpdatedAt time.Time `db:"updated_at"`
|
||||||
}
|
}
|
||||||
|
|||||||
167
pkg/probo/control_service.go
Normal file
167
pkg/probo/control_service.go
Normal file
@@ -0,0 +1,167 @@
|
|||||||
|
// 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 probo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/getprobo/probo/pkg/coredata"
|
||||||
|
"github.com/getprobo/probo/pkg/gid"
|
||||||
|
"github.com/getprobo/probo/pkg/page"
|
||||||
|
"go.gearno.de/kit/pg"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
ControlService struct {
|
||||||
|
svc *TenantService
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateControlRequest struct {
|
||||||
|
FrameworkID gid.GID
|
||||||
|
Name string
|
||||||
|
Description string
|
||||||
|
ContentRef string
|
||||||
|
Category string
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateControlRequest struct {
|
||||||
|
ID gid.GID
|
||||||
|
ExpectedVersion int
|
||||||
|
Name *string
|
||||||
|
Description *string
|
||||||
|
Category *string
|
||||||
|
State *coredata.ControlState
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s ControlService) Get(
|
||||||
|
ctx context.Context,
|
||||||
|
controlID gid.GID,
|
||||||
|
) (*coredata.Control, error) {
|
||||||
|
control := &coredata.Control{}
|
||||||
|
|
||||||
|
err := s.svc.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return control.LoadByID(ctx, conn, s.svc.scope, controlID)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return control, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s ControlService) Update(
|
||||||
|
ctx context.Context,
|
||||||
|
req UpdateControlRequest,
|
||||||
|
) (*coredata.Control, error) {
|
||||||
|
params := coredata.UpdateControlParams{
|
||||||
|
ExpectedVersion: req.ExpectedVersion,
|
||||||
|
Name: req.Name,
|
||||||
|
Description: req.Description,
|
||||||
|
Category: req.Category,
|
||||||
|
State: req.State,
|
||||||
|
}
|
||||||
|
|
||||||
|
control := &coredata.Control{ID: req.ID}
|
||||||
|
|
||||||
|
err := s.svc.pg.WithTx(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return control.Update(ctx, conn, s.svc.scope, params)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return control, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s ControlService) ListForFrameworkID(
|
||||||
|
ctx context.Context,
|
||||||
|
frameworkID gid.GID,
|
||||||
|
cursor *page.Cursor,
|
||||||
|
) (*page.Page[*coredata.Control], error) {
|
||||||
|
var controls coredata.Controls
|
||||||
|
|
||||||
|
err := s.svc.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return controls.LoadByFrameworkID(
|
||||||
|
ctx,
|
||||||
|
conn,
|
||||||
|
s.svc.scope,
|
||||||
|
frameworkID,
|
||||||
|
cursor,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return page.NewPage(controls, cursor), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s ControlService) Create(
|
||||||
|
ctx context.Context,
|
||||||
|
req CreateControlRequest,
|
||||||
|
) (*coredata.Control, error) {
|
||||||
|
now := time.Now()
|
||||||
|
controlID, err := gid.NewGID(s.svc.scope.GetTenantID(), coredata.ControlEntityType)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot create control global id: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
framework := &coredata.Framework{}
|
||||||
|
control := &coredata.Control{
|
||||||
|
ID: controlID,
|
||||||
|
FrameworkID: req.FrameworkID,
|
||||||
|
Name: req.Name,
|
||||||
|
Description: req.Description,
|
||||||
|
Category: req.Category,
|
||||||
|
State: coredata.ControlStateNotStarted,
|
||||||
|
ContentRef: req.ContentRef,
|
||||||
|
CreatedAt: now,
|
||||||
|
UpdatedAt: now,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.svc.pg.WithTx(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
if err := framework.LoadByID(ctx, conn, s.svc.scope, req.FrameworkID); err != nil {
|
||||||
|
return fmt.Errorf("cannot load framework %q: %w", req.FrameworkID, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := control.Insert(ctx, conn, s.svc.scope); err != nil {
|
||||||
|
return fmt.Errorf("cannot insert control: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return control, nil
|
||||||
|
}
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
CreateControlRequest struct {
|
|
||||||
FrameworkID gid.GID
|
|
||||||
Name string
|
|
||||||
Description string
|
|
||||||
ContentRef string
|
|
||||||
Category string
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Service) CreateControl(
|
|
||||||
ctx context.Context,
|
|
||||||
req CreateControlRequest,
|
|
||||||
) (*coredata.Control, error) {
|
|
||||||
now := time.Now()
|
|
||||||
controlID, err := gid.NewGID(s.scope.GetTenantID(), coredata.ControlEntityType)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("cannot create control global id: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
framework := &coredata.Framework{}
|
|
||||||
control := &coredata.Control{
|
|
||||||
ID: controlID,
|
|
||||||
FrameworkID: req.FrameworkID,
|
|
||||||
Name: req.Name,
|
|
||||||
Description: req.Description,
|
|
||||||
Category: req.Category,
|
|
||||||
State: coredata.ControlStateNotStarted,
|
|
||||||
ContentRef: req.ContentRef,
|
|
||||||
CreatedAt: now,
|
|
||||||
UpdatedAt: now,
|
|
||||||
}
|
|
||||||
|
|
||||||
err = s.pg.WithTx(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
if err := framework.LoadByID(ctx, conn, s.scope, req.FrameworkID); err != nil {
|
|
||||||
return fmt.Errorf("cannot load framework %q: %w", req.FrameworkID, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := control.Insert(ctx, conn, s.scope); err != nil {
|
|
||||||
return fmt.Errorf("cannot insert control: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return control, nil
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
CreateFrameworkRequest struct {
|
|
||||||
OrganizationID gid.GID
|
|
||||||
Name string
|
|
||||||
Description string
|
|
||||||
ContentRef string
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Service) CreateFramework(
|
|
||||||
ctx context.Context,
|
|
||||||
req CreateFrameworkRequest,
|
|
||||||
) (*coredata.Framework, error) {
|
|
||||||
now := time.Now()
|
|
||||||
frameworkID, err := gid.NewGID(s.scope.GetTenantID(), coredata.FrameworkEntityType)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("cannot create global id: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
framework := &coredata.Framework{
|
|
||||||
ID: frameworkID,
|
|
||||||
OrganizationID: req.OrganizationID,
|
|
||||||
Name: req.Name,
|
|
||||||
Description: req.Description,
|
|
||||||
ContentRef: req.ContentRef,
|
|
||||||
CreatedAt: now,
|
|
||||||
UpdatedAt: now,
|
|
||||||
}
|
|
||||||
|
|
||||||
err = s.pg.WithConn(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
return framework.Insert(ctx, conn, s.scope)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return framework, nil
|
|
||||||
}
|
|
||||||
@@ -1,79 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
CreatePeopleRequest struct {
|
|
||||||
OrganizationID gid.GID
|
|
||||||
FullName string
|
|
||||||
PrimaryEmailAddress string
|
|
||||||
AdditionalEmailAddresses []string
|
|
||||||
Kind coredata.PeopleKind
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Service) CreatePeople(
|
|
||||||
ctx context.Context,
|
|
||||||
req CreatePeopleRequest,
|
|
||||||
) (*coredata.People, error) {
|
|
||||||
now := time.Now()
|
|
||||||
peopleID, err := gid.NewGID(s.scope.GetTenantID(), coredata.PeopleEntityType)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("cannot create people global id: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
organization := &coredata.Organization{}
|
|
||||||
people := &coredata.People{
|
|
||||||
ID: peopleID,
|
|
||||||
OrganizationID: req.OrganizationID,
|
|
||||||
Kind: req.Kind,
|
|
||||||
FullName: req.FullName,
|
|
||||||
PrimaryEmailAddress: req.PrimaryEmailAddress,
|
|
||||||
AdditionalEmailAddresses: req.AdditionalEmailAddresses,
|
|
||||||
CreatedAt: now,
|
|
||||||
UpdatedAt: now,
|
|
||||||
}
|
|
||||||
|
|
||||||
err = s.pg.WithTx(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
if err := organization.LoadByID(ctx, conn, s.scope, req.OrganizationID); err != nil {
|
|
||||||
return fmt.Errorf("cannot load organization %q: %w", req.OrganizationID, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := people.Insert(ctx, conn, s.scope); err != nil {
|
|
||||||
return fmt.Errorf("cannot insert people: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return people, nil
|
|
||||||
}
|
|
||||||
@@ -1,78 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
CreateTaskRequest struct {
|
|
||||||
ControlID gid.GID
|
|
||||||
Name string
|
|
||||||
ContentRef string
|
|
||||||
Description string
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Service) CreateTask(
|
|
||||||
ctx context.Context,
|
|
||||||
req CreateTaskRequest,
|
|
||||||
) (*coredata.Task, error) {
|
|
||||||
now := time.Now()
|
|
||||||
taskID, err := gid.NewGID(s.scope.GetTenantID(), coredata.TaskEntityType)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("cannot create task global id: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
control := &coredata.Control{}
|
|
||||||
task := &coredata.Task{
|
|
||||||
ID: taskID,
|
|
||||||
ControlID: req.ControlID,
|
|
||||||
Name: req.Name,
|
|
||||||
ContentRef: req.ContentRef,
|
|
||||||
State: coredata.TaskStateTodo,
|
|
||||||
Description: req.Description,
|
|
||||||
CreatedAt: now,
|
|
||||||
UpdatedAt: now,
|
|
||||||
}
|
|
||||||
|
|
||||||
err = s.pg.WithTx(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
if err := control.LoadByID(ctx, conn, s.scope, req.ControlID); err != nil {
|
|
||||||
return fmt.Errorf("cannot laod control %q: %w", req.ControlID, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := task.Insert(ctx, conn, s.scope); err != nil {
|
|
||||||
return fmt.Errorf("cannot insert task: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return task, nil
|
|
||||||
}
|
|
||||||
@@ -14,76 +14,4 @@
|
|||||||
|
|
||||||
package probo
|
package probo
|
||||||
|
|
||||||
import (
|
type ()
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
type (
|
|
||||||
CreateVendorRequest struct {
|
|
||||||
OrganizationID gid.GID
|
|
||||||
Name string
|
|
||||||
Description string
|
|
||||||
ServiceStartAt time.Time
|
|
||||||
ServiceTerminationAt *time.Time
|
|
||||||
ServiceCriticality coredata.ServiceCriticality
|
|
||||||
RiskTier coredata.RiskTier
|
|
||||||
StatusPageURL *string
|
|
||||||
TermsOfServiceURL *string
|
|
||||||
PrivacyPolicyURL *string
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Service) CreateVendor(
|
|
||||||
ctx context.Context,
|
|
||||||
req CreateVendorRequest,
|
|
||||||
) (*coredata.Vendor, error) {
|
|
||||||
now := time.Now()
|
|
||||||
vendorID, err := gid.NewGID(s.scope.GetTenantID(), coredata.VendorEntityType)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("cannot create vendor global id: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
organization := &coredata.Organization{}
|
|
||||||
vendor := &coredata.Vendor{
|
|
||||||
ID: vendorID,
|
|
||||||
OrganizationID: req.OrganizationID,
|
|
||||||
Name: req.Name,
|
|
||||||
CreatedAt: now,
|
|
||||||
UpdatedAt: now,
|
|
||||||
Description: req.Description,
|
|
||||||
ServiceStartAt: req.ServiceStartAt,
|
|
||||||
ServiceTerminationAt: req.ServiceTerminationAt,
|
|
||||||
ServiceCriticality: req.ServiceCriticality,
|
|
||||||
RiskTier: req.RiskTier,
|
|
||||||
StatusPageURL: req.StatusPageURL,
|
|
||||||
TermsOfServiceURL: req.TermsOfServiceURL,
|
|
||||||
PrivacyPolicyURL: req.PrivacyPolicyURL,
|
|
||||||
}
|
|
||||||
|
|
||||||
err = s.pg.WithTx(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
if err := organization.LoadByID(ctx, conn, s.scope, req.OrganizationID); err != nil {
|
|
||||||
return fmt.Errorf("cannot load organization %q: %w", req.OrganizationID, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := vendor.Insert(ctx, conn, s.scope); err != nil {
|
|
||||||
return fmt.Errorf("cannot insert vendor: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return vendor, nil
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s *Service) DeleteEvidence(
|
|
||||||
ctx context.Context,
|
|
||||||
evidenceID gid.GID,
|
|
||||||
) error {
|
|
||||||
evidence := &coredata.Evidence{ID: evidenceID}
|
|
||||||
|
|
||||||
return s.pg.WithTx(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
if err := evidence.Delete(ctx, conn, s.scope); err != nil {
|
|
||||||
return fmt.Errorf("cannot delete evidence: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Service) DeleteFramework(
|
|
||||||
ctx context.Context,
|
|
||||||
frameworkID gid.GID,
|
|
||||||
) error {
|
|
||||||
framework := &coredata.Framework{ID: frameworkID}
|
|
||||||
|
|
||||||
return s.pg.WithConn(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
return framework.Delete(ctx, conn, s.scope)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Service) DeletePeople(
|
|
||||||
ctx context.Context,
|
|
||||||
peopleID gid.GID,
|
|
||||||
) error {
|
|
||||||
people := coredata.People{ID: peopleID}
|
|
||||||
|
|
||||||
return s.pg.WithConn(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
return people.Delete(ctx, conn, s.scope)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Service) DeleteTask(
|
|
||||||
ctx context.Context,
|
|
||||||
taskID gid.GID,
|
|
||||||
) error {
|
|
||||||
task := coredata.Task{ID: taskID}
|
|
||||||
return s.pg.WithConn(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
return task.Delete(ctx, conn, s.scope)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -1,36 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Service) DeleteVendor(
|
|
||||||
ctx context.Context,
|
|
||||||
vendorID gid.GID,
|
|
||||||
) error {
|
|
||||||
vendor := coredata.Vendor{ID: vendorID}
|
|
||||||
return s.pg.WithConn(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
return vendor.Delete(ctx, conn, s.scope)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
}
|
|
||||||
@@ -26,11 +26,16 @@ import (
|
|||||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
"github.com/getprobo/probo/pkg/coredata"
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
"github.com/getprobo/probo/pkg/gid"
|
||||||
|
"github.com/getprobo/probo/pkg/page"
|
||||||
"go.gearno.de/crypto/uuid"
|
"go.gearno.de/crypto/uuid"
|
||||||
"go.gearno.de/kit/pg"
|
"go.gearno.de/kit/pg"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
EvidenceService struct {
|
||||||
|
svc *TenantService
|
||||||
|
}
|
||||||
|
|
||||||
CreateEvidenceRequest struct {
|
CreateEvidenceRequest struct {
|
||||||
TaskID gid.GID
|
TaskID gid.GID
|
||||||
Name string
|
Name string
|
||||||
@@ -38,12 +43,32 @@ type (
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s Service) CreateEvidence(
|
func (s EvidenceService) Get(
|
||||||
|
ctx context.Context,
|
||||||
|
evidenceID gid.GID,
|
||||||
|
) (*coredata.Evidence, error) {
|
||||||
|
evidence := &coredata.Evidence{}
|
||||||
|
|
||||||
|
err := s.svc.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return evidence.LoadByID(ctx, conn, s.svc.scope, evidenceID)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return evidence, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s EvidenceService) Create(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req CreateEvidenceRequest,
|
req CreateEvidenceRequest,
|
||||||
) (*coredata.Evidence, error) {
|
) (*coredata.Evidence, error) {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
evidenceID, err := gid.NewGID(s.scope.GetTenantID(), coredata.EvidenceEntityType)
|
evidenceID, err := gid.NewGID(s.svc.scope.GetTenantID(), coredata.EvidenceEntityType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot create evidence global id: %w", err)
|
return nil, fmt.Errorf("cannot create evidence global id: %w", err)
|
||||||
}
|
}
|
||||||
@@ -60,8 +85,8 @@ func (s Service) CreateEvidence(
|
|||||||
return nil, fmt.Errorf("cannot generate object key: %w", err)
|
return nil, fmt.Errorf("cannot generate object key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
putObjectOutput, err := s.s3.PutObject(ctx, &s3.PutObjectInput{
|
putObjectOutput, err := s.svc.s3.PutObject(ctx, &s3.PutObjectInput{
|
||||||
Bucket: aws.String(s.bucket),
|
Bucket: aws.String(s.svc.bucket),
|
||||||
Key: aws.String(objectKey.String()),
|
Key: aws.String(objectKey.String()),
|
||||||
Body: req.File,
|
Body: req.File,
|
||||||
ContentType: aws.String(contentType),
|
ContentType: aws.String(contentType),
|
||||||
@@ -70,8 +95,8 @@ func (s Service) CreateEvidence(
|
|||||||
return nil, fmt.Errorf("cannot upload file to S3: %w", err)
|
return nil, fmt.Errorf("cannot upload file to S3: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
headOutput, err := s.s3.HeadObject(ctx, &s3.HeadObjectInput{
|
headOutput, err := s.svc.s3.HeadObject(ctx, &s3.HeadObjectInput{
|
||||||
Bucket: aws.String(s.bucket),
|
Bucket: aws.String(s.svc.bucket),
|
||||||
Key: aws.String(objectKey.String()),
|
Key: aws.String(objectKey.String()),
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -93,14 +118,14 @@ func (s Service) CreateEvidence(
|
|||||||
UpdatedAt: now,
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.pg.WithTx(
|
err = s.svc.pg.WithTx(
|
||||||
ctx,
|
ctx,
|
||||||
func(conn pg.Conn) error {
|
func(conn pg.Conn) error {
|
||||||
if err := task.LoadByID(ctx, conn, s.scope, req.TaskID); err != nil {
|
if err := task.LoadByID(ctx, conn, s.svc.scope, req.TaskID); err != nil {
|
||||||
return fmt.Errorf("cannot load task %q: %w", req.TaskID, err)
|
return fmt.Errorf("cannot load task %q: %w", req.TaskID, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := evidence.Insert(ctx, conn, s.scope); err != nil {
|
if err := evidence.Insert(ctx, conn, s.svc.scope); err != nil {
|
||||||
return fmt.Errorf("cannot insert evidence: %w", err)
|
return fmt.Errorf("cannot insert evidence: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,3 +140,75 @@ func (s Service) CreateEvidence(
|
|||||||
|
|
||||||
return evidence, nil
|
return evidence, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s EvidenceService) GenerateFileURL(
|
||||||
|
ctx context.Context,
|
||||||
|
evidenceID gid.GID,
|
||||||
|
expiresIn time.Duration,
|
||||||
|
) (*string, error) {
|
||||||
|
evidence, err := s.Get(ctx, evidenceID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot get evidence: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
presignClient := s3.NewPresignClient(s.svc.s3)
|
||||||
|
|
||||||
|
presignedReq, err := presignClient.PresignGetObject(ctx, &s3.GetObjectInput{
|
||||||
|
Bucket: aws.String(s.svc.bucket),
|
||||||
|
Key: aws.String(evidence.ObjectKey),
|
||||||
|
ResponseContentType: aws.String(evidence.MimeType),
|
||||||
|
ResponseContentDisposition: aws.String(fmt.Sprintf("attachment; filename=\"%s\"", evidence.Filename)),
|
||||||
|
}, func(opts *s3.PresignOptions) {
|
||||||
|
opts.Expires = expiresIn
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot presign GetObject request: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &presignedReq.URL, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s EvidenceService) ListForTaskID(
|
||||||
|
ctx context.Context,
|
||||||
|
taskID gid.GID,
|
||||||
|
cursor *page.Cursor,
|
||||||
|
) (*page.Page[*coredata.Evidence], error) {
|
||||||
|
var evidences coredata.Evidences
|
||||||
|
|
||||||
|
err := s.svc.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return evidences.LoadByTaskID(
|
||||||
|
ctx,
|
||||||
|
conn,
|
||||||
|
s.svc.scope,
|
||||||
|
taskID,
|
||||||
|
cursor,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return page.NewPage(evidences, cursor), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *EvidenceService) Delete(
|
||||||
|
ctx context.Context,
|
||||||
|
evidenceID gid.GID,
|
||||||
|
) error {
|
||||||
|
evidence := &coredata.Evidence{ID: evidenceID}
|
||||||
|
|
||||||
|
return s.svc.pg.WithTx(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
if err := evidence.Delete(ctx, conn, s.svc.scope); err != nil {
|
||||||
|
return fmt.Errorf("cannot delete evidence: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
165
pkg/probo/framework_service.go
Normal file
165
pkg/probo/framework_service.go
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
// 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 probo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/getprobo/probo/pkg/coredata"
|
||||||
|
"github.com/getprobo/probo/pkg/gid"
|
||||||
|
"github.com/getprobo/probo/pkg/page"
|
||||||
|
"go.gearno.de/kit/pg"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
FrameworkService struct {
|
||||||
|
svc *TenantService
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateFrameworkRequest struct {
|
||||||
|
OrganizationID gid.GID
|
||||||
|
Name string
|
||||||
|
Description string
|
||||||
|
ContentRef string
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateFrameworkRequest struct {
|
||||||
|
ID gid.GID
|
||||||
|
ExpectedVersion int
|
||||||
|
Name *string
|
||||||
|
Description *string
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s FrameworkService) Create(
|
||||||
|
ctx context.Context,
|
||||||
|
req CreateFrameworkRequest,
|
||||||
|
) (*coredata.Framework, error) {
|
||||||
|
now := time.Now()
|
||||||
|
frameworkID, err := gid.NewGID(s.svc.scope.GetTenantID(), coredata.FrameworkEntityType)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot create global id: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
framework := &coredata.Framework{
|
||||||
|
ID: frameworkID,
|
||||||
|
OrganizationID: req.OrganizationID,
|
||||||
|
Name: req.Name,
|
||||||
|
Description: req.Description,
|
||||||
|
ContentRef: req.ContentRef,
|
||||||
|
CreatedAt: now,
|
||||||
|
UpdatedAt: now,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.svc.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return framework.Insert(ctx, conn, s.svc.scope)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return framework, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s FrameworkService) ListForOrganizationID(
|
||||||
|
ctx context.Context,
|
||||||
|
organizationID gid.GID,
|
||||||
|
cursor *page.Cursor,
|
||||||
|
) (*page.Page[*coredata.Framework], error) {
|
||||||
|
var frameworks coredata.Frameworks
|
||||||
|
|
||||||
|
err := s.svc.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return frameworks.LoadByOrganizationID(
|
||||||
|
ctx,
|
||||||
|
conn,
|
||||||
|
s.svc.scope,
|
||||||
|
organizationID,
|
||||||
|
cursor,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return page.NewPage(frameworks, cursor), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s FrameworkService) Get(
|
||||||
|
ctx context.Context,
|
||||||
|
frameworkID gid.GID,
|
||||||
|
) (*coredata.Framework, error) {
|
||||||
|
framework := &coredata.Framework{}
|
||||||
|
|
||||||
|
err := s.svc.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return framework.LoadByID(ctx, conn, s.svc.scope, frameworkID)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return framework, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s FrameworkService) Update(
|
||||||
|
ctx context.Context,
|
||||||
|
req UpdateFrameworkRequest,
|
||||||
|
) (*coredata.Framework, error) {
|
||||||
|
params := coredata.UpdateFrameworkParams{
|
||||||
|
ExpectedVersion: req.ExpectedVersion,
|
||||||
|
Name: req.Name,
|
||||||
|
Description: req.Description,
|
||||||
|
}
|
||||||
|
|
||||||
|
framework := &coredata.Framework{ID: req.ID}
|
||||||
|
|
||||||
|
err := s.svc.pg.WithTx(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return framework.Update(ctx, conn, s.svc.scope, params)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return framework, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s FrameworkService) Delete(
|
||||||
|
ctx context.Context,
|
||||||
|
frameworkID gid.GID,
|
||||||
|
) error {
|
||||||
|
framework := &coredata.Framework{ID: frameworkID}
|
||||||
|
|
||||||
|
return s.svc.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return framework.Delete(ctx, conn, s.svc.scope)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Service) GetControl(
|
|
||||||
ctx context.Context,
|
|
||||||
controlID gid.GID,
|
|
||||||
) (*coredata.Control, error) {
|
|
||||||
control := &coredata.Control{}
|
|
||||||
|
|
||||||
err := s.pg.WithConn(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
return control.LoadByID(ctx, conn, s.scope, controlID)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return control, nil
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Service) GetEvidence(
|
|
||||||
ctx context.Context,
|
|
||||||
evidenceID gid.GID,
|
|
||||||
) (*coredata.Evidence, error) {
|
|
||||||
evidence := &coredata.Evidence{}
|
|
||||||
|
|
||||||
err := s.pg.WithConn(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
return evidence.LoadByID(ctx, conn, s.scope, evidenceID)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return evidence, nil
|
|
||||||
}
|
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/aws/aws-sdk-go-v2/aws"
|
|
||||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Service) GetEvidenceFileURL(
|
|
||||||
ctx context.Context,
|
|
||||||
evidenceID gid.GID,
|
|
||||||
expiresIn time.Duration,
|
|
||||||
) (*string, error) {
|
|
||||||
evidence, err := s.GetEvidence(ctx, evidenceID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("cannot get evidence: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
presignClient := s3.NewPresignClient(s.s3)
|
|
||||||
|
|
||||||
presignedReq, err := presignClient.PresignGetObject(ctx, &s3.GetObjectInput{
|
|
||||||
Bucket: aws.String(s.bucket),
|
|
||||||
Key: aws.String(evidence.ObjectKey),
|
|
||||||
ResponseContentType: aws.String(evidence.MimeType),
|
|
||||||
ResponseContentDisposition: aws.String(fmt.Sprintf("attachment; filename=\"%s\"", evidence.Filename)),
|
|
||||||
}, func(opts *s3.PresignOptions) {
|
|
||||||
opts.Expires = expiresIn
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("cannot presign GetObject request: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &presignedReq.URL, nil
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Service) GetFramework(
|
|
||||||
ctx context.Context,
|
|
||||||
frameworkID gid.GID,
|
|
||||||
) (*coredata.Framework, error) {
|
|
||||||
framework := &coredata.Framework{}
|
|
||||||
|
|
||||||
err := s.pg.WithConn(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
return framework.LoadByID(ctx, conn, s.scope, frameworkID)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return framework, nil
|
|
||||||
}
|
|
||||||
@@ -1,48 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Service) GetOrganization(
|
|
||||||
ctx context.Context,
|
|
||||||
organizationID gid.GID,
|
|
||||||
) (*coredata.Organization, error) {
|
|
||||||
organization := &coredata.Organization{}
|
|
||||||
|
|
||||||
err := s.pg.WithConn(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
return organization.LoadByID(
|
|
||||||
ctx,
|
|
||||||
conn,
|
|
||||||
s.scope,
|
|
||||||
organizationID,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return organization, nil
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Service) GetPeople(
|
|
||||||
ctx context.Context,
|
|
||||||
peopleID gid.GID,
|
|
||||||
) (*coredata.People, error) {
|
|
||||||
people := &coredata.People{}
|
|
||||||
|
|
||||||
err := s.pg.WithConn(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
return people.LoadByID(ctx, conn, s.scope, peopleID)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return people, nil
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Service) GetTask(
|
|
||||||
ctx context.Context,
|
|
||||||
taskID gid.GID,
|
|
||||||
) (*coredata.Task, error) {
|
|
||||||
task := &coredata.Task{}
|
|
||||||
|
|
||||||
err := s.pg.WithConn(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
return task.LoadByID(ctx, conn, s.scope, taskID)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return task, nil
|
|
||||||
}
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Service) GetVendor(
|
|
||||||
ctx context.Context,
|
|
||||||
vendorID gid.GID,
|
|
||||||
) (*coredata.Vendor, error) {
|
|
||||||
vendor := &coredata.Vendor{}
|
|
||||||
|
|
||||||
err := s.pg.WithConn(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
return vendor.LoadByID(ctx, conn, s.scope, vendorID)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return vendor, nil
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"github.com/getprobo/probo/pkg/page"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Service) ListControlTasks(
|
|
||||||
ctx context.Context,
|
|
||||||
controlID gid.GID,
|
|
||||||
cursor *page.Cursor,
|
|
||||||
) (*page.Page[*coredata.Task], error) {
|
|
||||||
var tasks coredata.Tasks
|
|
||||||
|
|
||||||
err := s.pg.WithConn(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
return tasks.LoadByControlID(
|
|
||||||
ctx,
|
|
||||||
conn,
|
|
||||||
s.scope,
|
|
||||||
controlID,
|
|
||||||
cursor,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return page.NewPage(tasks, cursor), nil
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"github.com/getprobo/probo/pkg/page"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Service) ListFrameworkControls(
|
|
||||||
ctx context.Context,
|
|
||||||
frameworkID gid.GID,
|
|
||||||
cursor *page.Cursor,
|
|
||||||
) (*page.Page[*coredata.Control], error) {
|
|
||||||
var controls coredata.Controls
|
|
||||||
|
|
||||||
err := s.pg.WithConn(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
return controls.LoadByFrameworkID(
|
|
||||||
ctx,
|
|
||||||
conn,
|
|
||||||
s.scope,
|
|
||||||
frameworkID,
|
|
||||||
cursor,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return page.NewPage(controls, cursor), nil
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"github.com/getprobo/probo/pkg/page"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Service) ListOrganizationFrameworks(
|
|
||||||
ctx context.Context,
|
|
||||||
organizationID gid.GID,
|
|
||||||
cursor *page.Cursor,
|
|
||||||
) (*page.Page[*coredata.Framework], error) {
|
|
||||||
var frameworks coredata.Frameworks
|
|
||||||
|
|
||||||
err := s.pg.WithConn(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
return frameworks.LoadByOrganizationID(
|
|
||||||
ctx,
|
|
||||||
conn,
|
|
||||||
s.scope,
|
|
||||||
organizationID,
|
|
||||||
cursor,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return page.NewPage(frameworks, cursor), nil
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"github.com/getprobo/probo/pkg/page"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Service) ListOrganizationPeoples(
|
|
||||||
ctx context.Context,
|
|
||||||
organizationID gid.GID,
|
|
||||||
cursor *page.Cursor,
|
|
||||||
) (*page.Page[*coredata.People], error) {
|
|
||||||
var peoples coredata.Peoples
|
|
||||||
|
|
||||||
err := s.pg.WithConn(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
return peoples.LoadByOrganizationID(
|
|
||||||
ctx,
|
|
||||||
conn,
|
|
||||||
s.scope,
|
|
||||||
organizationID,
|
|
||||||
cursor,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return page.NewPage(peoples, cursor), nil
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"github.com/getprobo/probo/pkg/page"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Service) ListOrganizationVendors(
|
|
||||||
ctx context.Context,
|
|
||||||
organizationID gid.GID,
|
|
||||||
cursor *page.Cursor,
|
|
||||||
) (*page.Page[*coredata.Vendor], error) {
|
|
||||||
var vendors coredata.Vendors
|
|
||||||
|
|
||||||
err := s.pg.WithConn(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
return vendors.LoadByOrganizationID(
|
|
||||||
ctx,
|
|
||||||
conn,
|
|
||||||
s.scope,
|
|
||||||
organizationID,
|
|
||||||
cursor,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return page.NewPage(vendors, cursor), nil
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"github.com/getprobo/probo/pkg/page"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (s Service) ListTaskEvidences(
|
|
||||||
ctx context.Context,
|
|
||||||
taskID gid.GID,
|
|
||||||
cursor *page.Cursor,
|
|
||||||
) (*page.Page[*coredata.Evidence], error) {
|
|
||||||
var evidences coredata.Evidences
|
|
||||||
|
|
||||||
err := s.pg.WithConn(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
return evidences.LoadByTaskID(
|
|
||||||
ctx,
|
|
||||||
conn,
|
|
||||||
s.scope,
|
|
||||||
taskID,
|
|
||||||
cursor,
|
|
||||||
)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return page.NewPage(evidences, cursor), nil
|
|
||||||
}
|
|
||||||
@@ -25,32 +25,34 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
OrganizationService struct {
|
||||||
|
svc *TenantService
|
||||||
|
}
|
||||||
|
|
||||||
CreateOrganizationRequest struct {
|
CreateOrganizationRequest struct {
|
||||||
Name string
|
Name string
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (s Service) CreateOrganization(
|
func (s OrganizationService) Create(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
req CreateOrganizationRequest,
|
req CreateOrganizationRequest,
|
||||||
) (*coredata.Organization, error) {
|
) (*coredata.Organization, error) {
|
||||||
tenantID := gid.NewTenantID()
|
|
||||||
|
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
organizationID, err := gid.NewGID(tenantID, coredata.OrganizationEntityType)
|
organizationID, err := gid.NewGID(s.svc.scope.GetTenantID(), coredata.OrganizationEntityType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot create organization global id: %w", err)
|
return nil, fmt.Errorf("cannot create organization global id: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
organization := &coredata.Organization{
|
organization := &coredata.Organization{
|
||||||
ID: organizationID,
|
ID: organizationID,
|
||||||
TenantID: tenantID,
|
TenantID: s.svc.scope.GetTenantID(),
|
||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
CreatedAt: now,
|
CreatedAt: now,
|
||||||
UpdatedAt: now,
|
UpdatedAt: now,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = s.pg.WithConn(
|
err = s.svc.pg.WithConn(
|
||||||
ctx,
|
ctx,
|
||||||
func(conn pg.Conn) error {
|
func(conn pg.Conn) error {
|
||||||
if err := organization.Insert(ctx, conn); err != nil {
|
if err := organization.Insert(ctx, conn); err != nil {
|
||||||
@@ -67,3 +69,28 @@ func (s Service) CreateOrganization(
|
|||||||
|
|
||||||
return organization, nil
|
return organization, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s OrganizationService) Get(
|
||||||
|
ctx context.Context,
|
||||||
|
organizationID gid.GID,
|
||||||
|
) (*coredata.Organization, error) {
|
||||||
|
organization := &coredata.Organization{}
|
||||||
|
|
||||||
|
err := s.svc.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return organization.LoadByID(
|
||||||
|
ctx,
|
||||||
|
conn,
|
||||||
|
s.svc.scope,
|
||||||
|
organizationID,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return organization, nil
|
||||||
|
}
|
||||||
180
pkg/probo/people_service.go
Normal file
180
pkg/probo/people_service.go
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
// 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 probo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/getprobo/probo/pkg/coredata"
|
||||||
|
"github.com/getprobo/probo/pkg/gid"
|
||||||
|
"github.com/getprobo/probo/pkg/page"
|
||||||
|
"go.gearno.de/kit/pg"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
PeopleService struct {
|
||||||
|
svc *TenantService
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdatePeopleRequest struct {
|
||||||
|
ID gid.GID
|
||||||
|
ExpectedVersion int
|
||||||
|
Kind *coredata.PeopleKind
|
||||||
|
FullName *string
|
||||||
|
PrimaryEmailAddress *string
|
||||||
|
AdditionalEmailAddresses *[]string
|
||||||
|
}
|
||||||
|
|
||||||
|
CreatePeopleRequest struct {
|
||||||
|
OrganizationID gid.GID
|
||||||
|
FullName string
|
||||||
|
PrimaryEmailAddress string
|
||||||
|
AdditionalEmailAddresses []string
|
||||||
|
Kind coredata.PeopleKind
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s PeopleService) Get(
|
||||||
|
ctx context.Context,
|
||||||
|
peopleID gid.GID,
|
||||||
|
) (*coredata.People, error) {
|
||||||
|
people := &coredata.People{}
|
||||||
|
|
||||||
|
err := s.svc.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return people.LoadByID(ctx, conn, s.svc.scope, peopleID)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return people, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s PeopleService) ListForOrganizationID(
|
||||||
|
ctx context.Context,
|
||||||
|
organizationID gid.GID,
|
||||||
|
cursor *page.Cursor,
|
||||||
|
) (*page.Page[*coredata.People], error) {
|
||||||
|
var peoples coredata.Peoples
|
||||||
|
|
||||||
|
err := s.svc.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return peoples.LoadByOrganizationID(
|
||||||
|
ctx,
|
||||||
|
conn,
|
||||||
|
s.svc.scope,
|
||||||
|
organizationID,
|
||||||
|
cursor,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return page.NewPage(peoples, cursor), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s PeopleService) Update(
|
||||||
|
ctx context.Context,
|
||||||
|
req UpdatePeopleRequest,
|
||||||
|
) (*coredata.People, error) {
|
||||||
|
params := coredata.UpdatePeopleParams{
|
||||||
|
ExpectedVersion: req.ExpectedVersion,
|
||||||
|
Kind: req.Kind,
|
||||||
|
FullName: req.FullName,
|
||||||
|
PrimaryEmailAddress: req.PrimaryEmailAddress,
|
||||||
|
AdditionalEmailAddresses: req.AdditionalEmailAddresses,
|
||||||
|
}
|
||||||
|
|
||||||
|
people := &coredata.People{ID: req.ID}
|
||||||
|
|
||||||
|
err := s.svc.pg.WithTx(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return people.Update(ctx, conn, s.svc.scope, params)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return people, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s PeopleService) Create(
|
||||||
|
ctx context.Context,
|
||||||
|
req CreatePeopleRequest,
|
||||||
|
) (*coredata.People, error) {
|
||||||
|
now := time.Now()
|
||||||
|
peopleID, err := gid.NewGID(s.svc.scope.GetTenantID(), coredata.PeopleEntityType)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot create people global id: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
organization := &coredata.Organization{}
|
||||||
|
people := &coredata.People{
|
||||||
|
ID: peopleID,
|
||||||
|
OrganizationID: req.OrganizationID,
|
||||||
|
Kind: req.Kind,
|
||||||
|
FullName: req.FullName,
|
||||||
|
PrimaryEmailAddress: req.PrimaryEmailAddress,
|
||||||
|
AdditionalEmailAddresses: req.AdditionalEmailAddresses,
|
||||||
|
CreatedAt: now,
|
||||||
|
UpdatedAt: now,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.svc.pg.WithTx(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
if err := organization.LoadByID(ctx, conn, s.svc.scope, req.OrganizationID); err != nil {
|
||||||
|
return fmt.Errorf("cannot load organization %q: %w", req.OrganizationID, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := people.Insert(ctx, conn, s.svc.scope); err != nil {
|
||||||
|
return fmt.Errorf("cannot insert people: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return people, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s PeopleService) Delete(
|
||||||
|
ctx context.Context,
|
||||||
|
peopleID gid.GID,
|
||||||
|
) error {
|
||||||
|
people := coredata.People{ID: peopleID}
|
||||||
|
|
||||||
|
return s.svc.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return people.Delete(ctx, conn, s.svc.scope)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -12,7 +12,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type PolicyService struct {
|
type PolicyService struct {
|
||||||
svc *Service
|
svc *TenantService
|
||||||
}
|
}
|
||||||
|
|
||||||
type (
|
type (
|
||||||
@@ -142,7 +142,7 @@ func (s *PolicyService) Delete(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *PolicyService) ListByOrganization(
|
func (s *PolicyService) ListByOrganizationID(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
organizationID gid.GID,
|
organizationID gid.GID,
|
||||||
cursor *page.Cursor,
|
cursor *page.Cursor,
|
||||||
|
|||||||
@@ -29,9 +29,23 @@ type (
|
|||||||
pg *pg.Client
|
pg *pg.Client
|
||||||
s3 *s3.Client
|
s3 *s3.Client
|
||||||
bucket string
|
bucket string
|
||||||
|
}
|
||||||
|
|
||||||
|
TenantService struct {
|
||||||
|
pg *pg.Client
|
||||||
|
s3 *s3.Client
|
||||||
|
bucket string
|
||||||
|
|
||||||
scope coredata.Scoper
|
scope coredata.Scoper
|
||||||
|
|
||||||
Policies *PolicyService
|
Policies *PolicyService
|
||||||
|
Controls *ControlService
|
||||||
|
Evidences *EvidenceService
|
||||||
|
Frameworks *FrameworkService
|
||||||
|
Tasks *TaskService
|
||||||
|
Peoples *PeopleService
|
||||||
|
Organizations *OrganizationService
|
||||||
|
Vendors *VendorService
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -49,23 +63,27 @@ func NewService(
|
|||||||
pg: pgClient,
|
pg: pgClient,
|
||||||
s3: s3Client,
|
s3: s3Client,
|
||||||
bucket: bucket,
|
bucket: bucket,
|
||||||
scope: coredata.NewNoScope(),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
svc.Policies = &PolicyService{svc: svc}
|
|
||||||
|
|
||||||
return svc, nil
|
return svc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) WithTenant(tenantID gid.TenantID) *Service {
|
func (s *Service) WithTenant(tenantID gid.TenantID) *TenantService {
|
||||||
newSvc := &Service{
|
tenantService := &TenantService{
|
||||||
pg: s.pg,
|
pg: s.pg,
|
||||||
s3: s.s3,
|
s3: s.s3,
|
||||||
bucket: s.bucket,
|
bucket: s.bucket,
|
||||||
scope: coredata.NewScope(tenantID),
|
scope: coredata.NewScope(tenantID),
|
||||||
}
|
}
|
||||||
|
|
||||||
newSvc.Policies = &PolicyService{svc: newSvc}
|
tenantService.Policies = &PolicyService{svc: tenantService}
|
||||||
|
tenantService.Controls = &ControlService{svc: tenantService}
|
||||||
|
tenantService.Evidences = &EvidenceService{svc: tenantService}
|
||||||
|
tenantService.Frameworks = &FrameworkService{svc: tenantService}
|
||||||
|
tenantService.Tasks = &TaskService{svc: tenantService}
|
||||||
|
tenantService.Peoples = &PeopleService{svc: tenantService}
|
||||||
|
tenantService.Organizations = &OrganizationService{svc: tenantService}
|
||||||
|
tenantService.Vendors = &VendorService{svc: tenantService}
|
||||||
|
|
||||||
return newSvc
|
return tenantService
|
||||||
}
|
}
|
||||||
|
|||||||
176
pkg/probo/task_service.go
Normal file
176
pkg/probo/task_service.go
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
// 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 probo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/getprobo/probo/pkg/coredata"
|
||||||
|
"github.com/getprobo/probo/pkg/gid"
|
||||||
|
"github.com/getprobo/probo/pkg/page"
|
||||||
|
"go.gearno.de/kit/pg"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
TaskService struct {
|
||||||
|
svc *TenantService
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateTaskRequest struct {
|
||||||
|
ControlID gid.GID
|
||||||
|
Name string
|
||||||
|
ContentRef string
|
||||||
|
Description string
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateTaskRequest struct {
|
||||||
|
ID gid.GID
|
||||||
|
ExpectedVersion int
|
||||||
|
Name *string
|
||||||
|
Description *string
|
||||||
|
State *coredata.TaskState
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s TaskService) Create(
|
||||||
|
ctx context.Context,
|
||||||
|
req CreateTaskRequest,
|
||||||
|
) (*coredata.Task, error) {
|
||||||
|
now := time.Now()
|
||||||
|
taskID, err := gid.NewGID(s.svc.scope.GetTenantID(), coredata.TaskEntityType)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot create task global id: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
control := &coredata.Control{}
|
||||||
|
task := &coredata.Task{
|
||||||
|
ID: taskID,
|
||||||
|
ControlID: req.ControlID,
|
||||||
|
Name: req.Name,
|
||||||
|
ContentRef: req.ContentRef,
|
||||||
|
State: coredata.TaskStateTodo,
|
||||||
|
Description: req.Description,
|
||||||
|
CreatedAt: now,
|
||||||
|
UpdatedAt: now,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.svc.pg.WithTx(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
if err := control.LoadByID(ctx, conn, s.svc.scope, req.ControlID); err != nil {
|
||||||
|
return fmt.Errorf("cannot laod control %q: %w", req.ControlID, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := task.Insert(ctx, conn, s.svc.scope); err != nil {
|
||||||
|
return fmt.Errorf("cannot insert task: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return task, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s TaskService) Update(
|
||||||
|
ctx context.Context,
|
||||||
|
req UpdateTaskRequest,
|
||||||
|
) (*coredata.Task, error) {
|
||||||
|
params := coredata.UpdateTaskParams{
|
||||||
|
ExpectedVersion: req.ExpectedVersion,
|
||||||
|
Name: req.Name,
|
||||||
|
Description: req.Description,
|
||||||
|
State: req.State,
|
||||||
|
}
|
||||||
|
|
||||||
|
task := &coredata.Task{ID: req.ID}
|
||||||
|
|
||||||
|
err := s.svc.pg.WithTx(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return task.Update(ctx, conn, s.svc.scope, params)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return task, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s TaskService) ListForControlID(
|
||||||
|
ctx context.Context,
|
||||||
|
controlID gid.GID,
|
||||||
|
cursor *page.Cursor,
|
||||||
|
) (*page.Page[*coredata.Task], error) {
|
||||||
|
var tasks coredata.Tasks
|
||||||
|
|
||||||
|
err := s.svc.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return tasks.LoadByControlID(
|
||||||
|
ctx,
|
||||||
|
conn,
|
||||||
|
s.svc.scope,
|
||||||
|
controlID,
|
||||||
|
cursor,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return page.NewPage(tasks, cursor), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s TaskService) Delete(
|
||||||
|
ctx context.Context,
|
||||||
|
taskID gid.GID,
|
||||||
|
) error {
|
||||||
|
task := coredata.Task{ID: taskID}
|
||||||
|
return s.svc.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return task.Delete(ctx, conn, s.svc.scope)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s TaskService) Get(
|
||||||
|
ctx context.Context,
|
||||||
|
taskID gid.GID,
|
||||||
|
) (*coredata.Task, error) {
|
||||||
|
task := &coredata.Task{}
|
||||||
|
|
||||||
|
err := s.svc.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return task.LoadByID(ctx, conn, s.svc.scope, taskID)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return task, nil
|
||||||
|
}
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UpdateControlRequest struct {
|
|
||||||
ID gid.GID
|
|
||||||
ExpectedVersion int
|
|
||||||
Name *string
|
|
||||||
Description *string
|
|
||||||
Category *string
|
|
||||||
State *coredata.ControlState
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Service) UpdateControl(
|
|
||||||
ctx context.Context,
|
|
||||||
req UpdateControlRequest,
|
|
||||||
) (*coredata.Control, error) {
|
|
||||||
params := coredata.UpdateControlParams{
|
|
||||||
ExpectedVersion: req.ExpectedVersion,
|
|
||||||
Name: req.Name,
|
|
||||||
Description: req.Description,
|
|
||||||
Category: req.Category,
|
|
||||||
State: req.State,
|
|
||||||
}
|
|
||||||
|
|
||||||
control := &coredata.Control{ID: req.ID}
|
|
||||||
|
|
||||||
err := s.pg.WithTx(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
return control.Update(ctx, conn, s.scope, params)
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return control, nil
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UpdateFrameworkRequest struct {
|
|
||||||
ID gid.GID
|
|
||||||
ExpectedVersion int
|
|
||||||
Name *string
|
|
||||||
Description *string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Service) UpdateFramework(
|
|
||||||
ctx context.Context,
|
|
||||||
req UpdateFrameworkRequest,
|
|
||||||
) (*coredata.Framework, error) {
|
|
||||||
params := coredata.UpdateFrameworkParams{
|
|
||||||
ExpectedVersion: req.ExpectedVersion,
|
|
||||||
Name: req.Name,
|
|
||||||
Description: req.Description,
|
|
||||||
}
|
|
||||||
|
|
||||||
framework := &coredata.Framework{ID: req.ID}
|
|
||||||
|
|
||||||
err := s.pg.WithTx(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
return framework.Update(ctx, conn, s.scope, params)
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return framework, nil
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UpdatePeopleRequest struct {
|
|
||||||
ID gid.GID
|
|
||||||
ExpectedVersion int
|
|
||||||
Kind *coredata.PeopleKind
|
|
||||||
FullName *string
|
|
||||||
PrimaryEmailAddress *string
|
|
||||||
AdditionalEmailAddresses *[]string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Service) UpdatePeople(
|
|
||||||
ctx context.Context,
|
|
||||||
req UpdatePeopleRequest,
|
|
||||||
) (*coredata.People, error) {
|
|
||||||
params := coredata.UpdatePeopleParams{
|
|
||||||
ExpectedVersion: req.ExpectedVersion,
|
|
||||||
Kind: req.Kind,
|
|
||||||
FullName: req.FullName,
|
|
||||||
PrimaryEmailAddress: req.PrimaryEmailAddress,
|
|
||||||
AdditionalEmailAddresses: req.AdditionalEmailAddresses,
|
|
||||||
}
|
|
||||||
|
|
||||||
people := &coredata.People{ID: req.ID}
|
|
||||||
|
|
||||||
err := s.pg.WithTx(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
return people.Update(ctx, conn, s.scope, params)
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return people, nil
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UpdateTaskRequest struct {
|
|
||||||
ID gid.GID
|
|
||||||
ExpectedVersion int
|
|
||||||
Name *string
|
|
||||||
Description *string
|
|
||||||
State *coredata.TaskState
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Service) UpdateTask(
|
|
||||||
ctx context.Context,
|
|
||||||
req UpdateTaskRequest,
|
|
||||||
) (*coredata.Task, error) {
|
|
||||||
params := coredata.UpdateTaskParams{
|
|
||||||
ExpectedVersion: req.ExpectedVersion,
|
|
||||||
Name: req.Name,
|
|
||||||
Description: req.Description,
|
|
||||||
State: req.State,
|
|
||||||
}
|
|
||||||
|
|
||||||
task := &coredata.Task{ID: req.ID}
|
|
||||||
|
|
||||||
err := s.pg.WithTx(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
return task.Update(ctx, conn, s.scope, params)
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return task, nil
|
|
||||||
}
|
|
||||||
@@ -1,69 +0,0 @@
|
|||||||
// 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 probo
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/getprobo/probo/pkg/coredata"
|
|
||||||
"github.com/getprobo/probo/pkg/gid"
|
|
||||||
"go.gearno.de/kit/pg"
|
|
||||||
)
|
|
||||||
|
|
||||||
type UpdateVendorRequest struct {
|
|
||||||
ID gid.GID
|
|
||||||
ExpectedVersion int
|
|
||||||
Name *string
|
|
||||||
Description *string
|
|
||||||
ServiceStartAt *time.Time
|
|
||||||
ServiceTerminationAt *time.Time
|
|
||||||
ServiceCriticality *coredata.ServiceCriticality
|
|
||||||
RiskTier *coredata.RiskTier
|
|
||||||
StatusPageURL *string
|
|
||||||
TermsOfServiceURL *string
|
|
||||||
PrivacyPolicyURL *string
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s Service) UpdateVendor(
|
|
||||||
ctx context.Context,
|
|
||||||
req UpdateVendorRequest,
|
|
||||||
) (*coredata.Vendor, error) {
|
|
||||||
params := coredata.UpdateVendorParams{
|
|
||||||
ExpectedVersion: req.ExpectedVersion,
|
|
||||||
Name: req.Name,
|
|
||||||
Description: req.Description,
|
|
||||||
ServiceStartAt: req.ServiceStartAt,
|
|
||||||
ServiceTerminationAt: req.ServiceTerminationAt,
|
|
||||||
ServiceCriticality: req.ServiceCriticality,
|
|
||||||
RiskTier: req.RiskTier,
|
|
||||||
StatusPageURL: req.StatusPageURL,
|
|
||||||
TermsOfServiceURL: req.TermsOfServiceURL,
|
|
||||||
PrivacyPolicyURL: req.PrivacyPolicyURL,
|
|
||||||
}
|
|
||||||
|
|
||||||
vendor := &coredata.Vendor{ID: req.ID}
|
|
||||||
|
|
||||||
err := s.pg.WithTx(
|
|
||||||
ctx,
|
|
||||||
func(conn pg.Conn) error {
|
|
||||||
return vendor.Update(ctx, conn, s.scope, params)
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return vendor, nil
|
|
||||||
}
|
|
||||||
199
pkg/probo/vendor_service.go
Normal file
199
pkg/probo/vendor_service.go
Normal file
@@ -0,0 +1,199 @@
|
|||||||
|
// 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 probo
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/getprobo/probo/pkg/coredata"
|
||||||
|
"github.com/getprobo/probo/pkg/gid"
|
||||||
|
"github.com/getprobo/probo/pkg/page"
|
||||||
|
"go.gearno.de/kit/pg"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
VendorService struct {
|
||||||
|
svc *TenantService
|
||||||
|
}
|
||||||
|
|
||||||
|
CreateVendorRequest struct {
|
||||||
|
OrganizationID gid.GID
|
||||||
|
Name string
|
||||||
|
Description string
|
||||||
|
ServiceStartAt time.Time
|
||||||
|
ServiceTerminationAt *time.Time
|
||||||
|
ServiceCriticality coredata.ServiceCriticality
|
||||||
|
RiskTier coredata.RiskTier
|
||||||
|
StatusPageURL *string
|
||||||
|
TermsOfServiceURL *string
|
||||||
|
PrivacyPolicyURL *string
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateVendorRequest struct {
|
||||||
|
ID gid.GID
|
||||||
|
ExpectedVersion int
|
||||||
|
Name *string
|
||||||
|
Description *string
|
||||||
|
ServiceStartAt *time.Time
|
||||||
|
ServiceTerminationAt *time.Time
|
||||||
|
ServiceCriticality *coredata.ServiceCriticality
|
||||||
|
RiskTier *coredata.RiskTier
|
||||||
|
StatusPageURL *string
|
||||||
|
TermsOfServiceURL *string
|
||||||
|
PrivacyPolicyURL *string
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s VendorService) ListForOrganizationID(
|
||||||
|
ctx context.Context,
|
||||||
|
organizationID gid.GID,
|
||||||
|
cursor *page.Cursor,
|
||||||
|
) (*page.Page[*coredata.Vendor], error) {
|
||||||
|
var vendors coredata.Vendors
|
||||||
|
|
||||||
|
err := s.svc.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return vendors.LoadByOrganizationID(
|
||||||
|
ctx,
|
||||||
|
conn,
|
||||||
|
s.svc.scope,
|
||||||
|
organizationID,
|
||||||
|
cursor,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return page.NewPage(vendors, cursor), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s VendorService) Update(
|
||||||
|
ctx context.Context,
|
||||||
|
req UpdateVendorRequest,
|
||||||
|
) (*coredata.Vendor, error) {
|
||||||
|
params := coredata.UpdateVendorParams{
|
||||||
|
ExpectedVersion: req.ExpectedVersion,
|
||||||
|
Name: req.Name,
|
||||||
|
Description: req.Description,
|
||||||
|
ServiceStartAt: req.ServiceStartAt,
|
||||||
|
ServiceTerminationAt: req.ServiceTerminationAt,
|
||||||
|
ServiceCriticality: req.ServiceCriticality,
|
||||||
|
RiskTier: req.RiskTier,
|
||||||
|
StatusPageURL: req.StatusPageURL,
|
||||||
|
TermsOfServiceURL: req.TermsOfServiceURL,
|
||||||
|
PrivacyPolicyURL: req.PrivacyPolicyURL,
|
||||||
|
}
|
||||||
|
|
||||||
|
vendor := &coredata.Vendor{ID: req.ID}
|
||||||
|
|
||||||
|
err := s.svc.pg.WithTx(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return vendor.Update(ctx, conn, s.svc.scope, params)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return vendor, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s VendorService) Get(
|
||||||
|
ctx context.Context,
|
||||||
|
vendorID gid.GID,
|
||||||
|
) (*coredata.Vendor, error) {
|
||||||
|
vendor := &coredata.Vendor{}
|
||||||
|
|
||||||
|
err := s.svc.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return vendor.LoadByID(ctx, conn, s.svc.scope, vendorID)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return vendor, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s VendorService) Delete(
|
||||||
|
ctx context.Context,
|
||||||
|
vendorID gid.GID,
|
||||||
|
) error {
|
||||||
|
vendor := coredata.Vendor{ID: vendorID}
|
||||||
|
return s.svc.pg.WithConn(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
return vendor.Delete(ctx, conn, s.svc.scope)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s VendorService) Create(
|
||||||
|
ctx context.Context,
|
||||||
|
req CreateVendorRequest,
|
||||||
|
) (*coredata.Vendor, error) {
|
||||||
|
now := time.Now()
|
||||||
|
vendorID, err := gid.NewGID(s.svc.scope.GetTenantID(), coredata.VendorEntityType)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("cannot create vendor global id: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
organization := &coredata.Organization{}
|
||||||
|
vendor := &coredata.Vendor{
|
||||||
|
ID: vendorID,
|
||||||
|
OrganizationID: req.OrganizationID,
|
||||||
|
Name: req.Name,
|
||||||
|
CreatedAt: now,
|
||||||
|
UpdatedAt: now,
|
||||||
|
Description: req.Description,
|
||||||
|
ServiceStartAt: req.ServiceStartAt,
|
||||||
|
ServiceTerminationAt: req.ServiceTerminationAt,
|
||||||
|
ServiceCriticality: req.ServiceCriticality,
|
||||||
|
RiskTier: req.RiskTier,
|
||||||
|
StatusPageURL: req.StatusPageURL,
|
||||||
|
TermsOfServiceURL: req.TermsOfServiceURL,
|
||||||
|
PrivacyPolicyURL: req.PrivacyPolicyURL,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = s.svc.pg.WithTx(
|
||||||
|
ctx,
|
||||||
|
func(conn pg.Conn) error {
|
||||||
|
if err := organization.LoadByID(ctx, conn, s.svc.scope, req.OrganizationID); err != nil {
|
||||||
|
return fmt.Errorf("cannot load organization %q: %w", req.OrganizationID, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := vendor.Insert(ctx, conn, s.svc.scope); err != nil {
|
||||||
|
return fmt.Errorf("cannot insert vendor: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return vendor, nil
|
||||||
|
}
|
||||||
@@ -23,7 +23,7 @@ func (r *controlResolver) Tasks(ctx context.Context, obj *types.Control, first *
|
|||||||
svc := r.proboSvc.WithTenant(obj.ID.TenantID())
|
svc := r.proboSvc.WithTenant(obj.ID.TenantID())
|
||||||
cursor := types.NewCursor(first, after, last, before)
|
cursor := types.NewCursor(first, after, last, before)
|
||||||
|
|
||||||
page, err := svc.ListControlTasks(ctx, obj.ID, cursor)
|
page, err := svc.Tasks.ListForControlID(ctx, obj.ID, cursor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot list control tasks: %w", err)
|
return nil, fmt.Errorf("cannot list control tasks: %w", err)
|
||||||
}
|
}
|
||||||
@@ -35,7 +35,7 @@ func (r *controlResolver) Tasks(ctx context.Context, obj *types.Control, first *
|
|||||||
func (r *evidenceResolver) FileURL(ctx context.Context, obj *types.Evidence) (string, error) {
|
func (r *evidenceResolver) FileURL(ctx context.Context, obj *types.Evidence) (string, error) {
|
||||||
svc := r.proboSvc.WithTenant(obj.ID.TenantID())
|
svc := r.proboSvc.WithTenant(obj.ID.TenantID())
|
||||||
|
|
||||||
fileURL, err := svc.GetEvidenceFileURL(ctx, obj.ID, 15*time.Minute)
|
fileURL, err := svc.Evidences.GenerateFileURL(ctx, obj.ID, 15*time.Minute)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", fmt.Errorf("cannot generate file URL: %w", err)
|
return "", fmt.Errorf("cannot generate file URL: %w", err)
|
||||||
}
|
}
|
||||||
@@ -48,7 +48,7 @@ func (r *frameworkResolver) Controls(ctx context.Context, obj *types.Framework,
|
|||||||
svc := r.proboSvc.WithTenant(obj.ID.TenantID())
|
svc := r.proboSvc.WithTenant(obj.ID.TenantID())
|
||||||
cursor := types.NewCursor(first, after, last, before)
|
cursor := types.NewCursor(first, after, last, before)
|
||||||
|
|
||||||
page, err := svc.ListFrameworkControls(ctx, obj.ID, cursor)
|
page, err := svc.Controls.ListForFrameworkID(ctx, obj.ID, cursor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot list framework controls: %w", err)
|
return nil, fmt.Errorf("cannot list framework controls: %w", err)
|
||||||
}
|
}
|
||||||
@@ -60,7 +60,7 @@ func (r *frameworkResolver) Controls(ctx context.Context, obj *types.Framework,
|
|||||||
func (r *mutationResolver) CreateVendor(ctx context.Context, input types.CreateVendorInput) (*types.CreateVendorPayload, error) {
|
func (r *mutationResolver) CreateVendor(ctx context.Context, input types.CreateVendorInput) (*types.CreateVendorPayload, error) {
|
||||||
svc := r.proboSvc.WithTenant(input.OrganizationID.TenantID())
|
svc := r.proboSvc.WithTenant(input.OrganizationID.TenantID())
|
||||||
|
|
||||||
vendor, err := svc.CreateVendor(ctx, probo.CreateVendorRequest{
|
vendor, err := svc.Vendors.Create(ctx, probo.CreateVendorRequest{
|
||||||
OrganizationID: input.OrganizationID,
|
OrganizationID: input.OrganizationID,
|
||||||
Name: input.Name,
|
Name: input.Name,
|
||||||
Description: input.Description,
|
Description: input.Description,
|
||||||
@@ -84,7 +84,7 @@ func (r *mutationResolver) CreateVendor(ctx context.Context, input types.CreateV
|
|||||||
func (r *mutationResolver) UpdateVendor(ctx context.Context, input types.UpdateVendorInput) (*types.UpdateVendorPayload, error) {
|
func (r *mutationResolver) UpdateVendor(ctx context.Context, input types.UpdateVendorInput) (*types.UpdateVendorPayload, error) {
|
||||||
svc := r.proboSvc.WithTenant(input.ID.TenantID())
|
svc := r.proboSvc.WithTenant(input.ID.TenantID())
|
||||||
|
|
||||||
vendor, err := svc.UpdateVendor(ctx, probo.UpdateVendorRequest{
|
vendor, err := svc.Vendors.Update(ctx, probo.UpdateVendorRequest{
|
||||||
ID: input.ID,
|
ID: input.ID,
|
||||||
ExpectedVersion: input.ExpectedVersion,
|
ExpectedVersion: input.ExpectedVersion,
|
||||||
Name: input.Name,
|
Name: input.Name,
|
||||||
@@ -110,7 +110,7 @@ func (r *mutationResolver) UpdateVendor(ctx context.Context, input types.UpdateV
|
|||||||
func (r *mutationResolver) DeleteVendor(ctx context.Context, input types.DeleteVendorInput) (*types.DeleteVendorPayload, error) {
|
func (r *mutationResolver) DeleteVendor(ctx context.Context, input types.DeleteVendorInput) (*types.DeleteVendorPayload, error) {
|
||||||
svc := r.proboSvc.WithTenant(input.VendorID.TenantID())
|
svc := r.proboSvc.WithTenant(input.VendorID.TenantID())
|
||||||
|
|
||||||
err := svc.DeleteVendor(ctx, input.VendorID)
|
err := svc.Vendors.Delete(ctx, input.VendorID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot delete vendor: %w", err)
|
return nil, fmt.Errorf("cannot delete vendor: %w", err)
|
||||||
}
|
}
|
||||||
@@ -124,7 +124,7 @@ func (r *mutationResolver) DeleteVendor(ctx context.Context, input types.DeleteV
|
|||||||
func (r *mutationResolver) CreatePeople(ctx context.Context, input types.CreatePeopleInput) (*types.CreatePeoplePayload, error) {
|
func (r *mutationResolver) CreatePeople(ctx context.Context, input types.CreatePeopleInput) (*types.CreatePeoplePayload, error) {
|
||||||
svc := r.proboSvc.WithTenant(input.OrganizationID.TenantID())
|
svc := r.proboSvc.WithTenant(input.OrganizationID.TenantID())
|
||||||
|
|
||||||
people, err := svc.CreatePeople(ctx, probo.CreatePeopleRequest{
|
people, err := svc.Peoples.Create(ctx, probo.CreatePeopleRequest{
|
||||||
OrganizationID: input.OrganizationID,
|
OrganizationID: input.OrganizationID,
|
||||||
FullName: input.FullName,
|
FullName: input.FullName,
|
||||||
PrimaryEmailAddress: input.PrimaryEmailAddress,
|
PrimaryEmailAddress: input.PrimaryEmailAddress,
|
||||||
@@ -145,7 +145,7 @@ func (r *mutationResolver) CreatePeople(ctx context.Context, input types.CreateP
|
|||||||
func (r *mutationResolver) UpdatePeople(ctx context.Context, input types.UpdatePeopleInput) (*types.UpdatePeoplePayload, error) {
|
func (r *mutationResolver) UpdatePeople(ctx context.Context, input types.UpdatePeopleInput) (*types.UpdatePeoplePayload, error) {
|
||||||
svc := r.proboSvc.WithTenant(input.ID.TenantID())
|
svc := r.proboSvc.WithTenant(input.ID.TenantID())
|
||||||
|
|
||||||
people, err := svc.UpdatePeople(ctx, probo.UpdatePeopleRequest{
|
people, err := svc.Peoples.Update(ctx, probo.UpdatePeopleRequest{
|
||||||
ID: input.ID,
|
ID: input.ID,
|
||||||
ExpectedVersion: input.ExpectedVersion,
|
ExpectedVersion: input.ExpectedVersion,
|
||||||
FullName: input.FullName,
|
FullName: input.FullName,
|
||||||
@@ -166,7 +166,7 @@ func (r *mutationResolver) UpdatePeople(ctx context.Context, input types.UpdateP
|
|||||||
func (r *mutationResolver) DeletePeople(ctx context.Context, input types.DeletePeopleInput) (*types.DeletePeoplePayload, error) {
|
func (r *mutationResolver) DeletePeople(ctx context.Context, input types.DeletePeopleInput) (*types.DeletePeoplePayload, error) {
|
||||||
svc := r.proboSvc.WithTenant(input.PeopleID.TenantID())
|
svc := r.proboSvc.WithTenant(input.PeopleID.TenantID())
|
||||||
|
|
||||||
err := svc.DeletePeople(ctx, input.PeopleID)
|
err := svc.Peoples.Delete(ctx, input.PeopleID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot delete people: %w", err)
|
return nil, fmt.Errorf("cannot delete people: %w", err)
|
||||||
}
|
}
|
||||||
@@ -178,7 +178,9 @@ func (r *mutationResolver) DeletePeople(ctx context.Context, input types.DeleteP
|
|||||||
|
|
||||||
// CreateOrganization is the resolver for the createOrganization field.
|
// CreateOrganization is the resolver for the createOrganization field.
|
||||||
func (r *mutationResolver) CreateOrganization(ctx context.Context, input types.CreateOrganizationInput) (*types.CreateOrganizationPayload, error) {
|
func (r *mutationResolver) CreateOrganization(ctx context.Context, input types.CreateOrganizationInput) (*types.CreateOrganizationPayload, error) {
|
||||||
organization, err := r.proboSvc.CreateOrganization(ctx, probo.CreateOrganizationRequest{
|
svc := r.proboSvc.WithTenant(gid.NewTenantID())
|
||||||
|
|
||||||
|
organization, err := svc.Organizations.Create(ctx, probo.CreateOrganizationRequest{
|
||||||
Name: input.Name,
|
Name: input.Name,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -204,7 +206,7 @@ func (r *mutationResolver) DeleteOrganization(ctx context.Context, input types.D
|
|||||||
func (r *mutationResolver) CreateTask(ctx context.Context, input types.CreateTaskInput) (*types.CreateTaskPayload, error) {
|
func (r *mutationResolver) CreateTask(ctx context.Context, input types.CreateTaskInput) (*types.CreateTaskPayload, error) {
|
||||||
svc := r.proboSvc.WithTenant(input.ControlID.TenantID())
|
svc := r.proboSvc.WithTenant(input.ControlID.TenantID())
|
||||||
|
|
||||||
task, err := svc.CreateTask(ctx, probo.CreateTaskRequest{
|
task, err := svc.Tasks.Create(ctx, probo.CreateTaskRequest{
|
||||||
ControlID: input.ControlID,
|
ControlID: input.ControlID,
|
||||||
Name: input.Name,
|
Name: input.Name,
|
||||||
Description: input.Description,
|
Description: input.Description,
|
||||||
@@ -222,7 +224,7 @@ func (r *mutationResolver) CreateTask(ctx context.Context, input types.CreateTas
|
|||||||
func (r *mutationResolver) UpdateTask(ctx context.Context, input types.UpdateTaskInput) (*types.UpdateTaskPayload, error) {
|
func (r *mutationResolver) UpdateTask(ctx context.Context, input types.UpdateTaskInput) (*types.UpdateTaskPayload, error) {
|
||||||
svc := r.proboSvc.WithTenant(input.TaskID.TenantID())
|
svc := r.proboSvc.WithTenant(input.TaskID.TenantID())
|
||||||
|
|
||||||
task, err := svc.UpdateTask(ctx, probo.UpdateTaskRequest{
|
task, err := svc.Tasks.Update(ctx, probo.UpdateTaskRequest{
|
||||||
ID: input.TaskID,
|
ID: input.TaskID,
|
||||||
ExpectedVersion: input.ExpectedVersion,
|
ExpectedVersion: input.ExpectedVersion,
|
||||||
Name: input.Name,
|
Name: input.Name,
|
||||||
@@ -242,7 +244,7 @@ func (r *mutationResolver) UpdateTask(ctx context.Context, input types.UpdateTas
|
|||||||
func (r *mutationResolver) DeleteTask(ctx context.Context, input types.DeleteTaskInput) (*types.DeleteTaskPayload, error) {
|
func (r *mutationResolver) DeleteTask(ctx context.Context, input types.DeleteTaskInput) (*types.DeleteTaskPayload, error) {
|
||||||
svc := r.proboSvc.WithTenant(input.TaskID.TenantID())
|
svc := r.proboSvc.WithTenant(input.TaskID.TenantID())
|
||||||
|
|
||||||
err := svc.DeleteTask(ctx, input.TaskID)
|
err := svc.Tasks.Delete(ctx, input.TaskID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot delete task: %w", err)
|
return nil, fmt.Errorf("cannot delete task: %w", err)
|
||||||
}
|
}
|
||||||
@@ -256,7 +258,7 @@ func (r *mutationResolver) DeleteTask(ctx context.Context, input types.DeleteTas
|
|||||||
func (r *mutationResolver) CreateFramework(ctx context.Context, input types.CreateFrameworkInput) (*types.CreateFrameworkPayload, error) {
|
func (r *mutationResolver) CreateFramework(ctx context.Context, input types.CreateFrameworkInput) (*types.CreateFrameworkPayload, error) {
|
||||||
svc := r.proboSvc.WithTenant(input.OrganizationID.TenantID())
|
svc := r.proboSvc.WithTenant(input.OrganizationID.TenantID())
|
||||||
|
|
||||||
framework, err := svc.CreateFramework(ctx, probo.CreateFrameworkRequest{
|
framework, err := svc.Frameworks.Create(ctx, probo.CreateFrameworkRequest{
|
||||||
OrganizationID: input.OrganizationID,
|
OrganizationID: input.OrganizationID,
|
||||||
Name: input.Name,
|
Name: input.Name,
|
||||||
Description: input.Description,
|
Description: input.Description,
|
||||||
@@ -274,7 +276,7 @@ func (r *mutationResolver) CreateFramework(ctx context.Context, input types.Crea
|
|||||||
func (r *mutationResolver) CreateControl(ctx context.Context, input types.CreateControlInput) (*types.CreateControlPayload, error) {
|
func (r *mutationResolver) CreateControl(ctx context.Context, input types.CreateControlInput) (*types.CreateControlPayload, error) {
|
||||||
svc := r.proboSvc.WithTenant(input.FrameworkID.TenantID())
|
svc := r.proboSvc.WithTenant(input.FrameworkID.TenantID())
|
||||||
|
|
||||||
control, err := svc.CreateControl(ctx, probo.CreateControlRequest{
|
control, err := svc.Controls.Create(ctx, probo.CreateControlRequest{
|
||||||
FrameworkID: input.FrameworkID,
|
FrameworkID: input.FrameworkID,
|
||||||
Name: input.Name,
|
Name: input.Name,
|
||||||
Description: input.Description,
|
Description: input.Description,
|
||||||
@@ -293,7 +295,7 @@ func (r *mutationResolver) CreateControl(ctx context.Context, input types.Create
|
|||||||
func (r *mutationResolver) UpdateFramework(ctx context.Context, input types.UpdateFrameworkInput) (*types.UpdateFrameworkPayload, error) {
|
func (r *mutationResolver) UpdateFramework(ctx context.Context, input types.UpdateFrameworkInput) (*types.UpdateFrameworkPayload, error) {
|
||||||
svc := r.proboSvc.WithTenant(input.ID.TenantID())
|
svc := r.proboSvc.WithTenant(input.ID.TenantID())
|
||||||
|
|
||||||
framework, err := svc.UpdateFramework(ctx, probo.UpdateFrameworkRequest{
|
framework, err := svc.Frameworks.Update(ctx, probo.UpdateFrameworkRequest{
|
||||||
ID: input.ID,
|
ID: input.ID,
|
||||||
ExpectedVersion: input.ExpectedVersion,
|
ExpectedVersion: input.ExpectedVersion,
|
||||||
Name: input.Name,
|
Name: input.Name,
|
||||||
@@ -312,7 +314,7 @@ func (r *mutationResolver) UpdateFramework(ctx context.Context, input types.Upda
|
|||||||
func (r *mutationResolver) UpdateControl(ctx context.Context, input types.UpdateControlInput) (*types.UpdateControlPayload, error) {
|
func (r *mutationResolver) UpdateControl(ctx context.Context, input types.UpdateControlInput) (*types.UpdateControlPayload, error) {
|
||||||
svc := r.proboSvc.WithTenant(input.ID.TenantID())
|
svc := r.proboSvc.WithTenant(input.ID.TenantID())
|
||||||
|
|
||||||
control, err := svc.UpdateControl(ctx, probo.UpdateControlRequest{
|
control, err := svc.Controls.Update(ctx, probo.UpdateControlRequest{
|
||||||
ID: input.ID,
|
ID: input.ID,
|
||||||
ExpectedVersion: input.ExpectedVersion,
|
ExpectedVersion: input.ExpectedVersion,
|
||||||
Name: input.Name,
|
Name: input.Name,
|
||||||
@@ -339,7 +341,7 @@ func (r *mutationResolver) UploadEvidence(ctx context.Context, input types.Uploa
|
|||||||
File: input.File.File,
|
File: input.File.File,
|
||||||
}
|
}
|
||||||
|
|
||||||
evidence, err := svc.CreateEvidence(ctx, req)
|
evidence, err := svc.Evidences.Create(ctx, req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to create evidence: %w", err)
|
return nil, fmt.Errorf("failed to create evidence: %w", err)
|
||||||
}
|
}
|
||||||
@@ -353,7 +355,7 @@ func (r *mutationResolver) UploadEvidence(ctx context.Context, input types.Uploa
|
|||||||
func (r *mutationResolver) DeleteEvidence(ctx context.Context, input types.DeleteEvidenceInput) (*types.DeleteEvidencePayload, error) {
|
func (r *mutationResolver) DeleteEvidence(ctx context.Context, input types.DeleteEvidenceInput) (*types.DeleteEvidencePayload, error) {
|
||||||
svc := r.proboSvc.WithTenant(input.EvidenceID.TenantID())
|
svc := r.proboSvc.WithTenant(input.EvidenceID.TenantID())
|
||||||
|
|
||||||
err := svc.DeleteEvidence(ctx, input.EvidenceID)
|
err := svc.Evidences.Delete(ctx, input.EvidenceID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to delete evidence: %w", err)
|
return nil, fmt.Errorf("failed to delete evidence: %w", err)
|
||||||
}
|
}
|
||||||
@@ -426,7 +428,7 @@ func (r *organizationResolver) Frameworks(ctx context.Context, obj *types.Organi
|
|||||||
|
|
||||||
cursor := types.NewCursor(first, after, last, before)
|
cursor := types.NewCursor(first, after, last, before)
|
||||||
|
|
||||||
page, err := svc.ListOrganizationFrameworks(ctx, obj.ID, cursor)
|
page, err := svc.Frameworks.ListForOrganizationID(ctx, obj.ID, cursor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot list organization frameworks: %w", err)
|
return nil, fmt.Errorf("cannot list organization frameworks: %w", err)
|
||||||
}
|
}
|
||||||
@@ -440,7 +442,7 @@ func (r *organizationResolver) Vendors(ctx context.Context, obj *types.Organizat
|
|||||||
|
|
||||||
cursor := types.NewCursor(first, after, last, before)
|
cursor := types.NewCursor(first, after, last, before)
|
||||||
|
|
||||||
page, err := svc.ListOrganizationVendors(ctx, obj.ID, cursor)
|
page, err := svc.Vendors.ListForOrganizationID(ctx, obj.ID, cursor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot list organization vendors: %w", err)
|
return nil, fmt.Errorf("cannot list organization vendors: %w", err)
|
||||||
}
|
}
|
||||||
@@ -454,7 +456,7 @@ func (r *organizationResolver) Peoples(ctx context.Context, obj *types.Organizat
|
|||||||
|
|
||||||
cursor := types.NewCursor(first, after, last, before)
|
cursor := types.NewCursor(first, after, last, before)
|
||||||
|
|
||||||
page, err := svc.ListOrganizationPeoples(ctx, obj.ID, cursor)
|
page, err := svc.Peoples.ListForOrganizationID(ctx, obj.ID, cursor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot list organization peoples: %w", err)
|
return nil, fmt.Errorf("cannot list organization peoples: %w", err)
|
||||||
}
|
}
|
||||||
@@ -467,7 +469,7 @@ func (r *organizationResolver) Policies(ctx context.Context, obj *types.Organiza
|
|||||||
svc := r.proboSvc.WithTenant(obj.ID.TenantID())
|
svc := r.proboSvc.WithTenant(obj.ID.TenantID())
|
||||||
cursor := types.NewCursor(first, after, last, before)
|
cursor := types.NewCursor(first, after, last, before)
|
||||||
|
|
||||||
page, err := svc.Policies.ListByOrganization(ctx, obj.ID, cursor)
|
page, err := svc.Policies.ListByOrganizationID(ctx, obj.ID, cursor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot list organization policies: %w", err)
|
return nil, fmt.Errorf("cannot list organization policies: %w", err)
|
||||||
}
|
}
|
||||||
@@ -485,7 +487,7 @@ func (r *policyResolver) Owner(ctx context.Context, obj *types.Policy) (*types.P
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the owner
|
// Get the owner
|
||||||
owner, err := svc.GetPeople(ctx, policy.OwnerID)
|
owner, err := svc.Peoples.Get(ctx, policy.OwnerID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot get owner: %w", err)
|
return nil, fmt.Errorf("cannot get owner: %w", err)
|
||||||
}
|
}
|
||||||
@@ -499,49 +501,49 @@ func (r *queryResolver) Node(ctx context.Context, id gid.GID) (types.Node, error
|
|||||||
|
|
||||||
switch id.EntityType() {
|
switch id.EntityType() {
|
||||||
case coredata.OrganizationEntityType:
|
case coredata.OrganizationEntityType:
|
||||||
organization, err := svc.GetOrganization(ctx, id)
|
organization, err := svc.Organizations.Get(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.NewOrganization(organization), nil
|
return types.NewOrganization(organization), nil
|
||||||
case coredata.PeopleEntityType:
|
case coredata.PeopleEntityType:
|
||||||
people, err := svc.GetPeople(ctx, id)
|
people, err := svc.Peoples.Get(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.NewPeople(people), nil
|
return types.NewPeople(people), nil
|
||||||
case coredata.VendorEntityType:
|
case coredata.VendorEntityType:
|
||||||
vendor, err := svc.GetVendor(ctx, id)
|
vendor, err := svc.Vendors.Get(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.NewVendor(vendor), nil
|
return types.NewVendor(vendor), nil
|
||||||
case coredata.FrameworkEntityType:
|
case coredata.FrameworkEntityType:
|
||||||
framework, err := svc.GetFramework(ctx, id)
|
framework, err := svc.Frameworks.Get(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.NewFramework(framework), nil
|
return types.NewFramework(framework), nil
|
||||||
case coredata.ControlEntityType:
|
case coredata.ControlEntityType:
|
||||||
control, err := svc.GetControl(ctx, id)
|
control, err := svc.Controls.Get(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.NewControl(control), nil
|
return types.NewControl(control), nil
|
||||||
case coredata.TaskEntityType:
|
case coredata.TaskEntityType:
|
||||||
task, err := svc.GetTask(ctx, id)
|
task, err := svc.Tasks.Get(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.NewTask(task), nil
|
return types.NewTask(task), nil
|
||||||
case coredata.EvidenceEntityType:
|
case coredata.EvidenceEntityType:
|
||||||
evidence, err := svc.GetEvidence(ctx, id)
|
evidence, err := svc.Evidences.Get(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -570,9 +572,9 @@ func (r *taskResolver) Evidences(ctx context.Context, obj *types.Task, first *in
|
|||||||
svc := r.proboSvc.WithTenant(obj.ID.TenantID())
|
svc := r.proboSvc.WithTenant(obj.ID.TenantID())
|
||||||
cursor := types.NewCursor(first, after, last, before)
|
cursor := types.NewCursor(first, after, last, before)
|
||||||
|
|
||||||
page, err := svc.ListTaskEvidences(ctx, obj.ID, cursor)
|
page, err := svc.Evidences.ListForTaskID(ctx, obj.ID, cursor)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("cannot list organization frameworks: %w", err)
|
return nil, fmt.Errorf("cannot list task evidences: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return types.NewEvidenceConnection(page), nil
|
return types.NewEvidenceConnection(page), nil
|
||||||
@@ -597,7 +599,9 @@ func (r *userResolver) Organizations(ctx context.Context, obj *types.User, first
|
|||||||
// Get the organization details for each organization ID
|
// Get the organization details for each organization ID
|
||||||
var edges []*types.OrganizationEdge
|
var edges []*types.OrganizationEdge
|
||||||
for _, organizationID := range organizationIDs {
|
for _, organizationID := range organizationIDs {
|
||||||
organization, err := r.proboSvc.GetOrganization(ctx, organizationID)
|
svc := r.proboSvc.WithTenant(organizationID.TenantID())
|
||||||
|
|
||||||
|
organization, err := svc.Organizations.Get(ctx, organizationID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to get organization details: %w", err)
|
return nil, fmt.Errorf("failed to get organization details: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user