greatape/components/core/access_control_manager.go

290 wiersze
11 KiB
Go

package core
import (
. "github.com/reiver/greatape/components/constants"
. "github.com/reiver/greatape/components/contracts"
. "github.com/reiver/greatape/components/contracts/model"
. "github.com/reiver/greatape/components/model/entity"
"github.com/reiver/greatape/components/model/repository"
. "github.com/xeronith/diamante/contracts/logging"
. "github.com/xeronith/diamante/contracts/security"
. "github.com/xeronith/diamante/contracts/settings"
. "github.com/xeronith/diamante/contracts/system"
. "github.com/xeronith/diamante/system"
)
// noinspection GoSnakeCaseUsage
const ACCESS_CONTROL_MANAGER = "AccessControlManager"
type accessControlManager struct {
systemComponent
cache ICache
}
func newAccessControlManager(configuration IConfiguration, logger ILogger, dependencies ...ISystemComponent) IAccessControlManager {
manager := &accessControlManager{
systemComponent: newSystemComponent(configuration, logger),
cache: NewCache(),
}
if err := manager.ResolveDependencies(dependencies...); err != nil {
return nil
}
return manager
}
func (manager *accessControlManager) Name() string {
return ACCESS_CONTROL_MANAGER
}
func (manager *accessControlManager) ResolveDependencies(_ ...ISystemComponent) error {
return nil
}
func (manager *accessControlManager) Load() error {
accessControlEntities, err := repository.AccessControls.FetchAll()
if err != nil {
return err
}
accessControls := make(SystemObjectCache)
for _, accessControlEntity := range accessControlEntities {
if accessControl, err := NewAccessControlFromEntity(accessControlEntity); err == nil {
accessControls[accessControl.Id()] = accessControl
} else {
return err
}
}
manager.cache.Load(accessControls)
return nil
}
func (manager *accessControlManager) Reload() error {
return manager.Load()
}
func (manager *accessControlManager) OnCacheChanged(callback AccessControlCacheCallback) {
manager.cache.OnChanged(callback)
}
func (manager *accessControlManager) Count() int {
return manager.cache.Size()
}
func (manager *accessControlManager) Exists(id int64) bool {
return manager.Find(id) != nil
}
func (manager *accessControlManager) ExistsWhich(condition AccessControlCondition) bool {
var accessControls AccessControls
manager.ForEach(func(accessControl IAccessControl) {
if condition(accessControl) {
accessControls = append(accessControls, accessControl)
}
})
return len(accessControls) > 0
}
func (manager *accessControlManager) ListAccessControls(_ /* pageIndex */ uint32, _ /* pageSize */ uint32, _ /* criteria */ string, _ Identity) IAccessControlCollection {
return manager.Filter(AccessControlPassThroughFilter)
}
func (manager *accessControlManager) GetAccessControl(id int64, _ Identity) (IAccessControl, error) {
if accessControl := manager.Find(id); accessControl == nil {
return nil, ERROR_ACCESS_CONTROL_NOT_FOUND
} else {
return accessControl, nil
}
}
func (manager *accessControlManager) AccessControls() map[uint64]uint64 {
result := make(map[uint64]uint64)
manager.ForEach(func(accessControl IAccessControl) {
result[accessControl.Key()] = accessControl.Value()
})
return result
}
func (manager *accessControlManager) AddOrUpdateAccessControl(key uint64, value uint64, editor Identity) error {
var accessControl IAccessControl
for _, _accessControl := range manager.Filter(AccessControlPassThroughFilter).Array() {
if _accessControl.Key() == key {
accessControl = _accessControl
break
}
}
if accessControl != nil {
_, err := manager.UpdateAccessControl(accessControl.Id(), accessControl.Key(), value, editor)
return err
} else {
_, err := manager.AddAccessControl(key, value, editor)
return err
}
}
func (manager *accessControlManager) AddAccessControl(key uint64, value uint64, editor Identity) (IAccessControl, error) {
accessControlEntity := NewAccessControlEntity(manager.UniqueId(), key, value)
return manager.Apply(accessControlEntity, repository.AccessControls.Add, manager.cache.Put, editor)
}
func (manager *accessControlManager) AddAccessControlWithCustomId(id int64, key uint64, value uint64, editor Identity) (IAccessControl, error) {
accessControlEntity := NewAccessControlEntity(id, key, value)
return manager.Apply(accessControlEntity, repository.AccessControls.Add, manager.cache.Put, editor)
}
func (manager *accessControlManager) AddAccessControlObject(accessControl IAccessControl, editor Identity) (IAccessControl, error) {
accessControlEntity := NewAccessControlEntity(manager.UniqueId(), accessControl.Key(), accessControl.Value())
return manager.Apply(accessControlEntity, repository.AccessControls.Add, manager.cache.Put, editor)
}
func (manager *accessControlManager) AddAccessControlAtomic(transaction ITransaction, key uint64, value uint64, editor Identity) (IAccessControl, error) {
accessControlEntity := NewAccessControlEntity(manager.UniqueId(), key, value)
return manager.ApplyAtomic(transaction, accessControlEntity, repository.AccessControls.AddAtomic, manager.cache.Put, editor)
}
func (manager *accessControlManager) AddAccessControlWithCustomIdAtomic(id int64, transaction ITransaction, key uint64, value uint64, editor Identity) (IAccessControl, error) {
accessControlEntity := NewAccessControlEntity(id, key, value)
return manager.ApplyAtomic(transaction, accessControlEntity, repository.AccessControls.AddAtomic, manager.cache.Put, editor)
}
func (manager *accessControlManager) AddAccessControlObjectAtomic(transaction ITransaction, accessControl IAccessControl, editor Identity) (IAccessControl, error) {
accessControlEntity := NewAccessControlEntity(manager.UniqueId(), accessControl.Key(), accessControl.Value())
return manager.ApplyAtomic(transaction, accessControlEntity, repository.AccessControls.AddAtomic, manager.cache.Put, editor)
}
func (manager *accessControlManager) Log(key uint64, value uint64, source string, editor Identity, payload string) {
accessControlPipeEntity := NewAccessControlPipeEntity(manager.UniqueId(), key, value, source, editor.Id(), payload)
repository.Pipe.Insert(accessControlPipeEntity)
accessControl, err := NewAccessControlFromEntity(accessControlPipeEntity)
if err != nil {
manager.Logger().Error(err)
} else {
manager.cache.Put(accessControl.Id(), accessControl)
}
}
func (manager *accessControlManager) UpdateAccessControl(id int64, key uint64, value uint64, editor Identity) (IAccessControl, error) {
accessControlEntity := NewAccessControlEntity(id, key, value)
return manager.Apply(accessControlEntity, repository.AccessControls.Update, manager.cache.Put, editor)
}
func (manager *accessControlManager) UpdateAccessControlObject(id int64, accessControl IAccessControl, editor Identity) (IAccessControl, error) {
accessControlEntity := NewAccessControlEntity(id, accessControl.Key(), accessControl.Value())
return manager.Apply(accessControlEntity, repository.AccessControls.Update, manager.cache.Put, editor)
}
func (manager *accessControlManager) UpdateAccessControlAtomic(transaction ITransaction, id int64, key uint64, value uint64, editor Identity) (IAccessControl, error) {
accessControlEntity := NewAccessControlEntity(id, key, value)
return manager.ApplyAtomic(transaction, accessControlEntity, repository.AccessControls.UpdateAtomic, manager.cache.Put, editor)
}
func (manager *accessControlManager) UpdateAccessControlObjectAtomic(transaction ITransaction, id int64, accessControl IAccessControl, editor Identity) (IAccessControl, error) {
accessControlEntity := NewAccessControlEntity(id, accessControl.Key(), accessControl.Value())
return manager.ApplyAtomic(transaction, accessControlEntity, repository.AccessControls.UpdateAtomic, manager.cache.Put, editor)
}
func (manager *accessControlManager) AddOrUpdateAccessControlObject(id int64, accessControl IAccessControl, editor Identity) (IAccessControl, error) {
if manager.Exists(id) {
return manager.UpdateAccessControlObject(id, accessControl, editor)
} else {
return manager.AddAccessControlObject(accessControl, editor)
}
}
func (manager *accessControlManager) AddOrUpdateAccessControlObjectAtomic(transaction ITransaction, id int64, accessControl IAccessControl, editor Identity) (IAccessControl, error) {
if manager.Exists(id) {
return manager.UpdateAccessControlObjectAtomic(transaction, id, accessControl, editor)
} else {
return manager.AddAccessControlObjectAtomic(transaction, accessControl, editor)
}
}
func (manager *accessControlManager) RemoveAccessControl(id int64, editor Identity) (IAccessControl, error) {
accessControlEntity := NewAccessControlEntity(id, 0, 0)
return manager.Apply(accessControlEntity, repository.AccessControls.Remove, manager.cache.Remove, editor)
}
func (manager *accessControlManager) RemoveAccessControlAtomic(transaction ITransaction, id int64, editor Identity) (IAccessControl, error) {
accessControlEntity := NewAccessControlEntity(id, 0, 0)
return manager.ApplyAtomic(transaction, accessControlEntity, repository.AccessControls.RemoveAtomic, manager.cache.Remove, editor)
}
func (manager *accessControlManager) Apply(accessControlEntity IAccessControlEntity, repositoryHandler func(IAccessControlEntity, int64) error, cacheHandler func(int64, ISystemObject), editor Identity) (IAccessControl, error) {
result, err := NewAccessControlFromEntity(accessControlEntity)
if err != nil {
return nil, err
}
if err := repositoryHandler(accessControlEntity, editor.Id()); err != nil {
return nil, err
}
cacheHandler(result.Id(), result)
return result, nil
}
func (manager *accessControlManager) ApplyAtomic(transaction ITransaction, accessControlEntity IAccessControlEntity, repositoryHandler func(IRepositoryTransaction, IAccessControlEntity, int64) error, cacheHandler func(int64, ISystemObject), editor Identity) (IAccessControl, error) {
result, err := NewAccessControlFromEntity(accessControlEntity)
if err != nil {
return nil, err
}
transaction.OnCommit(func() {
cacheHandler(result.Id(), result)
})
if err := repositoryHandler(transaction, accessControlEntity, editor.Id()); err != nil {
return nil, err
}
return result, nil
}
func (manager *accessControlManager) Find(id int64) IAccessControl {
if object, exists := manager.cache.Get(id); !exists {
return nil
} else {
return object.(IAccessControl)
}
}
func (manager *accessControlManager) ForEach(iterator AccessControlIterator) {
manager.cache.ForEachValue(func(object ISystemObject) {
iterator(object.(IAccessControl))
})
}
func (manager *accessControlManager) Filter(predicate AccessControlFilterPredicate) IAccessControlCollection {
accessControls := NewAccessControls()
if predicate == nil {
return accessControls
}
manager.ForEach(func(accessControl IAccessControl) {
if predicate(accessControl) {
accessControls.Append(accessControl)
}
})
return accessControls
}
func (manager *accessControlManager) Map(predicate AccessControlMapPredicate) IAccessControlCollection {
accessControls := NewAccessControls()
if predicate == nil {
return accessControls
}
manager.ForEach(func(accessControl IAccessControl) {
accessControls.Append(predicate(accessControl))
})
return accessControls
}