mirror of
https://github.com/datarhei/core.git
synced 2025-10-23 07:59:26 +08:00
Separate resource type and resource for IAM policies
This commit is contained in:
@@ -696,19 +696,22 @@ func (a *api) start(ctx context.Context) error {
|
||||
{
|
||||
Name: "$anon",
|
||||
Domain: "$none",
|
||||
Resource: "fs:/**",
|
||||
Types: []string{"fs"},
|
||||
Resource: "/**",
|
||||
Actions: []string{"GET", "HEAD", "OPTIONS"},
|
||||
},
|
||||
{
|
||||
Name: "$anon",
|
||||
Domain: "$none",
|
||||
Resource: "api:/api",
|
||||
Types: []string{"api"},
|
||||
Resource: "/api",
|
||||
Actions: []string{"GET", "HEAD", "OPTIONS"},
|
||||
},
|
||||
{
|
||||
Name: "$anon",
|
||||
Domain: "$none",
|
||||
Resource: "api:/api/v3/widget/process/**",
|
||||
Types: []string{"api"},
|
||||
Resource: "/api/v3/widget/process/**",
|
||||
Actions: []string{"GET", "HEAD", "OPTIONS"},
|
||||
},
|
||||
}
|
||||
@@ -728,7 +731,8 @@ func (a *api) start(ctx context.Context) error {
|
||||
policies = append(policies, iamaccess.Policy{
|
||||
Name: cfg.Storage.Memory.Auth.Username,
|
||||
Domain: "$none",
|
||||
Resource: "fs:/memfs/**",
|
||||
Types: []string{"fs"},
|
||||
Resource: "/memfs/**",
|
||||
Actions: []string{"ANY"},
|
||||
})
|
||||
}
|
||||
@@ -753,7 +757,8 @@ func (a *api) start(ctx context.Context) error {
|
||||
policies = append(policies, iamaccess.Policy{
|
||||
Name: s.Auth.Username,
|
||||
Domain: "$none",
|
||||
Resource: "fs:" + s.Mountpoint + "/**",
|
||||
Types: []string{"fs"},
|
||||
Resource: s.Mountpoint + "/**",
|
||||
Actions: []string{"ANY"},
|
||||
})
|
||||
}
|
||||
@@ -763,7 +768,8 @@ func (a *api) start(ctx context.Context) error {
|
||||
policies = append(policies, iamaccess.Policy{
|
||||
Name: "$anon",
|
||||
Domain: "$none",
|
||||
Resource: "rtmp:/**",
|
||||
Types: []string{"rtmp"},
|
||||
Resource: "/**",
|
||||
Actions: []string{"ANY"},
|
||||
})
|
||||
}
|
||||
@@ -772,7 +778,8 @@ func (a *api) start(ctx context.Context) error {
|
||||
policies = append(policies, iamaccess.Policy{
|
||||
Name: "$anon",
|
||||
Domain: "$none",
|
||||
Resource: "srt:**",
|
||||
Types: []string{"srt"},
|
||||
Resource: "**",
|
||||
Actions: []string{"ANY"},
|
||||
})
|
||||
}
|
||||
@@ -789,7 +796,7 @@ func (a *api) start(ctx context.Context) error {
|
||||
}
|
||||
|
||||
for _, policy := range policies {
|
||||
manager.AddPolicy(policy.Name, policy.Domain, policy.Resource, policy.Actions)
|
||||
manager.AddPolicy(policy.Name, policy.Domain, policy.Types, policy.Resource, policy.Actions)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1142,6 +1142,12 @@ const docTemplateClusterAPI = `{
|
||||
},
|
||||
"resource": {
|
||||
"type": "string"
|
||||
},
|
||||
"types": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@@ -1134,6 +1134,12 @@
|
||||
},
|
||||
"resource": {
|
||||
"type": "string"
|
||||
},
|
||||
"types": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@@ -12,6 +12,10 @@ definitions:
|
||||
type: string
|
||||
resource:
|
||||
type: string
|
||||
types:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
app.Config:
|
||||
properties:
|
||||
|
@@ -60,8 +60,8 @@ func (m *manager) apply(op store.Operation) {
|
||||
}
|
||||
}
|
||||
|
||||
func (m *manager) Enforce(name, domain, resource, action string) bool {
|
||||
return m.iam.Enforce(name, domain, resource, action)
|
||||
func (m *manager) Enforce(name, domain, rtype, resource, action string) bool {
|
||||
return m.iam.Enforce(name, domain, rtype, resource, action)
|
||||
}
|
||||
|
||||
func (m *manager) HasDomain(domain string) bool {
|
||||
@@ -72,20 +72,20 @@ func (m *manager) ListDomains() []string {
|
||||
return m.iam.ListDomains()
|
||||
}
|
||||
|
||||
func (m *manager) HasPolicy(name, domain, resource string, actions []string) bool {
|
||||
return m.iam.HasPolicy(name, domain, resource, actions)
|
||||
func (m *manager) HasPolicy(name, domain string, types []string, resource string, actions []string) bool {
|
||||
return m.iam.HasPolicy(name, domain, types, resource, actions)
|
||||
}
|
||||
|
||||
func (m *manager) AddPolicy(name, domain, resource string, actions []string) error {
|
||||
func (m *manager) AddPolicy(name, domain string, types []string, resource string, actions []string) error {
|
||||
return ErrClusterMode
|
||||
}
|
||||
|
||||
func (m *manager) RemovePolicy(name, domain, resource string, actions []string) error {
|
||||
func (m *manager) RemovePolicy(name, domain string, types []string, resource string, actions []string) error {
|
||||
return ErrClusterMode
|
||||
}
|
||||
|
||||
func (m *manager) ListPolicies(name, domain, resource string, actions []string) []access.Policy {
|
||||
return m.iam.ListPolicies(name, domain, resource, actions)
|
||||
func (m *manager) ListPolicies(name, domain string, types []string, resource string, actions []string) []access.Policy {
|
||||
return m.iam.ListPolicies(name, domain, types, resource, actions)
|
||||
}
|
||||
|
||||
func (m *manager) ReloadPolicies() error {
|
||||
|
@@ -5689,6 +5689,12 @@ const docTemplate = `{
|
||||
},
|
||||
"resource": {
|
||||
"type": "string"
|
||||
},
|
||||
"types": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@@ -5681,6 +5681,12 @@
|
||||
},
|
||||
"resource": {
|
||||
"type": "string"
|
||||
},
|
||||
"types": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@@ -770,6 +770,10 @@ definitions:
|
||||
type: string
|
||||
resource:
|
||||
type: string
|
||||
types:
|
||||
items:
|
||||
type: string
|
||||
type: array
|
||||
type: object
|
||||
api.IAMUser:
|
||||
properties:
|
||||
|
@@ -45,6 +45,7 @@ func (u *IAMUser) Marshal(user identity.User, policies []access.Policy) {
|
||||
for _, p := range policies {
|
||||
u.Policies = append(u.Policies, IAMPolicy{
|
||||
Domain: p.Domain,
|
||||
Types: p.Types,
|
||||
Resource: p.Resource,
|
||||
Actions: p.Actions,
|
||||
})
|
||||
@@ -84,6 +85,7 @@ func (u *IAMUser) Unmarshal() (identity.User, []access.Policy) {
|
||||
iampolicies = append(iampolicies, access.Policy{
|
||||
Name: u.Name,
|
||||
Domain: p.Domain,
|
||||
Types: p.Types,
|
||||
Resource: p.Resource,
|
||||
Actions: p.Actions,
|
||||
})
|
||||
@@ -122,6 +124,7 @@ type IAMAuth0Tenant struct {
|
||||
type IAMPolicy struct {
|
||||
Name string `json:"name,omitempty"`
|
||||
Domain string `json:"domain"`
|
||||
Types []string `json:"types"`
|
||||
Resource string `json:"resource"`
|
||||
Actions []string `json:"actions"`
|
||||
}
|
||||
|
@@ -19,7 +19,7 @@ import (
|
||||
func (r *queryResolver) PlayoutStatus(ctx context.Context, id string, domain string, input string) (*models.RawAVstream, error) {
|
||||
user, _ := ctx.Value("user").(string)
|
||||
|
||||
if !r.IAM.Enforce(user, domain, "process:"+id, "read") {
|
||||
if !r.IAM.Enforce(user, domain, "process", id, "read") {
|
||||
return nil, fmt.Errorf("forbidden")
|
||||
}
|
||||
|
||||
|
@@ -21,7 +21,7 @@ func (r *queryResolver) Processes(ctx context.Context, idpattern *string, refpat
|
||||
procs := []*models.Process{}
|
||||
|
||||
for _, id := range ids {
|
||||
if !r.IAM.Enforce(user, id.Domain, "process:"+id.ID, "read") {
|
||||
if !r.IAM.Enforce(user, id.Domain, "process", id.ID, "read") {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ func (r *queryResolver) Processes(ctx context.Context, idpattern *string, refpat
|
||||
func (r *queryResolver) Process(ctx context.Context, id string, domain string) (*models.Process, error) {
|
||||
user, _ := ctx.Value(GraphKey("user")).(string)
|
||||
|
||||
if !r.IAM.Enforce(user, domain, "process:"+id, "read") {
|
||||
if !r.IAM.Enforce(user, domain, "process", id, "read") {
|
||||
return nil, fmt.Errorf("forbidden")
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ func (r *queryResolver) Process(ctx context.Context, id string, domain string) (
|
||||
func (r *queryResolver) Probe(ctx context.Context, id string, domain string) (*models.Probe, error) {
|
||||
user, _ := ctx.Value(GraphKey("user")).(string)
|
||||
|
||||
if !r.IAM.Enforce(user, domain, "process:"+id, "write") {
|
||||
if !r.IAM.Enforce(user, domain, "process", id, "write") {
|
||||
return nil, fmt.Errorf("forbidden")
|
||||
}
|
||||
|
||||
|
@@ -36,12 +36,12 @@ func (h *ClusterHandler) AddIdentity(c echo.Context) error {
|
||||
|
||||
iamuser, iampolicies := user.Unmarshal()
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam:"+iamuser.Name, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam", iamuser.Name, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "Not allowed to create user '%s'", iamuser.Name)
|
||||
}
|
||||
|
||||
for _, p := range iampolicies {
|
||||
if !h.iam.Enforce(ctxuser, p.Domain, "iam:"+iamuser.Name, "write") {
|
||||
if !h.iam.Enforce(ctxuser, p.Domain, "iam", iamuser.Name, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "Not allowed to write policy: %v", p)
|
||||
}
|
||||
}
|
||||
@@ -84,7 +84,7 @@ func (h *ClusterHandler) UpdateIdentity(c echo.Context) error {
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
name := util.PathParam(c, "name")
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam", name, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "not allowed to modify this user")
|
||||
}
|
||||
|
||||
@@ -102,7 +102,7 @@ func (h *ClusterHandler) UpdateIdentity(c echo.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
iampolicies := h.iam.ListPolicies(name, "", "", nil)
|
||||
iampolicies := h.iam.ListPolicies(name, "", nil, "", nil)
|
||||
|
||||
user := api.IAMUser{}
|
||||
user.Marshal(iamuser, iampolicies)
|
||||
@@ -113,12 +113,12 @@ func (h *ClusterHandler) UpdateIdentity(c echo.Context) error {
|
||||
|
||||
iamuser, iampolicies = user.Unmarshal()
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam:"+iamuser.Name, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam", iamuser.Name, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "not allowed to create user '%s'", iamuser.Name)
|
||||
}
|
||||
|
||||
for _, p := range iampolicies {
|
||||
if !h.iam.Enforce(ctxuser, p.Domain, "iam:"+iamuser.Name, "write") {
|
||||
if !h.iam.Enforce(ctxuser, p.Domain, "iam", iamuser.Name, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "not allowed to write policy: %v", p)
|
||||
}
|
||||
}
|
||||
@@ -165,7 +165,7 @@ func (h *ClusterHandler) UpdateIdentityPolicies(c echo.Context) error {
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
name := util.PathParam(c, "name")
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam", name, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "not allowed to modify this user")
|
||||
}
|
||||
|
||||
@@ -199,7 +199,7 @@ func (h *ClusterHandler) UpdateIdentityPolicies(c echo.Context) error {
|
||||
accessPolicies := []access.Policy{}
|
||||
|
||||
for _, p := range policies {
|
||||
if !h.iam.Enforce(ctxuser, p.Domain, "iam:"+iamuser.Name, "write") {
|
||||
if !h.iam.Enforce(ctxuser, p.Domain, "iam", iamuser.Name, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "not allowed to write policy: %v", p)
|
||||
}
|
||||
|
||||
@@ -265,17 +265,17 @@ func (h *ClusterHandler) ListIdentities(c echo.Context) error {
|
||||
users := make([]api.IAMUser, len(identities)+1)
|
||||
|
||||
for i, iamuser := range identities {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam:"+iamuser.Name, "read") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam", iamuser.Name, "read") {
|
||||
continue
|
||||
}
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam:"+iamuser.Name, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam", iamuser.Name, "write") {
|
||||
iamuser = identity.User{
|
||||
Name: iamuser.Name,
|
||||
}
|
||||
}
|
||||
|
||||
policies := h.iam.ListPolicies(iamuser.Name, "", "", nil)
|
||||
policies := h.iam.ListPolicies(iamuser.Name, "", nil, "", nil)
|
||||
|
||||
users[i].Marshal(iamuser, policies)
|
||||
}
|
||||
@@ -284,7 +284,7 @@ func (h *ClusterHandler) ListIdentities(c echo.Context) error {
|
||||
Name: "$anon",
|
||||
}
|
||||
|
||||
policies := h.iam.ListPolicies("$anon", "", "", nil)
|
||||
policies := h.iam.ListPolicies("$anon", "", nil, "", nil)
|
||||
|
||||
users[len(users)-1].Marshal(anon, policies)
|
||||
|
||||
@@ -307,7 +307,7 @@ func (h *ClusterHandler) ListIdentity(c echo.Context) error {
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
name := util.PathParam(c, "name")
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "read") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam", name, "read") {
|
||||
return api.Err(http.StatusForbidden, "", "Not allowed to access this user")
|
||||
}
|
||||
|
||||
@@ -321,7 +321,7 @@ func (h *ClusterHandler) ListIdentity(c echo.Context) error {
|
||||
}
|
||||
|
||||
if ctxuser != iamuser.Name {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam", name, "write") {
|
||||
iamuser = identity.User{
|
||||
Name: iamuser.Name,
|
||||
}
|
||||
@@ -333,7 +333,7 @@ func (h *ClusterHandler) ListIdentity(c echo.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
iampolicies := h.iam.ListPolicies(name, "", "", nil)
|
||||
iampolicies := h.iam.ListPolicies(name, "", nil, "", nil)
|
||||
|
||||
user := api.IAMUser{}
|
||||
user.Marshal(iamuser, iampolicies)
|
||||
@@ -351,7 +351,7 @@ func (h *ClusterHandler) ListIdentity(c echo.Context) error {
|
||||
// @Security ApiKeyAuth
|
||||
// @Router /api/v3/cluster/iam/policies [get]
|
||||
func (h *ClusterHandler) ListPolicies(c echo.Context) error {
|
||||
iampolicies := h.iam.ListPolicies("", "", "", nil)
|
||||
iampolicies := h.iam.ListPolicies("", "", nil, "", nil)
|
||||
|
||||
policies := []api.IAMPolicy{}
|
||||
|
||||
@@ -385,7 +385,7 @@ func (h *ClusterHandler) RemoveIdentity(c echo.Context) error {
|
||||
domain := util.DefaultQuery(c, "domain", "$none")
|
||||
name := util.PathParam(c, "name")
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam", name, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "Not allowed to delete this user")
|
||||
}
|
||||
|
||||
|
@@ -194,7 +194,7 @@ func (h *ClusterHandler) ListNodeProcesses(c echo.Context) error {
|
||||
processes := []clientapi.Process{}
|
||||
|
||||
for _, p := range procs {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+p.Config.ID, "read") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process", p.Config.ID, "read") {
|
||||
continue
|
||||
}
|
||||
|
||||
|
@@ -65,7 +65,7 @@ func (h *ClusterHandler) GetAllProcesses(c echo.Context) error {
|
||||
pmap := map[app.ProcessID]struct{}{}
|
||||
|
||||
for _, p := range procs {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+p.ID, "read") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process", p.ID, "read") {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ func (h *ClusterHandler) GetAllProcesses(c echo.Context) error {
|
||||
filtered := h.getFilteredStoreProcesses(processes, wantids, domain, reference, idpattern, refpattern, ownerpattern, domainpattern)
|
||||
|
||||
for _, p := range filtered {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+p.Config.ID, "read") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process", p.Config.ID, "read") {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -313,7 +313,7 @@ func (h *ClusterHandler) GetProcess(c echo.Context) error {
|
||||
filter := newFilter(util.DefaultQuery(c, "filter", ""))
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "read") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process", id, "read") {
|
||||
return api.Err(http.StatusForbidden, "")
|
||||
}
|
||||
|
||||
@@ -370,12 +370,12 @@ func (h *ClusterHandler) AddProcess(c echo.Context) error {
|
||||
return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error())
|
||||
}
|
||||
|
||||
if !h.iam.Enforce(ctxuser, process.Domain, "process:"+process.ID, "write") {
|
||||
if !h.iam.Enforce(ctxuser, process.Domain, "process", process.ID, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "API user %s is not allowed to write this process in domain %s", ctxuser, process.Domain)
|
||||
}
|
||||
|
||||
if !superuser {
|
||||
if !h.iam.Enforce(process.Owner, process.Domain, "process:"+process.ID, "write") {
|
||||
if !h.iam.Enforce(process.Owner, process.Domain, "process", process.ID, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "user %s is not allowed to write this process in domain %s", process.Owner, process.Domain)
|
||||
}
|
||||
}
|
||||
@@ -431,7 +431,7 @@ func (h *ClusterHandler) UpdateProcess(c echo.Context) error {
|
||||
Autostart: true,
|
||||
}
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process", id, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "API user %s is not allowed to write the process in domain: %s", ctxuser, domain)
|
||||
}
|
||||
|
||||
@@ -449,12 +449,12 @@ func (h *ClusterHandler) UpdateProcess(c echo.Context) error {
|
||||
return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error())
|
||||
}
|
||||
|
||||
if !h.iam.Enforce(ctxuser, process.Domain, "process:"+process.ID, "write") {
|
||||
if !h.iam.Enforce(ctxuser, process.Domain, "process", process.ID, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "API user %s is not allowed to write this process", ctxuser)
|
||||
}
|
||||
|
||||
if !superuser {
|
||||
if !h.iam.Enforce(process.Owner, process.Domain, "process:"+process.ID, "write") {
|
||||
if !h.iam.Enforce(process.Owner, process.Domain, "process", process.ID, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "user %s is not allowed to write this process", process.Owner)
|
||||
}
|
||||
}
|
||||
@@ -499,7 +499,7 @@ func (h *ClusterHandler) SetProcessCommand(c echo.Context) error {
|
||||
ctxuser := util.DefaultContext(c, "user", "")
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process", id, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "API user %s is not allowed to write the process in domain: %s", ctxuser, domain)
|
||||
}
|
||||
|
||||
@@ -552,7 +552,7 @@ func (h *ClusterHandler) SetProcessMetadata(c echo.Context) error {
|
||||
ctxuser := util.DefaultContext(c, "user", "")
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process", id, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "API user %s is not allowed to write the process in domain: %s", ctxuser, domain)
|
||||
}
|
||||
|
||||
@@ -599,7 +599,7 @@ func (h *ClusterHandler) GetProcessMetadata(c echo.Context) error {
|
||||
ctxuser := util.DefaultContext(c, "user", "")
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "read") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process", id, "read") {
|
||||
return api.Err(http.StatusForbidden, "")
|
||||
}
|
||||
|
||||
@@ -633,7 +633,7 @@ func (h *ClusterHandler) ProbeProcess(c echo.Context) error {
|
||||
ctxuser := util.DefaultContext(c, "user", "")
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process", id, "write") {
|
||||
return api.Err(http.StatusForbidden, "")
|
||||
}
|
||||
|
||||
@@ -684,7 +684,7 @@ func (h *ClusterHandler) ProbeProcessConfig(c echo.Context) error {
|
||||
return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error())
|
||||
}
|
||||
|
||||
if !h.iam.Enforce(ctxuser, process.Domain, "process:"+process.ID, "write") {
|
||||
if !h.iam.Enforce(ctxuser, process.Domain, "process", process.ID, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "API user %s is not allowed to write this process in domain %s", ctxuser, process.Domain)
|
||||
}
|
||||
|
||||
@@ -729,7 +729,7 @@ func (h *ClusterHandler) DeleteProcess(c echo.Context) error {
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
id := util.PathParam(c, "id")
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process", id, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "API user %s is not allowed to write the process in domain: %s", ctxuser, domain)
|
||||
}
|
||||
|
||||
|
@@ -29,7 +29,7 @@ func (h *ClusterHandler) ListStoreProcesses(c echo.Context) error {
|
||||
processes := []api.Process{}
|
||||
|
||||
for _, p := range procs {
|
||||
if !h.iam.Enforce(ctxuser, p.Config.Domain, "process:"+p.Config.ID, "read") {
|
||||
if !h.iam.Enforce(ctxuser, p.Config.Domain, "process", p.Config.ID, "read") {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ func (h *ClusterHandler) GetStoreProcess(c echo.Context) error {
|
||||
Domain: domain,
|
||||
}
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "read") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process", id, "read") {
|
||||
return api.Err(http.StatusForbidden, "", "API user %s is not allowed to read this process", ctxuser)
|
||||
}
|
||||
|
||||
@@ -109,11 +109,11 @@ func (h *ClusterHandler) ListStoreIdentities(c echo.Context) error {
|
||||
users := make([]api.IAMUser, len(identities))
|
||||
|
||||
for i, iamuser := range identities {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam:"+iamuser.Name, "read") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam", iamuser.Name, "read") {
|
||||
continue
|
||||
}
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam:"+iamuser.Name, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam", iamuser.Name, "write") {
|
||||
iamuser = identity.User{
|
||||
Name: iamuser.Name,
|
||||
}
|
||||
@@ -144,7 +144,7 @@ func (h *ClusterHandler) ListStoreIdentity(c echo.Context) error {
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
name := util.PathParam(c, "name")
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "read") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam", name, "read") {
|
||||
return api.Err(http.StatusForbidden, "", "Not allowed to access this user")
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ func (h *ClusterHandler) ListStoreIdentity(c echo.Context) error {
|
||||
}
|
||||
|
||||
if ctxuser != iamuser.Name {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam", name, "write") {
|
||||
iamuser = identity.User{
|
||||
Name: iamuser.Name,
|
||||
}
|
||||
|
@@ -49,12 +49,12 @@ func (h *IAMHandler) AddIdentity(c echo.Context) error {
|
||||
|
||||
iamuser, iampolicies := user.Unmarshal()
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam:"+iamuser.Name, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam", iamuser.Name, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "not allowed to create user '%s'", iamuser.Name)
|
||||
}
|
||||
|
||||
for _, p := range iampolicies {
|
||||
if !h.iam.Enforce(ctxuser, p.Domain, "iam:"+iamuser.Name, "write") {
|
||||
if !h.iam.Enforce(ctxuser, p.Domain, "iam", iamuser.Name, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "not allowed to write policy: %v", p)
|
||||
}
|
||||
}
|
||||
@@ -69,7 +69,7 @@ func (h *IAMHandler) AddIdentity(c echo.Context) error {
|
||||
}
|
||||
|
||||
for _, p := range iampolicies {
|
||||
h.iam.AddPolicy(p.Name, p.Domain, p.Resource, p.Actions)
|
||||
h.iam.AddPolicy(p.Name, p.Domain, p.Types, p.Resource, p.Actions)
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, user)
|
||||
@@ -95,7 +95,7 @@ func (h *IAMHandler) RemoveIdentity(c echo.Context) error {
|
||||
domain := util.DefaultQuery(c, "domain", "$none")
|
||||
name := util.PathParam(c, "name")
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam", name, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "Not allowed to delete this user")
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ func (h *IAMHandler) RemoveIdentity(c echo.Context) error {
|
||||
}
|
||||
|
||||
// Remove all policies of that user
|
||||
if err := h.iam.RemovePolicy(name, "", "", nil); err != nil {
|
||||
if err := h.iam.RemovePolicy(name, "", nil, "", nil); err != nil {
|
||||
return api.Err(http.StatusBadRequest, "", "%s", err.Error())
|
||||
}
|
||||
|
||||
@@ -144,7 +144,7 @@ func (h *IAMHandler) UpdateIdentity(c echo.Context) error {
|
||||
domain := util.DefaultQuery(c, "domain", "$none")
|
||||
name := util.PathParam(c, "name")
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam", name, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "Not allowed to modify this user")
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ func (h *IAMHandler) UpdateIdentity(c echo.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
iampolicies := h.iam.ListPolicies(name, "", "", nil)
|
||||
iampolicies := h.iam.ListPolicies(name, "", nil, "", nil)
|
||||
|
||||
user := api.IAMUser{}
|
||||
user.Marshal(iamuser, iampolicies)
|
||||
@@ -173,12 +173,12 @@ func (h *IAMHandler) UpdateIdentity(c echo.Context) error {
|
||||
|
||||
iamuser, iampolicies = user.Unmarshal()
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam:"+iamuser.Name, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam", iamuser.Name, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "Not allowed to create user '%s'", iamuser.Name)
|
||||
}
|
||||
|
||||
for _, p := range iampolicies {
|
||||
if !h.iam.Enforce(ctxuser, p.Domain, "iam:"+iamuser.Name, "write") {
|
||||
if !h.iam.Enforce(ctxuser, p.Domain, "iam", iamuser.Name, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "Not allowed to write policy: %v", p)
|
||||
}
|
||||
}
|
||||
@@ -194,12 +194,12 @@ func (h *IAMHandler) UpdateIdentity(c echo.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := h.iam.RemovePolicy(name, "", "", nil); err != nil {
|
||||
if err := h.iam.RemovePolicy(name, "", nil, "", 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)
|
||||
h.iam.AddPolicy(p.Name, p.Domain, p.Types, p.Resource, p.Actions)
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, user)
|
||||
@@ -228,7 +228,7 @@ func (h *IAMHandler) UpdateIdentityPolicies(c echo.Context) error {
|
||||
domain := util.DefaultQuery(c, "domain", "$none")
|
||||
name := util.PathParam(c, "name")
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam", name, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "Not allowed to modify this user")
|
||||
}
|
||||
|
||||
@@ -260,7 +260,7 @@ func (h *IAMHandler) UpdateIdentityPolicies(c echo.Context) error {
|
||||
}
|
||||
|
||||
for _, p := range policies {
|
||||
if !h.iam.Enforce(ctxuser, p.Domain, "iam:"+iamuser.Name, "write") {
|
||||
if !h.iam.Enforce(ctxuser, p.Domain, "iam", iamuser.Name, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "not allowed to write policy: %v", p)
|
||||
}
|
||||
}
|
||||
@@ -269,12 +269,12 @@ func (h *IAMHandler) UpdateIdentityPolicies(c echo.Context) error {
|
||||
return api.Err(http.StatusForbidden, "", "only superusers can modify superusers")
|
||||
}
|
||||
|
||||
if err := h.iam.RemovePolicy(name, "", "", nil); err != nil {
|
||||
if err := h.iam.RemovePolicy(name, "", nil, "", 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)
|
||||
h.iam.AddPolicy(iamuser.Name, p.Domain, p.Types, p.Resource, p.Actions)
|
||||
}
|
||||
|
||||
return c.JSON(http.StatusOK, policies)
|
||||
@@ -298,17 +298,17 @@ func (h *IAMHandler) ListIdentities(c echo.Context) error {
|
||||
users := make([]api.IAMUser, len(identities)+1)
|
||||
|
||||
for i, iamuser := range identities {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam:"+iamuser.Name, "read") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam", iamuser.Name, "read") {
|
||||
continue
|
||||
}
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam:"+iamuser.Name, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam", iamuser.Name, "write") {
|
||||
iamuser = identity.User{
|
||||
Name: iamuser.Name,
|
||||
}
|
||||
}
|
||||
|
||||
policies := h.iam.ListPolicies(iamuser.Name, "", "", nil)
|
||||
policies := h.iam.ListPolicies(iamuser.Name, "", nil, "", nil)
|
||||
|
||||
users[i].Marshal(iamuser, policies)
|
||||
}
|
||||
@@ -317,7 +317,7 @@ func (h *IAMHandler) ListIdentities(c echo.Context) error {
|
||||
Name: "$anon",
|
||||
}
|
||||
|
||||
policies := h.iam.ListPolicies("$anon", "", "", nil)
|
||||
policies := h.iam.ListPolicies("$anon", "", nil, "", nil)
|
||||
|
||||
users[len(users)-1].Marshal(anon, policies)
|
||||
|
||||
@@ -342,7 +342,7 @@ func (h *IAMHandler) GetIdentity(c echo.Context) error {
|
||||
domain := util.DefaultQuery(c, "domain", "$none")
|
||||
name := util.PathParam(c, "name")
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "read") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam", name, "read") {
|
||||
return api.Err(http.StatusForbidden, "", "not allowed to access this user")
|
||||
}
|
||||
|
||||
@@ -356,7 +356,7 @@ func (h *IAMHandler) GetIdentity(c echo.Context) error {
|
||||
}
|
||||
|
||||
if ctxuser != iamuser.Name {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam:"+name, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "iam", name, "write") {
|
||||
iamuser = identity.User{
|
||||
Name: iamuser.Name,
|
||||
}
|
||||
@@ -368,7 +368,7 @@ func (h *IAMHandler) GetIdentity(c echo.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
iampolicies := h.iam.ListPolicies(name, "", "", nil)
|
||||
iampolicies := h.iam.ListPolicies(name, "", nil, "", nil)
|
||||
|
||||
user := api.IAMUser{}
|
||||
user.Marshal(iamuser, iampolicies)
|
||||
|
@@ -35,7 +35,7 @@ func (h *RestreamHandler) PlayoutStatus(c echo.Context) error {
|
||||
user := util.DefaultContext(c, "user", "")
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
|
||||
if !h.iam.Enforce(user, domain, "process:"+id, "read") {
|
||||
if !h.iam.Enforce(user, domain, "process:", id, "read") {
|
||||
return api.Err(http.StatusForbidden, "")
|
||||
}
|
||||
|
||||
@@ -104,7 +104,7 @@ func (h *RestreamHandler) PlayoutKeyframe(c echo.Context) error {
|
||||
user := util.DefaultContext(c, "user", "")
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
|
||||
if !h.iam.Enforce(user, domain, "process:"+id, "read") {
|
||||
if !h.iam.Enforce(user, domain, "process:", id, "read") {
|
||||
return api.Err(http.StatusForbidden, "")
|
||||
}
|
||||
|
||||
@@ -162,7 +162,7 @@ func (h *RestreamHandler) PlayoutEncodeErrorframe(c echo.Context) error {
|
||||
user := util.DefaultContext(c, "user", "")
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
|
||||
if !h.iam.Enforce(user, domain, "process:"+id, "write") {
|
||||
if !h.iam.Enforce(user, domain, "process:", id, "write") {
|
||||
return api.Err(http.StatusForbidden, "")
|
||||
}
|
||||
|
||||
@@ -217,7 +217,7 @@ func (h *RestreamHandler) PlayoutSetErrorframe(c echo.Context) error {
|
||||
user := util.DefaultContext(c, "user", "")
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
|
||||
if !h.iam.Enforce(user, domain, "process:"+id, "write") {
|
||||
if !h.iam.Enforce(user, domain, "process:", id, "write") {
|
||||
return api.Err(http.StatusForbidden, "")
|
||||
}
|
||||
|
||||
@@ -273,7 +273,7 @@ func (h *RestreamHandler) PlayoutReopenInput(c echo.Context) error {
|
||||
user := util.DefaultContext(c, "user", "")
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
|
||||
if !h.iam.Enforce(user, domain, "process:"+id, "write") {
|
||||
if !h.iam.Enforce(user, domain, "process:", id, "write") {
|
||||
return api.Err(http.StatusForbidden, "Forbidden")
|
||||
}
|
||||
|
||||
@@ -327,7 +327,7 @@ func (h *RestreamHandler) PlayoutSetStream(c echo.Context) error {
|
||||
user := util.DefaultContext(c, "user", "")
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
|
||||
if !h.iam.Enforce(user, domain, "process:"+id, "write") {
|
||||
if !h.iam.Enforce(user, domain, "process:", id, "write") {
|
||||
return api.Err(http.StatusForbidden, "")
|
||||
}
|
||||
|
||||
|
@@ -59,12 +59,12 @@ func (h *RestreamHandler) Add(c echo.Context) error {
|
||||
return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error())
|
||||
}
|
||||
|
||||
if !h.iam.Enforce(ctxuser, process.Domain, "process:"+process.ID, "write") {
|
||||
if !h.iam.Enforce(ctxuser, process.Domain, "process", process.ID, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "You are not allowed to write this process, check the domain and process ID")
|
||||
}
|
||||
|
||||
if !superuser {
|
||||
if !h.iam.Enforce(process.Owner, process.Domain, "process:"+process.ID, "write") {
|
||||
if !h.iam.Enforce(process.Owner, process.Domain, "process", process.ID, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "The owner '%s' is not allowed to write this process", process.Owner)
|
||||
}
|
||||
}
|
||||
@@ -131,7 +131,7 @@ func (h *RestreamHandler) GetAll(c echo.Context) error {
|
||||
ids := []app.ProcessID{}
|
||||
|
||||
for _, id := range preids {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+id.ID, "read") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process", id.ID, "read") {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -184,7 +184,7 @@ func (h *RestreamHandler) Get(c echo.Context) error {
|
||||
filter := util.DefaultQuery(c, "filter", "")
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "read") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process", id, "read") {
|
||||
return api.Err(http.StatusForbidden, "Forbidden")
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ func (h *RestreamHandler) Delete(c echo.Context) error {
|
||||
}
|
||||
|
||||
if !superuser {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process", id, "write") {
|
||||
return api.Err(http.StatusForbidden, "")
|
||||
}
|
||||
}
|
||||
@@ -271,7 +271,7 @@ func (h *RestreamHandler) Update(c echo.Context) error {
|
||||
Autostart: true,
|
||||
}
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process", id, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "You are not allowed to write this process: %s", id)
|
||||
}
|
||||
|
||||
@@ -292,12 +292,12 @@ func (h *RestreamHandler) Update(c echo.Context) error {
|
||||
return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error())
|
||||
}
|
||||
|
||||
if !h.iam.Enforce(ctxuser, process.Domain, "process:"+process.ID, "write") {
|
||||
if !h.iam.Enforce(ctxuser, process.Domain, "process", process.ID, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "You are not allowed to write this process: %s", process.ID)
|
||||
}
|
||||
|
||||
if !superuser {
|
||||
if !h.iam.Enforce(process.Owner, process.Domain, "process:"+process.ID, "write") {
|
||||
if !h.iam.Enforce(process.Owner, process.Domain, "process", process.ID, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "The owner '%s' is not allowed to write this process: %s", process.Owner, process.ID)
|
||||
}
|
||||
}
|
||||
@@ -352,7 +352,7 @@ func (h *RestreamHandler) Command(c echo.Context) error {
|
||||
ctxuser := util.DefaultContext(c, "user", "")
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process", id, "write") {
|
||||
return api.Err(http.StatusForbidden, "")
|
||||
}
|
||||
|
||||
@@ -406,7 +406,7 @@ func (h *RestreamHandler) GetConfig(c echo.Context) error {
|
||||
ctxuser := util.DefaultContext(c, "user", "")
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "read") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process", id, "read") {
|
||||
return api.Err(http.StatusForbidden, "")
|
||||
}
|
||||
|
||||
@@ -445,7 +445,7 @@ func (h *RestreamHandler) GetState(c echo.Context) error {
|
||||
ctxuser := util.DefaultContext(c, "user", "")
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "read") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process", id, "read") {
|
||||
return api.Err(http.StatusForbidden, "")
|
||||
}
|
||||
|
||||
@@ -507,7 +507,7 @@ func (h *RestreamHandler) GetReport(c echo.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "read") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process", id, "read") {
|
||||
return api.Err(http.StatusForbidden, "")
|
||||
}
|
||||
|
||||
@@ -651,7 +651,7 @@ func (h *RestreamHandler) Probe(c echo.Context) error {
|
||||
ctxuser := util.DefaultContext(c, "user", "")
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process", id, "write") {
|
||||
return api.Err(http.StatusForbidden, "")
|
||||
}
|
||||
|
||||
@@ -698,7 +698,7 @@ func (h *RestreamHandler) ProbeConfig(c echo.Context) error {
|
||||
return api.Err(http.StatusBadRequest, "", "invalid JSON: %s", err.Error())
|
||||
}
|
||||
|
||||
if !h.iam.Enforce(ctxuser, process.Domain, "process:"+process.ID, "write") {
|
||||
if !h.iam.Enforce(ctxuser, process.Domain, "process", process.ID, "write") {
|
||||
return api.Err(http.StatusForbidden, "", "You are not allowed to probe this process, check the domain and process ID")
|
||||
}
|
||||
|
||||
@@ -778,7 +778,7 @@ func (h *RestreamHandler) GetProcessMetadata(c echo.Context) error {
|
||||
ctxuser := util.DefaultContext(c, "user", "")
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "read") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process", id, "read") {
|
||||
return api.Err(http.StatusForbidden, "")
|
||||
}
|
||||
|
||||
@@ -821,7 +821,7 @@ func (h *RestreamHandler) SetProcessMetadata(c echo.Context) error {
|
||||
ctxuser := util.DefaultContext(c, "user", "")
|
||||
domain := util.DefaultQuery(c, "domain", "")
|
||||
|
||||
if !h.iam.Enforce(ctxuser, domain, "process:"+id, "write") {
|
||||
if !h.iam.Enforce(ctxuser, domain, "process", id, "write") {
|
||||
return api.Err(http.StatusForbidden, "")
|
||||
}
|
||||
|
||||
|
@@ -61,9 +61,9 @@ func getDummyRestreamHandler() (*RestreamHandler, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iam.AddPolicy("$anon", "$none", "api:/**", []string{"ANY"})
|
||||
iam.AddPolicy("$anon", "$none", "fs:/**", []string{"ANY"})
|
||||
iam.AddPolicy("$anon", "$none", "process:**", []string{"ANY"})
|
||||
iam.AddPolicy("$anon", "$none", []string{"api"}, "/**", []string{"ANY"})
|
||||
iam.AddPolicy("$anon", "$none", []string{"fs"}, "/**", []string{"ANY"})
|
||||
iam.AddPolicy("$anon", "$none", []string{"process"}, "**", []string{"ANY"})
|
||||
|
||||
handler := NewRestream(rs, iam)
|
||||
|
||||
|
@@ -124,6 +124,7 @@ func NewWithConfig(config Config) echo.MiddlewareFunc {
|
||||
|
||||
username := "$anon"
|
||||
resource := c.Request().URL.Path
|
||||
rtype := "fs"
|
||||
var domain string
|
||||
|
||||
c.Set("user", username)
|
||||
@@ -184,7 +185,7 @@ func NewWithConfig(config Config) echo.MiddlewareFunc {
|
||||
}
|
||||
|
||||
domain = c.QueryParam("domain")
|
||||
resource = "api:" + resource
|
||||
rtype = "api"
|
||||
} else {
|
||||
identity, err = mw.findIdentityFromSession(c)
|
||||
if err != nil {
|
||||
@@ -215,7 +216,7 @@ func NewWithConfig(config Config) echo.MiddlewareFunc {
|
||||
}
|
||||
|
||||
domain = mw.findDomainFromFilesystem(resource)
|
||||
resource = "fs:" + resource
|
||||
rtype = "fs"
|
||||
}
|
||||
|
||||
superuser := false
|
||||
@@ -234,11 +235,11 @@ func NewWithConfig(config Config) echo.MiddlewareFunc {
|
||||
|
||||
action := c.Request().Method
|
||||
|
||||
if username == "$anon" && resource == "api:/api" {
|
||||
if username == "$anon" && rtype == "api" && resource == "/api" {
|
||||
return next(c)
|
||||
}
|
||||
|
||||
if !config.IAM.Enforce(username, domain, resource, action) {
|
||||
if !config.IAM.Enforce(username, domain, rtype, resource, action) {
|
||||
return api.Err(http.StatusForbidden, "Forbidden", "access denied")
|
||||
}
|
||||
|
||||
@@ -263,7 +264,7 @@ func (m *iammiddleware) findIdentityFromBasicAuth(c echo.Context) (iamidentity.V
|
||||
domain = "$none"
|
||||
}
|
||||
|
||||
if !m.iam.Enforce("$anon", domain, "fs:"+path, c.Request().Method) {
|
||||
if !m.iam.Enforce("$anon", domain, "fs", path, c.Request().Method) {
|
||||
return nil, ErrAuthRequired
|
||||
}
|
||||
|
||||
|
@@ -101,7 +101,7 @@ func TestBasicAuth(t *testing.T) {
|
||||
iam, err := getIAM()
|
||||
require.NoError(t, err)
|
||||
|
||||
iam.AddPolicy("foobar", "$none", "fs:/**", []string{"ANY"})
|
||||
iam.AddPolicy("foobar", "$none", []string{"fs"}, "/**", []string{"ANY"})
|
||||
|
||||
e := echo.New()
|
||||
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
||||
@@ -160,7 +160,7 @@ func TestBasicAuthEncoding(t *testing.T) {
|
||||
iam, err := getIAM()
|
||||
require.NoError(t, err)
|
||||
|
||||
iam.AddPolicy("foobar:2", "$none", "fs:/**", []string{"ANY"})
|
||||
iam.AddPolicy("foobar:2", "$none", []string{"fs"}, "/**", []string{"ANY"})
|
||||
|
||||
e := echo.New()
|
||||
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
||||
@@ -196,9 +196,9 @@ func TestFindDomainFromFilesystem(t *testing.T) {
|
||||
iam, err := getIAM()
|
||||
require.NoError(t, err)
|
||||
|
||||
iam.AddPolicy("$anon", "$none", "fs:/**", []string{"ANY"})
|
||||
iam.AddPolicy("foobar", "group", "fs:/group/**", []string{"ANY"})
|
||||
iam.AddPolicy("foobar", "anothergroup", "fs:/memfs/anothergroup/**", []string{"ANY"})
|
||||
iam.AddPolicy("$anon", "$none", []string{"fs"}, "/**", []string{"ANY"})
|
||||
iam.AddPolicy("foobar", "group", []string{"fs"}, "/group/**", []string{"ANY"})
|
||||
iam.AddPolicy("foobar", "anothergroup", []string{"fs"}, "/memfs/anothergroup/**", []string{"ANY"})
|
||||
|
||||
mw := &iammiddleware{
|
||||
iam: iam,
|
||||
@@ -222,8 +222,8 @@ func TestBasicAuthDomain(t *testing.T) {
|
||||
iam, err := getIAM()
|
||||
require.NoError(t, err)
|
||||
|
||||
iam.AddPolicy("$anon", "$none", "fs:/**", []string{"ANY"})
|
||||
iam.AddPolicy("foobar", "group", "fs:/group/**", []string{"ANY"})
|
||||
iam.AddPolicy("$anon", "$none", []string{"fs"}, "/**", []string{"ANY"})
|
||||
iam.AddPolicy("foobar", "group", []string{"fs"}, "/group/**", []string{"ANY"})
|
||||
|
||||
e := echo.New()
|
||||
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
||||
@@ -255,7 +255,7 @@ func TestBasicAuthDomain(t *testing.T) {
|
||||
require.NoError(t, h(c))
|
||||
|
||||
// Allow anonymous group read access
|
||||
iam.AddPolicy("$anon", "group", "fs:/group/**", []string{"GET"})
|
||||
iam.AddPolicy("$anon", "group", []string{"fs"}, "/group/**", []string{"GET"})
|
||||
|
||||
req.Header.Del(echo.HeaderAuthorization)
|
||||
require.NoError(t, h(c))
|
||||
@@ -265,7 +265,7 @@ func TestAPILoginAndRefresh(t *testing.T) {
|
||||
iam, err := getIAM()
|
||||
require.NoError(t, err)
|
||||
|
||||
iam.AddPolicy("foobar", "$none", "api:/**", []string{"ANY"})
|
||||
iam.AddPolicy("foobar", "$none", []string{"api"}, "/**", []string{"ANY"})
|
||||
|
||||
jwthandler := apihandler.NewJWT(iam)
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package access
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/datarhei/core/v16/log"
|
||||
@@ -12,12 +13,13 @@ import (
|
||||
type Policy struct {
|
||||
Name string
|
||||
Domain string
|
||||
Types []string
|
||||
Resource string
|
||||
Actions []string
|
||||
}
|
||||
|
||||
type Enforcer interface {
|
||||
Enforce(name, domain, resource, action string) (bool, string)
|
||||
Enforce(name, domain, rtype, resource, action string) (bool, string)
|
||||
|
||||
HasDomain(name string) bool
|
||||
ListDomains() []string
|
||||
@@ -26,10 +28,10 @@ type Enforcer interface {
|
||||
type Manager interface {
|
||||
Enforcer
|
||||
|
||||
HasPolicy(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
|
||||
HasPolicy(name, domain string, types []string, resource string, actions []string) bool
|
||||
AddPolicy(name, domain string, types []string, resource string, actions []string) error
|
||||
RemovePolicy(name, domain string, types []string, resource string, actions []string) error
|
||||
ListPolicies(name, domain string, types []string, resource string, actions []string) []Policy
|
||||
ReloadPolicies() error
|
||||
}
|
||||
|
||||
@@ -77,14 +79,14 @@ func New(config Config) (Manager, error) {
|
||||
return am, nil
|
||||
}
|
||||
|
||||
func (am *access) HasPolicy(name, domain, resource string, actions []string) bool {
|
||||
policy := []string{name, domain, resource, strings.Join(actions, "|")}
|
||||
func (am *access) HasPolicy(name, domain string, types []string, resource string, actions []string) bool {
|
||||
policy := []string{name, domain, encodeResource(types, resource), encodeActions(actions)}
|
||||
|
||||
return am.enforcer.HasPolicy(policy)
|
||||
}
|
||||
|
||||
func (am *access) AddPolicy(name, domain, resource string, actions []string) error {
|
||||
policy := []string{name, domain, resource, strings.Join(actions, "|")}
|
||||
func (am *access) AddPolicy(name, domain string, types []string, resource string, actions []string) error {
|
||||
policy := []string{name, domain, encodeResource(types, resource), encodeActions(actions)}
|
||||
|
||||
if am.enforcer.HasPolicy(policy) {
|
||||
return nil
|
||||
@@ -95,24 +97,26 @@ func (am *access) AddPolicy(name, domain, resource string, actions []string) err
|
||||
return err
|
||||
}
|
||||
|
||||
func (am *access) RemovePolicy(name, domain, resource string, actions []string) error {
|
||||
policies := am.enforcer.GetFilteredPolicy(0, name, domain, resource, strings.Join(actions, "|"))
|
||||
func (am *access) RemovePolicy(name, domain string, types []string, resource string, actions []string) error {
|
||||
policies := am.enforcer.GetFilteredPolicy(0, name, domain, encodeResource(types, resource), encodeActions(actions))
|
||||
_, err := am.enforcer.RemovePolicies(policies)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func (am *access) ListPolicies(name, domain, resource string, actions []string) []Policy {
|
||||
func (am *access) ListPolicies(name, domain string, types []string, resource string, actions []string) []Policy {
|
||||
policies := []Policy{}
|
||||
|
||||
ps := am.enforcer.GetFilteredPolicy(0, name, domain, resource, strings.Join(actions, "|"))
|
||||
ps := am.enforcer.GetFilteredPolicy(0, name, domain, encodeResource(types, resource), encodeActions(actions))
|
||||
|
||||
for _, p := range ps {
|
||||
types, resource := decodeResource(p[2])
|
||||
policies = append(policies, Policy{
|
||||
Name: p[0],
|
||||
Domain: p[1],
|
||||
Resource: p[2],
|
||||
Actions: strings.Split(p[3], "|"),
|
||||
Types: types,
|
||||
Resource: resource,
|
||||
Actions: decodeActions(p[3]),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -133,8 +137,37 @@ func (am *access) ListDomains() []string {
|
||||
return am.adapter.AllDomains()
|
||||
}
|
||||
|
||||
func (am *access) Enforce(name, domain, resource, action string) (bool, string) {
|
||||
func (am *access) Enforce(name, domain, rtype, resource, action string) (bool, string) {
|
||||
resource = rtype + ":" + resource
|
||||
|
||||
ok, rule, _ := am.enforcer.EnforceEx(name, domain, resource, action)
|
||||
|
||||
return ok, strings.Join(rule, ", ")
|
||||
}
|
||||
|
||||
func encodeActions(actions []string) string {
|
||||
return strings.Join(actions, "|")
|
||||
}
|
||||
|
||||
func decodeActions(actions string) []string {
|
||||
return strings.Split(actions, "|")
|
||||
}
|
||||
|
||||
func encodeResource(types []string, resource string) string {
|
||||
if len(types) == 0 {
|
||||
return resource
|
||||
}
|
||||
|
||||
sort.Strings(types)
|
||||
|
||||
return strings.Join(types, "|") + ":" + resource
|
||||
}
|
||||
|
||||
func decodeResource(resource string) ([]string, string) {
|
||||
before, after, found := strings.Cut(resource, ":")
|
||||
if !found {
|
||||
return []string{}, resource
|
||||
}
|
||||
|
||||
return strings.Split(before, "|"), after
|
||||
}
|
||||
|
@@ -26,42 +26,47 @@ func TestAccessManager(t *testing.T) {
|
||||
})
|
||||
require.NoError(t, err)
|
||||
|
||||
policies := am.ListPolicies("", "", "", nil)
|
||||
policies := am.ListPolicies("", "", nil, "", nil)
|
||||
require.ElementsMatch(t, []Policy{
|
||||
{
|
||||
Name: "ingo",
|
||||
Domain: "$none",
|
||||
Resource: "rtmp:/bla-*",
|
||||
Types: []string{"rtmp"},
|
||||
Resource: "/bla-*",
|
||||
Actions: []string{"play", "publish"},
|
||||
},
|
||||
{
|
||||
Name: "ingo",
|
||||
Domain: "igelcamp",
|
||||
Resource: "rtmp:/igelcamp/**",
|
||||
Types: []string{"rtmp"},
|
||||
Resource: "/igelcamp/**",
|
||||
Actions: []string{"publish"},
|
||||
},
|
||||
}, policies)
|
||||
|
||||
am.AddPolicy("foobar", "group", "bla:/", []string{"write"})
|
||||
am.AddPolicy("foobar", "group", []string{"bla"}, "/", []string{"write"})
|
||||
|
||||
policies = am.ListPolicies("", "", "", nil)
|
||||
policies = am.ListPolicies("", "", nil, "", nil)
|
||||
require.ElementsMatch(t, []Policy{
|
||||
{
|
||||
Name: "ingo",
|
||||
Domain: "$none",
|
||||
Resource: "rtmp:/bla-*",
|
||||
Types: []string{"rtmp"},
|
||||
Resource: "/bla-*",
|
||||
Actions: []string{"play", "publish"},
|
||||
},
|
||||
{
|
||||
Name: "ingo",
|
||||
Domain: "igelcamp",
|
||||
Resource: "rtmp:/igelcamp/**",
|
||||
Types: []string{"rtmp"},
|
||||
Resource: "/igelcamp/**",
|
||||
Actions: []string{"publish"},
|
||||
},
|
||||
{
|
||||
Name: "foobar",
|
||||
Domain: "group",
|
||||
Resource: "bla:/",
|
||||
Types: []string{"bla"},
|
||||
Resource: "/",
|
||||
Actions: []string{"write"},
|
||||
},
|
||||
}, policies)
|
||||
@@ -70,14 +75,15 @@ func TestAccessManager(t *testing.T) {
|
||||
require.True(t, am.HasDomain("group"))
|
||||
require.False(t, am.HasDomain("$none"))
|
||||
|
||||
am.RemovePolicy("ingo", "", "", nil)
|
||||
am.RemovePolicy("ingo", "", nil, "", nil)
|
||||
|
||||
policies = am.ListPolicies("", "", "", nil)
|
||||
policies = am.ListPolicies("", "", nil, "", nil)
|
||||
require.ElementsMatch(t, []Policy{
|
||||
{
|
||||
Name: "foobar",
|
||||
Domain: "group",
|
||||
Resource: "bla:/",
|
||||
Types: []string{"bla"},
|
||||
Resource: "/",
|
||||
Actions: []string{"write"},
|
||||
},
|
||||
}, policies)
|
||||
@@ -86,9 +92,9 @@ func TestAccessManager(t *testing.T) {
|
||||
require.True(t, am.HasDomain("group"))
|
||||
require.False(t, am.HasDomain("$none"))
|
||||
|
||||
ok, _ := am.Enforce("foobar", "group", "bla:/", "read")
|
||||
ok, _ := am.Enforce("foobar", "group", "bla", "/", "read")
|
||||
require.False(t, ok)
|
||||
|
||||
ok, _ = am.Enforce("foobar", "group", "bla:/", "write")
|
||||
ok, _ = am.Enforce("foobar", "group", "bla", "/", "write")
|
||||
require.True(t, ok)
|
||||
}
|
||||
|
@@ -92,7 +92,7 @@ func (a *adapter) loadPolicyFile(model model.Model) error {
|
||||
rule[1] = "role:" + name
|
||||
for _, role := range roles {
|
||||
rule[3] = role.Resource
|
||||
rule[4] = formatActions(role.Actions)
|
||||
rule[4] = formatList(role.Actions)
|
||||
|
||||
if err := a.importPolicy(model, rule[0:5]); err != nil {
|
||||
return err
|
||||
@@ -103,7 +103,7 @@ func (a *adapter) loadPolicyFile(model model.Model) error {
|
||||
for _, policy := range domain.Policies {
|
||||
rule[1] = policy.Username
|
||||
rule[3] = policy.Resource
|
||||
rule[4] = formatActions(policy.Actions)
|
||||
rule[4] = formatList(policy.Actions)
|
||||
|
||||
if err := a.importPolicy(model, rule[0:5]); err != nil {
|
||||
return err
|
||||
@@ -220,7 +220,7 @@ func (a *adapter) addPolicy(ptype string, rule []string) error {
|
||||
username = rule[0]
|
||||
domain = rule[1]
|
||||
resource = rule[2]
|
||||
actions = formatActions(rule[3])
|
||||
actions = formatList(rule[3])
|
||||
|
||||
a.logger.Debug().WithFields(log.Fields{
|
||||
"subject": username,
|
||||
@@ -307,7 +307,7 @@ func (a *adapter) hasPolicy(ptype string, rule []string) (bool, error) {
|
||||
username = rule[0]
|
||||
domain = rule[1]
|
||||
resource = rule[2]
|
||||
actions = formatActions(rule[3])
|
||||
actions = formatList(rule[3])
|
||||
} else if ptype == "g" {
|
||||
if len(rule) < 3 {
|
||||
return false, fmt.Errorf("invalid rule length. must be 'user, role, domain'")
|
||||
@@ -348,13 +348,13 @@ func (a *adapter) hasPolicy(ptype string, rule []string) (bool, error) {
|
||||
}
|
||||
|
||||
for _, role := range roles {
|
||||
if role.Resource == resource && formatActions(role.Actions) == actions {
|
||||
if role.Resource == resource && formatList(role.Actions) == actions {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for _, p := range dom.Policies {
|
||||
if p.Username == username && p.Resource == resource && formatActions(p.Actions) == actions {
|
||||
if p.Username == username && p.Resource == resource && formatList(p.Actions) == actions {
|
||||
return true, nil
|
||||
}
|
||||
}
|
||||
@@ -420,7 +420,7 @@ func (a *adapter) removePolicy(ptype string, rule []string) error {
|
||||
username = rule[0]
|
||||
domain = rule[1]
|
||||
resource = rule[2]
|
||||
actions = formatActions(rule[3])
|
||||
actions = formatList(rule[3])
|
||||
|
||||
a.logger.Debug().WithFields(log.Fields{
|
||||
"subject": username,
|
||||
@@ -463,7 +463,7 @@ func (a *adapter) removePolicy(ptype string, rule []string) error {
|
||||
newRoles := []Role{}
|
||||
|
||||
for _, role := range roles {
|
||||
if role.Resource == resource && formatActions(role.Actions) == actions {
|
||||
if role.Resource == resource && formatList(role.Actions) == actions {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -475,7 +475,7 @@ func (a *adapter) removePolicy(ptype string, rule []string) error {
|
||||
policies := []DomainPolicy{}
|
||||
|
||||
for _, p := range dom.Policies {
|
||||
if p.Username == username && p.Resource == resource && formatActions(p.Actions) == actions {
|
||||
if p.Username == username && p.Resource == resource && formatList(p.Actions) == actions {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -579,8 +579,8 @@ type DomainPolicy struct {
|
||||
Role
|
||||
}
|
||||
|
||||
func formatActions(actions string) string {
|
||||
a := strings.Split(actions, "|")
|
||||
func formatList(list string) string {
|
||||
a := strings.Split(list, "|")
|
||||
|
||||
sort.Strings(a)
|
||||
|
||||
|
@@ -48,7 +48,7 @@ func TestFormatActions(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, d := range data {
|
||||
require.Equal(t, d[1], formatActions(d[0]), d[0])
|
||||
require.Equal(t, d[1], formatList(d[0]), d[0])
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -10,14 +10,28 @@ func resourceMatch(request, policy string) bool {
|
||||
reqPrefix, reqResource := getPrefix(request)
|
||||
polPrefix, polResource := getPrefix(policy)
|
||||
|
||||
if reqPrefix != polPrefix {
|
||||
var match bool = false
|
||||
var err error = nil
|
||||
|
||||
reqType := strings.ToLower(reqPrefix)
|
||||
polTypes := strings.Split(strings.ToLower(polPrefix), "|")
|
||||
|
||||
for _, polType := range polTypes {
|
||||
if reqType != polType {
|
||||
continue
|
||||
}
|
||||
|
||||
match = true
|
||||
break
|
||||
}
|
||||
|
||||
if !match {
|
||||
return false
|
||||
}
|
||||
|
||||
var match bool
|
||||
var err error
|
||||
match = false
|
||||
|
||||
if reqPrefix == "api" || reqPrefix == "fs" || reqPrefix == "rtmp" || reqPrefix == "srt" {
|
||||
if reqType == "api" || reqType == "fs" || reqType == "rtmp" || reqType == "srt" {
|
||||
match, err = glob.Match(polResource, reqResource, rune('/'))
|
||||
if err != nil {
|
||||
return false
|
||||
|
31
iam/iam.go
31
iam/iam.go
@@ -7,7 +7,7 @@ import (
|
||||
)
|
||||
|
||||
type Enforcer interface {
|
||||
Enforce(name, domain, resource, action string) bool
|
||||
Enforce(name, domain, rtype, resource, action string) bool
|
||||
}
|
||||
|
||||
type IAM interface {
|
||||
@@ -16,10 +16,10 @@ type IAM interface {
|
||||
HasDomain(domain string) bool
|
||||
ListDomains() []string
|
||||
|
||||
HasPolicy(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
|
||||
HasPolicy(name, domain string, types []string, resource string, actions []string) bool
|
||||
AddPolicy(name, domain string, types []string, resource string, actions []string) error
|
||||
RemovePolicy(name, domain string, types []string, resource string, actions []string) error
|
||||
ListPolicies(name, domain string, types []string, resource string, actions []string) []access.Policy
|
||||
ReloadPolicies() error
|
||||
|
||||
Validators() []string
|
||||
@@ -96,7 +96,7 @@ func (i *iam) Close() {
|
||||
i.am = nil
|
||||
}
|
||||
|
||||
func (i *iam) Enforce(name, domain, resource, action string) bool {
|
||||
func (i *iam) Enforce(name, domain, rtype, resource, action string) bool {
|
||||
if len(name) == 0 {
|
||||
name = "$anon"
|
||||
}
|
||||
@@ -116,6 +116,7 @@ func (i *iam) Enforce(name, domain, resource, action string) bool {
|
||||
l := i.logger.Debug().WithFields(log.Fields{
|
||||
"subject": name,
|
||||
"domain": domain,
|
||||
"type": rtype,
|
||||
"resource": resource,
|
||||
"action": action,
|
||||
"superuser": superuser,
|
||||
@@ -125,7 +126,7 @@ func (i *iam) Enforce(name, domain, resource, action string) bool {
|
||||
name = "$superuser"
|
||||
}
|
||||
|
||||
ok, rule := i.am.Enforce(name, domain, resource, action)
|
||||
ok, rule := i.am.Enforce(name, domain, rtype, resource, action)
|
||||
|
||||
if !ok {
|
||||
l.Log("no match")
|
||||
@@ -194,7 +195,7 @@ func (i *iam) Validators() []string {
|
||||
return i.im.Validators()
|
||||
}
|
||||
|
||||
func (i *iam) HasPolicy(name, domain, resource string, actions []string) bool {
|
||||
func (i *iam) HasPolicy(name, domain string, types []string, resource string, actions []string) bool {
|
||||
if len(name) == 0 {
|
||||
name = "$anon"
|
||||
}
|
||||
@@ -203,10 +204,10 @@ func (i *iam) HasPolicy(name, domain, resource string, actions []string) bool {
|
||||
domain = "$none"
|
||||
}
|
||||
|
||||
return i.am.HasPolicy(name, domain, resource, actions)
|
||||
return i.am.HasPolicy(name, domain, types, resource, actions)
|
||||
}
|
||||
|
||||
func (i *iam) AddPolicy(name, domain, resource string, actions []string) error {
|
||||
func (i *iam) AddPolicy(name, domain string, types []string, resource string, actions []string) error {
|
||||
if len(name) == 0 {
|
||||
name = "$anon"
|
||||
}
|
||||
@@ -222,10 +223,10 @@ func (i *iam) AddPolicy(name, domain, resource string, actions []string) error {
|
||||
}
|
||||
}
|
||||
|
||||
return i.am.AddPolicy(name, domain, resource, actions)
|
||||
return i.am.AddPolicy(name, domain, types, resource, actions)
|
||||
}
|
||||
|
||||
func (i *iam) RemovePolicy(name, domain, resource string, actions []string) error {
|
||||
func (i *iam) RemovePolicy(name, domain string, types []string, resource string, actions []string) error {
|
||||
if len(name) != 0 && name != "$anon" {
|
||||
if user, err := i.im.Get(name); err == nil {
|
||||
// Update the "updatedAt" field
|
||||
@@ -233,11 +234,11 @@ func (i *iam) RemovePolicy(name, domain, resource string, actions []string) erro
|
||||
}
|
||||
}
|
||||
|
||||
return i.am.RemovePolicy(name, domain, resource, actions)
|
||||
return i.am.RemovePolicy(name, domain, types, resource, actions)
|
||||
}
|
||||
|
||||
func (i *iam) ListPolicies(name, domain, resource string, actions []string) []access.Policy {
|
||||
return i.am.ListPolicies(name, domain, resource, actions)
|
||||
func (i *iam) ListPolicies(name, domain string, types []string, resource string, actions []string) []access.Policy {
|
||||
return i.am.ListPolicies(name, domain, types, resource, actions)
|
||||
}
|
||||
|
||||
func (i *iam) ReloadPolicies() error {
|
||||
|
@@ -69,7 +69,7 @@ func getDummyRestreamer(portrange net.Portranger, validatorIn, validatorOut ffmp
|
||||
return nil, err
|
||||
}
|
||||
|
||||
iam.AddPolicy("$anon", "$none", "process:*", []string{"CREATE", "GET", "DELETE", "UPDATE", "COMMAND", "PROBE", "METADATA", "PLAYOUT"})
|
||||
iam.AddPolicy("$anon", "$none", []string{"process"}, "*", []string{"CREATE", "GET", "DELETE", "UPDATE", "COMMAND", "PROBE", "METADATA", "PLAYOUT"})
|
||||
|
||||
rewriter, err := rewrite.New(rewrite.Config{
|
||||
IAM: iam,
|
||||
|
@@ -273,9 +273,9 @@ func (s *server) handlePlay(conn *rtmp.Conn) {
|
||||
}
|
||||
|
||||
domain := s.findDomainFromPlaypath(playpath)
|
||||
resource := "rtmp:" + playpath
|
||||
resource := playpath
|
||||
|
||||
if !s.iam.Enforce(identity, domain, resource, "PLAY") {
|
||||
if !s.iam.Enforce(identity, domain, "rtmp", resource, "PLAY") {
|
||||
s.log(identity, "PLAY", "FORBIDDEN", playpath, "access denied", remote)
|
||||
return
|
||||
}
|
||||
@@ -402,9 +402,9 @@ func (s *server) handlePublish(conn *rtmp.Conn) {
|
||||
}
|
||||
|
||||
domain := s.findDomainFromPlaypath(playpath)
|
||||
resource := "rtmp:" + playpath
|
||||
resource := playpath
|
||||
|
||||
if !s.iam.Enforce(identity, domain, resource, "PUBLISH") {
|
||||
if !s.iam.Enforce(identity, domain, "rtmp", resource, "PUBLISH") {
|
||||
s.log(identity, "PUBLISH", "FORBIDDEN", playpath, "access denied", remote)
|
||||
return
|
||||
}
|
||||
|
@@ -330,13 +330,13 @@ func (s *server) handleConnect(req srt.ConnRequest) srt.ConnType {
|
||||
}
|
||||
|
||||
domain := s.findDomainFromPlaypath(si.Resource)
|
||||
resource := "srt:" + si.Resource
|
||||
resource := si.Resource
|
||||
action := "PLAY"
|
||||
if mode == srt.PUBLISH {
|
||||
action = "PUBLISH"
|
||||
}
|
||||
|
||||
if !s.iam.Enforce(identity, domain, resource, action) {
|
||||
if !s.iam.Enforce(identity, domain, "srt", resource, action) {
|
||||
s.log(identity, "CONNECT", "FORBIDDEN", si.Resource, "access denied", client)
|
||||
return srt.REJECT
|
||||
}
|
||||
|
Reference in New Issue
Block a user