Return error if iam wants to be modified in cluster mode via non-cluster API

This commit is contained in:
Ingo Oppermann 2023-06-20 22:40:36 +02:00
parent 8283815dec
commit 435adfb6ea
No known key found for this signature in database
GPG Key ID: 2AB32426E9DD229E
4 changed files with 41 additions and 32 deletions

View File

@ -1,6 +1,8 @@
package iam
import (
"errors"
"github.com/datarhei/core/v16/cluster/store"
"github.com/datarhei/core/v16/iam"
"github.com/datarhei/core/v16/iam/access"
@ -8,6 +10,8 @@ import (
"github.com/datarhei/core/v16/log"
)
var ErrClusterMode = errors.New("not available in cluster mode")
type manager struct {
iam iam.IAM
store store.Store
@ -65,12 +69,12 @@ func (m *manager) HasPolicy(name, domain, resource string, actions []string) boo
return m.iam.HasPolicy(name, domain, resource, actions)
}
func (m *manager) AddPolicy(name, domain, resource string, actions []string) bool {
return true
func (m *manager) AddPolicy(name, domain, resource string, actions []string) error {
return ErrClusterMode
}
func (m *manager) RemovePolicy(name, domain, resource string, actions []string) bool {
return true
func (m *manager) RemovePolicy(name, domain, resource string, actions []string) error {
return ErrClusterMode
}
func (m *manager) ListPolicies(name, domain, resource string, actions []string) []access.Policy {
@ -87,7 +91,7 @@ func (m *manager) Validators() []string {
}
func (m *manager) CreateIdentity(u identity.User) error {
return nil
return ErrClusterMode
}
func (m *manager) GetIdentity(name string) (identity.User, error) {
@ -95,11 +99,11 @@ func (m *manager) GetIdentity(name string) (identity.User, error) {
}
func (m *manager) UpdateIdentity(name string, u identity.User) error {
return nil
return ErrClusterMode
}
func (m *manager) DeleteIdentity(name string) error {
return nil
return ErrClusterMode
}
func (m *manager) ListIdentities() []identity.User {

View File

@ -109,13 +109,14 @@ func (h *IAMHandler) RemoveIdentity(c echo.Context) error {
}
// Remove the user
err = h.iam.DeleteIdentity(name)
if err != nil {
if err := h.iam.DeleteIdentity(name); err != nil {
return api.Err(http.StatusBadRequest, "Bad request", "%s", err)
}
// Remove all policies of that user
h.iam.RemovePolicy(name, "", "", nil)
if err := h.iam.RemovePolicy(name, "", "", nil); err != nil {
return api.Err(http.StatusBadRequest, "Bad request", "%s", err)
}
return c.JSON(http.StatusOK, "OK")
}
@ -189,11 +190,13 @@ func (h *IAMHandler) UpdateIdentity(c echo.Context) error {
if name != "$anon" {
err = h.iam.UpdateIdentity(name, iamuser)
if err != nil {
return api.Err(http.StatusBadRequest, "Bad request", "%s", err)
return api.Err(http.StatusBadRequest, "", "%s", err.Error())
}
}
h.iam.RemovePolicy(name, "", "", nil)
if err := h.iam.RemovePolicy(name, "", "", nil); err != nil {
return api.Err(http.StatusBadRequest, "", "%s", err.Error())
}
for _, p := range iampolicies {
h.iam.AddPolicy(p.Name, p.Domain, p.Resource, p.Actions)
@ -226,7 +229,7 @@ func (h *IAMHandler) UpdateIdentityPolicies(c echo.Context) error {
name := util.PathParam(c, "name")
if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "write") {
return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to modify this user")
return api.Err(http.StatusForbidden, "", "Not allowed to modify this user")
}
var iamuser identity.User
@ -235,7 +238,7 @@ func (h *IAMHandler) UpdateIdentityPolicies(c echo.Context) error {
if name != "$anon" {
iamuser, err = h.iam.GetIdentity(name)
if err != nil {
return api.Err(http.StatusNotFound, "Not found", "%s", err)
return api.Err(http.StatusNotFound, "", "%s", err.Error())
}
} else {
iamuser = identity.User{
@ -246,27 +249,29 @@ func (h *IAMHandler) UpdateIdentityPolicies(c echo.Context) error {
policies := []api.IAMPolicy{}
if err := util.ShouldBindJSONValidation(c, &policies, false); err != nil {
return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
return api.Err(http.StatusBadRequest, "", "Invalid JSON: %s", err.Error())
}
for _, p := range policies {
err := c.Validate(p)
if err != nil {
return api.Err(http.StatusBadRequest, "Invalid JSON", "%s", err)
return api.Err(http.StatusBadRequest, "", "Invalid JSON: %s", err.Error())
}
}
for _, p := range policies {
if !h.iam.Enforce(ctxuser, p.Domain, "iam:"+iamuser.Name, "write") {
return api.Err(http.StatusForbidden, "Forbidden", "Not allowed to write policy: %v", p)
return api.Err(http.StatusForbidden, "", "Not allowed to write policy: %v", p)
}
}
if !superuser && iamuser.Superuser {
return api.Err(http.StatusForbidden, "Forbidden", "Only superusers can modify superusers")
return api.Err(http.StatusForbidden, "", "Only superusers can modify superusers")
}
h.iam.RemovePolicy(name, "", "", nil)
if err := h.iam.RemovePolicy(name, "", "", nil); err != nil {
return api.Err(http.StatusBadRequest, "", "%s", err.Error())
}
for _, p := range policies {
h.iam.AddPolicy(iamuser.Name, p.Domain, p.Resource, p.Actions)

View File

@ -27,8 +27,8 @@ type Manager interface {
Enforcer
HasPolicy(name, domain, resource string, actions []string) bool
AddPolicy(name, domain, resource string, actions []string) bool
RemovePolicy(name, domain, resource string, actions []string) bool
AddPolicy(name, domain, resource string, actions []string) error
RemovePolicy(name, domain, resource string, actions []string) error
ListPolicies(name, domain, resource string, actions []string) []Policy
ReloadPolicies() error
}
@ -83,23 +83,23 @@ func (am *access) HasPolicy(name, domain, resource string, actions []string) boo
return am.enforcer.HasPolicy(policy)
}
func (am *access) AddPolicy(name, domain, resource string, actions []string) bool {
func (am *access) AddPolicy(name, domain, resource string, actions []string) error {
policy := []string{name, domain, resource, strings.Join(actions, "|")}
if am.enforcer.HasPolicy(policy) {
return true
return nil
}
ok, _ := am.enforcer.AddPolicy(policy)
_, err := am.enforcer.AddPolicy(policy)
return ok
return err
}
func (am *access) RemovePolicy(name, domain, resource string, actions []string) bool {
func (am *access) RemovePolicy(name, domain, resource string, actions []string) error {
policies := am.enforcer.GetFilteredPolicy(0, name, domain, resource, strings.Join(actions, "|"))
am.enforcer.RemovePolicies(policies)
_, err := am.enforcer.RemovePolicies(policies)
return true
return err
}
func (am *access) ListPolicies(name, domain, resource string, actions []string) []Policy {

View File

@ -17,8 +17,8 @@ type IAM interface {
ListDomains() []string
HasPolicy(name, domain, resource string, actions []string) bool
AddPolicy(name, domain, resource string, actions []string) bool
RemovePolicy(name, domain, resource string, actions []string) bool
AddPolicy(name, domain, resource string, actions []string) error
RemovePolicy(name, domain, resource string, actions []string) error
ListPolicies(name, domain, resource string, actions []string) []access.Policy
ReloadPolicies() error
@ -206,7 +206,7 @@ func (i *iam) HasPolicy(name, domain, resource string, actions []string) bool {
return i.am.HasPolicy(name, domain, resource, actions)
}
func (i *iam) AddPolicy(name, domain, resource string, actions []string) bool {
func (i *iam) AddPolicy(name, domain, resource string, actions []string) error {
if len(name) == 0 {
name = "$anon"
}
@ -218,7 +218,7 @@ func (i *iam) AddPolicy(name, domain, resource string, actions []string) bool {
return i.am.AddPolicy(name, domain, resource, actions)
}
func (i *iam) RemovePolicy(name, domain, resource string, actions []string) bool {
func (i *iam) RemovePolicy(name, domain, resource string, actions []string) error {
return i.am.RemovePolicy(name, domain, resource, actions)
}