From e0b38cc9ac8be027809fda097478c33cecb6333b Mon Sep 17 00:00:00 2001 From: nielash Date: Tue, 30 Apr 2024 08:50:11 -0400 Subject: [PATCH] onedrive: add support for group permissions This change adds support for "group" identities, and SharePoint variants "siteUser" and "siteGroup". It also adds support for using any identity type (including "application" and "device") as a recipient source when adding permissions. --- backend/onedrive/api/types.go | 5 +++++ backend/onedrive/metadata.go | 34 ++++++++++++++++++++++++++++------ 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/backend/onedrive/api/types.go b/backend/onedrive/api/types.go index 7b7bff5cc..0332f1c12 100644 --- a/backend/onedrive/api/types.go +++ b/backend/onedrive/api/types.go @@ -42,6 +42,8 @@ var _ error = (*Error)(nil) type Identity struct { DisplayName string `json:"displayName,omitempty"` ID string `json:"id,omitempty"` + Email string `json:"email,omitempty"` // not officially documented, but seems to sometimes exist + LoginName string `json:"loginName,omitempty"` // SharePoint only } // IdentitySet is a keyed collection of Identity objects. It is used @@ -51,6 +53,9 @@ type IdentitySet struct { User Identity `json:"user,omitempty"` Application Identity `json:"application,omitempty"` Device Identity `json:"device,omitempty"` + Group Identity `json:"group,omitempty"` + SiteGroup Identity `json:"siteGroup,omitempty"` // The SharePoint group associated with this action. Optional. + SiteUser Identity `json:"siteUser,omitempty"` // The SharePoint user associated with this action. Optional. } // Quota groups storage space quota-related information on OneDrive into a single structure. diff --git a/backend/onedrive/metadata.go b/backend/onedrive/metadata.go index a80cbefd7..b94dcb974 100644 --- a/backend/onedrive/metadata.go +++ b/backend/onedrive/metadata.go @@ -475,7 +475,7 @@ func (m *Metadata) processPermissions(ctx context.Context, add, update, remove [ } // fillRecipients looks for recipients to add from the permission passed in. -// It looks for an email address in identity.User.ID and DisplayName, otherwise it uses the identity.User.ID as r.ObjectID. +// It looks for an email address in identity.User.Email, ID, and DisplayName, otherwise it uses the identity.User.ID as r.ObjectID. // It considers both "GrantedTo" and "GrantedToIdentities". func fillRecipients(p *api.PermissionsType, driveType string) (recipients []api.DriveRecipient) { if p == nil { @@ -491,7 +491,10 @@ func fillRecipients(p *api.PermissionsType, driveType string) (recipients []api. r := api.DriveRecipient{} id := "" - if strings.ContainsRune(identity.User.ID, '@') { + if strings.ContainsRune(identity.User.Email, '@') { + id = identity.User.Email + r.Email = id + } else if strings.ContainsRune(identity.User.ID, '@') { id = identity.User.ID r.Email = id } else if strings.ContainsRune(identity.User.DisplayName, '@') { @@ -507,12 +510,31 @@ func fillRecipients(p *api.PermissionsType, driveType string) (recipients []api. ids[id] = struct{}{} recipients = append(recipients, r) } - for _, identity := range p.GetGrantedToIdentities(driveType) { - addRecipient(identity) + + forIdentitySet := func(iSet *api.IdentitySet) { + if iSet == nil { + return + } + iS := *iSet + forIdentity := func(i api.Identity) { + if i != (api.Identity{}) { + iS.User = i + addRecipient(&iS) + } + } + forIdentity(iS.User) + forIdentity(iS.SiteUser) + forIdentity(iS.Group) + forIdentity(iS.SiteGroup) + forIdentity(iS.Application) + forIdentity(iS.Device) } - if p.GetGrantedTo(driveType) != nil && p.GetGrantedTo(driveType).User != (api.Identity{}) { - addRecipient(p.GetGrantedTo(driveType)) + + for _, identitySet := range p.GetGrantedToIdentities(driveType) { + forIdentitySet(identitySet) } + forIdentitySet(p.GetGrantedTo(driveType)) + return recipients }