Skip to content

Commit

Permalink
This PR adds the following changes:
Browse files Browse the repository at this point in the history
1. Feature: Enables fetching reva-plugins from github.
2. Fix: Use struct based approach to encode and decode context kv pairs

Signed-off-by: Jimil Desai <jimildesai42@gmail.com>
  • Loading branch information
jimil749 committed Aug 6, 2021
1 parent 4be0e34 commit 21b0500
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 35 deletions.
2 changes: 1 addition & 1 deletion examples/plugin/plugin.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ address = "0.0.0.0:19000"
userprovidersvc = "localhost:19000"

[grpc.services.userprovider]
driver = "./json"
driver = "github.com/jimil749/json"

[grpc.services.userprovider.drivers.json]
users = "users.demo.json"
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ require (
github.com/google/go-querystring v1.0.0 // indirect
github.com/google/uuid v1.3.0
github.com/grpc-ecosystem/go-grpc-middleware v1.3.0
github.com/hashicorp/go-getter v1.5.6
github.com/hashicorp/go-hclog v0.14.1
github.com/hashicorp/go-plugin v1.4.2
github.com/huandu/xstrings v1.3.0 // indirect
Expand All @@ -42,7 +43,6 @@ require (
github.com/minio/minio-go/v7 v7.0.12
github.com/mitchellh/copystructure v1.0.0 // indirect
github.com/mitchellh/mapstructure v1.4.1
github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826
github.com/onsi/ginkgo v1.16.4
github.com/onsi/gomega v1.14.0
github.com/pkg/errors v0.9.1
Expand Down Expand Up @@ -76,5 +76,4 @@ go 1.16
replace (
github.com/eventials/go-tus => github.com/andrewmostello/go-tus v0.0.0-20200314041820-904a9904af9a
github.com/oleiade/reflections => github.com/oleiade/reflections v1.0.1
google.golang.org/grpc => google.golang.org/grpc v1.26.0 // temporary downgrade
)
84 changes: 77 additions & 7 deletions go.sum

Large diffs are not rendered by default.

26 changes: 19 additions & 7 deletions pkg/auth/rpc_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ import (
"net/rpc"

authpb "github.com/cs3org/go-cs3apis/cs3/auth/provider/v1beta1"
user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
"github.com/cs3org/reva/pkg/appctx"
userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
"github.com/cs3org/reva/pkg/plugin"
"github.com/cs3org/reva/pkg/token"
user "github.com/cs3org/reva/pkg/user"
hcplugin "github.com/hashicorp/go-plugin"
)

Expand Down Expand Up @@ -74,21 +75,21 @@ func (m *RPCClient) Configure(ml map[string]interface{}) error {

// AuthenticateArgs for RPC
type AuthenticateArgs struct {
Ctx map[interface{}]interface{}
Ctx *plugin.Ctx
ClientID string
ClientSecret string
}

// AuthenticateReply for RPC
type AuthenticateReply struct {
User *user.User
User *userpb.User
Auth map[string]*authpb.Scope
Error error
}

// Authenticate RPCClient Authenticate method
func (m *RPCClient) Authenticate(ctx context.Context, clientID, clientSecret string) (*user.User, map[string]*authpb.Scope, error) {
ctxVal := appctx.GetKeyValuesFromCtx(ctx)
func (m *RPCClient) Authenticate(ctx context.Context, clientID, clientSecret string) (*userpb.User, map[string]*authpb.Scope, error) {
ctxVal := plugin.GetContextKV(ctx)
args := AuthenticateArgs{Ctx: ctxVal, ClientID: clientID, ClientSecret: clientSecret}
reply := AuthenticateReply{}
err := m.Client.Call("Plugin.Authenticate", args, &reply)
Expand All @@ -112,7 +113,18 @@ func (m *RPCServer) Configure(args ConfigureArg, resp *ConfigureReply) error {

// Authenticate RPCServer Authenticate method
func (m *RPCServer) Authenticate(args AuthenticateArgs, resp *AuthenticateReply) error {
ctx := appctx.PutKeyValuesToCtx(args.Ctx)
ctx := setContext(args.Ctx.Token, args.Ctx.User)
resp.User, resp.Auth, resp.Error = m.Impl.Authenticate(ctx, args.ClientID, args.ClientSecret)
return nil
}

func setContext(ctxToken []string, userCtx []*userpb.User) context.Context {
ctx := context.Background()
for _, u := range userCtx {
ctx = user.ContextSetUser(ctx, u)
}
for _, tkn := range ctxToken {
ctx = token.ContextSetToken(ctx, tkn)
}
return ctx
}
27 changes: 27 additions & 0 deletions pkg/plugin/context.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package plugin

import (
"context"

userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
"github.com/cs3org/reva/pkg/appctx"
)

type Ctx struct {
User []*userpb.User
Token []string
}

func GetContextKV(ctx context.Context) *Ctx {
ctxVal := &Ctx{}
m := appctx.GetKeyValuesFromCtx(ctx)
for _, v := range m {
switch c := v.(type) {
case string:
ctxVal.Token = append(ctxVal.Token, c)
case *userpb.User:
ctxVal.User = append(ctxVal.User, c)
}
}
return ctxVal
}
45 changes: 42 additions & 3 deletions pkg/plugin/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ package plugin

import (
"bytes"
"context"
"fmt"
"os"
"os/exec"
"path/filepath"
"regexp"

"github.com/cs3org/reva/pkg/errtypes"
"github.com/hashicorp/go-getter"
"github.com/hashicorp/go-hclog"
"github.com/hashicorp/go-plugin"
)
Expand All @@ -41,6 +43,8 @@ const dirname = "/var/tmp/reva"

var isAlphaNum = regexp.MustCompile(`^[A-Za-z0-9]+$`).MatchString

var isURL = regexp.MustCompile(`^(www\.)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}(:[0-9]{1,5})?(\/.*)?$`).MatchString

// Kill kills the plugin process
func (plug *RevaPlugin) Kill() {
plug.Client.Kill()
Expand All @@ -57,6 +61,7 @@ func compile(pluginType string, path string) (string, error) {
binaryPath := filepath.Join(dirname, "bin", pluginType, filepath.Base(path))
command := fmt.Sprintf("go build -o %s %s", binaryPath, path)
cmd := exec.Command("bash", "-c", command)
cmd.Dir = path
cmd.Stderr = &errb
err := cmd.Run()
if err != nil {
Expand All @@ -82,14 +87,48 @@ func checkDirAndCompile(pluginType, driver string) (string, error) {
return bin, nil
}

// downloadPlugin downloads the plugin and stores it into local filesystem
func downloadAndCompilePlugin(pluginType, driver string) (string, error) {
destination := fmt.Sprintf("%s/ext/%s/%s", dirname, pluginType, filepath.Base(driver))
client := &getter.Client{
Ctx: context.Background(),
Dst: destination,
Src: driver,
Mode: getter.ClientModeDir,
}
if err := client.Get(); err != nil {
return "", err
}
bin, err := compile(pluginType, destination)
if err != nil {
return "", nil
}
return bin, nil
}

// isValidURL tests a string to determine if it is a well-structure URL
func isValidURL(driver string) bool {
return isURL(driver)
}

// Load loads the plugin using the hashicorp go-plugin system
func Load(pluginType, driver string) (*RevaPlugin, error) {
var bin string
var err error
if isAlphaNum(driver) {
return nil, errtypes.NotFound(driver)
}
bin, err := checkDirAndCompile(pluginType, driver)
if err != nil {
return nil, err

if isValidURL(driver) {
bin, err = downloadAndCompilePlugin(pluginType, driver)
if err != nil {
return nil, err
}
} else {
bin, err = checkDirAndCompile(pluginType, driver)
if err != nil {
return nil, err
}
}

logger := hclog.New(&hclog.LoggerOptions{
Expand Down
39 changes: 24 additions & 15 deletions pkg/user/rpc_user.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,15 @@ package user

import (
"context"
"encoding/gob"
"net/rpc"

userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
"github.com/cs3org/reva/pkg/appctx"
"github.com/cs3org/reva/pkg/plugin"
"github.com/cs3org/reva/pkg/token"
hcplugin "github.com/hashicorp/go-plugin"
)

func init() {
gob.Register(&userpb.User{})
plugin.Register("userprovider", &ProviderPlugin{})
}

Expand Down Expand Up @@ -75,7 +73,7 @@ func (m *RPCClient) Configure(ml map[string]interface{}) error {

// GetUserArg for RPC
type GetUserArg struct {
Ctx map[interface{}]interface{}
Ctx *plugin.Ctx
UID *userpb.UserId
}

Expand All @@ -87,7 +85,7 @@ type GetUserReply struct {

// GetUser RPCClient GetUser method
func (m *RPCClient) GetUser(ctx context.Context, uid *userpb.UserId) (*userpb.User, error) {
ctxVal := appctx.GetKeyValuesFromCtx(ctx)
ctxVal := plugin.GetContextKV(ctx)
args := GetUserArg{Ctx: ctxVal, UID: uid}
resp := GetUserReply{}
err := m.Client.Call("Plugin.GetUser", args, &resp)
Expand All @@ -99,7 +97,7 @@ func (m *RPCClient) GetUser(ctx context.Context, uid *userpb.UserId) (*userpb.Us

// GetUserByClaimArg for RPC
type GetUserByClaimArg struct {
Ctx map[interface{}]interface{}
Ctx *plugin.Ctx
Claim string
Value string
}
Expand All @@ -112,7 +110,7 @@ type GetUserByClaimReply struct {

// GetUserByClaim RPCClient GetUserByClaim method
func (m *RPCClient) GetUserByClaim(ctx context.Context, claim, value string) (*userpb.User, error) {
ctxVal := appctx.GetKeyValuesFromCtx(ctx)
ctxVal := plugin.GetContextKV(ctx)
args := GetUserByClaimArg{Ctx: ctxVal, Claim: claim, Value: value}
resp := GetUserByClaimReply{}
err := m.Client.Call("Plugin.GetUserByClaim", args, &resp)
Expand All @@ -124,7 +122,7 @@ func (m *RPCClient) GetUserByClaim(ctx context.Context, claim, value string) (*u

// GetUserGroupsArg for RPC
type GetUserGroupsArg struct {
Ctx map[interface{}]interface{}
Ctx *plugin.Ctx
User *userpb.UserId
}

Expand All @@ -136,7 +134,7 @@ type GetUserGroupsReply struct {

// GetUserGroups RPCClient GetUserGroups method
func (m *RPCClient) GetUserGroups(ctx context.Context, user *userpb.UserId) ([]string, error) {
ctxVal := appctx.GetKeyValuesFromCtx(ctx)
ctxVal := plugin.GetContextKV(ctx)
args := GetUserGroupsArg{Ctx: ctxVal, User: user}
resp := GetUserGroupsReply{}
err := m.Client.Call("Plugin.GetUserGroups", args, &resp)
Expand All @@ -148,7 +146,7 @@ func (m *RPCClient) GetUserGroups(ctx context.Context, user *userpb.UserId) ([]s

// FindUsersArg for RPC
type FindUsersArg struct {
Ctx map[interface{}]interface{}
Ctx *plugin.Ctx
Query string
}

Expand All @@ -160,7 +158,7 @@ type FindUsersReply struct {

// FindUsers RPCClient FindUsers method
func (m *RPCClient) FindUsers(ctx context.Context, query string) ([]*userpb.User, error) {
ctxVal := appctx.GetKeyValuesFromCtx(ctx)
ctxVal := plugin.GetContextKV(ctx)
args := FindUsersArg{Ctx: ctxVal, Query: query}
resp := FindUsersReply{}
err := m.Client.Call("Plugin.FindUsers", args, &resp)
Expand All @@ -184,28 +182,39 @@ func (m *RPCServer) Configure(args ConfigureArg, resp *ConfigureReply) error {

// GetUser RPCServer GetUser method
func (m *RPCServer) GetUser(args GetUserArg, resp *GetUserReply) error {
ctx := appctx.PutKeyValuesToCtx(args.Ctx)
ctx := setContext(args.Ctx.Token, args.Ctx.User)
resp.User, resp.Err = m.Impl.GetUser(ctx, args.UID)
return nil
}

// GetUserByClaim RPCServer GetUserByClaim method
func (m *RPCServer) GetUserByClaim(args GetUserByClaimArg, resp *GetUserByClaimReply) error {
ctx := appctx.PutKeyValuesToCtx(args.Ctx)
ctx := setContext(args.Ctx.Token, args.Ctx.User)
resp.User, resp.Err = m.Impl.GetUserByClaim(ctx, args.Claim, args.Value)
return nil
}

// GetUserGroups RPCServer GetUserGroups method
func (m *RPCServer) GetUserGroups(args GetUserGroupsArg, resp *GetUserGroupsReply) error {
ctx := appctx.PutKeyValuesToCtx(args.Ctx)
ctx := setContext(args.Ctx.Token, args.Ctx.User)
resp.Group, resp.Err = m.Impl.GetUserGroups(ctx, args.User)
return nil
}

// FindUsers RPCServer FindUsers method
func (m *RPCServer) FindUsers(args FindUsersArg, resp *FindUsersReply) error {
ctx := appctx.PutKeyValuesToCtx(args.Ctx)
ctx := setContext(args.Ctx.Token, args.Ctx.User)
resp.User, resp.Err = m.Impl.FindUsers(ctx, args.Query)
return nil
}

func setContext(ctxToken []string, user []*userpb.User) context.Context {
ctx := context.Background()
for _, u := range user {
ctx = ContextSetUser(ctx, u)
}
for _, tkn := range ctxToken {
ctx = token.ContextSetToken(ctx, tkn)
}
return ctx
}

0 comments on commit 21b0500

Please sign in to comment.