Skip to content

Commit

Permalink
Following cs3org/reva#4849, fetch the grantee user type when retrievi…
Browse files Browse the repository at this point in the history
…ng shares
  • Loading branch information
glpatcern committed Sep 26, 2024
1 parent e034e86 commit 4a5d8eb
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 24 deletions.
76 changes: 55 additions & 21 deletions share/sql/sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,16 @@ import (
"strings"
"time"

user "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
userpb "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
collaboration "github.com/cs3org/go-cs3apis/cs3/sharing/collaboration/v1beta1"
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
typespb "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
"github.com/cs3org/reva"
"github.com/cs3org/reva/pkg/appctx"
conversions "github.com/cs3org/reva/pkg/cbox/utils"
"github.com/cs3org/reva/pkg/errtypes"
"github.com/cs3org/reva/pkg/rgrpc/status"
"github.com/cs3org/reva/pkg/rgrpc/todo/pool"
"github.com/cs3org/reva/pkg/share"
"github.com/cs3org/reva/pkg/sharedconf"
Expand Down Expand Up @@ -120,7 +122,7 @@ func (m *mgr) Share(ctx context.Context, md *provider.ResourceInfo, g *collabora
ResourceId: md.Id,
Grantee: g.Grantee,
}
_, err := m.getByKey(ctx, key, true)
_, err := m.getByKey(ctx, key, g.Grantee.GetUserId().Type, true)

// share already exists
if err == nil {
Expand Down Expand Up @@ -175,7 +177,7 @@ func (m *mgr) Share(ctx context.Context, md *provider.ResourceInfo, g *collabora
}, nil
}

func (m *mgr) getByID(ctx context.Context, id *collaboration.ShareId, checkOwner bool) (*collaboration.Share, error) {
func (m *mgr) getByID(ctx context.Context, id *collaboration.ShareId, gtype userpb.UserType, checkOwner bool) (*collaboration.Share, error) {
uid := conversions.FormatUserID(appctx.ContextMustGetUser(ctx).Id)
s := conversions.DBShare{ID: id.OpaqueId}
query := "select coalesce(uid_owner, '') as uid_owner, coalesce(uid_initiator, '') as uid_initiator, lower(coalesce(share_with, '')) as share_with, coalesce(fileid_prefix, '') as fileid_prefix, coalesce(item_source, '') as item_source, coalesce(item_type, '') as item_type, stime, permissions, share_type FROM oc_share WHERE (orphan = 0 or orphan IS NULL) AND id=?"
Expand All @@ -190,10 +192,10 @@ func (m *mgr) getByID(ctx context.Context, id *collaboration.ShareId, checkOwner
}
return nil, err
}
return conversions.ConvertToCS3Share(s), nil
return conversions.ConvertToCS3Share(s, gtype), nil
}

func (m *mgr) getByKey(ctx context.Context, key *collaboration.ShareKey, checkOwner bool) (*collaboration.Share, error) {
func (m *mgr) getByKey(ctx context.Context, key *collaboration.ShareKey, gtype userpb.UserType, checkOwner bool) (*collaboration.Share, error) {
owner := conversions.FormatUserID(key.Owner)
uid := conversions.FormatUserID(appctx.ContextMustGetUser(ctx).Id)

Expand All @@ -211,35 +213,36 @@ func (m *mgr) getByKey(ctx context.Context, key *collaboration.ShareKey, checkOw
}
return nil, err
}
return conversions.ConvertToCS3Share(s), nil
return conversions.ConvertToCS3Share(s, gtype), nil
}

func (m *mgr) GetShare(ctx context.Context, ref *collaboration.ShareReference) (*collaboration.Share, error) {

var s *collaboration.Share
var err error
switch {
case ref.GetId() != nil:
s, err = m.getByID(ctx, ref.GetId(), false)
s, err = m.getByID(ctx, ref.GetId(), userpb.UserType_USER_TYPE_INVALID, false)
if err != nil {
return nil, err
}
case ref.GetKey() != nil:
s, err = m.getByKey(ctx, ref.GetKey(), false)
s, err = m.getByKey(ctx, ref.GetKey(), userpb.UserType_USER_TYPE_INVALID, false)
if err != nil {
return nil, err
}
default:
err = errtypes.NotFound(ref.String())
}

// resolve grantee's user type
s.Grantee.GetUserId().Type, _ = m.getUserType(ctx, s.Grantee.GetUserId().OpaqueId)

path, err := m.getPath(ctx, s.ResourceId)
if err != nil {
return nil, err
}

user := appctx.ContextMustGetUser(ctx)

if m.isProjectAdmin(user, path) {
return s, nil
}
Expand Down Expand Up @@ -359,7 +362,8 @@ func (m *mgr) addPathIntoCtx(ctx context.Context, ref *collaboration.ShareRefere
var err error
switch {
case ref.GetId() != nil:
share, err := m.getByID(ctx, ref.GetId(), false)
// here we don't manipulate the grantee's user type, so just assume PRIMARY
share, err := m.getByID(ctx, ref.GetId(), userpb.UserType_USER_TYPE_PRIMARY, false)
if err != nil {
return nil, err
}
Expand All @@ -379,15 +383,15 @@ func (m *mgr) addPathIntoCtx(ctx context.Context, ref *collaboration.ShareRefere
return appctx.ContextSetResourcePath(ctx, path), nil
}

func (m *mgr) isProjectAdminFromCtx(ctx context.Context, u *user.User) bool {
func (m *mgr) isProjectAdminFromCtx(ctx context.Context, u *userpb.User) bool {
path, ok := appctx.ContextGetResourcePath(ctx)
if !ok {
return false
}
return m.isProjectAdmin(u, path)
}

func (m *mgr) isProjectAdmin(u *user.User, path string) bool {
func (m *mgr) isProjectAdmin(u *userpb.User, path string) bool {
if strings.HasPrefix(path, projectPathPrefix) {
// The path will look like /eos/project/c/cernbox, we need to extract the project name
parts := strings.SplitN(path, "/", 6)
Expand Down Expand Up @@ -451,7 +455,11 @@ func (m *mgr) ListShares(ctx context.Context, filters []*collaboration.Filter) (
if err := rows.Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.ItemType, &s.ID, &s.STime, &s.Permissions, &s.ShareType); err != nil {
continue
}
shares = append(shares, conversions.ConvertToCS3Share(s))
gtype, _ := m.getUserType(ctx, s.ShareWith)
// if err != nil {
// failed to resolve grantee's user type, TODO Log
// }
shares = append(shares, conversions.ConvertToCS3Share(s, gtype))
}
if err = rows.Err(); err != nil {
return nil, err
Expand Down Expand Up @@ -504,7 +512,11 @@ func (m *mgr) ListReceivedShares(ctx context.Context, filters []*collaboration.F
if err := rows.Scan(&s.UIDOwner, &s.UIDInitiator, &s.ShareWith, &s.Prefix, &s.ItemSource, &s.ItemType, &s.ID, &s.STime, &s.Permissions, &s.ShareType, &s.State); err != nil {
continue
}
shares = append(shares, conversions.ConvertToCS3ReceivedShare(s))
gtype, _ := m.getUserType(ctx, s.ShareWith)
// if err != nil {
// failed to resolve grantee's user type, TODO Log
// }
shares = append(shares, conversions.ConvertToCS3ReceivedShare(s, gtype))
}
if err = rows.Err(); err != nil {
return nil, err
Expand All @@ -513,7 +525,7 @@ func (m *mgr) ListReceivedShares(ctx context.Context, filters []*collaboration.F
return shares, nil
}

func (m *mgr) getReceivedByID(ctx context.Context, id *collaboration.ShareId) (*collaboration.ReceivedShare, error) {
func (m *mgr) getReceivedByID(ctx context.Context, id *collaboration.ShareId, gtype userpb.UserType) (*collaboration.ReceivedShare, error) {
user := appctx.ContextMustGetUser(ctx)
uid := conversions.FormatUserID(user.Id)

Expand All @@ -539,10 +551,10 @@ func (m *mgr) getReceivedByID(ctx context.Context, id *collaboration.ShareId) (*
}
return nil, err
}
return conversions.ConvertToCS3ReceivedShare(s), nil
return conversions.ConvertToCS3ReceivedShare(s, gtype), nil
}

func (m *mgr) getReceivedByKey(ctx context.Context, key *collaboration.ShareKey) (*collaboration.ReceivedShare, error) {
func (m *mgr) getReceivedByKey(ctx context.Context, key *collaboration.ShareKey, gtype userpb.UserType) (*collaboration.ReceivedShare, error) {
user := appctx.ContextMustGetUser(ctx)
uid := conversions.FormatUserID(user.Id)

Expand Down Expand Up @@ -570,17 +582,17 @@ func (m *mgr) getReceivedByKey(ctx context.Context, key *collaboration.ShareKey)
}
return nil, err
}
return conversions.ConvertToCS3ReceivedShare(s), nil
return conversions.ConvertToCS3ReceivedShare(s, gtype), nil
}

func (m *mgr) GetReceivedShare(ctx context.Context, ref *collaboration.ShareReference) (*collaboration.ReceivedShare, error) {
var s *collaboration.ReceivedShare
var err error
switch {
case ref.GetId() != nil:
s, err = m.getReceivedByID(ctx, ref.GetId())
s, err = m.getReceivedByID(ctx, ref.GetId(), userpb.UserType_USER_TYPE_INVALID)
case ref.GetKey() != nil:
s, err = m.getReceivedByKey(ctx, ref.GetKey())
s, err = m.getReceivedByKey(ctx, ref.GetKey(), userpb.UserType_USER_TYPE_INVALID)
default:
err = errtypes.NotFound(ref.String())
}
Expand All @@ -589,6 +601,9 @@ func (m *mgr) GetReceivedShare(ctx context.Context, ref *collaboration.ShareRefe
return nil, err
}

// resolve grantee's user type
s.Share.Grantee.GetUserId().Type, _ = m.getUserType(ctx, s.Share.Grantee.GetUserId().OpaqueId)

return s, nil
}

Expand Down Expand Up @@ -719,3 +734,22 @@ func translateFilters(filters map[collaboration.Filter_Type][]*collaboration.Fil
}
return filterQuery, params, nil
}

func (m *mgr) getUserType(ctx context.Context, username string) (userpb.UserType, error) {
client, err := pool.GetGatewayServiceClient(pool.Endpoint(m.c.GatewaySvc))
if err != nil {
return userpb.UserType_USER_TYPE_PRIMARY, err
}
userRes, err := client.GetUserByClaim(ctx, &userpb.GetUserByClaimRequest{
Claim: "username",
Value: username,
})
if err != nil {
return userpb.UserType_USER_TYPE_PRIMARY, errors.Wrapf(err, "error getting user by username '%v'", username)
}
if userRes.Status.Code != rpc.Code_CODE_OK {
return userpb.UserType_USER_TYPE_PRIMARY, status.NewErrorFromCode(userRes.Status.Code, "oidc")
}

return userRes.GetUser().Id.Type, nil
}
8 changes: 5 additions & 3 deletions user/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ type Identity struct {
Upn string `json:"upn"`
DisplayName string `json:"displayName"`
Source string `json:"source,omitempty"`
ActiveUser bool `json:"activeUser,omitempty"`
UID int `json:"uid,omitempty"`
GID int `json:"gid,omitempty"`
}
Expand All @@ -184,8 +185,9 @@ func (i *Identity) UserType() userpb.UserType {
case "Secondary":
return userpb.UserType_USER_TYPE_SECONDARY
case "Person":
if i.Source == "cern" && i.UID > 0 {
return userpb.UserType_USER_TYPE_PRIMARY // CERN user
if i.Source == "cern" && i.ActiveUser {
// this is a CERN account; incidentally, also i.UID > 0 qualifies for that
return userpb.UserType_USER_TYPE_PRIMARY
}
return userpb.UserType_USER_TYPE_LIGHTWEIGHT // external user
default:
Expand All @@ -194,7 +196,7 @@ func (i *Identity) UserType() userpb.UserType {
}

func (m *manager) fetchAllUserAccounts(ctx context.Context) error {
url := fmt.Sprintf("%s/api/v1.0/Identity?field=upn&field=primaryAccountEmail&field=displayName&field=uid&field=gid&field=type&field=source", m.conf.APIBaseURL)
url := fmt.Sprintf("%s/api/v1.0/Identity?field=upn&field=primaryAccountEmail&field=displayName&field=uid&field=gid&field=type&field=source&field=activeUser", m.conf.APIBaseURL)

for {
var r IdentitiesResponse
Expand Down

0 comments on commit 4a5d8eb

Please sign in to comment.