[MM-63421] add openID Authorization API-compliant PDP interface (#30462)
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
f8e16780ef
Коммит
3eb854c58d
@@ -37,3 +37,9 @@ var metricsInterfaceFn func(*PlatformService, string, string) einterfaces.Metric
|
|||||||
func RegisterMetricsInterface(f func(*PlatformService, string, string) einterfaces.MetricsInterface) {
|
func RegisterMetricsInterface(f func(*PlatformService, string, string) einterfaces.MetricsInterface) {
|
||||||
metricsInterfaceFn = f
|
metricsInterfaceFn = f
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var pdpInterface func(*PlatformService) einterfaces.PolicyDecisionPointInterface
|
||||||
|
|
||||||
|
func RegisterPdpInterface(f func(*PlatformService) einterfaces.PolicyDecisionPointInterface) {
|
||||||
|
pdpInterface = f
|
||||||
|
}
|
||||||
|
|||||||
@@ -111,6 +111,8 @@ type PlatformService struct {
|
|||||||
// This is a test mode setting used to enable Redis
|
// This is a test mode setting used to enable Redis
|
||||||
// without a license.
|
// without a license.
|
||||||
forceEnableRedis bool
|
forceEnableRedis bool
|
||||||
|
|
||||||
|
pdpService einterfaces.PolicyDecisionPointInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
type HookRunner interface {
|
type HookRunner interface {
|
||||||
@@ -474,6 +476,10 @@ func (ps *PlatformService) initEnterprise() {
|
|||||||
if licenseInterface != nil {
|
if licenseInterface != nil {
|
||||||
ps.licenseManager = licenseInterface(ps)
|
ps.licenseManager = licenseInterface(ps)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if pdpInterface != nil {
|
||||||
|
ps.pdpService = pdpInterface(ps)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ps *PlatformService) TotalWebsocketConnections() int {
|
func (ps *PlatformService) TotalWebsocketConnections() int {
|
||||||
|
|||||||
62
server/einterfaces/mocks/PolicyDecisionPointInterface.go
Обычный файл
62
server/einterfaces/mocks/PolicyDecisionPointInterface.go
Обычный файл
@@ -0,0 +1,62 @@
|
|||||||
|
// Code generated by mockery v2.42.2. DO NOT EDIT.
|
||||||
|
|
||||||
|
// Regenerate this file using `make einterfaces-mocks`.
|
||||||
|
|
||||||
|
package mocks
|
||||||
|
|
||||||
|
import (
|
||||||
|
model "github.com/mattermost/mattermost/server/public/model"
|
||||||
|
request "github.com/mattermost/mattermost/server/public/shared/request"
|
||||||
|
mock "github.com/stretchr/testify/mock"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PolicyDecisionPointInterface is an autogenerated mock type for the PolicyDecisionPointInterface type
|
||||||
|
type PolicyDecisionPointInterface struct {
|
||||||
|
mock.Mock
|
||||||
|
}
|
||||||
|
|
||||||
|
// AccessEvaluation provides a mock function with given fields: rctx, accessRequest
|
||||||
|
func (_m *PolicyDecisionPointInterface) AccessEvaluation(rctx request.CTX, accessRequest model.AccessRequest) (*model.AccessDecision, *model.AppError) {
|
||||||
|
ret := _m.Called(rctx, accessRequest)
|
||||||
|
|
||||||
|
if len(ret) == 0 {
|
||||||
|
panic("no return value specified for AccessEvaluation")
|
||||||
|
}
|
||||||
|
|
||||||
|
var r0 *model.AccessDecision
|
||||||
|
var r1 *model.AppError
|
||||||
|
if rf, ok := ret.Get(0).(func(request.CTX, model.AccessRequest) (*model.AccessDecision, *model.AppError)); ok {
|
||||||
|
return rf(rctx, accessRequest)
|
||||||
|
}
|
||||||
|
if rf, ok := ret.Get(0).(func(request.CTX, model.AccessRequest) *model.AccessDecision); ok {
|
||||||
|
r0 = rf(rctx, accessRequest)
|
||||||
|
} else {
|
||||||
|
if ret.Get(0) != nil {
|
||||||
|
r0 = ret.Get(0).(*model.AccessDecision)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if rf, ok := ret.Get(1).(func(request.CTX, model.AccessRequest) *model.AppError); ok {
|
||||||
|
r1 = rf(rctx, accessRequest)
|
||||||
|
} else {
|
||||||
|
if ret.Get(1) != nil {
|
||||||
|
r1 = ret.Get(1).(*model.AppError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return r0, r1
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPolicyDecisionPointInterface creates a new instance of PolicyDecisionPointInterface. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
|
||||||
|
// The first argument is typically a *testing.T value.
|
||||||
|
func NewPolicyDecisionPointInterface(t interface {
|
||||||
|
mock.TestingT
|
||||||
|
Cleanup(func())
|
||||||
|
}) *PolicyDecisionPointInterface {
|
||||||
|
mock := &PolicyDecisionPointInterface{}
|
||||||
|
mock.Mock.Test(t)
|
||||||
|
|
||||||
|
t.Cleanup(func() { mock.AssertExpectations(t) })
|
||||||
|
|
||||||
|
return mock
|
||||||
|
}
|
||||||
16
server/einterfaces/pdp.go
Обычный файл
16
server/einterfaces/pdp.go
Обычный файл
@@ -0,0 +1,16 @@
|
|||||||
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
|
package einterfaces
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/mattermost/mattermost/server/public/model"
|
||||||
|
"github.com/mattermost/mattermost/server/public/shared/request"
|
||||||
|
)
|
||||||
|
|
||||||
|
// PolicyDecisionPointInterface is the service that evaluates access requests
|
||||||
|
// using the OpenID Auth API spec. It determines whether a subject can perform
|
||||||
|
// an action on a resource based on the resource policy.
|
||||||
|
type PolicyDecisionPointInterface interface {
|
||||||
|
AccessEvaluation(rctx request.CTX, accessRequest model.AccessRequest) (*model.AccessDecision, *model.AppError)
|
||||||
|
}
|
||||||
43
server/public/model/access_request.go
Обычный файл
43
server/public/model/access_request.go
Обычный файл
@@ -0,0 +1,43 @@
|
|||||||
|
// Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
|
||||||
|
// See LICENSE.txt for license information.
|
||||||
|
|
||||||
|
package model
|
||||||
|
|
||||||
|
// Subject represents the user or a virtual entity for which the Authorization
|
||||||
|
// API is called.
|
||||||
|
type Subject struct {
|
||||||
|
// ID is the unique identifier of the Subject.
|
||||||
|
// it can be a user ID, bot ID, etc and it is scoped to the Type.
|
||||||
|
ID string `json:"id"`
|
||||||
|
// Type specifies the type of the Subject, eg. user, bot, etc.
|
||||||
|
Type string `json:"type"`
|
||||||
|
// Properties are the key-value pairs assicuated with the subject.
|
||||||
|
// An attribute may be single-valued or multi-valued and can be a primitive type
|
||||||
|
// (string, boolean, number) or a complex type like a JSON object or array.
|
||||||
|
Properties map[string]any `json:"properties"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// Resource is the target of an access request.
|
||||||
|
type Resource struct {
|
||||||
|
// ID is the unique identifier of the Resource.
|
||||||
|
// It can be a channel ID, post ID, etc and it is scoped to the Type.
|
||||||
|
ID string `json:"id"`
|
||||||
|
// Type specifies the type of the Resource, eg. channel, post, etc.
|
||||||
|
Type string `json:"type"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// AccessRequest represents the input to the Policy Decision Point (PDP).
|
||||||
|
// It contains the Subject, Resource, Action and optional Context attributes.
|
||||||
|
type AccessRequest struct {
|
||||||
|
Subject Subject `json:"subject"`
|
||||||
|
Resource Resource `json:"resource"`
|
||||||
|
Action string `json:"action"`
|
||||||
|
Context map[string]any `json:"context,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// The PDP evaluates the request and returns an AccessDecision.
|
||||||
|
// The Decision field is a boolean indicating whether the request is allowed or not.
|
||||||
|
type AccessDecision struct {
|
||||||
|
Decision bool `json:"decision"`
|
||||||
|
Context map[string]any `json:"context,omitempty"`
|
||||||
|
}
|
||||||
Ссылка в новой задаче
Block a user