snapshot of https://github.com/cortezaproject/corteza.git (2024.9.x, 2026-09-18; blobs > 131072B omitted)
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
Some checks failed
SonarQube / SonarQube (push) Failing after 5m28s
E2e test on main branch push / server and client test (map[name:admin port:8080]) (push) Failing after 3m33s
Server and lib tests / Library test (js) (push) Failing after 1m36s
Server and lib tests / Library test (vue) (push) Successful in 2m24s
Server and lib tests / Web client test (admin) (push) Successful in 2m52s
Server and lib tests / Web client test (compose) (push) Successful in 3m23s
Server and lib tests / Web client test (discovery) (push) Successful in 2m49s
Server and lib tests / Web client test (one) (push) Successful in 2m52s
Server and lib tests / Web client test (privacy) (push) Successful in 2m44s
Server and lib tests / Web client test (reporter) (push) Successful in 2m56s
Server and lib tests / Web client test (workflow) (push) Successful in 3m0s
Server and lib tests / Server tests (push) Failing after 4m55s
E2e test on main branch push / notify-failure (push) Failing after 9s
Server and lib tests / Send matrix testing notification (push) Successful in 2s
Mark stale issues and pull requests / stale (push) Successful in 40s
This commit is contained in:
296
server/system/service/data_privacy.go
Normal file
296
server/system/service/data_privacy.go
Normal file
@@ -0,0 +1,296 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"github.com/cortezaproject/corteza/server/pkg/actionlog"
|
||||
a "github.com/cortezaproject/corteza/server/pkg/auth"
|
||||
"github.com/cortezaproject/corteza/server/pkg/errors"
|
||||
"github.com/cortezaproject/corteza/server/store"
|
||||
"github.com/cortezaproject/corteza/server/system/service/event"
|
||||
"github.com/cortezaproject/corteza/server/system/types"
|
||||
)
|
||||
|
||||
type (
|
||||
dataPrivacy struct {
|
||||
actionlog actionlog.Recorder
|
||||
store store.Storer
|
||||
|
||||
ac dataPrivacyAccessController
|
||||
eventbus eventDispatcher
|
||||
dalConn dalConnectionService
|
||||
}
|
||||
|
||||
dataPrivacyAccessController interface {
|
||||
CanSearchDataPrivacyRequests(context.Context) bool
|
||||
CanCreateDataPrivacyRequest(context.Context) bool
|
||||
CanReadDataPrivacyRequest(context.Context, *types.DataPrivacyRequest) bool
|
||||
CanApproveDataPrivacyRequest(context.Context, *types.DataPrivacyRequest) bool
|
||||
|
||||
CanSearchDalConnections(context.Context) bool
|
||||
}
|
||||
|
||||
dalConnectionService interface {
|
||||
Search(ctx context.Context, filter types.DalConnectionFilter) (r types.DalConnectionSet, f types.DalConnectionFilter, err error)
|
||||
}
|
||||
|
||||
DataPrivacyService interface {
|
||||
FindConnections(ctx context.Context, filter types.DalConnectionFilter) (out types.PrivacyDalConnectionSet, f types.DalConnectionFilter, err error)
|
||||
|
||||
FindRequestByID(ctx context.Context, requestID uint64) (*types.DataPrivacyRequest, error)
|
||||
FindRequests(context.Context, types.DataPrivacyRequestFilter) (types.DataPrivacyRequestSet, types.DataPrivacyRequestFilter, error)
|
||||
CreateRequest(ctx context.Context, request *types.DataPrivacyRequest) (*types.DataPrivacyRequest, error)
|
||||
UpdateRequestStatus(ctx context.Context, request *types.DataPrivacyRequest) (*types.DataPrivacyRequest, error)
|
||||
|
||||
FindRequestComments(ctx context.Context, filter types.DataPrivacyRequestCommentFilter) (rr types.DataPrivacyRequestCommentSet, f types.DataPrivacyRequestCommentFilter, err error)
|
||||
CreateRequestComment(ctx context.Context, new *types.DataPrivacyRequestComment) (r *types.DataPrivacyRequestComment, err error)
|
||||
}
|
||||
)
|
||||
|
||||
func DataPrivacy(s store.Storer, ac dataPrivacyAccessController, al actionlog.Recorder, eb eventDispatcher) *dataPrivacy {
|
||||
return &dataPrivacy{
|
||||
actionlog: al,
|
||||
store: s,
|
||||
ac: ac,
|
||||
eventbus: eb,
|
||||
dalConn: DefaultDalConnection,
|
||||
}
|
||||
}
|
||||
|
||||
func (svc dataPrivacy) FindConnections(ctx context.Context, filter types.DalConnectionFilter) (out types.PrivacyDalConnectionSet, f types.DalConnectionFilter, err error) {
|
||||
var (
|
||||
cc types.DalConnectionSet
|
||||
)
|
||||
err = func() error {
|
||||
if cc, f, err = store.SearchDalConnections(ctx, svc.store, filter); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = cc.Walk(func(c *types.DalConnection) error {
|
||||
pc := types.PrivacyDalConnection{
|
||||
ID: c.ID,
|
||||
Handle: c.Handle,
|
||||
Type: c.Type,
|
||||
Meta: types.PrivacyDalConnectionMeta{
|
||||
Name: c.Meta.Name,
|
||||
Ownership: c.Meta.Ownership,
|
||||
Location: c.Meta.Location,
|
||||
},
|
||||
Config: types.PrivacyDalConnectionConfig{
|
||||
Privacy: c.Config.Privacy,
|
||||
},
|
||||
CreatedAt: c.CreatedAt,
|
||||
CreatedBy: c.CreatedBy,
|
||||
UpdatedAt: c.UpdatedAt,
|
||||
UpdatedBy: c.UpdatedBy,
|
||||
DeletedAt: c.DeletedAt,
|
||||
DeletedBy: c.DeletedBy,
|
||||
}
|
||||
out = append(out, &pc)
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}()
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (svc dataPrivacy) FindRequestByID(ctx context.Context, requestID uint64) (r *types.DataPrivacyRequest, err error) {
|
||||
var (
|
||||
raProps = &dataPrivacyActionProps{dataPrivacyRequest: &types.DataPrivacyRequest{ID: requestID}}
|
||||
)
|
||||
|
||||
err = func() error {
|
||||
r, err = loadDataPrivacyRequest(ctx, svc.store, requestID)
|
||||
if r, err = svc.procRequest(ctx, r, err); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
raProps.setDataPrivacyRequest(r)
|
||||
|
||||
if !svc.ac.CanReadDataPrivacyRequest(ctx, r) {
|
||||
return DataPrivacyErrNotAllowedToRead()
|
||||
}
|
||||
|
||||
return nil
|
||||
}()
|
||||
|
||||
return r, svc.recordAction(ctx, raProps, DataPrivacyActionLookup, err)
|
||||
}
|
||||
|
||||
func (svc dataPrivacy) procRequest(_ context.Context, r *types.DataPrivacyRequest, err error) (*types.DataPrivacyRequest, error) {
|
||||
if err != nil {
|
||||
if errors.IsNotFound(err) {
|
||||
return nil, DataPrivacyErrNotFound()
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return r, nil
|
||||
}
|
||||
|
||||
func (svc dataPrivacy) FindRequests(ctx context.Context, filter types.DataPrivacyRequestFilter) (rr types.DataPrivacyRequestSet, f types.DataPrivacyRequestFilter, err error) {
|
||||
var (
|
||||
raProps = &dataPrivacyActionProps{filter: &filter}
|
||||
)
|
||||
|
||||
// For each fetched item, store backend will check if it is valid or not
|
||||
filter.Check = func(req *types.DataPrivacyRequest) (bool, error) {
|
||||
if !svc.ac.CanReadDataPrivacyRequest(ctx, req) {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
err = func() error {
|
||||
if !svc.ac.CanSearchDataPrivacyRequests(ctx) {
|
||||
return DataPrivacyErrNotAllowedToSearch()
|
||||
}
|
||||
|
||||
if rr, f, err = store.SearchDataPrivacyRequests(ctx, svc.store, filter); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}()
|
||||
|
||||
return rr, f, svc.recordAction(ctx, raProps, DataPrivacyActionSearch, err)
|
||||
}
|
||||
|
||||
func (svc dataPrivacy) CreateRequest(ctx context.Context, new *types.DataPrivacyRequest) (r *types.DataPrivacyRequest, err error) {
|
||||
var (
|
||||
raProps = &dataPrivacyActionProps{new: new}
|
||||
)
|
||||
|
||||
err = func() (err error) {
|
||||
if len(new.Kind.String()) == 0 {
|
||||
return DataPrivacyErrInvalidKind()
|
||||
}
|
||||
|
||||
if !svc.ac.CanCreateDataPrivacyRequest(ctx) {
|
||||
return DataPrivacyErrNotAllowedToCreate()
|
||||
}
|
||||
|
||||
if err = svc.eventbus.WaitFor(ctx, event.DataPrivacyRequestBeforeCreate(new, r)); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
new.ID = nextID()
|
||||
new.Status = types.RequestStatusPending
|
||||
new.RequestedAt = *now()
|
||||
new.RequestedBy = a.GetIdentityFromContext(ctx).Identity()
|
||||
new.CreatedAt = *now()
|
||||
|
||||
if err = store.CreateDataPrivacyRequest(ctx, svc.store, new); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
r = new
|
||||
|
||||
svc.eventbus.Dispatch(ctx, event.DataPrivacyRequestAfterCreate(new, r))
|
||||
return
|
||||
}()
|
||||
|
||||
return r, svc.recordAction(ctx, raProps, DataPrivacyActionCreate, err)
|
||||
}
|
||||
|
||||
func (svc dataPrivacy) UpdateRequestStatus(ctx context.Context, upd *types.DataPrivacyRequest) (r *types.DataPrivacyRequest, err error) {
|
||||
var (
|
||||
raProps = &dataPrivacyActionProps{update: upd}
|
||||
)
|
||||
|
||||
err = func() (err error) {
|
||||
if len(upd.Status.String()) == 0 {
|
||||
return DataPrivacyErrInvalidStatus()
|
||||
}
|
||||
|
||||
if upd.Status == types.RequestStatusPending {
|
||||
return DataPrivacyErrInvalidStatus()
|
||||
}
|
||||
|
||||
if upd.Status == types.RequestStatusApproved || upd.Status == types.RequestStatusRejected {
|
||||
if !svc.ac.CanApproveDataPrivacyRequest(ctx, upd) {
|
||||
return DataPrivacyErrNotAllowedToApprove()
|
||||
}
|
||||
}
|
||||
|
||||
if r, err = loadDataPrivacyRequest(ctx, svc.store, upd.ID); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
raProps.setDataPrivacyRequest(r)
|
||||
|
||||
if err = svc.eventbus.WaitFor(ctx, event.DataPrivacyRequestBeforeUpdate(upd, r)); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
r.Status = upd.Status
|
||||
r.CompletedAt = now()
|
||||
r.CompletedBy = a.GetIdentityFromContext(ctx).Identity()
|
||||
r.UpdatedAt = now()
|
||||
|
||||
// Assign changed values
|
||||
if err = store.UpdateDataPrivacyRequest(ctx, svc.store, r); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
svc.eventbus.Dispatch(ctx, event.DataPrivacyRequestAfterUpdate(upd, r))
|
||||
|
||||
return nil
|
||||
}()
|
||||
|
||||
return r, svc.recordAction(ctx, raProps, DataPrivacyActionApprove, err)
|
||||
}
|
||||
|
||||
func (svc dataPrivacy) FindRequestComments(ctx context.Context, filter types.DataPrivacyRequestCommentFilter) (rr types.DataPrivacyRequestCommentSet, f types.DataPrivacyRequestCommentFilter, err error) {
|
||||
err = func() error {
|
||||
if rr, f, err = store.SearchDataPrivacyRequestComments(ctx, svc.store, filter); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}()
|
||||
|
||||
return rr, f, err
|
||||
}
|
||||
|
||||
func (svc dataPrivacy) CreateRequestComment(ctx context.Context, new *types.DataPrivacyRequestComment) (r *types.DataPrivacyRequestComment, err error) {
|
||||
err = func() (err error) {
|
||||
|
||||
_, err = svc.FindRequestByID(ctx, new.RequestID)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
new.ID = nextID()
|
||||
new.CreatedBy = a.GetIdentityFromContext(ctx).Identity()
|
||||
new.CreatedAt = *now()
|
||||
|
||||
if err = store.CreateDataPrivacyRequestComment(ctx, svc.store, new); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
r = new
|
||||
|
||||
return
|
||||
}()
|
||||
|
||||
return r, err
|
||||
}
|
||||
|
||||
func loadDataPrivacyRequest(ctx context.Context, s store.DataPrivacyRequests, ID uint64) (res *types.DataPrivacyRequest, err error) {
|
||||
if ID == 0 {
|
||||
return nil, DataPrivacyErrInvalidID()
|
||||
}
|
||||
|
||||
if res, err = store.LookupDataPrivacyRequestByID(ctx, s, ID); errors.IsNotFound(err) {
|
||||
return nil, DataPrivacyErrNotFound()
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user