From f57a4ecb6087db94ed0045247785f427ec8230fc Mon Sep 17 00:00:00 2001 From: David Christofas Date: Fri, 17 Dec 2021 16:50:37 +0100 Subject: [PATCH] add permission service implementation for CI I add a special ocis CI manager since our "real" implementation is in the ocis repository, which I don't want to import into reva. --- .drone.star | 1 + cmd/revad/runtime/loader.go | 1 + internal/grpc/services/gateway/permissions.go | 2 +- internal/grpc/services/loader/loader.go | 1 + .../grpc/services/permissions/permissions.go | 104 ++++++++++++++++++ pkg/permission/manager/loader/loader.go | 25 +++++ pkg/permission/manager/ocisci/ocisci.go | 43 ++++++++ pkg/permission/manager/registry/registry.go | 34 ++++++ pkg/permission/permission.go | 27 +++++ .../oc-integration-tests/drone/frontend.toml | 1 - tests/oc-integration-tests/drone/gateway.toml | 2 + .../drone/permissions-ocis-ci.toml | 12 ++ .../drone/storage-home-ocis.toml | 2 + .../drone/storage-users-ocis.toml | 2 + .../oc-integration-tests/local/frontend.toml | 1 - tests/oc-integration-tests/local/gateway.toml | 2 + .../local/permissions-ocis-ci.toml | 12 ++ .../local/storage-home.toml | 1 + .../local/storage-users.toml | 1 + 19 files changed, 271 insertions(+), 3 deletions(-) create mode 100644 internal/grpc/services/permissions/permissions.go create mode 100644 pkg/permission/manager/loader/loader.go create mode 100644 pkg/permission/manager/ocisci/ocisci.go create mode 100644 pkg/permission/manager/registry/registry.go create mode 100644 pkg/permission/permission.go create mode 100644 tests/oc-integration-tests/drone/permissions-ocis-ci.toml create mode 100644 tests/oc-integration-tests/local/permissions-ocis-ci.toml diff --git a/.drone.star b/.drone.star index 2cff58c71f8..ccd2eb42ca6 100644 --- a/.drone.star +++ b/.drone.star @@ -679,6 +679,7 @@ def litmusOcisSpacesDav(): "/drone/src/cmd/revad/revad -c gateway.toml &", "/drone/src/cmd/revad/revad -c storage-home-ocis.toml &", "/drone/src/cmd/revad/revad -c storage-users-ocis.toml &", + "/drone/src/cmd/revad/revad -c permissions-ocis-ci.toml &", "/drone/src/cmd/revad/revad -c users.toml", ] }, diff --git a/cmd/revad/runtime/loader.go b/cmd/revad/runtime/loader.go index 93f5c68acee..a0df6920276 100644 --- a/cmd/revad/runtime/loader.go +++ b/cmd/revad/runtime/loader.go @@ -38,6 +38,7 @@ import ( _ "github.com/cs3org/reva/pkg/ocm/invite/manager/loader" _ "github.com/cs3org/reva/pkg/ocm/provider/authorizer/loader" _ "github.com/cs3org/reva/pkg/ocm/share/manager/loader" + _ "github.com/cs3org/reva/pkg/permission/manager/loader" _ "github.com/cs3org/reva/pkg/publicshare/manager/loader" _ "github.com/cs3org/reva/pkg/rhttp/datatx/manager/loader" _ "github.com/cs3org/reva/pkg/share/cache/loader" diff --git a/internal/grpc/services/gateway/permissions.go b/internal/grpc/services/gateway/permissions.go index faf26f22450..2b1806633ad 100644 --- a/internal/grpc/services/gateway/permissions.go +++ b/internal/grpc/services/gateway/permissions.go @@ -1,4 +1,4 @@ -// Copyright 2018-2021 CERN +// Copyright 2021 CERN // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/internal/grpc/services/loader/loader.go b/internal/grpc/services/loader/loader.go index 118eeed39ee..e0161997d24 100644 --- a/internal/grpc/services/loader/loader.go +++ b/internal/grpc/services/loader/loader.go @@ -33,6 +33,7 @@ import ( _ "github.com/cs3org/reva/internal/grpc/services/ocminvitemanager" _ "github.com/cs3org/reva/internal/grpc/services/ocmproviderauthorizer" _ "github.com/cs3org/reva/internal/grpc/services/ocmshareprovider" + _ "github.com/cs3org/reva/internal/grpc/services/permissions" _ "github.com/cs3org/reva/internal/grpc/services/preferences" _ "github.com/cs3org/reva/internal/grpc/services/publicshareprovider" _ "github.com/cs3org/reva/internal/grpc/services/publicstorageprovider" diff --git a/internal/grpc/services/permissions/permissions.go b/internal/grpc/services/permissions/permissions.go new file mode 100644 index 00000000000..4479fdb88c6 --- /dev/null +++ b/internal/grpc/services/permissions/permissions.go @@ -0,0 +1,104 @@ +// Copyright 2021 CERN +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// In applying this license, CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +package permissions + +import ( + "context" + "fmt" + + permissions "github.com/cs3org/go-cs3apis/cs3/permissions/v1beta1" + rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1" + "github.com/cs3org/reva/pkg/permission" + "github.com/cs3org/reva/pkg/permission/manager/registry" + "github.com/cs3org/reva/pkg/rgrpc" + "github.com/mitchellh/mapstructure" + "github.com/pkg/errors" + "google.golang.org/grpc" +) + +func init() { + rgrpc.Register("permissions", New) +} + +type config struct { + Driver string `mapstructure:"driver" docs:"localhome;The permission driver to be used."` + Drivers map[string]map[string]interface{} `mapstructure:"drivers" docs:"url:pkg/permission/permission.go"` +} + +func parseConfig(m map[string]interface{}) (*config, error) { + c := &config{} + if err := mapstructure.Decode(m, c); err != nil { + err = errors.Wrap(err, "error decoding conf") + return nil, err + } + return c, nil +} + +type service struct { + manager permission.Manager +} + +// New returns a new PermissionsServiceServer +func New(m map[string]interface{}, ss *grpc.Server) (rgrpc.Service, error) { + c, err := parseConfig(m) + if err != nil { + return nil, err + } + + f, ok := registry.NewFuncs[c.Driver] + if !ok { + return nil, fmt.Errorf("could not get permission manager '%s'", c.Driver) + } + manager, err := f(c.Drivers[c.Driver]) + if err != nil { + return nil, err + } + + service := &service{manager: manager} + return service, nil +} + +func (s *service) Close() error { + return nil +} + +func (s *service) UnprotectedEndpoints() []string { + return []string{} +} + +func (s *service) Register(ss *grpc.Server) { + permissions.RegisterPermissionsAPIServer(ss, s) +} + +func (s *service) CheckPermission(ctx context.Context, req *permissions.CheckPermissionRequest) (*permissions.CheckPermissionResponse, error) { + var subject string + switch ref := req.SubjectRef.Spec.(type) { + case *permissions.SubjectReference_UserId: + subject = ref.UserId.OpaqueId + case *permissions.SubjectReference_GroupId: + subject = ref.GroupId.OpaqueId + } + var status *rpc.Status + if ok := s.manager.CheckPermission(req.Permission, subject, req.Ref); ok { + status = &rpc.Status{Code: rpc.Code_CODE_OK} + } else { + status = &rpc.Status{Code: rpc.Code_CODE_PERMISSION_DENIED} + } + return &permissions.CheckPermissionResponse{Status: status}, nil +} diff --git a/pkg/permission/manager/loader/loader.go b/pkg/permission/manager/loader/loader.go new file mode 100644 index 00000000000..a1598bd3883 --- /dev/null +++ b/pkg/permission/manager/loader/loader.go @@ -0,0 +1,25 @@ +// Copyright 2021 CERN +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// In applying this license, CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +package loader + +import ( + // Load permission manager drivers + _ "github.com/cs3org/reva/pkg/permission/manager/ocisci" + // Add your own here +) diff --git a/pkg/permission/manager/ocisci/ocisci.go b/pkg/permission/manager/ocisci/ocisci.go new file mode 100644 index 00000000000..340bc88db67 --- /dev/null +++ b/pkg/permission/manager/ocisci/ocisci.go @@ -0,0 +1,43 @@ +// Copyright 2021 CERN +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// In applying this license, CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +package ocisci + +import ( + provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" + "github.com/cs3org/reva/pkg/permission" + "github.com/cs3org/reva/pkg/permission/manager/registry" +) + +func init() { + registry.Register("ocisci", New) +} + +// New returns a new permission manager specific for the CI +func New(c map[string]interface{}) (permission.Manager, error) { + return manager{}, nil +} + +type manager struct { +} + +func (m manager) CheckPermission(permission string, subject string, ref *provider.Reference) bool { + // We can currently return false all the time. + // Once we beginn testing roles we need to somehow check the roles of the users here + return false +} diff --git a/pkg/permission/manager/registry/registry.go b/pkg/permission/manager/registry/registry.go new file mode 100644 index 00000000000..26f55bebade --- /dev/null +++ b/pkg/permission/manager/registry/registry.go @@ -0,0 +1,34 @@ +// Copyright 2021 CERN +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// In applying this license, CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +package registry + +import "github.com/cs3org/reva/pkg/permission" + +// NewFunc is the function that permission managers +// should register at init time. +type NewFunc func(map[string]interface{}) (permission.Manager, error) + +// NewFuncs is a map containing all the registered share managers. +var NewFuncs = map[string]NewFunc{} + +// Register registers a new permission manager new function. +// Not safe for concurrent use. Safe for use from package init. +func Register(name string, f NewFunc) { + NewFuncs[name] = f +} diff --git a/pkg/permission/permission.go b/pkg/permission/permission.go new file mode 100644 index 00000000000..5483000ce24 --- /dev/null +++ b/pkg/permission/permission.go @@ -0,0 +1,27 @@ +// Copyright 2021 CERN +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// In applying this license, CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +package permission + +import ( + provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1" +) + +type Manager interface { + CheckPermission(permission string, subject string, ref *provider.Reference) bool +} diff --git a/tests/oc-integration-tests/drone/frontend.toml b/tests/oc-integration-tests/drone/frontend.toml index ce4f7f90d36..84ed3b43f78 100644 --- a/tests/oc-integration-tests/drone/frontend.toml +++ b/tests/oc-integration-tests/drone/frontend.toml @@ -59,7 +59,6 @@ files_namespace = "/users" webdav_namespace = "/home" [http.services.ocs] -storage_registry_svc = "localhost:19000" [http.services.ocs.capabilities.capabilities.core.status] version = "10.0.11.5" diff --git a/tests/oc-integration-tests/drone/gateway.toml b/tests/oc-integration-tests/drone/gateway.toml index e00e43158da..85c17b20c22 100644 --- a/tests/oc-integration-tests/drone/gateway.toml +++ b/tests/oc-integration-tests/drone/gateway.toml @@ -30,6 +30,8 @@ ocmcoresvc = "localhost:14000" ocmshareprovidersvc = "localhost:14000" ocminvitemanagersvc = "localhost:14000" ocmproviderauthorizersvc = "localhost:14000" +# permissions +permissionssvc = "localhost:10000" # other commit_share_to_storage_grant = true commit_share_to_storage_ref = true diff --git a/tests/oc-integration-tests/drone/permissions-ocis-ci.toml b/tests/oc-integration-tests/drone/permissions-ocis-ci.toml new file mode 100644 index 00000000000..d97d4687d32 --- /dev/null +++ b/tests/oc-integration-tests/drone/permissions-ocis-ci.toml @@ -0,0 +1,12 @@ +# This config file will start a reva service that: +# - serves the ocis ci permissions service +[shared] +jwt_secret = "Pive-Fumkiu4" + +[grpc] +address = "0.0.0.0:10000" + +[grpc.services.permissions] +driver = "ocisci" + +[grpc.services.publicshareprovider.drivers.ocisci] diff --git a/tests/oc-integration-tests/drone/storage-home-ocis.toml b/tests/oc-integration-tests/drone/storage-home-ocis.toml index dbc0748f0a5..098aaf7fcab 100644 --- a/tests/oc-integration-tests/drone/storage-home-ocis.toml +++ b/tests/oc-integration-tests/drone/storage-home-ocis.toml @@ -23,12 +23,14 @@ mount_id = "123e4567-e89b-12d3-a456-426655440000" expose_data_server = true data_server_url = "http://revad-services:12001/data" enable_home_creation = true +gateway_addr = "0.0.0.0:19000" [grpc.services.storageprovider.drivers.ocis] root = "/drone/src/tmp/reva/data" enable_home = true treetime_accounting = true treesize_accounting = true +gateway_addr = "0.0.0.0:19000" # we have a locally running dataprovider [http] diff --git a/tests/oc-integration-tests/drone/storage-users-ocis.toml b/tests/oc-integration-tests/drone/storage-users-ocis.toml index 2d6ef8fc2d4..795ba41d548 100644 --- a/tests/oc-integration-tests/drone/storage-users-ocis.toml +++ b/tests/oc-integration-tests/drone/storage-users-ocis.toml @@ -19,12 +19,14 @@ mount_path = "/users" mount_id = "123e4567-e89b-12d3-a456-426655440000" expose_data_server = true data_server_url = "http://revad-services:11001/data" +gateway_addr = "0.0.0.0:19000" [grpc.services.storageprovider.drivers.ocis] root = "/drone/src/tmp/reva/data" treetime_accounting = true treesize_accounting = true userprovidersvc = "localhost:18000" +gateway_addr = "0.0.0.0:19000" # we have a locally running dataprovider [http] diff --git a/tests/oc-integration-tests/local/frontend.toml b/tests/oc-integration-tests/local/frontend.toml index 8111b454fcb..97536ddd717 100644 --- a/tests/oc-integration-tests/local/frontend.toml +++ b/tests/oc-integration-tests/local/frontend.toml @@ -50,7 +50,6 @@ webdav_namespace = "/home" # serve /ocs which contains the sharing and user provisioning api of owncloud classic [http.services.ocs] -storage_registry_svc = "localhost:19000" [http.services.ocs.capabilities.capabilities.core.status] version = "10.0.11.5" diff --git a/tests/oc-integration-tests/local/gateway.toml b/tests/oc-integration-tests/local/gateway.toml index 6a4f46ee231..39d387d724f 100644 --- a/tests/oc-integration-tests/local/gateway.toml +++ b/tests/oc-integration-tests/local/gateway.toml @@ -30,6 +30,8 @@ ocmcoresvc = "localhost:14000" ocmshareprovidersvc = "localhost:14000" ocminvitemanagersvc = "localhost:14000" ocmproviderauthorizersvc = "localhost:14000" +# permissions +permissionssvc = "localhost:10000" # other commit_share_to_storage_grant = true commit_share_to_storage_ref = true diff --git a/tests/oc-integration-tests/local/permissions-ocis-ci.toml b/tests/oc-integration-tests/local/permissions-ocis-ci.toml new file mode 100644 index 00000000000..d97d4687d32 --- /dev/null +++ b/tests/oc-integration-tests/local/permissions-ocis-ci.toml @@ -0,0 +1,12 @@ +# This config file will start a reva service that: +# - serves the ocis ci permissions service +[shared] +jwt_secret = "Pive-Fumkiu4" + +[grpc] +address = "0.0.0.0:10000" + +[grpc.services.permissions] +driver = "ocisci" + +[grpc.services.publicshareprovider.drivers.ocisci] diff --git a/tests/oc-integration-tests/local/storage-home.toml b/tests/oc-integration-tests/local/storage-home.toml index 03b4d6ab6f2..cd019d9dff4 100644 --- a/tests/oc-integration-tests/local/storage-home.toml +++ b/tests/oc-integration-tests/local/storage-home.toml @@ -30,6 +30,7 @@ root = "/var/tmp/reva/data" enable_home = true treetime_accounting = true treesize_accounting = true +gateway_addr = "0.0.0.0:19000" #user_layout = # do we need owner for users? #owner = 95cb8724-03b2-11eb-a0a6-c33ef8ef53ad diff --git a/tests/oc-integration-tests/local/storage-users.toml b/tests/oc-integration-tests/local/storage-users.toml index d2023fc72a3..cb37e053421 100644 --- a/tests/oc-integration-tests/local/storage-users.toml +++ b/tests/oc-integration-tests/local/storage-users.toml @@ -38,3 +38,4 @@ root = "/var/tmp/reva/data" enable_home = false treetime_accounting = true treesize_accounting = true +gateway_addr = "0.0.0.0:19000"