Improve DAL sensitivity level

* Integrate with pkg/dal package
* Additional validation/constraints
This commit is contained in:
Tomaž Jerman
2022-05-26 13:24:16 +02:00
parent aeec20018c
commit 94fbe4bd44
21 changed files with 609 additions and 78 deletions
+44 -6
View File
@@ -33,8 +33,8 @@ type (
}
dalConnections interface {
AddConnection(ctx context.Context, connectionID uint64, cp dal.ConnectionParams, dft dal.ConnectionDefaults, capabilities ...capabilities.Capability) (err error)
UpdateConnection(ctx context.Context, connectionID uint64, cp dal.ConnectionParams, dft dal.ConnectionDefaults, capabilities ...capabilities.Capability) (err error)
AddConnection(ctx context.Context, connectionID uint64, cp dal.ConnectionParams, dft dal.ConnectionMeta, capabilities ...capabilities.Capability) (err error)
UpdateConnection(ctx context.Context, connectionID uint64, cp dal.ConnectionParams, dft dal.ConnectionMeta, capabilities ...capabilities.Capability) (err error)
RemoveConnection(ctx context.Context, connectionID uint64) (err error)
}
)
@@ -119,7 +119,13 @@ func (svc *dalConnection) Create(ctx context.Context, new *types.DalConnection)
q = new
return svc.dal.AddConnection(ctx, new.ID, new.Config.Connection, new.ConnectionDefaults(), new.ActiveCapabilities()...)
var cm dal.ConnectionMeta
cm, err = svc.makeConnectionMeta(ctx, new)
if err != nil {
return
}
return svc.dal.AddConnection(ctx, new.ID, new.Config.Connection, cm, new.ActiveCapabilities()...)
}()
return q, svc.recordAction(ctx, qProps, DalConnectionActionCreate, err)
@@ -151,7 +157,13 @@ func (svc *dalConnection) Update(ctx context.Context, upd *types.DalConnection)
q = upd
return svc.dal.UpdateConnection(ctx, upd.ID, upd.Config.Connection, upd.ConnectionDefaults(), upd.ActiveCapabilities()...)
var cm dal.ConnectionMeta
cm, err = svc.makeConnectionMeta(ctx, upd)
if err != nil {
return
}
return svc.dal.UpdateConnection(ctx, upd.ID, upd.Config.Connection, cm, upd.ActiveCapabilities()...)
}()
return q, svc.recordAction(ctx, qProps, DalConnectionActionUpdate, err)
@@ -219,7 +231,13 @@ func (svc *dalConnection) UndeleteByID(ctx context.Context, ID uint64) (err erro
return
}
return svc.dal.AddConnection(ctx, q.ID, q.Config.Connection, q.ConnectionDefaults(), q.ActiveCapabilities()...)
var cm dal.ConnectionMeta
cm, err = svc.makeConnectionMeta(ctx, q)
if err != nil {
return
}
return svc.dal.AddConnection(ctx, q.ID, q.Config.Connection, cm, q.ActiveCapabilities()...)
}()
return svc.recordAction(ctx, qProps, DalConnectionActionDelete, err)
@@ -262,10 +280,30 @@ func (svc *dalConnection) reloadConnections(ctx context.Context) (err error) {
}
for _, c := range cc {
if err = svc.dal.AddConnection(ctx, c.ID, c.Config.Connection, c.ConnectionDefaults(), c.ActiveCapabilities()...); err != nil {
var cm dal.ConnectionMeta
cm, err = svc.makeConnectionMeta(ctx, c)
if err != nil {
return
}
if err = svc.dal.AddConnection(ctx, c.ID, c.Config.Connection, cm, c.ActiveCapabilities()...); err != nil {
return
}
}
return
}
func (svc *dalConnection) makeConnectionMeta(ctx context.Context, c *types.DalConnection) (cm dal.ConnectionMeta, err error) {
// @todo we could probably utilize connection params more here
cm = dal.ConnectionMeta{
ConnectionDefaults: dal.ConnectionDefaults{
ModelIdent: c.Config.DefaultModelIdent,
AttributeIdent: c.Config.DefaultAttributeIdent,
PartitionFormat: c.Config.DefaultPartitionFormat,
},
SensitivityLevel: c.SensitivityLevel,
Label: c.Handle,
}
return
}
+131 -36
View File
@@ -2,9 +2,13 @@ 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/pkg/filter"
"github.com/cortezaproject/corteza-server/store"
"github.com/cortezaproject/corteza-server/system/types"
@@ -15,29 +19,27 @@ type (
actionlog actionlog.Recorder
store store.Storer
ac sensitivityLevelAccessController
// dal dalSensitivityLevels
dal dalSensitivityLevels
}
sensitivityLevelAccessController interface {
CanManageDalSensitivityLevel(context.Context) bool
}
// dalSensitivityLevels interface {
// AddSensitivityLevel(ctx context.Context, sensitivityLevelID uint64, cp dal.SensitivityLevelParams, dft dal.SensitivityLevelDefaults, capabilities ...capabilities.Capability) (err error)
// UpdateSensitivityLevel(ctx context.Context, sensitivityLevelID uint64, cp dal.SensitivityLevelParams, dft dal.SensitivityLevelDefaults, capabilities ...capabilities.Capability) (err error)
// RemoveSensitivityLevel(ctx context.Context, sensitivityLevelID uint64) (err error)
// }
dalSensitivityLevels interface {
ReloadSensitivityLevels(raw dal.SensitivityLevelSet) (err error)
}
)
func SensitivityLevel(ctx context.Context) (*dalSensitivityLevel, error) {
func SensitivityLevel(ctx context.Context, dal dalSensitivityLevels) (*dalSensitivityLevel, error) {
out := &dalSensitivityLevel{
ac: DefaultAccessControl,
actionlog: DefaultActionlog,
store: DefaultStore,
// dal: dal,
dal: dal,
}
return out, nil // out.reloadSensitivityLevels(ctx)
return out, out.reloadSensitivityLevels(ctx, out.store)
}
func (svc *dalSensitivityLevel) FindByID(ctx context.Context, ID uint64) (q *types.DalSensitivityLevel, err error) {
@@ -76,18 +78,22 @@ func (svc *dalSensitivityLevel) Create(ctx context.Context, new *types.DalSensit
return DalSensitivityLevelErrNotAllowedToManage(qProps)
}
new.ID = nextID()
new.CreatedAt = *now()
new.CreatedBy = a.GetIdentityFromContext(ctx).Identity()
ups, err := svc.prepare(ctx, svc.store, new)
if err != nil {
return
}
new.ID = nextID()
if err = store.CreateDalSensitivityLevel(ctx, svc.store, new); err != nil {
return err
err = store.UpsertDalSensitivityLevel(ctx, svc.store, ups...)
if err != nil {
return
}
q = new
// return svc.dal.AddSensitivityLevel(ctx, new.ID, new.Config.SensitivityLevel, new.SensitivityLevelDefaults(), new.ActiveCapabilities()...)
return
return svc.reloadSensitivityLevels(ctx, svc.store)
}()
return q, svc.recordAction(ctx, qProps, DalSensitivityLevelActionCreate, err)
@@ -113,14 +119,18 @@ func (svc *dalSensitivityLevel) Update(ctx context.Context, upd *types.DalSensit
upd.CreatedAt = qq.CreatedAt
upd.UpdatedBy = a.GetIdentityFromContext(ctx).Identity()
if err = store.UpdateDalSensitivityLevel(ctx, svc.store, upd); err != nil {
ups, err := svc.prepare(ctx, svc.store, upd)
if err != nil {
return
}
err = store.UpsertDalSensitivityLevel(ctx, svc.store, ups...)
if err != nil {
return
}
q = upd
// return svc.dal.UpdateSensitivityLevel(ctx, upd.ID, upd.Config.SensitivityLevel, upd.SensitivityLevelDefaults(), upd.ActiveCapabilities()...)
return
return svc.reloadSensitivityLevels(ctx, svc.store)
}()
return q, svc.recordAction(ctx, qProps, DalSensitivityLevelActionUpdate, err)
@@ -150,12 +160,16 @@ func (svc *dalSensitivityLevel) DeleteByID(ctx context.Context, ID uint64) (err
q.DeletedAt = now()
q.DeletedBy = a.GetIdentityFromContext(ctx).Identity()
if err = store.UpdateDalSensitivityLevel(ctx, svc.store, q); err != nil {
ups, err := svc.prepare(ctx, svc.store, q)
if err != nil {
return
}
err = store.UpsertDalSensitivityLevel(ctx, svc.store, ups...)
if err != nil {
return
}
// return svc.dal.RemoveSensitivityLevel(ctx, q.ID)
return
return svc.reloadSensitivityLevels(ctx, svc.store)
}()
return svc.recordAction(ctx, qProps, DalSensitivityLevelActionDelete, err)
@@ -189,8 +203,7 @@ func (svc *dalSensitivityLevel) UndeleteByID(ctx context.Context, ID uint64) (er
return
}
// return svc.dal.AddSensitivityLevel(ctx, q.ID, q.Config.SensitivityLevel, q.SensitivityLevelDefaults(), q.ActiveCapabilities()...)
return
return svc.reloadSensitivityLevels(ctx, svc.store)
}()
return svc.recordAction(ctx, qProps, DalSensitivityLevelActionDelete, err)
@@ -225,19 +238,101 @@ func (svc *dalSensitivityLevel) Search(ctx context.Context, filter types.DalSens
return r, f, svc.recordAction(ctx, aProps, DalSensitivityLevelActionSearch, err)
}
// func (svc *dalSensitivityLevel) reloadSensitivityLevels(ctx context.Context) (err error) {
// // Get all available sensitivityLevels
// cc, _, err := store.SearchDalSensitivityLevels(ctx, svc.store, types.DalSensitivityLevelFilter{})
// if err != nil {
// return
// }
func (svc *dalSensitivityLevel) reloadSensitivityLevels(ctx context.Context, s store.Storer) (err error) {
ll, err := svc.getSensitivityLevels(ctx, s)
if err != nil {
return
}
// for _, c := range cc {
// // if err = svc.dal.AddSensitivityLevel(ctx, c.ID, c.Config.SensitivityLevel, c.SensitivityLevelDefaults(), c.ActiveCapabilities()...); err != nil {
// return
// return
// }
// }
return svc.dal.ReloadSensitivityLevels(ll)
}
// return
// }
func (svc *dalSensitivityLevel) getSensitivityLevels(ctx context.Context, s store.Storer) (out dal.SensitivityLevelSet, err error) {
ll, _, err := store.SearchDalSensitivityLevels(ctx, s, types.DalSensitivityLevelFilter{Deleted: filter.StateExcluded})
if err != nil {
return
}
sort.Sort(ll)
for _, l := range ll {
out = append(out, dal.SensitivityLevel{
ID: l.ID,
Handle: l.Handle,
})
}
return
}
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 {
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)
// 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
}
+1 -1
View File
@@ -155,7 +155,7 @@ func Initialize(ctx context.Context, log *zap.Logger, s store.Storer, primaryCon
return
}
DefaultDalSensitivityLevel, err = SensitivityLevel(ctx)
DefaultDalSensitivityLevel, err = SensitivityLevel(ctx, dal.Service())
if err != nil {
return
}
+8
View File
@@ -75,3 +75,11 @@ func (nm *DalSensitivityLevelMeta) Scan(value interface{}) error {
func (nm DalSensitivityLevelMeta) Value() (driver.Value, error) {
return json.Marshal(nm)
}
func (ss DalSensitivityLevelSet) Len() int { return len(ss) }
func (ss DalSensitivityLevelSet) Less(i, j int) bool {
return ss[i].Level < ss[j].Level
}
func (ss DalSensitivityLevelSet) Swap(i, j int) {
ss[i], ss[j] = ss[j], ss[i]
}