Files
upstream-corteza/server/system/service/dal_sensitivity_level.go
upstream-mirror 7e385fc126
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
snapshot of https://github.com/cortezaproject/corteza.git (2024.9.x, 2026-09-18; blobs > 131072B omitted)
2026-09-18 01:22:23 +05:00

380 lines
9.6 KiB
Go

package service
import (
"context"
"fmt"
"sort"
"github.com/cortezaproject/corteza/server/pkg/actionlog"
a "github.com/cortezaproject/corteza/server/pkg/auth"
"github.com/cortezaproject/corteza/server/pkg/dal"
"github.com/cortezaproject/corteza/server/store"
"github.com/cortezaproject/corteza/server/system/types"
)
type (
dalSensitivityLevel struct {
actionlog actionlog.Recorder
store store.Storer
ac sensitivityLevelAccessController
dal dalSensitivityLevelManager
}
sensitivityLevelAccessController interface {
CanManageDalSensitivityLevel(context.Context) bool
}
dalSensitivityLevelManager interface {
ReplaceSensitivityLevel(levels ...dal.SensitivityLevel) (err error)
RemoveSensitivityLevel(levels ...uint64) (err error)
InUseSensitivityLevel(levelID uint64) (usage dal.SensitivityLevelUsage)
}
)
func SensitivityLevel(ctx context.Context, dal dalSensitivityLevelManager) *dalSensitivityLevel {
return &dalSensitivityLevel{
ac: DefaultAccessControl,
actionlog: DefaultActionlog,
store: DefaultStore,
dal: dal,
}
}
func (svc *dalSensitivityLevel) FindByID(ctx context.Context, ID uint64) (q *types.DalSensitivityLevel, err error) {
var (
rProps = &dalSensitivityLevelActionProps{}
)
err = func() error {
if ID == 0 {
return DalSensitivityLevelErrInvalidID()
}
if q, err = store.LookupDalSensitivityLevelByID(ctx, svc.store, ID); err != nil {
return DalSensitivityLevelErrInvalidID().Wrap(err)
}
rProps.setSensitivityLevel(q)
if !svc.ac.CanManageDalSensitivityLevel(ctx) {
return DalSensitivityLevelErrNotAllowedToManage(rProps)
}
return nil
}()
return q, svc.recordAction(ctx, rProps, DalSensitivityLevelActionLookup, err)
}
func (svc *dalSensitivityLevel) Create(ctx context.Context, new *types.DalSensitivityLevel) (q *types.DalSensitivityLevel, err error) {
var (
qProps = &dalSensitivityLevelActionProps{new: new}
)
err = store.Tx(ctx, svc.store, func(ctx context.Context, s store.Storer) (err error) {
if new.Meta.Name == "" {
return DalSensitivityLevelErrMissingName()
}
if !svc.ac.CanManageDalSensitivityLevel(ctx) {
return DalSensitivityLevelErrNotAllowedToManage(qProps)
}
new.CreatedAt = *now()
new.CreatedBy = a.GetIdentityFromContext(ctx).Identity()
ups, err := svc.prepare(ctx, s, new)
if err != nil {
return
}
new.ID = nextID()
err = store.UpsertDalSensitivityLevel(ctx, s, ups...)
if err != nil {
return
}
q = new
return dalSensitivityLevelReplace(ctx, svc.dal, new)
})
return q, svc.recordAction(ctx, qProps, DalSensitivityLevelActionCreate, err)
}
func (svc *dalSensitivityLevel) Update(ctx context.Context, upd *types.DalSensitivityLevel) (q *types.DalSensitivityLevel, err error) {
var (
qProps = &dalSensitivityLevelActionProps{update: upd}
qq *types.DalSensitivityLevel
e error
)
err = store.Tx(ctx, svc.store, func(ctx context.Context, s store.Storer) (err error) {
if qq, e = store.LookupDalSensitivityLevelByID(ctx, s, upd.ID); e != nil {
return DalSensitivityLevelErrNotFound(qProps)
}
if upd.Meta.Name == "" {
return DalSensitivityLevelErrMissingName()
}
if !svc.ac.CanManageDalSensitivityLevel(ctx) {
return DalSensitivityLevelErrNotAllowedToManage(qProps)
}
// Test if stale (update has an older version of data)
if isStale(upd.UpdatedAt, qq.UpdatedAt, qq.CreatedAt) {
return DalSensitivityLevelErrStaleData()
}
upd.UpdatedAt = now()
upd.CreatedAt = qq.CreatedAt
upd.UpdatedBy = a.GetIdentityFromContext(ctx).Identity()
ups, err := svc.prepare(ctx, s, upd)
if err != nil {
return
}
err = store.UpsertDalSensitivityLevel(ctx, s, ups...)
if err != nil {
return
}
q = upd
return dalSensitivityLevelReplace(ctx, svc.dal, upd)
})
return q, svc.recordAction(ctx, qProps, DalSensitivityLevelActionUpdate, err)
}
func (svc *dalSensitivityLevel) DeleteByID(ctx context.Context, ID uint64) (err error) {
var (
qProps = &dalSensitivityLevelActionProps{}
q *types.DalSensitivityLevel
)
err = store.Tx(ctx, svc.store, func(ctx context.Context, s store.Storer) (err error) {
if ID == 0 {
return DalSensitivityLevelErrInvalidID()
}
if q, err = store.LookupDalSensitivityLevelByID(ctx, s, ID); err != nil {
return
}
if !svc.ac.CanManageDalSensitivityLevel(ctx) {
return DalSensitivityLevelErrNotAllowedToManage(qProps)
}
if !svc.dal.InUseSensitivityLevel(ID).Empty() {
return DalSensitivityLevelErrDeleteInUse()
}
qProps.setSensitivityLevel(q)
q.DeletedAt = now()
q.DeletedBy = a.GetIdentityFromContext(ctx).Identity()
ups, err := svc.prepare(ctx, s, q)
if err != nil {
return
}
err = store.UpsertDalSensitivityLevel(ctx, s, ups...)
if err != nil {
return
}
var (
dd = make(types.DalSensitivityLevelSet, 0, len(ups)/2+1)
uu = make(types.DalSensitivityLevelSet, 0, len(ups)/2+1)
)
for _, l := range ups {
if l.DeletedAt != nil {
dd = append(dd, l)
} else {
uu = append(uu, l)
}
}
if err = dalSensitivityLevelReplace(ctx, svc.dal, uu...); err != nil {
return err
}
if err = dalSensitivityLevelRemove(ctx, svc.dal, dd...); err != nil {
return err
}
return nil
})
return svc.recordAction(ctx, qProps, DalSensitivityLevelActionDelete, err)
}
func (svc *dalSensitivityLevel) UndeleteByID(ctx context.Context, ID uint64) (err error) {
var (
qProps = &dalSensitivityLevelActionProps{}
q *types.DalSensitivityLevel
)
err = store.Tx(ctx, svc.store, func(ctx context.Context, s store.Storer) (err error) {
if ID == 0 {
return DalSensitivityLevelErrInvalidID()
}
if q, err = store.LookupDalSensitivityLevelByID(ctx, s, ID); err != nil {
return
}
if !svc.ac.CanManageDalSensitivityLevel(ctx) {
return DalSensitivityLevelErrNotAllowedToManage(qProps)
}
qProps.setSensitivityLevel(q)
q.DeletedAt = nil
q.UpdatedBy = a.GetIdentityFromContext(ctx).Identity()
if err = store.UpdateDalSensitivityLevel(ctx, s, q); err != nil {
return
}
return dalSensitivityLevelReplace(ctx, svc.dal, q)
})
return svc.recordAction(ctx, qProps, DalSensitivityLevelActionDelete, err)
}
func (svc *dalSensitivityLevel) Search(ctx context.Context, filter types.DalSensitivityLevelFilter) (r types.DalSensitivityLevelSet, f types.DalSensitivityLevelFilter, err error) {
var (
aProps = &dalSensitivityLevelActionProps{search: &filter}
)
// For each fetched item, store backend will check if it is valid or not
filter.Check = func(res *types.DalSensitivityLevel) (bool, error) {
if !svc.ac.CanManageDalSensitivityLevel(ctx) {
return false, nil
}
return true, nil
}
err = func() error {
if !svc.ac.CanManageDalSensitivityLevel(ctx) {
return DalSensitivityLevelErrNotAllowedToManage()
}
if r, f, err = store.SearchDalSensitivityLevels(ctx, svc.store, filter); err != nil {
return err
}
return nil
}()
return r, f, svc.recordAction(ctx, aProps, DalSensitivityLevelActionSearch, err)
}
func (svc *dalSensitivityLevel) ReloadSensitivityLevels(ctx context.Context, s store.Storer) (err error) {
return dalSensitivityLevelReload(ctx, svc.store, svc.dal)
}
func (svc *dalSensitivityLevel) prepare(ctx context.Context, s store.Storer, sl *types.DalSensitivityLevel) (_ types.DalSensitivityLevelSet, err error) {
set, _, err := store.SearchDalSensitivityLevels(ctx, s, types.DalSensitivityLevelFilter{})
if err != nil {
return
}
updating := sl.ID != 0
deleting := sl.DeletedAt != nil
// Validation
{
// Assure unique level
for _, crt := range set {
if crt.Level == sl.Level && crt.ID != sl.ID {
return nil, fmt.Errorf("invalid sensitivity level: duplicated level value %d", sl.Level)
}
}
var current *types.DalSensitivityLevel
for _, crt := range set {
if crt.ID == sl.ID {
current = crt
break
}
}
if (updating || deleting) && current == nil {
return nil, fmt.Errorf("cannot update sensitivity level %s: does not exist", sl.Handle)
} else if !updating && current != nil {
return nil, fmt.Errorf("cannot create sensitivity level %s: already exists", sl.Handle)
}
}
// Preparations
{
// Make sure to properly update
for i, s := range set {
if s.ID == sl.ID {
set[i] = sl
break
}
}
// Make sure it's in there
if !deleting && !updating {
set = append(set, sl)
}
// Sort by level for easier normalization
sort.Sort(set)
// @todo uncomment sensitivity level normalization after we redo the user interface
// // Normalize sensitivity level
// offset := 0
// for i := range set {
// if set[i].DeletedAt != nil {
// offset++
// }
// nxtLvl := i + 1 - offset
// if nxtLvl != set[i].Level {
// set[i].UpdatedAt = now()
// // Same user so we can cheat a bit
// set[i].UpdatedBy = sl.CreatedBy
// }
// set[i].Level = nxtLvl
// }
}
return set, err
}
func dalSensitivityLevelReload(ctx context.Context, s store.Storer, dsm dalSensitivityLevelManager) (err error) {
// Get all available sensitivityLevels
ll, _, err := store.SearchDalSensitivityLevels(ctx, s, types.DalSensitivityLevelFilter{})
if err != nil {
return
}
return dalSensitivityLevelReplace(ctx, dsm, ll...)
}
func dalSensitivityLevelReplace(ctx context.Context, dsm dalSensitivityLevelManager, ll ...*types.DalSensitivityLevel) (err error) {
levels := make(dal.SensitivityLevelSet, len(ll))
for i, l := range ll {
levels[i] = dal.MakeSensitivityLevel(l.ID, l.Level, l.Handle)
}
return dsm.ReplaceSensitivityLevel(levels...)
}
func dalSensitivityLevelRemove(ctx context.Context, dsm dalSensitivityLevelManager, ll ...*types.DalSensitivityLevel) (err error) {
dd := make([]uint64, len(ll))
for i, l := range ll {
dd[i] = l.ID
}
return dsm.RemoveSensitivityLevel(dd...)
}