Merge pull request #59 from owncloud/permission-endpoints
Add permission endpoint for extracting one permission from a set of roleIDs
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
Change: Add filter option for bundle ids in ListBundles and ListRoles
|
||||
|
||||
We added bundle ids as filter option for ListBundles and ListRoles and a new endpoint for fetching a permission by ID.
|
||||
|
||||
https://github.com/owncloud/ocis-settings/pull/59
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
// Code generated by fileb0x at "2020-08-26 18:01:22.299544 +0200 CEST m=+0.042142555" from config file "embed.yml" DO NOT EDIT.
|
||||
// modification hash(b166c77fcc0c0fbd95b4ebb476d86f32.8058aec596c5fb73022d09bb97af796e)
|
||||
// Code generated by fileb0x at "2020-08-27 15:42:12.738259 +0200 CEST m=+0.038980633" from config file "embed.yml" DO NOT EDIT.
|
||||
// modification hash(72fc92ee28815272b98623a481d7cc37.8058aec596c5fb73022d09bb97af796e)
|
||||
|
||||
package assets
|
||||
|
||||
|
||||
+688
-527
File diff suppressed because it is too large
Load Diff
@@ -579,6 +579,13 @@ func NewPermissionServiceEndpoints() []*api.Endpoint {
|
||||
Body: "*",
|
||||
Handler: "rpc",
|
||||
},
|
||||
&api.Endpoint{
|
||||
Name: "PermissionService.GetPermissionByID",
|
||||
Path: []string{"/api/v0/settings/permissions-get-by-id"},
|
||||
Method: []string{"POST"},
|
||||
Body: "*",
|
||||
Handler: "rpc",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -586,6 +593,7 @@ func NewPermissionServiceEndpoints() []*api.Endpoint {
|
||||
|
||||
type PermissionService interface {
|
||||
ListPermissionsByResource(ctx context.Context, in *ListPermissionsByResourceRequest, opts ...client.CallOption) (*ListPermissionsByResourceResponse, error)
|
||||
GetPermissionByID(ctx context.Context, in *GetPermissionByIDRequest, opts ...client.CallOption) (*GetPermissionByIDResponse, error)
|
||||
}
|
||||
|
||||
type permissionService struct {
|
||||
@@ -610,15 +618,27 @@ func (c *permissionService) ListPermissionsByResource(ctx context.Context, in *L
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func (c *permissionService) GetPermissionByID(ctx context.Context, in *GetPermissionByIDRequest, opts ...client.CallOption) (*GetPermissionByIDResponse, error) {
|
||||
req := c.c.NewRequest(c.name, "PermissionService.GetPermissionByID", in)
|
||||
out := new(GetPermissionByIDResponse)
|
||||
err := c.c.Call(ctx, req, out, opts...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
// Server API for PermissionService service
|
||||
|
||||
type PermissionServiceHandler interface {
|
||||
ListPermissionsByResource(context.Context, *ListPermissionsByResourceRequest, *ListPermissionsByResourceResponse) error
|
||||
GetPermissionByID(context.Context, *GetPermissionByIDRequest, *GetPermissionByIDResponse) error
|
||||
}
|
||||
|
||||
func RegisterPermissionServiceHandler(s server.Server, hdlr PermissionServiceHandler, opts ...server.HandlerOption) error {
|
||||
type permissionService interface {
|
||||
ListPermissionsByResource(ctx context.Context, in *ListPermissionsByResourceRequest, out *ListPermissionsByResourceResponse) error
|
||||
GetPermissionByID(ctx context.Context, in *GetPermissionByIDRequest, out *GetPermissionByIDResponse) error
|
||||
}
|
||||
type PermissionService struct {
|
||||
permissionService
|
||||
@@ -631,6 +651,13 @@ func RegisterPermissionServiceHandler(s server.Server, hdlr PermissionServiceHan
|
||||
Body: "*",
|
||||
Handler: "rpc",
|
||||
}))
|
||||
opts = append(opts, api.WithEndpoint(&api.Endpoint{
|
||||
Name: "PermissionService.GetPermissionByID",
|
||||
Path: []string{"/api/v0/settings/permissions-get-by-id"},
|
||||
Method: []string{"POST"},
|
||||
Body: "*",
|
||||
Handler: "rpc",
|
||||
}))
|
||||
return s.Handle(s.NewHandler(&PermissionService{h}, opts...))
|
||||
}
|
||||
|
||||
@@ -641,3 +668,7 @@ type permissionServiceHandler struct {
|
||||
func (h *permissionServiceHandler) ListPermissionsByResource(ctx context.Context, in *ListPermissionsByResourceRequest, out *ListPermissionsByResourceResponse) error {
|
||||
return h.PermissionServiceHandler.ListPermissionsByResource(ctx, in, out)
|
||||
}
|
||||
|
||||
func (h *permissionServiceHandler) GetPermissionByID(ctx context.Context, in *GetPermissionByIDRequest, out *GetPermissionByIDResponse) error {
|
||||
return h.PermissionServiceHandler.GetPermissionByID(ctx, in, out)
|
||||
}
|
||||
|
||||
@@ -422,6 +422,30 @@ func (h *webPermissionServiceHandler) ListPermissionsByResource(w http.ResponseW
|
||||
render.JSON(w, r, resp)
|
||||
}
|
||||
|
||||
func (h *webPermissionServiceHandler) GetPermissionByID(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
req := &GetPermissionByIDRequest{}
|
||||
|
||||
resp := &GetPermissionByIDResponse{}
|
||||
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusPreconditionFailed)
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.h.GetPermissionByID(
|
||||
r.Context(),
|
||||
req,
|
||||
resp,
|
||||
); err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
render.Status(r, http.StatusCreated)
|
||||
render.JSON(w, r, resp)
|
||||
}
|
||||
|
||||
func RegisterPermissionServiceWeb(r chi.Router, i PermissionServiceHandler, middlewares ...func(http.Handler) http.Handler) {
|
||||
handler := &webPermissionServiceHandler{
|
||||
r: r,
|
||||
@@ -429,6 +453,7 @@ func RegisterPermissionServiceWeb(r chi.Router, i PermissionServiceHandler, midd
|
||||
}
|
||||
|
||||
r.MethodFunc("POST", "/api/v0/settings/permissions-list-by-resource", handler.ListPermissionsByResource)
|
||||
r.MethodFunc("POST", "/api/v0/settings/permissions-get-by-id", handler.GetPermissionByID)
|
||||
}
|
||||
|
||||
// SaveBundleRequestJSONMarshaler describes the default jsonpb.Marshaler used by all
|
||||
@@ -1367,6 +1392,78 @@ func (m *ListPermissionsByResourceResponse) UnmarshalJSON(b []byte) error {
|
||||
|
||||
var _ json.Unmarshaler = (*ListPermissionsByResourceResponse)(nil)
|
||||
|
||||
// GetPermissionByIDRequestJSONMarshaler describes the default jsonpb.Marshaler used by all
|
||||
// instances of GetPermissionByIDRequest. This struct is safe to replace or modify but
|
||||
// should not be done so concurrently.
|
||||
var GetPermissionByIDRequestJSONMarshaler = new(jsonpb.Marshaler)
|
||||
|
||||
// MarshalJSON satisfies the encoding/json Marshaler interface. This method
|
||||
// uses the more correct jsonpb package to correctly marshal the message.
|
||||
func (m *GetPermissionByIDRequest) MarshalJSON() ([]byte, error) {
|
||||
if m == nil {
|
||||
return json.Marshal(nil)
|
||||
}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
|
||||
if err := GetPermissionByIDRequestJSONMarshaler.Marshal(buf, m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
var _ json.Marshaler = (*GetPermissionByIDRequest)(nil)
|
||||
|
||||
// GetPermissionByIDRequestJSONUnmarshaler describes the default jsonpb.Unmarshaler used by all
|
||||
// instances of GetPermissionByIDRequest. This struct is safe to replace or modify but
|
||||
// should not be done so concurrently.
|
||||
var GetPermissionByIDRequestJSONUnmarshaler = new(jsonpb.Unmarshaler)
|
||||
|
||||
// UnmarshalJSON satisfies the encoding/json Unmarshaler interface. This method
|
||||
// uses the more correct jsonpb package to correctly unmarshal the message.
|
||||
func (m *GetPermissionByIDRequest) UnmarshalJSON(b []byte) error {
|
||||
return GetPermissionByIDRequestJSONUnmarshaler.Unmarshal(bytes.NewReader(b), m)
|
||||
}
|
||||
|
||||
var _ json.Unmarshaler = (*GetPermissionByIDRequest)(nil)
|
||||
|
||||
// GetPermissionByIDResponseJSONMarshaler describes the default jsonpb.Marshaler used by all
|
||||
// instances of GetPermissionByIDResponse. This struct is safe to replace or modify but
|
||||
// should not be done so concurrently.
|
||||
var GetPermissionByIDResponseJSONMarshaler = new(jsonpb.Marshaler)
|
||||
|
||||
// MarshalJSON satisfies the encoding/json Marshaler interface. This method
|
||||
// uses the more correct jsonpb package to correctly marshal the message.
|
||||
func (m *GetPermissionByIDResponse) MarshalJSON() ([]byte, error) {
|
||||
if m == nil {
|
||||
return json.Marshal(nil)
|
||||
}
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
|
||||
if err := GetPermissionByIDResponseJSONMarshaler.Marshal(buf, m); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf.Bytes(), nil
|
||||
}
|
||||
|
||||
var _ json.Marshaler = (*GetPermissionByIDResponse)(nil)
|
||||
|
||||
// GetPermissionByIDResponseJSONUnmarshaler describes the default jsonpb.Unmarshaler used by all
|
||||
// instances of GetPermissionByIDResponse. This struct is safe to replace or modify but
|
||||
// should not be done so concurrently.
|
||||
var GetPermissionByIDResponseJSONUnmarshaler = new(jsonpb.Unmarshaler)
|
||||
|
||||
// UnmarshalJSON satisfies the encoding/json Unmarshaler interface. This method
|
||||
// uses the more correct jsonpb package to correctly unmarshal the message.
|
||||
func (m *GetPermissionByIDResponse) UnmarshalJSON(b []byte) error {
|
||||
return GetPermissionByIDResponseJSONUnmarshaler.Unmarshal(bytes.NewReader(b), m)
|
||||
}
|
||||
|
||||
var _ json.Unmarshaler = (*GetPermissionByIDResponse)(nil)
|
||||
|
||||
// ResourceJSONMarshaler describes the default jsonpb.Marshaler used by all
|
||||
// instances of Resource. This struct is safe to replace or modify but
|
||||
// should not be done so concurrently.
|
||||
|
||||
@@ -125,6 +125,12 @@ service PermissionService {
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
rpc GetPermissionByID(GetPermissionByIDRequest) returns (GetPermissionByIDResponse) {
|
||||
option (google.api.http) = {
|
||||
post: "/api/v0/settings/permissions-get-by-id",
|
||||
body: "*"
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
// ---
|
||||
@@ -147,6 +153,7 @@ message GetBundleResponse {
|
||||
}
|
||||
|
||||
message ListBundlesRequest {
|
||||
repeated string bundle_ids = 1;
|
||||
}
|
||||
|
||||
message ListBundlesResponse {
|
||||
@@ -259,6 +266,15 @@ message ListPermissionsByResourceResponse {
|
||||
repeated Permission permissions = 1;
|
||||
}
|
||||
|
||||
message GetPermissionByIDRequest {
|
||||
string permission_id = 1;
|
||||
repeated string role_ids = 2;
|
||||
}
|
||||
|
||||
message GetPermissionByIDResponse {
|
||||
Permission permission = 1;
|
||||
}
|
||||
|
||||
// ---
|
||||
// resource payloads
|
||||
// ---
|
||||
|
||||
@@ -280,6 +280,38 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/v0/settings/permissions-get-by-id": {
|
||||
"post": {
|
||||
"operationId": "PermissionService_GetPermissionByID",
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "A successful response.",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/protoGetPermissionByIDResponse"
|
||||
}
|
||||
},
|
||||
"default": {
|
||||
"description": "An unexpected error response",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/runtimeError"
|
||||
}
|
||||
}
|
||||
},
|
||||
"parameters": [
|
||||
{
|
||||
"name": "body",
|
||||
"in": "body",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/definitions/protoGetPermissionByIDRequest"
|
||||
}
|
||||
}
|
||||
],
|
||||
"tags": [
|
||||
"PermissionService"
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/v0/settings/permissions-list-by-resource": {
|
||||
"post": {
|
||||
"operationId": "PermissionService_ListPermissionsByResource",
|
||||
@@ -589,6 +621,28 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"protoGetPermissionByIDRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"permission_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"role_ids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"protoGetPermissionByIDResponse": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"permission": {
|
||||
"$ref": "#/definitions/protoPermission"
|
||||
}
|
||||
}
|
||||
},
|
||||
"protoGetValueByUniqueIdentifiersRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -655,7 +709,15 @@
|
||||
}
|
||||
},
|
||||
"protoListBundlesRequest": {
|
||||
"type": "object"
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"bundle_ids": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"protoListBundlesResponse": {
|
||||
"type": "object",
|
||||
|
||||
@@ -23,13 +23,16 @@ func Server(opts ...Option) grpc.Service {
|
||||
|
||||
handle := svc.NewService(options.Config, options.Logger)
|
||||
if err := proto.RegisterBundleServiceHandler(service.Server(), handle); err != nil {
|
||||
options.Logger.Fatal().Err(err).Msg("could not register SettingsBundles service handler")
|
||||
options.Logger.Fatal().Err(err).Msg("could not register Bundle service handler")
|
||||
}
|
||||
if err := proto.RegisterValueServiceHandler(service.Server(), handle); err != nil {
|
||||
options.Logger.Fatal().Err(err).Msg("could not register SettingsValues service handler")
|
||||
options.Logger.Fatal().Err(err).Msg("could not register Value service handler")
|
||||
}
|
||||
if err := proto.RegisterRoleServiceHandler(service.Server(), handle); err != nil {
|
||||
options.Logger.Fatal().Err(err).Msg("could not register SettingsRoles service handler")
|
||||
options.Logger.Fatal().Err(err).Msg("could not register Role service handler")
|
||||
}
|
||||
if err := proto.RegisterPermissionServiceHandler(service.Server(), handle); err != nil {
|
||||
options.Logger.Fatal().Err(err).Msg("could not register Permission service handler")
|
||||
}
|
||||
|
||||
service.Init()
|
||||
|
||||
@@ -66,6 +66,7 @@ func Server(opts ...Option) http.Service {
|
||||
proto.RegisterBundleServiceWeb(r, handle)
|
||||
proto.RegisterValueServiceWeb(r, handle)
|
||||
proto.RegisterRoleServiceWeb(r, handle)
|
||||
proto.RegisterPermissionServiceWeb(r, handle)
|
||||
})
|
||||
|
||||
service.Handle(
|
||||
|
||||
+51
-33
@@ -17,6 +17,7 @@ import (
|
||||
|
||||
// Service represents a service.
|
||||
type Service struct {
|
||||
id string
|
||||
config *config.Config
|
||||
logger log.Logger
|
||||
manager settings.Manager
|
||||
@@ -25,6 +26,7 @@ type Service struct {
|
||||
// NewService returns a service implementation for Service.
|
||||
func NewService(cfg *config.Config, logger log.Logger) Service {
|
||||
service := Service{
|
||||
id: "ocis-settings",
|
||||
config: cfg,
|
||||
logger: logger,
|
||||
manager: store.New(cfg),
|
||||
@@ -59,11 +61,11 @@ func (g Service) RegisterDefaultRoles() {
|
||||
func (g Service) SaveBundle(c context.Context, req *proto.SaveBundleRequest, res *proto.SaveBundleResponse) error {
|
||||
cleanUpResource(c, req.Bundle.Resource)
|
||||
if validationError := validateSaveBundle(req); validationError != nil {
|
||||
return merrors.BadRequest("ocis-settings", "%s", validationError)
|
||||
return merrors.BadRequest(g.id, "%s", validationError)
|
||||
}
|
||||
r, err := g.manager.WriteBundle(req.Bundle)
|
||||
if err != nil {
|
||||
return merrors.BadRequest("ocis-settings", "%s", err)
|
||||
return merrors.BadRequest(g.id, "%s", err)
|
||||
}
|
||||
res.Bundle = r
|
||||
return nil
|
||||
@@ -73,17 +75,17 @@ func (g Service) SaveBundle(c context.Context, req *proto.SaveBundleRequest, res
|
||||
func (g Service) GetBundle(c context.Context, req *proto.GetBundleRequest, res *proto.GetBundleResponse) error {
|
||||
accountUUID := getValidatedAccountUUID(c, "me")
|
||||
if validationError := validateGetBundle(req); validationError != nil {
|
||||
return merrors.BadRequest("ocis-settings", "%s", validationError)
|
||||
return merrors.BadRequest(g.id, "%s", validationError)
|
||||
}
|
||||
bundle, err := g.manager.ReadBundle(req.BundleId)
|
||||
if err != nil {
|
||||
return merrors.NotFound("ocis-settings", "%s", err)
|
||||
return merrors.NotFound(g.id, "%s", err)
|
||||
}
|
||||
roleIDs := g.getRoleIDs(c, accountUUID)
|
||||
filteredBundle := g.getFilteredBundle(roleIDs, bundle)
|
||||
if len(filteredBundle.Settings) == 0 {
|
||||
err = fmt.Errorf("could not read bundle: %s", req.BundleId)
|
||||
return merrors.NotFound("ocis-settings", "%s", err)
|
||||
return merrors.NotFound(g.id, "%s", err)
|
||||
}
|
||||
res.Bundle = filteredBundle
|
||||
return nil
|
||||
@@ -94,11 +96,11 @@ func (g Service) ListBundles(c context.Context, req *proto.ListBundlesRequest, r
|
||||
// fetch all bundles
|
||||
accountUUID := getValidatedAccountUUID(c, "me")
|
||||
if validationError := validateListBundles(req); validationError != nil {
|
||||
return merrors.BadRequest("ocis-settings", "%s", validationError)
|
||||
return merrors.BadRequest(g.id, "%s", validationError)
|
||||
}
|
||||
bundles, err := g.manager.ListBundles(proto.Bundle_TYPE_DEFAULT)
|
||||
bundles, err := g.manager.ListBundles(proto.Bundle_TYPE_DEFAULT, req.BundleIds)
|
||||
if err != nil {
|
||||
return merrors.NotFound("ocis-settings", "%s", err)
|
||||
return merrors.NotFound(g.id, "%s", err)
|
||||
}
|
||||
roleIDs := g.getRoleIDs(c, accountUUID)
|
||||
|
||||
@@ -154,11 +156,11 @@ func (g Service) getFilteredBundle(roleIDs []string, bundle *proto.Bundle) *prot
|
||||
func (g Service) AddSettingToBundle(c context.Context, req *proto.AddSettingToBundleRequest, res *proto.AddSettingToBundleResponse) error {
|
||||
cleanUpResource(c, req.Setting.Resource)
|
||||
if validationError := validateAddSettingToBundle(req); validationError != nil {
|
||||
return merrors.BadRequest("ocis-settings", "%s", validationError)
|
||||
return merrors.BadRequest(g.id, "%s", validationError)
|
||||
}
|
||||
r, err := g.manager.AddSettingToBundle(req.BundleId, req.Setting)
|
||||
if err != nil {
|
||||
return merrors.BadRequest("ocis-settings", "%s", err)
|
||||
return merrors.BadRequest(g.id, "%s", err)
|
||||
}
|
||||
res.Setting = r
|
||||
return nil
|
||||
@@ -167,10 +169,10 @@ func (g Service) AddSettingToBundle(c context.Context, req *proto.AddSettingToBu
|
||||
// RemoveSettingFromBundle implements the BundleServiceHandler interface
|
||||
func (g Service) RemoveSettingFromBundle(c context.Context, req *proto.RemoveSettingFromBundleRequest, _ *empty.Empty) error {
|
||||
if validationError := validateRemoveSettingFromBundle(req); validationError != nil {
|
||||
return merrors.BadRequest("ocis-settings", "%s", validationError)
|
||||
return merrors.BadRequest(g.id, "%s", validationError)
|
||||
}
|
||||
if err := g.manager.RemoveSettingFromBundle(req.BundleId, req.SettingId); err != nil {
|
||||
return merrors.BadRequest("ocis-settings", "%s", err)
|
||||
return merrors.BadRequest(g.id, "%s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -182,15 +184,15 @@ func (g Service) SaveValue(c context.Context, req *proto.SaveValueRequest, res *
|
||||
cleanUpResource(c, req.Value.Resource)
|
||||
// TODO: we need to check, if the authenticated user has permission to write the value for the specified resource (e.g. global, file with id xy, ...)
|
||||
if validationError := validateSaveValue(req); validationError != nil {
|
||||
return merrors.BadRequest("ocis-settings", "%s", validationError)
|
||||
return merrors.BadRequest(g.id, "%s", validationError)
|
||||
}
|
||||
r, err := g.manager.WriteValue(req.Value)
|
||||
if err != nil {
|
||||
return merrors.BadRequest("ocis-settings", "%s", err)
|
||||
return merrors.BadRequest(g.id, "%s", err)
|
||||
}
|
||||
valueWithIdentifier, err := g.getValueWithIdentifier(r)
|
||||
if err != nil {
|
||||
return merrors.NotFound("ocis-settings", "%s", err)
|
||||
return merrors.NotFound(g.id, "%s", err)
|
||||
}
|
||||
res.Value = valueWithIdentifier
|
||||
return nil
|
||||
@@ -199,15 +201,15 @@ func (g Service) SaveValue(c context.Context, req *proto.SaveValueRequest, res *
|
||||
// GetValue implements the ValueServiceHandler interface
|
||||
func (g Service) GetValue(c context.Context, req *proto.GetValueRequest, res *proto.GetValueResponse) error {
|
||||
if validationError := validateGetValue(req); validationError != nil {
|
||||
return merrors.BadRequest("ocis-settings", "%s", validationError)
|
||||
return merrors.BadRequest(g.id, "%s", validationError)
|
||||
}
|
||||
r, err := g.manager.ReadValue(req.Id)
|
||||
if err != nil {
|
||||
return merrors.NotFound("ocis-settings", "%s", err)
|
||||
return merrors.NotFound(g.id, "%s", err)
|
||||
}
|
||||
valueWithIdentifier, err := g.getValueWithIdentifier(r)
|
||||
if err != nil {
|
||||
return merrors.NotFound("ocis-settings", "%s", err)
|
||||
return merrors.NotFound(g.id, "%s", err)
|
||||
}
|
||||
res.Value = valueWithIdentifier
|
||||
return nil
|
||||
@@ -217,13 +219,13 @@ func (g Service) GetValue(c context.Context, req *proto.GetValueRequest, res *pr
|
||||
func (g Service) GetValueByUniqueIdentifiers(ctx context.Context, in *proto.GetValueByUniqueIdentifiersRequest, res *proto.GetValueResponse) error {
|
||||
v, err := g.manager.ReadValueByUniqueIdentifiers(in.AccountUuid, in.SettingId)
|
||||
if err != nil {
|
||||
return merrors.NotFound("ocis-settings", "%s", err)
|
||||
return merrors.NotFound(g.id, "%s", err)
|
||||
}
|
||||
|
||||
if v.BundleId != "" {
|
||||
valueWithIdentifier, err := g.getValueWithIdentifier(v)
|
||||
if err != nil {
|
||||
return merrors.NotFound("ocis-settings", "%s", err)
|
||||
return merrors.NotFound(g.id, "%s", err)
|
||||
}
|
||||
|
||||
res.Value = valueWithIdentifier
|
||||
@@ -235,11 +237,11 @@ func (g Service) GetValueByUniqueIdentifiers(ctx context.Context, in *proto.GetV
|
||||
func (g Service) ListValues(c context.Context, req *proto.ListValuesRequest, res *proto.ListValuesResponse) error {
|
||||
req.AccountUuid = getValidatedAccountUUID(c, req.AccountUuid)
|
||||
if validationError := validateListValues(req); validationError != nil {
|
||||
return merrors.BadRequest("ocis-settings", "%s", validationError)
|
||||
return merrors.BadRequest(g.id, "%s", validationError)
|
||||
}
|
||||
r, err := g.manager.ListValues(req.BundleId, req.AccountUuid)
|
||||
if err != nil {
|
||||
return merrors.NotFound("ocis-settings", "%s", err)
|
||||
return merrors.NotFound(g.id, "%s", err)
|
||||
}
|
||||
var result []*proto.ValueWithIdentifier
|
||||
for _, value := range r {
|
||||
@@ -256,11 +258,11 @@ func (g Service) ListValues(c context.Context, req *proto.ListValuesRequest, res
|
||||
func (g Service) ListRoles(c context.Context, req *proto.ListBundlesRequest, res *proto.ListBundlesResponse) error {
|
||||
//accountUUID := getValidatedAccountUUID(c, "me")
|
||||
if validationError := validateListRoles(req); validationError != nil {
|
||||
return merrors.BadRequest("ocis-settings", "%s", validationError)
|
||||
return merrors.BadRequest(g.id, "%s", validationError)
|
||||
}
|
||||
r, err := g.manager.ListBundles(proto.Bundle_TYPE_ROLE)
|
||||
r, err := g.manager.ListBundles(proto.Bundle_TYPE_ROLE, req.BundleIds)
|
||||
if err != nil {
|
||||
return merrors.NotFound("ocis-settings", "%s", err)
|
||||
return merrors.NotFound(g.id, "%s", err)
|
||||
}
|
||||
// TODO: only allow to list roles when user has account management permissions
|
||||
res.Bundles = r
|
||||
@@ -271,11 +273,11 @@ func (g Service) ListRoles(c context.Context, req *proto.ListBundlesRequest, res
|
||||
func (g Service) ListRoleAssignments(c context.Context, req *proto.ListRoleAssignmentsRequest, res *proto.ListRoleAssignmentsResponse) error {
|
||||
req.AccountUuid = getValidatedAccountUUID(c, req.AccountUuid)
|
||||
if validationError := validateListRoleAssignments(req); validationError != nil {
|
||||
return merrors.BadRequest("ocis-settings", "%s", validationError)
|
||||
return merrors.BadRequest(g.id, "%s", validationError)
|
||||
}
|
||||
r, err := g.manager.ListRoleAssignments(req.AccountUuid)
|
||||
if err != nil {
|
||||
return merrors.NotFound("ocis-settings", "%s", err)
|
||||
return merrors.NotFound(g.id, "%s", err)
|
||||
}
|
||||
res.Assignments = r
|
||||
return nil
|
||||
@@ -285,11 +287,11 @@ func (g Service) ListRoleAssignments(c context.Context, req *proto.ListRoleAssig
|
||||
func (g Service) AssignRoleToUser(c context.Context, req *proto.AssignRoleToUserRequest, res *proto.AssignRoleToUserResponse) error {
|
||||
req.AccountUuid = getValidatedAccountUUID(c, req.AccountUuid)
|
||||
if validationError := validateAssignRoleToUser(req); validationError != nil {
|
||||
return merrors.BadRequest("ocis-settings", "%s", validationError)
|
||||
return merrors.BadRequest(g.id, "%s", validationError)
|
||||
}
|
||||
r, err := g.manager.WriteRoleAssignment(req.AccountUuid, req.RoleId)
|
||||
if err != nil {
|
||||
return merrors.BadRequest("ocis-settings", "%s", err)
|
||||
return merrors.BadRequest(g.id, "%s", err)
|
||||
}
|
||||
res.Assignment = r
|
||||
return nil
|
||||
@@ -298,10 +300,10 @@ func (g Service) AssignRoleToUser(c context.Context, req *proto.AssignRoleToUser
|
||||
// RemoveRoleFromUser implements the RoleServiceHandler interface
|
||||
func (g Service) RemoveRoleFromUser(c context.Context, req *proto.RemoveRoleFromUserRequest, _ *empty.Empty) error {
|
||||
if validationError := validateRemoveRoleFromUser(req); validationError != nil {
|
||||
return merrors.BadRequest("ocis-settings", "%s", validationError)
|
||||
return merrors.BadRequest(g.id, "%s", validationError)
|
||||
}
|
||||
if err := g.manager.RemoveRoleAssignment(req.Id); err != nil {
|
||||
return merrors.BadRequest("ocis-settings", "%s", err)
|
||||
return merrors.BadRequest(g.id, "%s", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -309,16 +311,32 @@ func (g Service) RemoveRoleFromUser(c context.Context, req *proto.RemoveRoleFrom
|
||||
// ListPermissionsByResource implements the PermissionServiceHandler interface
|
||||
func (g Service) ListPermissionsByResource(c context.Context, req *proto.ListPermissionsByResourceRequest, res *proto.ListPermissionsByResourceResponse) error {
|
||||
if validationError := validateListPermissionsByResource(req); validationError != nil {
|
||||
return merrors.BadRequest("ocis-settings", "%s", validationError)
|
||||
return merrors.BadRequest(g.id, "%s", validationError)
|
||||
}
|
||||
permissions, err := g.manager.ListPermissionsByResource(req.Resource, req.RoleIds)
|
||||
if err != nil {
|
||||
return merrors.BadRequest("ocis-settings", "%s", err)
|
||||
return merrors.BadRequest(g.id, "%s", err)
|
||||
}
|
||||
res.Permissions = permissions
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetPermissionByID implements the PermissionServiceHandler interface
|
||||
func (g Service) GetPermissionByID(c context.Context, req *proto.GetPermissionByIDRequest, res *proto.GetPermissionByIDResponse) error {
|
||||
if validationError := validateGetPermissionByID(req); validationError != nil {
|
||||
return merrors.BadRequest(g.id, "%s", validationError)
|
||||
}
|
||||
permission, err := g.manager.ReadPermissionByID(req.PermissionId, req.RoleIds)
|
||||
if err != nil {
|
||||
return merrors.BadRequest(g.id, "%s", err)
|
||||
}
|
||||
if permission == nil {
|
||||
return merrors.NotFound(g.id, "%s", fmt.Errorf("permission %s not found in roles", req.PermissionId))
|
||||
}
|
||||
res.Permission = permission
|
||||
return nil
|
||||
}
|
||||
|
||||
// cleanUpResource makes sure that the account uuid of the authenticated user is injected if needed.
|
||||
func cleanUpResource(c context.Context, resource *proto.Resource) {
|
||||
if resource != nil && resource.Type == proto.Resource_TYPE_USER {
|
||||
|
||||
@@ -132,6 +132,14 @@ func validateListPermissionsByResource(req *proto.ListPermissionsByResourceReque
|
||||
)
|
||||
}
|
||||
|
||||
func validateGetPermissionByID(req *proto.GetPermissionByIDRequest) error {
|
||||
return validation.ValidateStruct(
|
||||
req,
|
||||
validation.Field(&req.PermissionId, requireAlphanumeric...),
|
||||
validation.Field(&req.RoleIds, validation.Each(requireAlphanumeric...)),
|
||||
)
|
||||
}
|
||||
|
||||
// validateResource is an internal helper for validating the content of a resource.
|
||||
func validateResource(resource *proto.Resource) error {
|
||||
if err := validation.Validate(&resource, validation.Required); err != nil {
|
||||
|
||||
@@ -23,7 +23,7 @@ type Manager interface {
|
||||
|
||||
// BundleManager is a bundle service interface for abstraction of storage implementations
|
||||
type BundleManager interface {
|
||||
ListBundles(bundleType proto.Bundle_Type) ([]*proto.Bundle, error)
|
||||
ListBundles(bundleType proto.Bundle_Type, bundleIDs []string) ([]*proto.Bundle, error)
|
||||
ReadBundle(bundleID string) (*proto.Bundle, error)
|
||||
WriteBundle(bundle *proto.Bundle) (*proto.Bundle, error)
|
||||
ReadSetting(settingID string) (*proto.Setting, error)
|
||||
@@ -49,4 +49,5 @@ type RoleAssignmentManager interface {
|
||||
// PermissionManager is a permissions service interface for abstraction of storage implementations
|
||||
type PermissionManager interface {
|
||||
ListPermissionsByResource(resource *proto.Resource, roleIDs []string) ([]*proto.Permission, error)
|
||||
ReadPermissionByID(permissionID string, roleIDs []string) (*proto.Permission, error)
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
var m = &sync.RWMutex{}
|
||||
|
||||
// ListBundles returns all bundles in the dataPath folder that match the given type.
|
||||
func (s Store) ListBundles(bundleType proto.Bundle_Type) ([]*proto.Bundle, error) {
|
||||
func (s Store) ListBundles(bundleType proto.Bundle_Type, bundleIDs []string) ([]*proto.Bundle, error) {
|
||||
// FIXME: list requests should be ran against a cache, not FS
|
||||
m.RLock()
|
||||
defer m.RUnlock()
|
||||
@@ -36,12 +36,25 @@ func (s Store) ListBundles(bundleType proto.Bundle_Type) ([]*proto.Bundle, error
|
||||
if record.Type != bundleType {
|
||||
continue
|
||||
}
|
||||
if len(bundleIDs) > 0 && !containsStr(record.Id, bundleIDs) {
|
||||
continue
|
||||
}
|
||||
records = append(records, &record)
|
||||
}
|
||||
|
||||
return records, nil
|
||||
}
|
||||
|
||||
// containsStr checks if the strs slice contains str
|
||||
func containsStr(str string, strs []string) bool {
|
||||
for _, s := range strs {
|
||||
if s == str {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// ReadBundle tries to find a bundle by the given id within the dataPath.
|
||||
func (s Store) ReadBundle(bundleID string) (*proto.Bundle, error) {
|
||||
m.RLock()
|
||||
@@ -62,7 +75,7 @@ func (s Store) ReadSetting(settingID string) (*proto.Setting, error) {
|
||||
m.RLock()
|
||||
defer m.RUnlock()
|
||||
|
||||
bundles, err := s.ListBundles(proto.Bundle_TYPE_DEFAULT)
|
||||
bundles, err := s.ListBundles(proto.Bundle_TYPE_DEFAULT, []string{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@ func TestBundles(t *testing.T) {
|
||||
}
|
||||
|
||||
// check that ListBundles only returns bundles with type DEFAULT
|
||||
bundles, err := s.ListBundles(proto.Bundle_TYPE_DEFAULT)
|
||||
bundles, err := s.ListBundles(proto.Bundle_TYPE_DEFAULT, []string{})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
@@ -132,8 +132,18 @@ func TestBundles(t *testing.T) {
|
||||
assert.Equal(t, proto.Bundle_TYPE_DEFAULT, bundles[i].Type)
|
||||
}
|
||||
|
||||
// check that ListBundles filtered by an id only returns that bundle
|
||||
filteredBundles, err := s.ListBundles(proto.Bundle_TYPE_DEFAULT, []string{bundle2})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
assert.Equal(t, 1, len(filteredBundles))
|
||||
if len(filteredBundles) == 1 {
|
||||
assert.Equal(t, bundle2, filteredBundles[0].Id)
|
||||
}
|
||||
|
||||
// check that ListRoles only returns bundles with type ROLE
|
||||
roles, err := s.ListBundles(proto.Bundle_TYPE_ROLE)
|
||||
roles, err := s.ListBundles(proto.Bundle_TYPE_ROLE, []string{})
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
@@ -19,14 +19,32 @@ func (s Store) ListPermissionsByResource(resource *proto.Resource, roleIDs []str
|
||||
return records, nil
|
||||
}
|
||||
|
||||
// ReadPermissionByID finds the permission in the roles, specified by the provided roleIDs
|
||||
func (s Store) ReadPermissionByID(permissionID string, roleIDs []string) (*proto.Permission, error) {
|
||||
for _, roleID := range roleIDs {
|
||||
role, err := s.ReadBundle(roleID)
|
||||
if err != nil {
|
||||
s.Logger.Debug().Str("roleID", roleID).Msg("role not found, skipping")
|
||||
continue
|
||||
}
|
||||
for _, permission := range role.Settings {
|
||||
if permission.Id == permissionID {
|
||||
if value, ok := permission.Value.(*proto.Setting_PermissionValue); ok {
|
||||
return value.PermissionValue, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
// extractPermissionsByResource collects all permissions from the provided role that match the requested resource
|
||||
func extractPermissionsByResource(resource *proto.Resource, role *proto.Bundle) []*proto.Permission {
|
||||
permissions := make([]*proto.Permission, 0)
|
||||
for _, setting := range role.Settings {
|
||||
if _, ok := setting.Value.(*proto.Setting_PermissionValue); ok {
|
||||
value := setting.Value.(*proto.Setting_PermissionValue).PermissionValue
|
||||
if value, ok := setting.Value.(*proto.Setting_PermissionValue); ok {
|
||||
if util.IsResourceMatched(setting.Resource, resource) {
|
||||
permissions = append(permissions, value)
|
||||
permissions = append(permissions, value.PermissionValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,6 +395,52 @@ export const BundleService_RemoveSettingFromBundleURL = function(parameters = {}
|
||||
let keys = Object.keys(queryParameters)
|
||||
return domain + path + (keys.length > 0 ? '?' + (keys.map(key => key + '=' + encodeURIComponent(queryParameters[key])).join('&')) : '')
|
||||
}
|
||||
/**
|
||||
*
|
||||
* request: PermissionService_GetPermissionById
|
||||
* url: PermissionService_GetPermissionByIdURL
|
||||
* method: PermissionService_GetPermissionById_TYPE
|
||||
* raw_url: PermissionService_GetPermissionById_RAW_URL
|
||||
* @param body -
|
||||
*/
|
||||
export const PermissionService_GetPermissionById = function(parameters = {}) {
|
||||
const domain = parameters.$domain ? parameters.$domain : getDomain()
|
||||
const config = parameters.$config
|
||||
let path = '/api/v0/settings/permissions-get-by-id'
|
||||
let body
|
||||
let queryParameters = {}
|
||||
let form = {}
|
||||
if (parameters['body'] !== undefined) {
|
||||
body = parameters['body']
|
||||
}
|
||||
if (parameters['body'] === undefined) {
|
||||
return Promise.reject(new Error('Missing required parameter: body'))
|
||||
}
|
||||
if (parameters.$queryParameters) {
|
||||
Object.keys(parameters.$queryParameters).forEach(function(parameterName) {
|
||||
queryParameters[parameterName] = parameters.$queryParameters[parameterName]
|
||||
});
|
||||
}
|
||||
return request('post', domain + path, body, queryParameters, form, config)
|
||||
}
|
||||
export const PermissionService_GetPermissionById_RAW_URL = function() {
|
||||
return '/api/v0/settings/permissions-get-by-id'
|
||||
}
|
||||
export const PermissionService_GetPermissionById_TYPE = function() {
|
||||
return 'post'
|
||||
}
|
||||
export const PermissionService_GetPermissionByIdURL = function(parameters = {}) {
|
||||
let queryParameters = {}
|
||||
const domain = parameters.$domain ? parameters.$domain : getDomain()
|
||||
let path = '/api/v0/settings/permissions-get-by-id'
|
||||
if (parameters.$queryParameters) {
|
||||
Object.keys(parameters.$queryParameters).forEach(function(parameterName) {
|
||||
queryParameters[parameterName] = parameters.$queryParameters[parameterName]
|
||||
})
|
||||
}
|
||||
let keys = Object.keys(queryParameters)
|
||||
return domain + path + (keys.length > 0 ? '?' + (keys.map(key => key + '=' + encodeURIComponent(queryParameters[key])).join('&')) : '')
|
||||
}
|
||||
/**
|
||||
*
|
||||
* request: PermissionService_ListPermissionsByResource
|
||||
|
||||
Reference in New Issue
Block a user