mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-03-16 04:05:55 +00:00
oc-calendar: Add edit/delete own and Folder Contact/Owner sharing perm
By storing these custom MAPI roles in the ACL. The extension field 'X-SOGO-COMPONENT-CREATED-BY' is used to store the event creator when it is done from Outlook. It is the same field SOGo uses when an event is created from a shared folder in the webmail. The creator and the organizer/owner of the event can be different and it can be used from external sources by checking the organizer field. This matches the specification from [MS-OXOCAL] Section 1.1 which defines the organizer as the owner or creator of the event.
This commit is contained in:
@@ -68,6 +68,9 @@
|
||||
- (void) fillMessageData: (struct mapistore_message *) dataPtr
|
||||
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
|
||||
- (NSString *) creator;
|
||||
- (NSString *) owner;
|
||||
|
||||
- (enum mapistore_error) getPidTagSenderEmailAddress: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
- (enum mapistore_error) getPidTagSenderAddressType: (void **) data
|
||||
|
||||
@@ -1023,6 +1023,63 @@ static NSCharacterSet *hexCharacterSet = nil;
|
||||
inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
/* creator (only if created from Outlook/SOGo or organizer as fallback */
|
||||
- (NSString *) creator
|
||||
{
|
||||
iCalPerson *person;
|
||||
NSDictionary *contactInfos;
|
||||
NSString *creator = nil, *email;
|
||||
SOGoUserManager *mgr;
|
||||
|
||||
creator = [[event uniqueChildWithTag: @"x-sogo-component-created-by"]
|
||||
flattenedValuesForKey: @""];
|
||||
if ([creator length] == 0)
|
||||
{
|
||||
person = [event organizer];
|
||||
if (person)
|
||||
{
|
||||
email = [person rfc822Email];
|
||||
if ([email length] > 0)
|
||||
{
|
||||
mgr = [SOGoUserManager sharedUserManager];
|
||||
contactInfos = [mgr contactInfosForUserWithUIDorEmail: email];
|
||||
if (contactInfos)
|
||||
creator = [contactInfos objectForKey: @"sAMAccountName"];
|
||||
}
|
||||
}
|
||||
}
|
||||
return creator;
|
||||
}
|
||||
|
||||
/* owner is the organizer of the event, if none, try with the creator
|
||||
who has saved only from Outlook or SOGo */
|
||||
- (NSString *) owner
|
||||
{
|
||||
iCalPerson *person;
|
||||
NSDictionary *contactInfos;
|
||||
NSString *email, *owner = nil;
|
||||
SOGoUserManager *mgr;
|
||||
|
||||
person = [event organizer];
|
||||
if (person)
|
||||
{
|
||||
email = [person rfc822Email];
|
||||
if ([email length] > 0)
|
||||
{
|
||||
mgr = [SOGoUserManager sharedUserManager];
|
||||
contactInfos = [mgr contactInfosForUserWithUIDorEmail: email];
|
||||
if (contactInfos)
|
||||
owner = [contactInfos objectForKey: @"sAMAccountName"];
|
||||
}
|
||||
}
|
||||
|
||||
if (!owner)
|
||||
owner = [[event uniqueChildWithTag: @"x-sogo-component-created-by"]
|
||||
flattenedValuesForKey: @""];
|
||||
|
||||
return owner;
|
||||
}
|
||||
|
||||
/* sender representing */
|
||||
- (enum mapistore_error) getPidTagSentRepresentingEmailAddress: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
|
||||
@@ -208,6 +208,7 @@
|
||||
[[container event] updateFromMAPIProperties: properties
|
||||
inUserContext: [self userContext]
|
||||
withActiveUser: activeUser
|
||||
isNew: NO
|
||||
inMemCtx: memCtx];
|
||||
}
|
||||
|
||||
|
||||
@@ -81,11 +81,7 @@
|
||||
|
||||
Following rights are not supported by SOGo specifically:
|
||||
|
||||
- DeleteOwned : Delete only own objects
|
||||
- EditOwned : Edit only own objects
|
||||
- CreateSubfolders: No calendar subfolders
|
||||
- FolderOwner: No sharing folder ownership?
|
||||
- FolderContact: No support to store this information
|
||||
- FolderVisible: It is inferred by other rights when extracting
|
||||
*/
|
||||
NSMutableArray *roles;
|
||||
@@ -95,26 +91,35 @@
|
||||
[roles addObject: SOGoRole_ObjectCreator];
|
||||
if (rights & RightsDeleteAll)
|
||||
[roles addObject: SOGoRole_ObjectEraser];
|
||||
if (rights & RightsDeleteOwn)
|
||||
[roles addObject: MAPIStoreRightDeleteOwn];
|
||||
|
||||
if (rights & RightsEditAll)
|
||||
{
|
||||
[roles addObject: SOGoCalendarRole_PublicModifier];
|
||||
[roles addObject: SOGoCalendarRole_PrivateModifier];
|
||||
[roles addObject: SOGoCalendarRole_ConfidentialModifier];
|
||||
}
|
||||
else if (rights & RightsReadItems)
|
||||
if (rights & RightsEditOwn)
|
||||
[roles addObject: MAPIStoreRightEditOwn];
|
||||
|
||||
if (rights & RightsReadItems)
|
||||
{
|
||||
[roles addObject: SOGoCalendarRole_PublicViewer];
|
||||
[roles addObject: SOGoCalendarRole_PrivateViewer];
|
||||
[roles addObject: SOGoCalendarRole_ConfidentialViewer];
|
||||
}
|
||||
if (rights & RightsFreeBusySimple)
|
||||
{
|
||||
[roles addObject: SOGoCalendarRole_PublicDAndTViewer];
|
||||
}
|
||||
[roles addObject: SOGoCalendarRole_PublicDAndTViewer];
|
||||
|
||||
if (rights & RightsFreeBusyDetailed)
|
||||
{
|
||||
[roles addObject: SOGoCalendarRole_ConfidentialDAndTViewer];
|
||||
}
|
||||
[roles addObject: SOGoCalendarRole_ConfidentialDAndTViewer];
|
||||
|
||||
if (rights & RightsFolderOwner)
|
||||
[roles addObject: MAPIStoreRightFolderOwner];
|
||||
|
||||
if (rights & RightsFolderContact)
|
||||
[roles addObject: MAPIStoreRightFolderContact];
|
||||
|
||||
// [self logWithFormat: @"roles for rights %.8x = (%@)", rights, roles];
|
||||
|
||||
@@ -136,19 +141,28 @@
|
||||
else if ([roles containsObject: SOGoCalendarRole_PublicViewer]
|
||||
&& [roles containsObject: SOGoCalendarRole_PrivateViewer]
|
||||
&& [roles containsObject: SOGoCalendarRole_ConfidentialViewer])
|
||||
// We have to set by hand other rights as only the highest role is returned
|
||||
// See SOGoAppointmentFolder.m:aclsForUser for details
|
||||
rights |= RightsReadItems | RightsFreeBusySimple | RightsFreeBusyDetailed;
|
||||
rights |= RightsReadItems;
|
||||
|
||||
if ([roles containsObject: MAPIStoreRightEditOwn])
|
||||
rights |= RightsEditOwn;
|
||||
if ([roles containsObject: MAPIStoreRightDeleteOwn])
|
||||
rights |= RightsDeleteOwn;
|
||||
|
||||
if ([roles containsObject: SOGoCalendarRole_PublicDAndTViewer])
|
||||
rights |= RightsFreeBusySimple;
|
||||
|
||||
if ([roles containsObject: SOGoCalendarRole_ConfidentialDAndTViewer])
|
||||
rights |= RightsFreeBusyDetailed;
|
||||
rights |= RightsFreeBusySimple | RightsFreeBusyDetailed;
|
||||
|
||||
if ((rights & RightsReadItems) != 0 || (rights & RightsCreateItems) != 0 || (rights & RightsDeleteAll) != 0)
|
||||
rights |= RoleNone; /* actually "folder visible" */
|
||||
|
||||
if ([roles containsObject: MAPIStoreRightFolderOwner])
|
||||
rights |= RightsFolderOwner | RoleNone;
|
||||
|
||||
if ([roles containsObject: MAPIStoreRightFolderContact])
|
||||
rights |= RightsFolderContact;
|
||||
|
||||
// [self logWithFormat: @"rights for roles (%@) = %.8x", roles, rights];
|
||||
|
||||
return rights;
|
||||
|
||||
@@ -528,6 +528,16 @@ static Class NSArrayK, MAPIStoreAppointmentWrapperK;
|
||||
ASSIGN (sogoObject, newObject);
|
||||
}
|
||||
|
||||
- (NSString *) creator
|
||||
{
|
||||
return [[self _appointmentWrapper] creator];
|
||||
}
|
||||
|
||||
- (NSString *) owner
|
||||
{
|
||||
return [[self _appointmentWrapper] owner];
|
||||
}
|
||||
|
||||
- (BOOL) subscriberCanReadMessage
|
||||
{
|
||||
NSArray *roles;
|
||||
@@ -539,20 +549,6 @@ static Class NSArrayK, MAPIStoreAppointmentWrapperK;
|
||||
|| [self subscriberCanModifyMessage]);
|
||||
}
|
||||
|
||||
- (BOOL) subscriberCanModifyMessage
|
||||
{
|
||||
BOOL rc;
|
||||
NSArray *roles = [self activeUserRoles];
|
||||
|
||||
if (isNew)
|
||||
rc = [roles containsObject: SOGoRole_ObjectCreator];
|
||||
else
|
||||
rc = ([roles containsObject: SOGoCalendarRole_ComponentModifier]
|
||||
|| [roles containsObject: SOGoCalendarRole_ComponentResponder]);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
- (void) _updateAttachedEvents
|
||||
{
|
||||
NSArray *allAttachments;
|
||||
@@ -632,6 +628,7 @@ static Class NSArrayK, MAPIStoreAppointmentWrapperK;
|
||||
[masterEvent updateFromMAPIProperties: properties
|
||||
inUserContext: [self userContext]
|
||||
withActiveUser: activeUser
|
||||
isNew: isNew
|
||||
inMemCtx: memCtx];
|
||||
[self _updateAttachedEvents];
|
||||
[[self userContext] activate];
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
- (void) updateFromMAPIProperties: (NSDictionary *) properties
|
||||
inUserContext: (MAPIStoreUserContext *) userContext
|
||||
withActiveUser: (SOGoUser *) activeUser
|
||||
isNew: (BOOL) isNew
|
||||
inMemCtx: (TALLOC_CTX *) memCtx;
|
||||
@end
|
||||
|
||||
|
||||
@@ -247,6 +247,7 @@
|
||||
- (void) updateFromMAPIProperties: (NSDictionary *) properties
|
||||
inUserContext: (MAPIStoreUserContext *) userContext
|
||||
withActiveUser: (SOGoUser *) activeUser
|
||||
isNew: (BOOL) isNew
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
BOOL isAllDay;
|
||||
@@ -573,6 +574,14 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
// Creator (with sharing purposes)
|
||||
if (isNew)
|
||||
{
|
||||
value = [properties objectForKey: MAPIPropertyKey (PidTagLastModifierName)];
|
||||
if (value)
|
||||
[[self uniqueChildWithTag: @"x-sogo-component-created-by"] setSingleValue: value
|
||||
forKey: @""];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Reference in New Issue
Block a user