Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions services/graph/pkg/service/v0/api_driveitem_permissions.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@
}

// Invite invites a user to a drive item.
func (s DriveItemPermissionsService) Invite(ctx context.Context, resourceId *storageprovider.ResourceId, invite libregraph.DriveItemInvite) (libregraph.Permission, error) {

Check failure on line 106 in services/graph/pkg/service/v0/api_driveitem_permissions.go

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this method to reduce its Cognitive Complexity from 59 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=opencloud-eu_opencloud&issues=AZ34UhxbsrRB7EZGe_S3&open=AZ34UhxbsrRB7EZGe_S3&pullRequest=2717
tenantId := revactx.ContextMustGetUser(ctx).GetId().GetTenantId()
gatewayClient, err := s.gatewaySelector.Next()
if err != nil {
Expand Down Expand Up @@ -179,12 +179,54 @@
}
createShareResponse, err := gatewayClient.CreateShare(ctx, createShareRequest)
if err := errorcode.FromCS3Status(createShareResponse.GetStatus(), err); err != nil {
s.logger.Debug().Err(err).Msg("share creation failed")

Check failure on line 182 in services/graph/pkg/service/v0/api_driveitem_permissions.go

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Define a constant instead of duplicating this literal "share creation failed" 4 times.

See more on https://sonarcloud.io/project/issues?id=opencloud-eu_opencloud&issues=AZ34UhxbsrRB7EZGe_S2&open=AZ34UhxbsrRB7EZGe_S2&pullRequest=2717
return libregraph.Permission{}, err
}
shareid = createShareResponse.GetShare().GetId().GetOpaqueId()
cTime = createShareResponse.GetShare().GetCtime()
expiration = createShareResponse.GetShare().GetExpiration()
case "mail":
email := strings.TrimSpace(objectID)
if len(email) == 0 {
return libregraph.Permission{}, errorcode.New(errorcode.InvalidRequest, "invalid mail recipient")
}

createShareRequest := &collaboration.CreateShareRequest{
ResourceInfo: statResponse.GetInfo(),
Grant: &collaboration.ShareGrant{
Grantee: &storageprovider.Grantee{
Type: storageprovider.GranteeType_GRANTEE_TYPE_MAIL,
Id: &storageprovider.Grantee_Mail{
Mail: strings.ToLower(email),
},
},
Permissions: &collaboration.SharePermissions{
Permissions: cs3ResourcePermissions,
},
},
}
if invite.ExpirationDateTime != nil {
createShareRequest.GetGrant().Expiration = utils.TimeToTS(*invite.ExpirationDateTime)
}
createShareResponse, err := gatewayClient.CreateShare(ctx, createShareRequest)
if err := errorcode.FromCS3Status(createShareResponse.GetStatus(), err); err != nil {
s.logger.Debug().Err(err).Msg("share creation failed")
return libregraph.Permission{}, err
}
shareid = createShareResponse.GetShare().GetId().GetOpaqueId()
cTime = createShareResponse.GetShare().GetCtime()
expiration = createShareResponse.GetShare().GetExpiration()

identity := &libregraph.Identity{
Id: conversions.ToPointer(email),
DisplayName: email,
LibreGraphUserType: conversions.ToPointer("Mail"),
}

permission.GrantedToV2 = &libregraph.SharePointIdentitySet{
User: identity,
}

default:
user, err := s.identityCache.GetCS3User(ctx, tenantId, objectID)
if errors.Is(err, identity.ErrNotFound) && s.config.IncludeOCMSharees {
Expand Down
29 changes: 29 additions & 0 deletions services/graph/pkg/service/v0/api_driveitem_permissions_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,34 @@ var _ = Describe("DriveItemPermissionsService", func() {
Expect(permission.GrantedToV2.Group.GetId()).To(Equal("2"))
})

It("creates guest share using an email address", func() {
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gatewayClient.On("CreateShare", mock.Anything, mock.Anything).Return(createShareResponse, nil)
driveItemInvite.Recipients = []libregraph.DriveRecipient{
{ObjectId: libregraph.PtrString("guest@example.com"), LibreGraphRecipientType: libregraph.PtrString("mail")},
}
createShareResponse.Share = &collaboration.Share{
Id: &collaboration.ShareId{OpaqueId: "guest123"},
}

permission, err := driveItemPermissionsService.Invite(ctx, driveItemId, driveItemInvite)
Expect(err).ToNot(HaveOccurred())
Expect(permission.GetId()).To(Equal("guest123"))
Expect(permission.GrantedToV2.User.GetDisplayName()).To(Equal("guest@example.com"))
Expect(permission.GrantedToV2.User.GetId()).To(Equal("guest@example.com"))
Expect(permission.GrantedToV2.User.GetLibreGraphUserType()).To(Equal("Mail"))
})

It("verifies that empty email addresses are handled", func() {
driveItemInvite.Recipients = []libregraph.DriveRecipient{
{ObjectId: libregraph.PtrString(" "), LibreGraphRecipientType: libregraph.PtrString("mail")},
}

_, err := driveItemPermissionsService.Invite(ctx, driveItemId, driveItemInvite)
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("invalid mail recipient"))
})

It("succeeds with file roles (happy path)", func() {
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gatewayClient.On("CreateShare", mock.Anything, mock.Anything).Return(createShareResponse, nil)
Expand Down Expand Up @@ -326,6 +354,7 @@ var _ = Describe("DriveItemPermissionsService", func() {
gatewayClient.On("ListStorageSpaces", mock.Anything, mock.Anything).Return(listSpacesResponse, nil)
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gatewayClient.On("Stat", mock.Anything, mock.Anything).Return(statResponse, nil)
gatewayClient.On("GetUser", mock.Anything, mock.Anything).Return(getUserResponse, nil)
gatewayClient.On("CreateShare", mock.Anything, mock.Anything).Return(createShareResponse, nil)
driveItemInvite.Recipients = []libregraph.DriveRecipient{
{ObjectId: libregraph.PtrString("1"), LibreGraphRecipientType: libregraph.PtrString("user")},
Expand Down
17 changes: 17 additions & 0 deletions services/graph/pkg/service/v0/base.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"fmt"
"net/url"
"path"
"strings"
"time"

gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
Expand Down Expand Up @@ -274,6 +275,7 @@
share.UserGranteeFilter(),
share.GroupGranteeFilter(),
share.SpaceRootFilter(spaceRoot),
share.MailGranteeFilter(),
}
concreteFilters = append(concreteFilters, filters...)

Expand Down Expand Up @@ -555,7 +557,7 @@
return driveItems, nil
}

func (g BaseGraphService) cs3UserShareToPermission(ctx context.Context, share *collaboration.Share, roleCondition string) (*libregraph.Permission, error) {

Check failure on line 560 in services/graph/pkg/service/v0/base.go

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this method to reduce its Cognitive Complexity from 16 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=opencloud-eu_opencloud&issues=AZ34Uh1SsrRB7EZGe_S4&open=AZ34Uh1SsrRB7EZGe_S4&pullRequest=2717
perm := libregraph.Permission{}
perm.SetRoles([]string{})
perm.SetId(share.GetId().GetOpaqueId())
Expand Down Expand Up @@ -585,6 +587,14 @@
default:
grantedTo.SetGroup(group)
}
case storageprovider.GranteeType_GRANTEE_TYPE_MAIL:
grantedTo.SetUser(libregraph.Identity{
Id: libregraph.PtrString("mail:" + strings.ToLower(share.Grantee.GetMail())),
DisplayName: share.Grantee.GetMail(),
})
if roleCondition == unifiedrole.UnifiedRoleConditionDrive {
perm.SetId("m:" + strings.ToLower(share.Grantee.GetMail()))
}
}

// set expiration date
Expand Down Expand Up @@ -628,7 +638,7 @@
}
return &perm, nil
}
func (g BaseGraphService) cs3OCMShareToPermission(ctx context.Context, share *ocm.Share, roleCondition string) (*libregraph.Permission, error) {

Check failure on line 641 in services/graph/pkg/service/v0/base.go

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Refactor this method to reduce its Cognitive Complexity from 24 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=opencloud-eu_opencloud&issues=AZ34Uh1SsrRB7EZGe_S5&open=AZ34Uh1SsrRB7EZGe_S5&pullRequest=2717
perm := libregraph.Permission{}
perm.SetRoles([]string{})
if roleCondition != unifiedrole.UnifiedRoleConditionDrive {
Expand Down Expand Up @@ -667,6 +677,13 @@
perm.SetId("g:" + group.GetId())
}
}
case storageprovider.GranteeType_GRANTEE_TYPE_MAIL:
grantedTo.SetUser(libregraph.Identity{
Id: libregraph.PtrString(share.Grantee.GetMail()),
})
if roleCondition == unifiedrole.UnifiedRoleConditionDrive {
perm.SetId("m:" + share.Grantee.GetMail())
}
}

// set expiration date
Expand Down
2 changes: 1 addition & 1 deletion services/graph/pkg/validate/libregraph.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ func libregraphDriveItemInvite(v *validator.Validate) {
func libregraphDriveRecipient(v *validator.Validate) {
v.RegisterStructValidationMapRules(map[string]string{
"ObjectId": "ne=",
"LibreGraphRecipientType": "oneof=user group",
"LibreGraphRecipientType": "oneof=user group mail",
}, libregraph.DriveRecipient{})
}

Expand Down