Monotone-Parent: d102adf292e54c9c4f3572b83e38879d24b721d0
Monotone-Revision: 1d22ee7adc99b9420d9a7b859dfb1048c8c92eaa Monotone-Author: wsourdeau@inverse.ca Monotone-Date: 2011-11-18T15:26:03 Monotone-Branch: ca.inverse.sogo
This commit is contained in:
parent
5eccd63a2b
commit
4e17404e8c
35
ChangeLog
35
ChangeLog
|
@ -1,5 +1,40 @@
|
|||
2011-11-18 Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
|
||||
* OpenChange/MAPIStoreFolder.m (-permissionEntries): new public
|
||||
method.
|
||||
(-modifyPermissions:withCount:andFlags:): new backend op public
|
||||
method.
|
||||
(-aclFolder, -rolesForExchangeRights:, -exchangeRightsForRoles:):
|
||||
new mandatory methods.
|
||||
|
||||
* OpenChange/SOGoMAPIFSFolder.m (-defaultUserID, -addUserInAcls:)
|
||||
(-removeAclsForUsers:, -aclUsers, -aclsForUser:)
|
||||
(-setRoles:forUser:): implemented standard ACL methods.
|
||||
|
||||
* OpenChange/MAPIStorePermissionsTable.m
|
||||
(+[MAPIStorePermissionEntry
|
||||
entryWithUserId:andMemberId:forFolder:]): constructor now takes a
|
||||
memberId and the container folder as parameters.
|
||||
(-[MAPIStorePermissionEntry getPrMemberId:inMemCtx:]): now based
|
||||
on the new memberId ivar.
|
||||
(-[MAPIStorePermissionEntry getPrEntryId:inMemCtx:]): now make use
|
||||
of MAPIStoreInternalEntryId for regular member ids and return an
|
||||
empty blob for special ones, as specified in oxcperm.
|
||||
(-[MAPIStorePermissionEntry getPrMemberName:inMemCtx:]): now
|
||||
returns the real CN of the user for regular member ids and return
|
||||
@"" or @"Anonymous" for special ones, as specified in oxcperm.
|
||||
(-[MAPIStorePermissionEntry getPrMemberName:inMemCtx:]): now
|
||||
returns the real member rights, based on the aclFolder of the
|
||||
container, using standard SOGo methods.
|
||||
|
||||
* OpenChange/MAPIStorePermissionsTable.h
|
||||
(MAPIStorePermissionsEntry): made class public.
|
||||
|
||||
* OpenChange/MAPIStoreSOGo.m (sogo_folder_modify_permissions): new
|
||||
backend op.
|
||||
(sogo_backend_init): invoke "disableLocalCache" to avoid the
|
||||
caching of ACL.
|
||||
|
||||
* SoObjects/SOGo/SOGoCache.m (-disableLocalCache): new method to
|
||||
disable the local cache altogether (helper for non-WO access).
|
||||
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#import <Foundation/NSURL.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <EOControl/EOQualifier.h>
|
||||
#import <SOGo/SOGoPermissions.h>
|
||||
#import <Appointments/SOGoAppointmentFolder.h>
|
||||
#import <Appointments/SOGoAppointmentFolders.h>
|
||||
#import <Appointments/SOGoAppointmentObject.h>
|
||||
|
@ -36,6 +37,9 @@
|
|||
|
||||
#import "MAPIStoreCalendarFolder.h"
|
||||
|
||||
#include <util/time.h>
|
||||
#include <gen_ndr/exchange.h>
|
||||
|
||||
@implementation MAPIStoreCalendarFolder
|
||||
|
||||
- (id) initWithURL: (NSURL *) newURL
|
||||
|
@ -106,4 +110,51 @@
|
|||
return newMessage;
|
||||
}
|
||||
|
||||
- (NSArray *) rolesForExchangeRights: (uint32_t) rights
|
||||
{
|
||||
NSMutableArray *roles;
|
||||
|
||||
roles = [NSMutableArray arrayWithCapacity: 6];
|
||||
if (rights & RightsCreateItems)
|
||||
[roles addObject: SOGoRole_ObjectCreator];
|
||||
if (rights & RightsDeleteAll)
|
||||
[roles addObject: SOGoRole_ObjectEraser];
|
||||
if (rights & RightsEditAll)
|
||||
{
|
||||
[roles addObject: SOGoCalendarRole_PublicModifier];
|
||||
[roles addObject: SOGoCalendarRole_PrivateModifier];
|
||||
[roles addObject: SOGoCalendarRole_ConfidentialModifier];
|
||||
}
|
||||
else if (rights & RightsReadItems)
|
||||
{
|
||||
[roles addObject: SOGoCalendarRole_PublicViewer];
|
||||
[roles addObject: SOGoCalendarRole_PrivateViewer];
|
||||
[roles addObject: SOGoCalendarRole_ConfidentialViewer];
|
||||
}
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
- (uint32_t) exchangeRightsForRoles: (NSArray *) roles
|
||||
{
|
||||
uint32_t rights = 0;
|
||||
|
||||
if ([roles containsObject: SOGoRole_ObjectCreator])
|
||||
rights |= RightsCreateItems;
|
||||
if ([roles containsObject: SOGoRole_ObjectEraser])
|
||||
rights |= RightsDeleteAll;
|
||||
if ([roles containsObject: SOGoCalendarRole_PublicModifier]
|
||||
&& [roles containsObject: SOGoCalendarRole_PrivateModifier]
|
||||
&& [roles containsObject: SOGoCalendarRole_ConfidentialModifier])
|
||||
rights |= RightsReadItems | RightsEditAll;
|
||||
else if ([roles containsObject: SOGoCalendarRole_PublicViewer]
|
||||
&& [roles containsObject: SOGoCalendarRole_PrivateViewer]
|
||||
&& [roles containsObject: SOGoCalendarRole_ConfidentialViewer])
|
||||
rights |= RightsReadItems;
|
||||
if (rights != 0)
|
||||
rights |= RoleNone; /* actually "folder visible" */
|
||||
|
||||
return rights;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#import <Foundation/NSURL.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <EOControl/EOQualifier.h>
|
||||
#import <SOGo/SOGoPermissions.h>
|
||||
#import <Contacts/SOGoContactGCSEntry.h>
|
||||
#import <Contacts/SOGoContactFolders.h>
|
||||
|
||||
|
@ -33,6 +34,9 @@
|
|||
|
||||
#import "MAPIStoreContactsFolder.h"
|
||||
|
||||
#include <util/time.h>
|
||||
#include <gen_ndr/exchange.h>
|
||||
|
||||
@implementation MAPIStoreContactsFolder
|
||||
|
||||
- (id) initWithURL: (NSURL *) newURL
|
||||
|
@ -103,4 +107,39 @@
|
|||
return newMessage;
|
||||
}
|
||||
|
||||
- (NSArray *) rolesForExchangeRights: (uint32_t) rights
|
||||
{
|
||||
NSMutableArray *roles;
|
||||
|
||||
roles = [NSMutableArray arrayWithCapacity: 6];
|
||||
if (rights & RightsCreateItems)
|
||||
[roles addObject: SOGoRole_ObjectCreator];
|
||||
if (rights & RightsDeleteAll)
|
||||
[roles addObject: SOGoRole_ObjectEraser];
|
||||
if (rights & RightsEditAll)
|
||||
[roles addObject: SOGoRole_ObjectEditor];
|
||||
if (rights & RightsReadItems)
|
||||
[roles addObject: SOGoRole_ObjectViewer];
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
- (uint32_t) exchangeRightsForRoles: (NSArray *) roles
|
||||
{
|
||||
uint32_t rights = 0;
|
||||
|
||||
if ([roles containsObject: SOGoRole_ObjectCreator])
|
||||
rights |= RightsCreateItems;
|
||||
if ([roles containsObject: SOGoRole_ObjectEraser])
|
||||
rights |= RightsDeleteAll;
|
||||
if ([roles containsObject: SOGoRole_ObjectEditor])
|
||||
rights |= RightsEditAll;
|
||||
if ([roles containsObject: SOGoRole_ObjectViewer])
|
||||
rights |= RightsReadItems;
|
||||
if (rights != 0)
|
||||
rights |= RoleNone; /* actually "folder visible" */
|
||||
|
||||
return rights;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -193,4 +193,64 @@ static Class EOKeyValueQualifierK;
|
|||
return date;
|
||||
}
|
||||
|
||||
- (SOGoFolder *) aclFolder
|
||||
{
|
||||
return propsFolder;
|
||||
}
|
||||
|
||||
- (NSArray *) rolesForExchangeRights: (uint32_t) rights
|
||||
{
|
||||
NSMutableArray *roles;
|
||||
|
||||
roles = [NSMutableArray arrayWithCapacity: 9];
|
||||
if (rights & RightsReadItems)
|
||||
[roles addObject: @"RightsReadItems"];
|
||||
if (rights & RightsCreateItems)
|
||||
[roles addObject: @"RightsCreateItems"];
|
||||
if (rights & RightsEditOwn)
|
||||
[roles addObject: @"RightsEditOwn"];
|
||||
if (rights & RightsDeleteOwn)
|
||||
[roles addObject: @"RightsDeleteOwn"];
|
||||
if (rights & RightsEditAll)
|
||||
[roles addObject: @"RightsEditAll"];
|
||||
if (rights & RightsDeleteAll)
|
||||
[roles addObject: @"RightsDeleteAll"];
|
||||
if (rights & RightsCreateSubfolders)
|
||||
[roles addObject: @"RightsCreateSubfolders"];
|
||||
if (rights & RightsFolderOwner)
|
||||
[roles addObject: @"RightsFolderOwner"];
|
||||
if (rights & RightsFolderContact)
|
||||
[roles addObject: @"RightsFolderContact"];
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
- (uint32_t) exchangeRightsForRoles: (NSArray *) roles
|
||||
{
|
||||
uint32_t rights = 0;
|
||||
|
||||
if ([roles containsObject: @"RightsReadItems"])
|
||||
rights |= RightsReadItems;
|
||||
if ([roles containsObject: @"RightsCreateItems"])
|
||||
rights |= RightsCreateItems;
|
||||
if ([roles containsObject: @"RightsEditOwn"])
|
||||
rights |= RightsEditOwn;
|
||||
if ([roles containsObject: @"RightsDeleteOwn"])
|
||||
rights |= RightsDeleteOwn;
|
||||
if ([roles containsObject: @"RightsEditAll"])
|
||||
rights |= RightsEditAll;
|
||||
if ([roles containsObject: @"RightsDeleteAll"])
|
||||
rights |= RightsDeleteAll;
|
||||
if ([roles containsObject: @"RightsCreateSubfolders"])
|
||||
rights |= RightsCreateSubfolders;
|
||||
if ([roles containsObject: @"RightsFolderOwner"])
|
||||
rights |= RightsFolderOwner;
|
||||
if ([roles containsObject: @"RightsFolderContact"])
|
||||
rights |= RightsFolderContact;
|
||||
if (rights != 0)
|
||||
rights |= RoleNone; /* actually "folder visible" */
|
||||
|
||||
return rights;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -40,10 +40,10 @@
|
|||
@class MAPIStoreFolderTable;
|
||||
@class MAPIStoreMessageTable;
|
||||
@class MAPIStorePermissionsTable;
|
||||
@class SOGoFolder;
|
||||
@class SOGoMAPIFSFolder;
|
||||
@class SOGoMAPIFSMessage;
|
||||
|
||||
|
||||
#import "MAPIStoreObject.h"
|
||||
|
||||
@interface MAPIStoreFolder : MAPIStoreObject
|
||||
|
@ -74,6 +74,7 @@
|
|||
|
||||
/* permissions */
|
||||
- (MAPIStorePermissionsTable *) permissionsTable;
|
||||
- (NSArray *) permissionEntries;
|
||||
|
||||
/* message objects and tables */
|
||||
- (id) lookupMessage: (NSString *) messageKey;
|
||||
|
@ -135,6 +136,10 @@
|
|||
tableType: (uint8_t) tableType
|
||||
andHandleId: (uint32_t) handleId;
|
||||
|
||||
- (int) modifyPermissions: (struct PermissionData *) permissions
|
||||
withCount: (uint16_t) pcount
|
||||
andFlags: (int8_t) flags;
|
||||
|
||||
/* helpers */
|
||||
- (uint64_t) idForObjectWithKey: (NSString *) childKey;
|
||||
|
||||
|
@ -152,6 +157,10 @@
|
|||
|
||||
- (NSCalendarDate *) lastMessageModificationTime;
|
||||
|
||||
- (SOGoFolder *) aclFolder;
|
||||
- (NSArray *) rolesForExchangeRights: (uint32_t) rights;
|
||||
- (uint32_t) exchangeRightsForRoles: (NSArray *) roles;
|
||||
|
||||
/* subclass helpers */
|
||||
- (void) postNotificationsForMoveCopyMessagesWithMIDs: (uint64_t *) srcMids
|
||||
andMessageURLs: (NSArray *) oldMessageURLs
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#import "MAPIStoreMapping.h"
|
||||
#import "MAPIStoreMessage.h"
|
||||
#import "MAPIStorePermissionsTable.h"
|
||||
#import "MAPIStoreSamDBUtils.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "NSDate+MAPIStore.h"
|
||||
#import "NSString+MAPIStore.h"
|
||||
|
@ -700,6 +701,23 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
return rc;
|
||||
}
|
||||
|
||||
- (SOGoFolder *) aclFolder
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void) _modifyPermissionEntryForUser: (NSString *) user
|
||||
withRoles: (NSArray *) roles
|
||||
isAddition: (BOOL) isAddition
|
||||
withACLFolder: (SOGoFolder *) aclFolder
|
||||
{
|
||||
if (isAddition)
|
||||
[aclFolder addUserInAcls: user];
|
||||
[aclFolder setRoles: roles forUser: user];
|
||||
}
|
||||
|
||||
- (void) postNotificationsForMoveCopyMessagesWithMIDs: (uint64_t *) srcMids
|
||||
andMessageURLs: (NSArray *) oldMessageURLs
|
||||
andCount: (uint32_t) midCount
|
||||
|
@ -1247,6 +1265,196 @@ Class NSExceptionK, MAPIStoreFAIMessageK, MAPIStoreMessageTableK, MAPIStoreFAIMe
|
|||
return [MAPIStorePermissionsTable tableForContainer: self];
|
||||
}
|
||||
|
||||
- (NSArray *) permissionEntries
|
||||
{
|
||||
NSMutableArray *permissionEntries;
|
||||
MAPIStorePermissionEntry *entry;
|
||||
NSArray *aclUsers;
|
||||
uint64_t memberId, regularMemberId = 1;
|
||||
NSUInteger count, max;
|
||||
NSString *username, *defaultUserId;
|
||||
SOGoFolder *aclFolder;
|
||||
|
||||
aclFolder = [self aclFolder];
|
||||
|
||||
defaultUserId = [aclFolder defaultUserID];
|
||||
aclUsers = [aclFolder aclUsers];
|
||||
max = [aclUsers count];
|
||||
permissionEntries = [NSMutableArray arrayWithCapacity: max];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
username = [aclUsers objectAtIndex: count];
|
||||
if (![username hasPrefix: @"@"])
|
||||
{
|
||||
if ([username isEqualToString: defaultUserId])
|
||||
memberId = 0;
|
||||
else if ([username isEqualToString: @"anonymous"])
|
||||
memberId = ULLONG_MAX;
|
||||
else
|
||||
{
|
||||
memberId = regularMemberId;
|
||||
regularMemberId++;
|
||||
}
|
||||
entry = [MAPIStorePermissionEntry entryWithUserId: username
|
||||
andMemberId: memberId
|
||||
forFolder: self];
|
||||
[permissionEntries addObject: entry];
|
||||
}
|
||||
}
|
||||
|
||||
return permissionEntries;
|
||||
}
|
||||
|
||||
- (NSArray *) rolesForExchangeRights: (uint32_t) rights
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (uint32_t) exchangeRightsForRoles: (NSArray *) roles
|
||||
{
|
||||
[self subclassResponsibility: _cmd];
|
||||
return 0;
|
||||
}
|
||||
|
||||
- (NSString *) _usernameFromEntryId: (struct SBinary_short *) bin
|
||||
{
|
||||
struct Binary_r bin32;
|
||||
struct AddressBookEntryId *entryId;
|
||||
NSString *username;
|
||||
struct ldb_context *samCtx;
|
||||
|
||||
bin32.cb = bin->cb;
|
||||
bin32.lpb = bin->lpb;
|
||||
|
||||
entryId = get_AddressBookEntryId (NULL, &bin32);
|
||||
if (entryId)
|
||||
{
|
||||
samCtx = [[self context] connectionInfo]->sam_ctx;
|
||||
username = MAPIStoreSamDBUserAttribute (samCtx, @"legacyExchangeDN",
|
||||
[NSString stringWithUTF8String: entryId->X500DN],
|
||||
@"sAMAccountName");
|
||||
}
|
||||
else
|
||||
username = nil;
|
||||
talloc_free (entryId);
|
||||
|
||||
return username;
|
||||
}
|
||||
|
||||
- (NSString *) _usernameFromMemberId: (uint64_t) memberId
|
||||
inEntries: (NSArray *) entries
|
||||
{
|
||||
NSString *username = nil;
|
||||
NSUInteger count, max;
|
||||
MAPIStorePermissionEntry *entry;
|
||||
|
||||
max = [entries count];
|
||||
for (count = 0; !username && count < max; count++)
|
||||
{
|
||||
entry = [entries objectAtIndex: count];
|
||||
if ([entry memberId] == memberId)
|
||||
username = [entry userId];
|
||||
}
|
||||
|
||||
return username;
|
||||
}
|
||||
|
||||
- (void) _emptyACL
|
||||
{
|
||||
NSUInteger count, max;
|
||||
NSArray *users;
|
||||
SOGoFolder *aclFolder;
|
||||
|
||||
aclFolder = [self aclFolder];
|
||||
|
||||
users = [aclFolder aclUsers];
|
||||
max = [users count];
|
||||
for (count = 0; count < max; count++)
|
||||
[aclFolder removeUserFromAcls: [users objectAtIndex: count]];
|
||||
}
|
||||
|
||||
- (int) modifyPermissions: (struct PermissionData *) permissions
|
||||
withCount: (uint16_t) pcount
|
||||
andFlags: (int8_t) flags
|
||||
{
|
||||
NSUInteger count, propCount;
|
||||
struct PermissionData *currentPermission;
|
||||
struct mapi_SPropValue *mapiValue;
|
||||
NSString *permissionUser;
|
||||
NSArray *entries;
|
||||
NSArray *permissionRoles;
|
||||
BOOL reset, isAdd;
|
||||
SOGoFolder *aclFolder;
|
||||
|
||||
aclFolder = [self aclFolder];
|
||||
|
||||
reset = ((flags & ModifyPerms_ReplaceRows) != 0);
|
||||
if (reset)
|
||||
[self _emptyACL];
|
||||
|
||||
entries = [self permissionEntries];
|
||||
|
||||
for (count = 0; count < pcount; count++)
|
||||
{
|
||||
currentPermission = permissions + count;
|
||||
|
||||
permissionUser = nil;
|
||||
permissionRoles = nil;
|
||||
|
||||
isAdd = (currentPermission->PermissionDataFlags == ROW_ADD);
|
||||
for (propCount = 0;
|
||||
propCount < currentPermission->lpProps.cValues;
|
||||
propCount++)
|
||||
{
|
||||
mapiValue = currentPermission->lpProps.lpProps + propCount;
|
||||
switch (mapiValue->ulPropTag)
|
||||
{
|
||||
case PR_ENTRYID:
|
||||
permissionUser
|
||||
= [self _usernameFromEntryId: &mapiValue->value.bin];
|
||||
break;
|
||||
case PR_MEMBER_ID:
|
||||
permissionUser = [self _usernameFromMemberId: mapiValue->value.d
|
||||
inEntries: entries];
|
||||
break;
|
||||
case PR_MEMBER_RIGHTS:
|
||||
permissionRoles = [self
|
||||
rolesForExchangeRights: mapiValue->value.l];
|
||||
break;
|
||||
default:
|
||||
if (mapiValue->ulPropTag != PR_MEMBER_NAME)
|
||||
[self warnWithFormat: @"unhandled permission property: %.8x",
|
||||
mapiValue->ulPropTag];
|
||||
}
|
||||
}
|
||||
|
||||
if (reset)
|
||||
{
|
||||
if (isAdd)
|
||||
[self _modifyPermissionEntryForUser: permissionUser
|
||||
withRoles: permissionRoles
|
||||
isAddition: YES
|
||||
withACLFolder: aclFolder];
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isAdd || currentPermission->PermissionDataFlags == ROW_MODIFY)
|
||||
[self _modifyPermissionEntryForUser: permissionUser
|
||||
withRoles: permissionRoles
|
||||
isAddition: isAdd
|
||||
withACLFolder: aclFolder];
|
||||
else if (currentPermission->PermissionDataFlags == ROW_REMOVE)
|
||||
[aclFolder removeUserFromAcls: permissionUser];
|
||||
else
|
||||
[self errorWithFormat: @"unhandled permission action flag: %d",
|
||||
currentPermission->PermissionDataFlags];
|
||||
}
|
||||
}
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
||||
- (uint64_t) objectId
|
||||
{
|
||||
uint64_t objectId;
|
||||
|
|
|
@ -133,6 +133,11 @@
|
|||
return value;
|
||||
}
|
||||
|
||||
- (SOGoFolder *) aclFolder
|
||||
{
|
||||
return (SOGoFolder *) sogoObject;
|
||||
}
|
||||
|
||||
/* synchronisation */
|
||||
|
||||
/* Tree
|
||||
|
|
|
@ -43,11 +43,11 @@
|
|||
#import <Mailer/SOGoTrashFolder.h>
|
||||
#import <SOGo/NSArray+Utilities.h>
|
||||
#import <SOGo/NSString+Utilities.h>
|
||||
#import <SOGo/SOGoPermissions.h>
|
||||
|
||||
#import "MAPIApplication.h"
|
||||
#import "MAPIStoreAppointmentWrapper.h"
|
||||
#import "MAPIStoreContext.h"
|
||||
// #import "MAPIStoreDraftsMessage.h"
|
||||
#import "MAPIStoreFAIMessage.h"
|
||||
#import "MAPIStoreMailMessageTable.h"
|
||||
#import "MAPIStoreMapping.h"
|
||||
|
@ -391,6 +391,11 @@ static Class SOGoMailFolderK;
|
|||
return value;
|
||||
}
|
||||
|
||||
- (SOGoFolder *) aclFolder
|
||||
{
|
||||
return (SOGoFolder *) sogoObject;
|
||||
}
|
||||
|
||||
/* synchronisation */
|
||||
|
||||
/* Tree:
|
||||
|
@ -1008,6 +1013,65 @@ _parseCOPYUID (NSString *line, NSArray **destUIDsP)
|
|||
return newMessage;
|
||||
}
|
||||
|
||||
|
||||
- (NSArray *) rolesForExchangeRights: (uint32_t) rights
|
||||
{
|
||||
NSMutableArray *roles;
|
||||
|
||||
roles = [NSMutableArray arrayWithCapacity: 6];
|
||||
if (rights & RoleOwner)
|
||||
[roles addObject: SOGoMailRole_Administrator];
|
||||
if (rights & RightsCreateItems)
|
||||
{
|
||||
[roles addObject: SOGoRole_ObjectCreator];
|
||||
[roles addObject: SOGoMailRole_Writer];
|
||||
[roles addObject: SOGoMailRole_Poster];
|
||||
}
|
||||
if (rights & RightsDeleteAll)
|
||||
{
|
||||
[roles addObject: SOGoRole_ObjectEraser];
|
||||
[roles addObject: SOGoRole_FolderEraser];
|
||||
[roles addObject: SOGoMailRole_Expunger];
|
||||
}
|
||||
if (rights & RightsEditAll)
|
||||
[roles addObject: SOGoRole_ObjectEditor];
|
||||
if (rights & RightsReadItems)
|
||||
[roles addObject: SOGoRole_ObjectViewer];
|
||||
if (rights & RightsCreateSubfolders)
|
||||
[roles addObject: SOGoRole_FolderCreator];
|
||||
if (rights & RightsCreateSubfolders)
|
||||
[roles addObject: SOGoRole_FolderCreator];
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
- (uint32_t) exchangeRightsForRoles: (NSArray *) roles
|
||||
{
|
||||
uint32_t rights = 0;
|
||||
|
||||
if ([roles containsObject: SOGoMailRole_Administrator])
|
||||
rights |= (RoleOwner ^ RightsAll);
|
||||
if ([roles containsObject: SOGoRole_ObjectCreator])
|
||||
rights |= RightsCreateItems;
|
||||
if ([roles containsObject: SOGoRole_ObjectEraser]
|
||||
&& [roles containsObject: SOGoRole_FolderEraser])
|
||||
rights |= RightsDeleteAll;
|
||||
|
||||
if ([roles containsObject: SOGoRole_ObjectEditor])
|
||||
rights |= RightsEditAll;
|
||||
if ([roles containsObject: SOGoRole_ObjectViewer])
|
||||
rights |= RightsReadItems;
|
||||
if ([roles containsObject: SOGoRole_FolderCreator])
|
||||
rights |= RightsCreateSubfolders;
|
||||
if ([roles containsObject: SOGoRole_FolderCreator])
|
||||
rights |= RightsCreateSubfolders;
|
||||
|
||||
if (rights != 0)
|
||||
rights |= RoleNone; /* actually "folder visible" */
|
||||
|
||||
return rights;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation MAPIStoreInboxFolder : MAPIStoreMailFolder
|
||||
|
|
|
@ -25,7 +25,31 @@
|
|||
|
||||
#import "MAPIStoreTable.h"
|
||||
|
||||
struct ldb_context;
|
||||
|
||||
@interface MAPIStorePermissionEntry : MAPIStoreObject
|
||||
{
|
||||
NSString *userId;
|
||||
uint64_t memberId;
|
||||
}
|
||||
|
||||
+ (id) entryWithUserId: (NSString *) newUserId
|
||||
andMemberId: (uint64_t) newMemberId
|
||||
forFolder: (MAPIStoreFolder *) newFolder;
|
||||
- (id) initWithUserId: (NSString *) newUserId
|
||||
andMemberId: (uint64_t) newMemberId
|
||||
forFolder: (MAPIStoreFolder *) newFolder;
|
||||
|
||||
- (NSString *) userId;
|
||||
- (uint64_t) memberId;
|
||||
|
||||
@end
|
||||
|
||||
@interface MAPIStorePermissionsTable : MAPIStoreTable
|
||||
{
|
||||
NSMutableDictionary *entries;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif /* MAPISTOREPERMISSIONSTABLE_H */
|
||||
|
|
|
@ -21,44 +21,48 @@
|
|||
*/
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSString.h>
|
||||
|
||||
#import "MAPIStoreObject.h"
|
||||
#import <SOGo/SOGoObject.h>
|
||||
#import <SOGo/SOGoUser.h>
|
||||
|
||||
#import "MAPIStoreContext.h"
|
||||
#import "MAPIStoreFolder.h"
|
||||
#import "MAPIStoreTypes.h"
|
||||
#import "MAPIStoreSamDBUtils.h"
|
||||
#import "NSData+MAPIStore.h"
|
||||
#import "NSString+MAPIStore.h"
|
||||
|
||||
#import "MAPIStorePermissionsTable.h"
|
||||
|
||||
#undef DEBUG
|
||||
#include <mapistore/mapistore.h>
|
||||
#include <mapistore/mapistore_errors.h>
|
||||
|
||||
@interface MAPIStorePermissionEntry : MAPIStoreObject
|
||||
{
|
||||
NSString *userId;
|
||||
}
|
||||
|
||||
+ (id) entryWithUserId: (NSString *) newUserId;
|
||||
- (id) initWithUserId: (NSString *) newUserId;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MAPIStorePermissionEntry
|
||||
|
||||
+ (id) entryWithUserId: (NSString *) newUserId
|
||||
andMemberId: (uint64_t) newMemberId
|
||||
forFolder: (MAPIStoreFolder *) newFolder
|
||||
{
|
||||
MAPIStorePermissionEntry *newEntry;
|
||||
|
||||
newEntry = [[self alloc] initWithUserId: newUserId];
|
||||
newEntry = [[self alloc] initWithUserId: newUserId andMemberId: newMemberId
|
||||
forFolder: newFolder];
|
||||
[newEntry autorelease];
|
||||
|
||||
return newEntry;
|
||||
}
|
||||
|
||||
- (id) initWithUserId: (NSString *) newUserId
|
||||
andMemberId: (uint64_t) newMemberId
|
||||
forFolder: (MAPIStoreFolder *) newFolder
|
||||
{
|
||||
if ((self = [self init]))
|
||||
if ((self = [self initWithSOGoObject: nil inContainer: newFolder]))
|
||||
{
|
||||
ASSIGN (userId, newUserId);
|
||||
memberId = newMemberId;
|
||||
}
|
||||
|
||||
return self;
|
||||
|
@ -70,15 +74,20 @@
|
|||
[super dealloc];
|
||||
}
|
||||
|
||||
- (NSString *) userId
|
||||
{
|
||||
return userId;
|
||||
}
|
||||
|
||||
- (uint64_t) memberId
|
||||
{
|
||||
return memberId;
|
||||
}
|
||||
|
||||
- (int) getPrMemberId: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
uint64_t value = 0;
|
||||
|
||||
if ([userId isEqualToString: @"anonymous"])
|
||||
value = ULLONG_MAX;
|
||||
|
||||
*data = MAPILongLongValue (memCtx, value);
|
||||
*data = MAPILongLongValue (memCtx, memberId);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
@ -86,7 +95,17 @@
|
|||
- (int) getPrEntryid: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
*data = [[NSData data] asBinaryInMemCtx: memCtx];
|
||||
NSData *entryId;
|
||||
struct mapistore_connection_info *connInfo;
|
||||
|
||||
if (memberId == 0 || memberId == ULLONG_MAX)
|
||||
entryId = [NSData data];
|
||||
else
|
||||
{
|
||||
connInfo = [[container context] connectionInfo];
|
||||
entryId = MAPIStoreInternalEntryId (connInfo->sam_ctx, userId);
|
||||
}
|
||||
*data = [entryId asBinaryInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
@ -94,7 +113,16 @@
|
|||
- (int) getPrMemberName: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
*data = [userId asUnicodeInMemCtx: memCtx];
|
||||
NSString *displayName;
|
||||
|
||||
if (memberId == 0)
|
||||
displayName = @"";
|
||||
else if (memberId == ULLONG_MAX)
|
||||
displayName = @"Anonymous";
|
||||
else
|
||||
displayName = [[SOGoUser userWithLogin: userId] cn];
|
||||
|
||||
*data = [displayName asUnicodeInMemCtx: memCtx];
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
@ -102,7 +130,13 @@
|
|||
- (int) getPrMemberRights: (void **) data
|
||||
inMemCtx: (TALLOC_CTX *) memCtx
|
||||
{
|
||||
*data = MAPILongValue (memCtx, 0);
|
||||
uint32_t rights;
|
||||
NSArray *roles;
|
||||
|
||||
roles = [[(MAPIStoreFolder *) container aclFolder] aclsForUser: userId];
|
||||
rights = [(MAPIStoreFolder *) container exchangeRightsForRoles: roles];
|
||||
|
||||
*data = MAPILongValue (memCtx, rights);
|
||||
|
||||
return MAPISTORE_SUCCESS;
|
||||
}
|
||||
|
@ -111,9 +145,37 @@
|
|||
|
||||
@implementation MAPIStorePermissionsTable
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[entries release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) _fetchEntries
|
||||
{
|
||||
NSArray *permEntries;
|
||||
NSUInteger count, max;
|
||||
MAPIStorePermissionEntry *entry;
|
||||
|
||||
entries = [NSMutableDictionary new];
|
||||
permEntries = [(MAPIStoreFolder *) container permissionEntries];
|
||||
max = [permEntries count];
|
||||
for (count = 0; count < max; count++)
|
||||
{
|
||||
entry = [permEntries objectAtIndex: count];
|
||||
[entries setObject: entry forKey: [entry userId]];
|
||||
}
|
||||
|
||||
childKeys = [entries allKeys];
|
||||
[childKeys retain];
|
||||
}
|
||||
|
||||
- (NSArray *) childKeys
|
||||
{
|
||||
return [NSArray arrayWithObjects: @"default", @"anonymous", nil];
|
||||
if (!entries)
|
||||
[self _fetchEntries];
|
||||
|
||||
return childKeys;
|
||||
}
|
||||
|
||||
- (NSArray *) restrictedChildKeys
|
||||
|
@ -123,7 +185,10 @@
|
|||
|
||||
- (id) lookupChild: (NSString *) childKey
|
||||
{
|
||||
return [MAPIStorePermissionEntry entryWithUserId: childKey];
|
||||
if (!entries)
|
||||
[self _fetchEntries];
|
||||
|
||||
return [entries objectForKey: childKey];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
/* MAPIStoreSOGo.m - this file is part of SOGo
|
||||
*
|
||||
* Copyright (C) 2010 Inverse inc.
|
||||
* Copyright (C) 2010, 2011 Inverse inc.
|
||||
*
|
||||
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
|
||||
*
|
||||
|
@ -100,6 +100,7 @@ sogo_backend_init (void)
|
|||
[[MAPIApplicationK new] activateApplication];
|
||||
|
||||
[[SOGoCache sharedCache] disableRequestsCache];
|
||||
[[SOGoCache sharedCache] disableLocalCache];
|
||||
|
||||
[pool release];
|
||||
|
||||
|
@ -554,6 +555,36 @@ sogo_folder_open_table(void *folder_object, TALLOC_CTX *mem_ctx,
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
sogo_folder_modify_permissions(void *folder_object, uint8_t flags,
|
||||
uint16_t pcount,
|
||||
struct PermissionData *permissions)
|
||||
{
|
||||
struct MAPIStoreTallocWrapper *wrapper;
|
||||
NSAutoreleasePool *pool;
|
||||
MAPIStoreFolder *folder;
|
||||
int rc;
|
||||
|
||||
DEBUG (5, ("[SOGo: %s:%d]\n", __FUNCTION__, __LINE__));
|
||||
|
||||
if (folder_object)
|
||||
{
|
||||
wrapper = folder_object;
|
||||
folder = wrapper->MAPIStoreSOGoObject;
|
||||
pool = [NSAutoreleasePool new];
|
||||
rc = [folder modifyPermissions: permissions
|
||||
withCount: pcount
|
||||
andFlags: flags];
|
||||
[pool release];
|
||||
}
|
||||
else
|
||||
{
|
||||
rc = sogo_backend_unexpected_error();
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int
|
||||
sogo_message_get_message_data(void *message_object,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
|
@ -1189,6 +1220,7 @@ int mapistore_init_backend(void)
|
|||
backend.folder.get_deleted_fmids = sogo_folder_get_deleted_fmids;
|
||||
backend.folder.get_child_count = sogo_folder_get_child_count;
|
||||
backend.folder.open_table = sogo_folder_open_table;
|
||||
backend.folder.modify_permissions = sogo_folder_modify_permissions;
|
||||
backend.message.create_attachment = sogo_message_create_attachment;
|
||||
backend.message.get_attachment_table = sogo_message_get_attachment_table;
|
||||
backend.message.open_attachment = sogo_message_open_attachment;
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#import <Foundation/NSURL.h>
|
||||
#import <NGObjWeb/WOContext+SoObjects.h>
|
||||
#import <EOControl/EOQualifier.h>
|
||||
#import <SOGo/SOGoPermissions.h>
|
||||
#import <Appointments/SOGoAppointmentFolder.h>
|
||||
#import <Appointments/SOGoAppointmentFolders.h>
|
||||
#import <Appointments/SOGoTaskObject.h>
|
||||
|
@ -36,6 +37,9 @@
|
|||
|
||||
#import "MAPIStoreTasksFolder.h"
|
||||
|
||||
#include <util/time.h>
|
||||
#include <gen_ndr/exchange.h>
|
||||
|
||||
@implementation MAPIStoreTasksFolder
|
||||
|
||||
- (id) initWithURL: (NSURL *) newURL
|
||||
|
@ -106,4 +110,51 @@
|
|||
return newMessage;
|
||||
}
|
||||
|
||||
- (NSArray *) rolesForExchangeRights: (uint32_t) rights
|
||||
{
|
||||
NSMutableArray *roles;
|
||||
|
||||
roles = [NSMutableArray arrayWithCapacity: 6];
|
||||
if (rights & RightsCreateItems)
|
||||
[roles addObject: SOGoRole_ObjectCreator];
|
||||
if (rights & RightsDeleteAll)
|
||||
[roles addObject: SOGoRole_ObjectEraser];
|
||||
if (rights & RightsEditAll)
|
||||
{
|
||||
[roles addObject: SOGoCalendarRole_PublicModifier];
|
||||
[roles addObject: SOGoCalendarRole_PrivateModifier];
|
||||
[roles addObject: SOGoCalendarRole_ConfidentialModifier];
|
||||
}
|
||||
else if (rights & RightsReadItems)
|
||||
{
|
||||
[roles addObject: SOGoCalendarRole_PublicViewer];
|
||||
[roles addObject: SOGoCalendarRole_PrivateViewer];
|
||||
[roles addObject: SOGoCalendarRole_ConfidentialViewer];
|
||||
}
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
- (uint32_t) exchangeRightsForRoles: (NSArray *) roles
|
||||
{
|
||||
uint32_t rights = 0;
|
||||
|
||||
if ([roles containsObject: SOGoRole_ObjectCreator])
|
||||
rights |= RightsCreateItems;
|
||||
if ([roles containsObject: SOGoRole_ObjectEraser])
|
||||
rights |= RightsDeleteAll;
|
||||
if ([roles containsObject: SOGoCalendarRole_PublicModifier]
|
||||
&& [roles containsObject: SOGoCalendarRole_PrivateModifier]
|
||||
&& [roles containsObject: SOGoCalendarRole_ConfidentialModifier])
|
||||
rights |= RightsReadItems | RightsEditAll;
|
||||
else if ([roles containsObject: SOGoCalendarRole_PublicViewer]
|
||||
&& [roles containsObject: SOGoCalendarRole_PrivateViewer]
|
||||
&& [roles containsObject: SOGoCalendarRole_ConfidentialViewer])
|
||||
rights |= RightsReadItems;
|
||||
if (rights != 0)
|
||||
rights |= RoleNone; /* actually "folder visible" */
|
||||
|
||||
return rights;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -21,13 +21,17 @@
|
|||
*/
|
||||
|
||||
#import <Foundation/NSArray.h>
|
||||
#import <Foundation/NSData.h>
|
||||
#import <Foundation/NSDictionary.h>
|
||||
#import <Foundation/NSException.h>
|
||||
#import <Foundation/NSFileManager.h>
|
||||
#import <Foundation/NSPropertyList.h>
|
||||
#import <Foundation/NSString.h>
|
||||
#import <Foundation/NSValue.h>
|
||||
#import <Foundation/NSURL.h>
|
||||
|
||||
#import <NGExtensions/NSObject+Logs.h>
|
||||
#import <SOGo/NSArray+Utilities.h>
|
||||
|
||||
#import "EOQualifier+MAPI.h"
|
||||
#import "SOGoMAPIFSMessage.h"
|
||||
|
@ -200,11 +204,14 @@ static NSString *privateDir = nil;
|
|||
for (count = 0; count < max; count++)
|
||||
{
|
||||
file = [contents objectAtIndex: count];
|
||||
fullName = [directory stringByAppendingPathComponent: file];
|
||||
if ([fm fileExistsAtPath: fullName
|
||||
isDirectory: &isDir]
|
||||
&& dirs == isDir)
|
||||
[files addObject: file];
|
||||
if (![file isEqualToString: @"permissions.plist"])
|
||||
{
|
||||
fullName = [directory stringByAppendingPathComponent: file];
|
||||
if ([fm fileExistsAtPath: fullName
|
||||
isDirectory: &isDir]
|
||||
&& dirs == isDir)
|
||||
[files addObject: file];
|
||||
}
|
||||
}
|
||||
|
||||
return files;
|
||||
|
@ -305,4 +312,108 @@ static NSString *privateDir = nil;
|
|||
return [self _fileAttributeForKey: NSFileModificationDate];
|
||||
}
|
||||
|
||||
/* acl */
|
||||
- (NSString *) defaultUserID
|
||||
{
|
||||
return @"default";
|
||||
}
|
||||
|
||||
- (NSMutableDictionary *) _aclEntries
|
||||
{
|
||||
NSMutableDictionary *aclEntries;
|
||||
NSData *content;
|
||||
NSString *error, *filename;
|
||||
NSPropertyListFormat format;
|
||||
|
||||
filename = [directory stringByAppendingPathComponent: @"permissions.plist"];
|
||||
content = [NSData dataWithContentsOfFile: filename];
|
||||
if (content)
|
||||
aclEntries = [NSPropertyListSerialization propertyListFromData: content
|
||||
mutabilityOption: NSPropertyListMutableContainers
|
||||
format: &format
|
||||
errorDescription: &error];
|
||||
else
|
||||
aclEntries = nil;
|
||||
if (!aclEntries)
|
||||
{
|
||||
aclEntries = [NSMutableDictionary dictionary];
|
||||
[aclEntries setObject: [NSMutableArray array] forKey: @"users"];
|
||||
[aclEntries setObject: [NSMutableDictionary dictionary]
|
||||
forKey: @"entries"];
|
||||
}
|
||||
|
||||
return aclEntries;
|
||||
}
|
||||
|
||||
- (void) _saveAcl: (NSDictionary *) acl
|
||||
{
|
||||
NSString *filename;
|
||||
NSData *content;
|
||||
|
||||
filename = [directory stringByAppendingPathComponent: @"permissions.plist"];
|
||||
[self ensureDirectory];
|
||||
|
||||
if (acl)
|
||||
content = [NSPropertyListSerialization
|
||||
dataFromPropertyList: acl
|
||||
format: NSPropertyListBinaryFormat_v1_0
|
||||
errorDescription: NULL];
|
||||
else
|
||||
content = [NSData data];
|
||||
if (![content writeToFile: filename atomically: NO])
|
||||
[NSException raise: @"MAPIStoreIOException"
|
||||
format: @"could not save acl"];
|
||||
}
|
||||
|
||||
- (void) addUserInAcls: (NSString *) user
|
||||
{
|
||||
NSMutableDictionary *acl;
|
||||
NSMutableArray *users;
|
||||
|
||||
acl = [self _aclEntries];
|
||||
users = [acl objectForKey: @"users"];
|
||||
[users addObjectUniquely: user];
|
||||
[self _saveAcl: acl];
|
||||
}
|
||||
|
||||
- (void) removeAclsForUsers: (NSArray *) oldUsers
|
||||
{
|
||||
NSDictionary *acl;
|
||||
NSMutableDictionary *entries;
|
||||
NSMutableArray *users;
|
||||
|
||||
acl = [self _aclEntries];
|
||||
entries = [acl objectForKey: @"entries"];
|
||||
[entries removeObjectsForKeys: oldUsers];
|
||||
users = [acl objectForKey: @"users"];
|
||||
[users removeObjectsInArray: oldUsers];
|
||||
[self _saveAcl: acl];
|
||||
}
|
||||
|
||||
- (NSArray *) aclUsers
|
||||
{
|
||||
return [[self _aclEntries] objectForKey: @"users"];
|
||||
}
|
||||
|
||||
- (NSArray *) aclsForUser: (NSString *) uid
|
||||
{
|
||||
NSDictionary *entries;
|
||||
|
||||
entries = [[self _aclEntries] objectForKey: @"entries"];
|
||||
|
||||
return [entries objectForKey: uid];
|
||||
}
|
||||
|
||||
- (void) setRoles: (NSArray *) roles
|
||||
forUser: (NSString *) uid
|
||||
{
|
||||
NSMutableDictionary *acl;
|
||||
NSMutableDictionary *entries;
|
||||
|
||||
acl = [self _aclEntries];
|
||||
entries = [acl objectForKey: @"entries"];
|
||||
[entries setObject: roles forKey: uid];
|
||||
[self _saveAcl: acl];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
Loading…
Reference in a new issue