unmarshal token to filter spaces for current user (#6596)
* unmarshal token to filter spaces for current user Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> * Fix tests --------- Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de> Co-authored-by: André Duffeck <andre.duffeck@firondu.de>
This commit is contained in:
co-authored by
André Duffeck
parent
abf94f1ccb
commit
2ea3b8c400
@@ -33,7 +33,7 @@ func Server(cfg *config.Config) *cli.Command {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = ogrpc.Configure(ogrpc.GetClientOptions(cfg.GRPCClientTLS)...)
|
err = ogrpc.Configure(append(ogrpc.GetClientOptions(cfg.GRPCClientTLS), ogrpc.WithTraceProvider(tracing.TraceProvider))...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -56,6 +56,7 @@ func Server(cfg *config.Config) *cli.Command {
|
|||||||
grpc.Name(cfg.Service.Name),
|
grpc.Name(cfg.Service.Name),
|
||||||
grpc.Context(ctx),
|
grpc.Context(ctx),
|
||||||
grpc.Metrics(mtrcs),
|
grpc.Metrics(mtrcs),
|
||||||
|
grpc.JWTSecret(cfg.Commons.TokenManager.JWTSecret),
|
||||||
)
|
)
|
||||||
defer teardown()
|
defer teardown()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ type Config struct {
|
|||||||
|
|
||||||
GRPC GRPCConfig `yaml:"grpc"`
|
GRPC GRPCConfig `yaml:"grpc"`
|
||||||
|
|
||||||
|
TokenManager *TokenManager `yaml:"token_manager"`
|
||||||
|
|
||||||
Reva *shared.Reva `yaml:"reva"`
|
Reva *shared.Reva `yaml:"reva"`
|
||||||
GRPCClientTLS *shared.GRPCClientTLS `yaml:"grpc_client_tls"`
|
GRPCClientTLS *shared.GRPCClientTLS `yaml:"grpc_client_tls"`
|
||||||
Events Events `yaml:"events"`
|
Events Events `yaml:"events"`
|
||||||
|
|||||||
@@ -83,6 +83,14 @@ func EnsureDefaults(cfg *config.Config) {
|
|||||||
cfg.Tracing = &config.Tracing{}
|
cfg.Tracing = &config.Tracing{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if cfg.TokenManager == nil && cfg.Commons != nil && cfg.Commons.TokenManager != nil {
|
||||||
|
cfg.TokenManager = &config.TokenManager{
|
||||||
|
JWTSecret: cfg.Commons.TokenManager.JWTSecret,
|
||||||
|
}
|
||||||
|
} else if cfg.TokenManager == nil {
|
||||||
|
cfg.TokenManager = &config.TokenManager{}
|
||||||
|
}
|
||||||
|
|
||||||
if cfg.MachineAuthAPIKey == "" && cfg.Commons != nil && cfg.Commons.MachineAuthAPIKey != "" {
|
if cfg.MachineAuthAPIKey == "" && cfg.Commons != nil && cfg.Commons.MachineAuthAPIKey != "" {
|
||||||
cfg.MachineAuthAPIKey = cfg.Commons.MachineAuthAPIKey
|
cfg.MachineAuthAPIKey = cfg.Commons.MachineAuthAPIKey
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,3 +4,8 @@ package config
|
|||||||
type Reva struct {
|
type Reva struct {
|
||||||
Address string `ocisConfig:"address" env:"OCIS_REVA_GATEWAY;REVA_GATEWAY" desc:"The CS3 gateway endpoint." deprecationVersion:"3.0" removalVersion:"4.0.0" deprecationInfo:"REVA_GATEWAY changing name for consistency" deprecationReplacement:"OCIS_REVA_GATEWAY"`
|
Address string `ocisConfig:"address" env:"OCIS_REVA_GATEWAY;REVA_GATEWAY" desc:"The CS3 gateway endpoint." deprecationVersion:"3.0" removalVersion:"4.0.0" deprecationInfo:"REVA_GATEWAY changing name for consistency" deprecationReplacement:"OCIS_REVA_GATEWAY"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TokenManager is the config for using the reva token manager
|
||||||
|
type TokenManager struct {
|
||||||
|
JWTSecret string `yaml:"jwt_secret" env:"OCIS_JWT_SECRET;SEARCH_JWT_SECRET" desc:"The secret to mint and validate jwt tokens."`
|
||||||
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||||
rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
||||||
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||||
|
revactx "github.com/cs3org/reva/v2/pkg/ctx"
|
||||||
"github.com/cs3org/reva/v2/pkg/errtypes"
|
"github.com/cs3org/reva/v2/pkg/errtypes"
|
||||||
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
|
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
|
||||||
sdk "github.com/cs3org/reva/v2/pkg/sdk/common"
|
sdk "github.com/cs3org/reva/v2/pkg/sdk/common"
|
||||||
@@ -81,8 +82,14 @@ func (s *Service) Search(ctx context.Context, req *searchsvc.SearchRequest) (*se
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
currentUser := revactx.ContextMustGetUser(ctx)
|
||||||
|
|
||||||
listSpacesRes, err := gatewayClient.ListStorageSpaces(ctx, &provider.ListStorageSpacesRequest{
|
listSpacesRes, err := gatewayClient.ListStorageSpaces(ctx, &provider.ListStorageSpacesRequest{
|
||||||
Filters: []*provider.ListStorageSpacesRequest_Filter{
|
Filters: []*provider.ListStorageSpacesRequest_Filter{
|
||||||
|
{
|
||||||
|
Type: provider.ListStorageSpacesRequest_Filter_TYPE_USER,
|
||||||
|
Term: &provider.ListStorageSpacesRequest_Filter_User{User: currentUser.GetId()},
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Type: provider.ListStorageSpacesRequest_Filter_TYPE_SPACE_TYPE,
|
Type: provider.ListStorageSpacesRequest_Filter_TYPE_SPACE_TYPE,
|
||||||
Term: &provider.ListStorageSpacesRequest_Filter_SpaceType{SpaceType: "+grant"},
|
Term: &provider.ListStorageSpacesRequest_Filter_SpaceType{SpaceType: "+grant"},
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import (
|
|||||||
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||||
sprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
sprovider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
||||||
typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
typesv1beta1 "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
|
||||||
|
revactx "github.com/cs3org/reva/v2/pkg/ctx"
|
||||||
"github.com/cs3org/reva/v2/pkg/rgrpc/status"
|
"github.com/cs3org/reva/v2/pkg/rgrpc/status"
|
||||||
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
|
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
|
||||||
cs3mocks "github.com/cs3org/reva/v2/tests/cs3mocks/mocks"
|
cs3mocks "github.com/cs3org/reva/v2/tests/cs3mocks/mocks"
|
||||||
@@ -83,7 +84,7 @@ var _ = Describe("Searchprovider", func() {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
|
||||||
ctx = context.Background()
|
ctx = revactx.ContextSetUser(context.Background(), user)
|
||||||
indexClient = &engineMocks.Engine{}
|
indexClient = &engineMocks.Engine{}
|
||||||
extractor = &contentMocks.Extractor{}
|
extractor = &contentMocks.Extractor{}
|
||||||
|
|
||||||
|
|||||||
@@ -15,13 +15,14 @@ type Option func(o *Options)
|
|||||||
|
|
||||||
// Options defines the available options for this package.
|
// Options defines the available options for this package.
|
||||||
type Options struct {
|
type Options struct {
|
||||||
Name string
|
Name string
|
||||||
Logger log.Logger
|
Logger log.Logger
|
||||||
Context context.Context
|
Context context.Context
|
||||||
Config *config.Config
|
Config *config.Config
|
||||||
Metrics *metrics.Metrics
|
Metrics *metrics.Metrics
|
||||||
Flags []cli.Flag
|
Flags []cli.Flag
|
||||||
Handler *svc.Service
|
Handler *svc.Service
|
||||||
|
JWTSecret string
|
||||||
}
|
}
|
||||||
|
|
||||||
// newOptions initializes the available default options.
|
// newOptions initializes the available default options.
|
||||||
@@ -83,3 +84,10 @@ func Handler(val *svc.Service) Option {
|
|||||||
o.Handler = val
|
o.Handler = val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JWTSecret provides a function to set the Config option.
|
||||||
|
func JWTSecret(val string) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.JWTSecret = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ func Server(opts ...Option) (grpc.Service, func(), error) {
|
|||||||
handle, teardown, err := svc.NewHandler(
|
handle, teardown, err := svc.NewHandler(
|
||||||
svc.Config(options.Config),
|
svc.Config(options.Config),
|
||||||
svc.Logger(options.Logger),
|
svc.Logger(options.Logger),
|
||||||
|
svc.JWTSecret(options.JWTSecret),
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
options.Logger.Error().
|
options.Logger.Error().
|
||||||
|
|||||||
@@ -10,8 +10,9 @@ type Option func(o *Options)
|
|||||||
|
|
||||||
// Options defines the available options for this package.
|
// Options defines the available options for this package.
|
||||||
type Options struct {
|
type Options struct {
|
||||||
Logger log.Logger
|
Logger log.Logger
|
||||||
Config *config.Config
|
Config *config.Config
|
||||||
|
JWTSecret string
|
||||||
}
|
}
|
||||||
|
|
||||||
func newOptions(opts ...Option) Options {
|
func newOptions(opts ...Option) Options {
|
||||||
@@ -37,3 +38,10 @@ func Config(val *config.Config) Option {
|
|||||||
o.Config = val
|
o.Config = val
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JWTSecret provides a function to set the Config option.
|
||||||
|
func JWTSecret(val string) Option {
|
||||||
|
return func(o *Options) {
|
||||||
|
o.JWTSecret = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ import (
|
|||||||
"github.com/cs3org/reva/v2/pkg/errtypes"
|
"github.com/cs3org/reva/v2/pkg/errtypes"
|
||||||
"github.com/cs3org/reva/v2/pkg/events/stream"
|
"github.com/cs3org/reva/v2/pkg/events/stream"
|
||||||
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
|
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
|
||||||
|
"github.com/cs3org/reva/v2/pkg/token"
|
||||||
|
"github.com/cs3org/reva/v2/pkg/token/manager/jwt"
|
||||||
"github.com/go-micro/plugins/v4/events/natsjs"
|
"github.com/go-micro/plugins/v4/events/natsjs"
|
||||||
"github.com/jellydator/ttlcache/v2"
|
"github.com/jellydator/ttlcache/v2"
|
||||||
ociscrypto "github.com/owncloud/ocis/v2/ocis-pkg/crypto"
|
ociscrypto "github.com/owncloud/ocis/v2/ocis-pkg/crypto"
|
||||||
@@ -119,20 +121,30 @@ func NewHandler(opts ...Option) (searchsvc.SearchProviderHandler, func(), error)
|
|||||||
return nil, teardown, err
|
return nil, teardown, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tokenManager, err := jwt.New(map[string]interface{}{
|
||||||
|
"secret": options.JWTSecret,
|
||||||
|
"expires": int64(24 * 60 * 60),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, teardown, err
|
||||||
|
}
|
||||||
|
|
||||||
return &Service{
|
return &Service{
|
||||||
id: cfg.GRPC.Namespace + "." + cfg.Service.Name,
|
id: cfg.GRPC.Namespace + "." + cfg.Service.Name,
|
||||||
log: logger,
|
log: logger,
|
||||||
searcher: ss,
|
searcher: ss,
|
||||||
cache: cache,
|
cache: cache,
|
||||||
|
tokenManager: tokenManager,
|
||||||
}, teardown, nil
|
}, teardown, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Service implements the searchServiceHandler interface
|
// Service implements the searchServiceHandler interface
|
||||||
type Service struct {
|
type Service struct {
|
||||||
id string
|
id string
|
||||||
log log.Logger
|
log log.Logger
|
||||||
searcher search.Searcher
|
searcher search.Searcher
|
||||||
cache *ttlcache.Cache
|
cache *ttlcache.Cache
|
||||||
|
tokenManager token.Manager
|
||||||
}
|
}
|
||||||
|
|
||||||
// Search handles the search
|
// Search handles the search
|
||||||
@@ -145,7 +157,13 @@ func (s Service) Search(ctx context.Context, in *searchsvc.SearchRequest, out *s
|
|||||||
}
|
}
|
||||||
ctx = grpcmetadata.AppendToOutgoingContext(ctx, revactx.TokenHeader, t)
|
ctx = grpcmetadata.AppendToOutgoingContext(ctx, revactx.TokenHeader, t)
|
||||||
|
|
||||||
u, _ := revactx.ContextGetUser(ctx)
|
// unpack user
|
||||||
|
u, _, err := s.tokenManager.DismantleToken(ctx, t)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
ctx = revactx.ContextSetUser(ctx, u)
|
||||||
|
|
||||||
key := cacheKey(in.Query, in.PageSize, in.Ref, u)
|
key := cacheKey(in.Query, in.PageSize, in.Ref, u)
|
||||||
res, ok := s.FromCache(key)
|
res, ok := s.FromCache(key)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|||||||
Reference in New Issue
Block a user