forked from TrueCloudLab/frostfs-node
[#32] Add basic ACL helper
Basic ACL helper provides functions for simple access to bit fields of basic ACL. Signed-off-by: Alex Vanin <alexey@nspcc.ru>
This commit is contained in:
parent
f6904db84f
commit
49ee9a14a1
1 changed files with 180 additions and 0 deletions
180
pkg/services/object/acl/basic_helper.go
Normal file
180
pkg/services/object/acl/basic_helper.go
Normal file
|
@ -0,0 +1,180 @@
|
||||||
|
package acl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl"
|
||||||
|
)
|
||||||
|
|
||||||
|
// wrapper around basic ACL to provide easy access to basic ACL fields
|
||||||
|
type basicACLHelper uint32
|
||||||
|
|
||||||
|
const (
|
||||||
|
reservedBitNumber = 2 // first left bits are reserved
|
||||||
|
stickyBitPos = reservedBitNumber // X-bit after reserved bits
|
||||||
|
finalBitPos = stickyBitPos + 1 // F-bit after X-bit
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
opOffset = finalBitPos + 1 // offset of operation bits
|
||||||
|
bitsPerOp = 4 // number of bits per operation
|
||||||
|
opNumber = 7 // number of operation bit sections
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
bitUser uint8 = iota
|
||||||
|
bitSystem
|
||||||
|
bitOthers
|
||||||
|
bitBearer
|
||||||
|
)
|
||||||
|
|
||||||
|
const leftACLBitPos = opOffset + bitsPerOp*opNumber - 1
|
||||||
|
|
||||||
|
var (
|
||||||
|
order = map[eacl.Operation]uint8{
|
||||||
|
eacl.OperationRangeHash: 0,
|
||||||
|
eacl.OperationRange: 1,
|
||||||
|
eacl.OperationSearch: 2,
|
||||||
|
eacl.OperationDelete: 3,
|
||||||
|
eacl.OperationPut: 4,
|
||||||
|
eacl.OperationHead: 5,
|
||||||
|
eacl.OperationGet: 6,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// returns true if n-th left bit is set (starting at 0).
|
||||||
|
func isLeftBitSet(value basicACLHelper, n uint8) bool {
|
||||||
|
bitMask := basicACLHelper(1 << (leftACLBitPos - n))
|
||||||
|
return bitMask != 0 && value&bitMask == bitMask
|
||||||
|
}
|
||||||
|
|
||||||
|
// sets n-th left bit (starting at 0).
|
||||||
|
func setLeftBit(value *basicACLHelper, n uint8) {
|
||||||
|
*value |= basicACLHelper(1 << (leftACLBitPos - n))
|
||||||
|
}
|
||||||
|
|
||||||
|
// resets n-th left bit (starting at 0).
|
||||||
|
func resetLeftBit(value *basicACLHelper, n uint8) {
|
||||||
|
*value &= ^basicACLHelper(1 << (leftACLBitPos - n))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Final returns true if final option is enabled in ACL.
|
||||||
|
func (a basicACLHelper) Final() bool {
|
||||||
|
return isLeftBitSet(a, finalBitPos)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetFinal enables final option in ACL.
|
||||||
|
func (a *basicACLHelper) SetFinal() {
|
||||||
|
setLeftBit(a, finalBitPos)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetFinal disables final option in ACL.
|
||||||
|
func (a *basicACLHelper) ResetFinal() {
|
||||||
|
resetLeftBit(a, finalBitPos)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sticky returns true if sticky option is enabled in ACL.
|
||||||
|
func (a basicACLHelper) Sticky() bool {
|
||||||
|
return isLeftBitSet(a, stickyBitPos)
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetSticky enables the sticky option in ACL.
|
||||||
|
func (a *basicACLHelper) SetSticky() {
|
||||||
|
setLeftBit(a, stickyBitPos)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ResetSticky disables the sticky option in ACL.
|
||||||
|
func (a *basicACLHelper) ResetSticky() {
|
||||||
|
resetLeftBit(a, stickyBitPos)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UserAllowed returns true if user allowed the n-th operation in ACL.
|
||||||
|
func (a basicACLHelper) UserAllowed(op eacl.Operation) bool {
|
||||||
|
if n, ok := order[op]; ok {
|
||||||
|
return isLeftBitSet(a, opOffset+n*bitsPerOp+bitUser)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllowUser allows user the n-th operation in ACL.
|
||||||
|
func (a *basicACLHelper) AllowUser(op eacl.Operation) {
|
||||||
|
if n, ok := order[op]; ok {
|
||||||
|
setLeftBit(a, opOffset+n*bitsPerOp+bitUser)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ForbidUser forbids user the n-th operation in ACL.
|
||||||
|
func (a *basicACLHelper) ForbidUser(op eacl.Operation) {
|
||||||
|
if n, ok := order[op]; ok {
|
||||||
|
resetLeftBit(a, opOffset+n*bitsPerOp+bitUser)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SystemAllowed returns true if System group allowed the n-th operation is set in ACL.
|
||||||
|
func (a basicACLHelper) SystemAllowed(op eacl.Operation) bool {
|
||||||
|
if op != eacl.OperationDelete && op != eacl.OperationRange {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if n, ok := order[op]; ok {
|
||||||
|
return isLeftBitSet(a, opOffset+n*bitsPerOp+bitSystem)
|
||||||
|
}
|
||||||
|
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllowSystem allows System group the n-th operation in ACL.
|
||||||
|
func (a *basicACLHelper) AllowSystem(op eacl.Operation) {
|
||||||
|
if n, ok := order[op]; ok {
|
||||||
|
setLeftBit(a, opOffset+n*bitsPerOp+bitSystem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ForbidSystem forbids System group the n-th operation in ACL.
|
||||||
|
func (a *basicACLHelper) ForbidSystem(op eacl.Operation) {
|
||||||
|
if n, ok := order[op]; ok {
|
||||||
|
resetLeftBit(a, opOffset+n*bitsPerOp+bitSystem)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// OthersAllowed returns true if Others group allowed the n-th operation is set in ACL.
|
||||||
|
func (a basicACLHelper) OthersAllowed(op eacl.Operation) bool {
|
||||||
|
if n, ok := order[op]; ok {
|
||||||
|
return isLeftBitSet(a, opOffset+n*bitsPerOp+bitOthers)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllowOthers allows Others group the n-th operation in ACL.
|
||||||
|
func (a *basicACLHelper) AllowOthers(op eacl.Operation) {
|
||||||
|
if n, ok := order[op]; ok {
|
||||||
|
setLeftBit(a, opOffset+n*bitsPerOp+bitOthers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ForbidOthers forbids Others group the n-th operation in ACL.
|
||||||
|
func (a *basicACLHelper) ForbidOthers(op eacl.Operation) {
|
||||||
|
if n, ok := order[op]; ok {
|
||||||
|
resetLeftBit(a, opOffset+n*bitsPerOp+bitOthers)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BearerAllowed returns true if Bearer token usage is allowed for n-th operation in ACL.
|
||||||
|
func (a basicACLHelper) BearerAllowed(op eacl.Operation) bool {
|
||||||
|
if n, ok := order[op]; ok {
|
||||||
|
return isLeftBitSet(a, opOffset+n*bitsPerOp+bitBearer)
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// AllowBearer allows Bearer token usage for n-th operation in ACL.
|
||||||
|
func (a *basicACLHelper) AllowBearer(op eacl.Operation) {
|
||||||
|
if n, ok := order[op]; ok {
|
||||||
|
setLeftBit(a, opOffset+n*bitsPerOp+bitBearer)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ForbidBearer forbids Bearer token usage for n-th operation in ACL.
|
||||||
|
func (a *basicACLHelper) ForbidBearer(op eacl.Operation) {
|
||||||
|
if n, ok := order[op]; ok {
|
||||||
|
resetLeftBit(a, opOffset+n*bitsPerOp+bitBearer)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue