Added ldap and pam authentication
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
package access
|
||||
|
||||
import (
|
||||
"slices"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Visibility scope tokens shared by user-owned, filterable objects across uopi
|
||||
// (config sets/instances, control-logic graphs, synthetic signals). They drive
|
||||
// the per-tree "Mine / Group / Global" selector. Storage carries the scope as a
|
||||
// plain string so each subsystem can embed it in its own JSON without depending
|
||||
// on this package's types.
|
||||
const (
|
||||
// ScopePrivate: visible only to the owner.
|
||||
ScopePrivate = "private"
|
||||
// ScopeGroup: visible to the owner and members of any listed group.
|
||||
ScopeGroup = "group"
|
||||
// ScopeGlobal: visible to everyone. This is also the legacy default — an
|
||||
// empty/unknown scope is treated as global so objects created before scopes
|
||||
// existed stay visible to all.
|
||||
ScopeGlobal = "global"
|
||||
)
|
||||
|
||||
// CanSee reports whether user (a member of userGroups) may see an object with the
|
||||
// given owner, scope and itemGroups. An empty or unrecognised scope is treated as
|
||||
// global, so legacy objects without a scope remain visible to everyone.
|
||||
//
|
||||
// This is a visibility filter for selector trees, not a hard security boundary:
|
||||
// it governs which objects are offered in listings, and intentionally always
|
||||
// shows an object to its owner regardless of scope.
|
||||
func CanSee(user, owner, scope string, itemGroups, userGroups []string) bool {
|
||||
switch strings.ToLower(strings.TrimSpace(scope)) {
|
||||
case ScopePrivate:
|
||||
return owner != "" && owner == user
|
||||
case ScopeGroup:
|
||||
if owner != "" && owner == user {
|
||||
return true
|
||||
}
|
||||
for _, g := range itemGroups {
|
||||
if slices.Contains(userGroups, g) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
default: // global / empty / unknown
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
// CanSee reports whether user may see an object with the given owner, scope and
|
||||
// itemGroups, resolving the user's group memberships from the policy. It is the
|
||||
// convenience wrapper list handlers use.
|
||||
func (p *Policy) CanSee(user, owner, scope string, itemGroups []string) bool {
|
||||
return CanSee(user, owner, scope, itemGroups, p.GroupsOf(user))
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package access
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestCanSee(t *testing.T) {
|
||||
cases := []struct {
|
||||
name string
|
||||
user string
|
||||
owner string
|
||||
scope string
|
||||
itemGroups []string
|
||||
userGroups []string
|
||||
want bool
|
||||
}{
|
||||
{"global visible to anyone", "bob", "alice", ScopeGlobal, nil, nil, true},
|
||||
{"empty scope = global", "bob", "alice", "", nil, nil, true},
|
||||
{"unknown scope = global", "bob", "alice", "weird", nil, nil, true},
|
||||
{"private hidden from others", "bob", "alice", ScopePrivate, nil, nil, false},
|
||||
{"private visible to owner", "alice", "alice", ScopePrivate, nil, nil, true},
|
||||
{"private with empty owner hidden", "bob", "", ScopePrivate, nil, nil, false},
|
||||
{"group visible to member", "bob", "alice", ScopeGroup, []string{"ops"}, []string{"ops"}, true},
|
||||
{"group hidden from non-member", "bob", "alice", ScopeGroup, []string{"ops"}, []string{"eng"}, false},
|
||||
{"group visible to owner even if not a member", "alice", "alice", ScopeGroup, []string{"ops"}, nil, true},
|
||||
{"group with multiple item groups", "bob", "alice", ScopeGroup, []string{"ops", "eng"}, []string{"eng"}, true},
|
||||
{"case-insensitive scope token", "bob", "alice", "PRIVATE", nil, nil, false},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
if got := CanSee(c.user, c.owner, c.scope, c.itemGroups, c.userGroups); got != c.want {
|
||||
t.Errorf("CanSee(%q,%q,%q,%v,%v) = %v, want %v",
|
||||
c.user, c.owner, c.scope, c.itemGroups, c.userGroups, got, c.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPolicyCanSeeResolvesGroups(t *testing.T) {
|
||||
p := New("", []GroupSpec{{Name: "ops", Members: map[string]Role{"bob": RoleOperator}}})
|
||||
// bob is a member of ops; a group-scoped item shared with ops is visible.
|
||||
if !p.CanSee("bob", "alice", ScopeGroup, []string{"ops"}) {
|
||||
t.Errorf("expected bob to see an ops-scoped item")
|
||||
}
|
||||
// carol is in no group; the same item is hidden.
|
||||
if p.CanSee("carol", "alice", ScopeGroup, []string{"ops"}) {
|
||||
t.Errorf("expected carol not to see an ops-scoped item")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user