mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-02-17 07:33:57 +00:00
Applied PR90 as a patch due to too-many merge conflicts when cherry-picking
This commit is contained in:
@@ -2862,6 +2862,7 @@ static BOOL debugOn = NO;
|
|||||||
NSAutoreleasePool *pool;
|
NSAutoreleasePool *pool;
|
||||||
id builder, dom;
|
id builder, dom;
|
||||||
SEL aSelector;
|
SEL aSelector;
|
||||||
|
id activeUser;
|
||||||
|
|
||||||
NSString *cmdName, *deviceId;
|
NSString *cmdName, *deviceId;
|
||||||
NSData *d;
|
NSData *d;
|
||||||
@@ -2870,6 +2871,14 @@ static BOOL debugOn = NO;
|
|||||||
|
|
||||||
ASSIGN(context, theContext);
|
ASSIGN(context, theContext);
|
||||||
|
|
||||||
|
activeUser = [context activeUser];
|
||||||
|
if (![activeUser canAccessModule: @"ActiveSync"])
|
||||||
|
{
|
||||||
|
[theResponse setStatus: 403];
|
||||||
|
[self logWithFormat: @"EAS - Forbidden access for user %@", [activeUser loginInDomain]];
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
// Get the device ID, device type and "stash" them
|
// Get the device ID, device type and "stash" them
|
||||||
deviceId = [[theRequest uri] deviceId];
|
deviceId = [[theRequest uri] deviceId];
|
||||||
[context setObject: deviceId forKey: @"DeviceId"];
|
[context setObject: deviceId forKey: @"DeviceId"];
|
||||||
|
|||||||
@@ -178,56 +178,101 @@ rtf2html (NSData *compressedRTF)
|
|||||||
andColumns: (struct SPropTagArray *) columns
|
andColumns: (struct SPropTagArray *) columns
|
||||||
{
|
{
|
||||||
NSMutableDictionary *recipientProperties;
|
NSMutableDictionary *recipientProperties;
|
||||||
|
enum MAPITAGS prop_tag;
|
||||||
|
char *displayName = NULL;
|
||||||
|
char *email = NULL;
|
||||||
|
enum MAPI_OBJTYPE object_type = 0;
|
||||||
|
char *smtpAddress = NULL;
|
||||||
SOGoUser *recipientUser;
|
SOGoUser *recipientUser;
|
||||||
NSUInteger count;
|
NSUInteger count;
|
||||||
|
NSString *recipientEmail = nil;
|
||||||
|
NSString *recipientFullName = nil;
|
||||||
id value;
|
id value;
|
||||||
|
|
||||||
recipientProperties = [NSMutableDictionary dictionaryWithCapacity: columns->cValues + 2];
|
recipientProperties = [NSMutableDictionary dictionaryWithCapacity: columns->cValues + 2];
|
||||||
|
|
||||||
|
for (count = 0; count < columns->cValues; count++)
|
||||||
|
{
|
||||||
|
prop_tag = columns->aulPropTag[count];
|
||||||
|
switch(prop_tag) {
|
||||||
|
case PidTagDisplayName:
|
||||||
|
displayName = recipient->data[count];
|
||||||
|
break;
|
||||||
|
case PidTagEmailAddress:
|
||||||
|
email = recipient->data[count];
|
||||||
|
break;
|
||||||
|
case PidTagObjectType:
|
||||||
|
if (recipient->data[count])
|
||||||
|
object_type = *((uint8_t*) recipient->data[count]);
|
||||||
|
break;
|
||||||
|
case PidTagSmtpAddress:
|
||||||
|
smtpAddress = recipient->data[count];
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (recipient->data[count])
|
||||||
|
{
|
||||||
|
value = NSObjectFromValuePointer (prop_tag,
|
||||||
|
recipient->data[count]);
|
||||||
|
if (value)
|
||||||
|
[recipientProperties setObject: value
|
||||||
|
forKey: MAPIPropertyKey (prop_tag)];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (recipient->username)
|
if (recipient->username)
|
||||||
{
|
{
|
||||||
value = [NSString stringWithUTF8String: recipient->username];
|
value = [NSString stringWithUTF8String: recipient->username];
|
||||||
[recipientProperties setObject: value forKey: @"x500dn"];
|
[recipientProperties setObject: value forKey: @"x500dn"];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (object_type == MAPI_MAILUSER && recipient->username)
|
||||||
|
{
|
||||||
|
/* values from user object have priority over data sent by the client */
|
||||||
recipientUser = [SOGoUser userWithLogin: [value lowercaseString]];
|
recipientUser = [SOGoUser userWithLogin: [value lowercaseString]];
|
||||||
if (recipientUser)
|
if (recipientUser)
|
||||||
{
|
{
|
||||||
value = [recipientUser cn];
|
value = [recipientUser cn];
|
||||||
if ([value length] > 0)
|
if ([value length] > 0)
|
||||||
[recipientProperties setObject: value forKey: @"fullName"];
|
recipientFullName = value;
|
||||||
|
|
||||||
value = [[recipientUser allEmails] objectAtIndex: 0];
|
value = [[recipientUser allEmails] objectAtIndex: 0];
|
||||||
if ([value length] > 0)
|
if ([value length] > 0)
|
||||||
[recipientProperties setObject: value forKey: @"email"];
|
recipientEmail = value;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (recipient->data[0])
|
|
||||||
{
|
|
||||||
value = [NSString stringWithUTF8String: recipient->data[0]];
|
|
||||||
if ([value length] > 0)
|
|
||||||
[recipientProperties setObject: value forKey: @"fullName"];
|
|
||||||
}
|
|
||||||
if (recipient->data[1])
|
|
||||||
{
|
|
||||||
value = [NSString stringWithUTF8String: recipient->data[1]];
|
|
||||||
if ([value length] > 0)
|
|
||||||
[recipientProperties setObject: value forKey: @"email"];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (count = 0; count < columns->cValues; count++)
|
/* If we do not have values from the user object we try to get them from the parameters */
|
||||||
|
if (!recipientFullName && displayName)
|
||||||
{
|
{
|
||||||
if (recipient->data[count])
|
value = [NSString stringWithUTF8String: displayName];
|
||||||
{
|
if ([value length] > 0)
|
||||||
value = NSObjectFromValuePointer (columns->aulPropTag[count],
|
recipientFullName = value;
|
||||||
recipient->data[count]);
|
|
||||||
if (value)
|
|
||||||
[recipientProperties setObject: value
|
|
||||||
forKey: MAPIPropertyKey (columns->aulPropTag[count])];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!recipientEmail && email)
|
||||||
|
{
|
||||||
|
value = [NSString stringWithUTF8String: email];
|
||||||
|
if ([value length] > 0)
|
||||||
|
recipientEmail = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!recipientEmail && smtpAddress)
|
||||||
|
{
|
||||||
|
value = [NSString stringWithUTF8String: smtpAddress];
|
||||||
|
if ([value length] > 0)
|
||||||
|
recipientEmail = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now we can set the properties if we have them */
|
||||||
|
if (recipientFullName)
|
||||||
|
[recipientProperties setObject: recipientFullName forKey: @"fullName"];
|
||||||
|
|
||||||
|
if (recipientEmail)
|
||||||
|
[recipientProperties setObject: recipientEmail forKey: @"email"];
|
||||||
|
|
||||||
return recipientProperties;
|
return recipientProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2132,32 +2132,23 @@ inRecurrenceExceptionsForEvent: (iCalEvent *) theEvent
|
|||||||
//
|
//
|
||||||
if ([[newEvent attendees] count] || [[oldEvent attendees] count])
|
if ([[newEvent attendees] count] || [[oldEvent attendees] count])
|
||||||
{
|
{
|
||||||
NSString *uid;
|
BOOL userIsOrganizer;
|
||||||
|
|
||||||
// newEvent might be nil here, if we're deleting a RECURRENCE-ID with attendees
|
// newEvent might be nil here, if we're deleting a RECURRENCE-ID with attendees
|
||||||
// If that's the case, we use the oldEvent for now just to obtain the organizer
|
// If that's the case, we use the oldEvent to obtain the organizer
|
||||||
// and we'll swap it back to nil once we're done.
|
if (newEvent)
|
||||||
if (!newEvent)
|
userIsOrganizer = [newEvent userIsOrganizer: ownerUser];
|
||||||
newEvent = oldEvent;
|
else
|
||||||
|
userIsOrganizer = [oldEvent userIsOrganizer: ownerUser];
|
||||||
// We fetch the organizer's uid. Sometimes, the recurrence-id will
|
|
||||||
// have it, sometimes not. If it doesn't, we fetch it from the master event.
|
|
||||||
uid = [[newEvent organizer] uid];
|
|
||||||
|
|
||||||
if (!uid && !recurrenceId)
|
|
||||||
uid = [[[[[newEvent parent] events] objectAtIndex: 0] organizer] uid];
|
|
||||||
|
|
||||||
// With Thunderbird 10, if you create a recurring event with an exception
|
// With Thunderbird 10, if you create a recurring event with an exception
|
||||||
// occurence, and invite someone, the PUT will have the organizer in the
|
// occurence, and invite someone, the PUT will have the organizer in the
|
||||||
// recurrence-id and not in the master event. We must fix this, otherwise
|
// recurrence-id and not in the master event. We must fix this, otherwise
|
||||||
// SOGo will break.
|
// SOGo will break.
|
||||||
if (!recurrenceId && ![[[[[newEvent parent] events] objectAtIndex: 0] organizer] uid])
|
if (!recurrenceId && ![[[[[newEvent parent] events] objectAtIndex: 0] organizer] uid])
|
||||||
[[[[newEvent parent] events] objectAtIndex: 0] setOrganizer: [newEvent organizer]];
|
[[[[newEvent parent] events] objectAtIndex: 0] setOrganizer: [newEvent organizer]];
|
||||||
|
|
||||||
if (newEvent == oldEvent)
|
if (userIsOrganizer)
|
||||||
newEvent = nil;
|
|
||||||
|
|
||||||
if (uid && [uid caseInsensitiveCompare: owner] == NSOrderedSame)
|
|
||||||
{
|
{
|
||||||
// A RECCURENCE-ID was removed
|
// A RECCURENCE-ID was removed
|
||||||
if (!newEvent && oldEvent)
|
if (!newEvent && oldEvent)
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
//
|
/*
|
||||||
// BSONCodec.m
|
* BSONCodec.m
|
||||||
// BSON Codec for Objective-C.
|
* BSON Codec for Objective-C.
|
||||||
//
|
*
|
||||||
// Created by Martin Kou on 8/17/10.
|
* Created by Martin Kou on 8/17/10.
|
||||||
// MIT License, see LICENSE file for details.
|
* MIT License, see LICENSE file for details.
|
||||||
//
|
*
|
||||||
|
* Adapted by Ludovic Marcotte and Enrique J. Hernández
|
||||||
|
*/
|
||||||
|
|
||||||
#import "BSONCodec.h"
|
#import "BSONCodec.h"
|
||||||
#import <ctype.h>
|
#import <ctype.h>
|
||||||
@@ -570,7 +572,7 @@ static NSDictionary *BSONTypes()
|
|||||||
{
|
{
|
||||||
NSString *v;
|
NSString *v;
|
||||||
|
|
||||||
v = [self descriptionWithCalendarFormat: @"%Y-%m-%d %H:%M:%S %Z"
|
v = [self descriptionWithCalendarFormat: @"%Y-%m-%d %H:%M:%S %z"
|
||||||
locale: nil];
|
locale: nil];
|
||||||
|
|
||||||
return [v BSONEncode];
|
return [v BSONEncode];
|
||||||
@@ -599,7 +601,22 @@ static NSDictionary *BSONTypes()
|
|||||||
|
|
||||||
key = [NSString stringWithFormat: @"%s", timezone];
|
key = [NSString stringWithFormat: @"%s", timezone];
|
||||||
|
|
||||||
if (!(tz = [timezoneCache objectForKey: key]))
|
/* We may have the zone using the UTC offset
|
||||||
|
or abbreviation (deprecated) */
|
||||||
|
if (timezone && strlen(timezone) > 0 && (timezone[0] == '+' || timezone[0] == '-'))
|
||||||
|
{
|
||||||
|
NSCalendarDate *tzDate;
|
||||||
|
|
||||||
|
tzDate = [[NSCalendarDate alloc] initWithString: key
|
||||||
|
calendarFormat: @"%z"
|
||||||
|
locale: nil];
|
||||||
|
[tzDate autorelease];
|
||||||
|
if (tzDate)
|
||||||
|
tz = [tzDate timeZone];
|
||||||
|
else
|
||||||
|
tz = nil;
|
||||||
|
}
|
||||||
|
else if (!(tz = [timezoneCache objectForKey: key]))
|
||||||
{
|
{
|
||||||
tz = [NSTimeZone timeZoneWithAbbreviation: key];
|
tz = [NSTimeZone timeZoneWithAbbreviation: key];
|
||||||
|
|
||||||
|
|||||||
@@ -737,7 +737,8 @@ groupObjectClasses: (NSArray *) newGroupObjectClasses
|
|||||||
}
|
}
|
||||||
NS_HANDLER
|
NS_HANDLER
|
||||||
{
|
{
|
||||||
if ([[localException name] isEqual: @"LDAPException"] && ([[[localException userInfo] objectForKey: @"error_code"] intValue] == LDAP_CONSTRAINT_VIOLATION))
|
if ([[localException name] isEqual: @"LDAPException"] &&
|
||||||
|
([[[localException userInfo] objectForKey: @"error_code"] intValue] == LDAP_CONSTRAINT_VIOLATION))
|
||||||
{
|
{
|
||||||
*perr = PolicyInsufficientPasswordQuality;
|
*perr = PolicyInsufficientPasswordQuality;
|
||||||
}
|
}
|
||||||
@@ -1166,6 +1167,8 @@ groupObjectClasses: (NSArray *) newGroupObjectClasses
|
|||||||
intoLDIFRecord: (NSMutableDictionary *) ldifRecord];
|
intoLDIFRecord: (NSMutableDictionary *) ldifRecord];
|
||||||
[self _fillConstraints: ldapEntry forModule: @"Mail"
|
[self _fillConstraints: ldapEntry forModule: @"Mail"
|
||||||
intoLDIFRecord: (NSMutableDictionary *) ldifRecord];
|
intoLDIFRecord: (NSMutableDictionary *) ldifRecord];
|
||||||
|
[self _fillConstraints: ldapEntry forModule: @"ActiveSync"
|
||||||
|
intoLDIFRecord: (NSMutableDictionary *) ldifRecord];
|
||||||
|
|
||||||
if (contactMapping)
|
if (contactMapping)
|
||||||
[self _applyContactMappingToResult: ldifRecord];
|
[self _applyContactMappingToResult: ldifRecord];
|
||||||
|
|||||||
@@ -157,7 +157,7 @@
|
|||||||
// that much about this for now.
|
// that much about this for now.
|
||||||
//
|
//
|
||||||
+ (NSString *) securedValue: (NSString *) theValue
|
+ (NSString *) securedValue: (NSString *) theValue
|
||||||
usingKey: (NSString *) theKey
|
usingKey: (NSString *) theKey
|
||||||
{
|
{
|
||||||
NSData *data;
|
NSData *data;
|
||||||
NSString *s;
|
NSString *s;
|
||||||
@@ -171,13 +171,12 @@
|
|||||||
klen = [data length];
|
klen = [data length];
|
||||||
|
|
||||||
// Get the key - padding it with 0 with key length
|
// Get the key - padding it with 0 with key length
|
||||||
pass = (char *)malloc(klen);
|
pass = (char *) calloc(klen, sizeof(char));
|
||||||
memset(pass, 0, klen);
|
|
||||||
[theValue getCString: pass maxLength: klen encoding: NSUTF8StringEncoding];
|
[theValue getCString: pass maxLength: klen encoding: NSUTF8StringEncoding];
|
||||||
|
|
||||||
// Target buffer
|
// Target buffer
|
||||||
buf = (char *)malloc(klen);
|
buf = (char *)malloc(klen);
|
||||||
|
|
||||||
for (i = 0; i < klen; i++)
|
for (i = 0; i < klen; i++)
|
||||||
{
|
{
|
||||||
buf[i] = key[i] ^ pass[i];
|
buf[i] = key[i] ^ pass[i];
|
||||||
@@ -186,36 +185,38 @@
|
|||||||
free(pass);
|
free(pass);
|
||||||
|
|
||||||
data = [NSData dataWithBytesNoCopy: buf length: klen freeWhenDone: YES];
|
data = [NSData dataWithBytesNoCopy: buf length: klen freeWhenDone: YES];
|
||||||
|
|
||||||
s = [[NSString alloc] initWithData: [data dataByEncodingBase64WithLineLength: 1024]
|
s = [[NSString alloc] initWithData: [data dataByEncodingBase64WithLineLength: 1024]
|
||||||
encoding: NSASCIIStringEncoding];
|
encoding: NSASCIIStringEncoding];
|
||||||
return [s autorelease];
|
return [s autorelease];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
+ (NSString *) valueFromSecuredValue: (NSString *) theValue
|
+ (NSString *) valueFromSecuredValue: (NSString *) theValue
|
||||||
usingKey: (NSString *) theKey
|
usingKey: (NSString *) theKey
|
||||||
{
|
{
|
||||||
NSData *data;
|
NSData *dataKey, *dataValue;
|
||||||
NSString *s;
|
NSString *s;
|
||||||
|
|
||||||
char *buf, *key, *pass;
|
char *buf, *key, *value;
|
||||||
int i, klen;
|
size_t i, klen, vlen;
|
||||||
|
|
||||||
// Get the key length and its bytes
|
// Get the key length and its bytes
|
||||||
data = [theKey dataByDecodingBase64];
|
dataKey = [theKey dataByDecodingBase64];
|
||||||
key = (char *)[data bytes];
|
key = (char *)[dataKey bytes];
|
||||||
klen = [data length];
|
klen = [dataKey length];
|
||||||
|
|
||||||
|
// Get the secured value length and its bytes
|
||||||
|
dataValue = [theValue dataByDecodingBase64];
|
||||||
|
value = (char *)[dataValue bytes];
|
||||||
|
vlen = [dataValue length];
|
||||||
|
|
||||||
// Get the secured password
|
|
||||||
pass = (char *)[[theValue dataByDecodingBase64] bytes];
|
|
||||||
|
|
||||||
// Target buffer
|
// Target buffer
|
||||||
buf = (char *)malloc(klen);
|
buf = (char *) calloc(klen, sizeof(char));
|
||||||
|
|
||||||
for (i = 0; i < klen; i++)
|
for (i = 0; i < klen && i < vlen; i++)
|
||||||
{
|
{
|
||||||
buf[i] = key[i] ^ pass[i];
|
buf[i] = key[i] ^ value[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
// buf is now our C string in UTF8
|
// buf is now our C string in UTF8
|
||||||
|
|||||||
@@ -438,14 +438,16 @@ static Class NSNullK;
|
|||||||
NSEnumerator *authIDs;
|
NSEnumerator *authIDs;
|
||||||
NSString *currentID;
|
NSString *currentID;
|
||||||
BOOL checkOK;
|
BOOL checkOK;
|
||||||
|
SOGoSystemDefaults *sd;
|
||||||
|
NSRange r;
|
||||||
|
|
||||||
checkOK = NO;
|
checkOK = NO;
|
||||||
|
|
||||||
authIDs = [[self authenticationSourceIDsInDomain: *domain] objectEnumerator];
|
authIDs = [[self authenticationSourceIDsInDomain: *domain] objectEnumerator];
|
||||||
while (!checkOK && (currentID = [authIDs nextObject]))
|
while (!checkOK && (currentID = [authIDs nextObject]))
|
||||||
{
|
{
|
||||||
sogoSource = [_sources objectForKey: currentID];
|
sogoSource = [_sources objectForKey: currentID];
|
||||||
|
|
||||||
checkOK = [sogoSource checkLogin: login
|
checkOK = [sogoSource checkLogin: login
|
||||||
password: password
|
password: password
|
||||||
perr: perr
|
perr: perr
|
||||||
@@ -649,7 +651,7 @@ static Class NSNullK;
|
|||||||
[currentSource setBindPassword: _pwd];
|
[currentSource setBindPassword: _pwd];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return checkOK;
|
return checkOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -742,6 +744,12 @@ static Class NSNullK;
|
|||||||
NSNumber *isGroup;
|
NSNumber *isGroup;
|
||||||
NSArray *c_emails;
|
NSArray *c_emails;
|
||||||
BOOL access;
|
BOOL access;
|
||||||
|
NSEnumerator *enumerator;
|
||||||
|
NSString *access_type;
|
||||||
|
NSArray *access_types_list = [NSArray arrayWithObjects: @"CalendarAccess",
|
||||||
|
@"MailAccess",
|
||||||
|
@"ActiveSyncAccess",
|
||||||
|
nil];
|
||||||
|
|
||||||
emails = [NSMutableArray array];
|
emails = [NSMutableArray array];
|
||||||
cn = nil;
|
cn = nil;
|
||||||
@@ -751,10 +759,10 @@ static Class NSNullK;
|
|||||||
c_imaplogin = nil;
|
c_imaplogin = nil;
|
||||||
c_sievehostname = nil;
|
c_sievehostname = nil;
|
||||||
|
|
||||||
[theCurrentUser setObject: [NSNumber numberWithBool: YES]
|
enumerator = [access_types_list objectEnumerator];
|
||||||
forKey: @"CalendarAccess"];
|
while ((access_type = [enumerator nextObject]) != nil)
|
||||||
[theCurrentUser setObject: [NSNumber numberWithBool: YES]
|
[theCurrentUser setObject: [NSNumber numberWithBool: YES]
|
||||||
forKey: @"MailAccess"];
|
forKey: access_type];
|
||||||
|
|
||||||
if ([[theCurrentUser objectForKey: @"DomainLessLogin"] boolValue])
|
if ([[theCurrentUser objectForKey: @"DomainLessLogin"] boolValue])
|
||||||
{
|
{
|
||||||
@@ -763,7 +771,6 @@ static Class NSNullK;
|
|||||||
r = [theUID rangeOfString: [NSString stringWithFormat: @"@%@", theDomain]];
|
r = [theUID rangeOfString: [NSString stringWithFormat: @"@%@", theDomain]];
|
||||||
theUID = [theUID substringToIndex: r.location];
|
theUID = [theUID substringToIndex: r.location];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sogoSources = [[self authenticationSourceIDsInDomain: theDomain] objectEnumerator];
|
sogoSources = [[self authenticationSourceIDsInDomain: theDomain] objectEnumerator];
|
||||||
userEntry = nil;
|
userEntry = nil;
|
||||||
@@ -791,14 +798,15 @@ static Class NSNullK;
|
|||||||
c_imaplogin = [userEntry objectForKey: @"c_imaplogin"];
|
c_imaplogin = [userEntry objectForKey: @"c_imaplogin"];
|
||||||
if (!c_sievehostname)
|
if (!c_sievehostname)
|
||||||
c_sievehostname = [userEntry objectForKey: @"c_sievehostname"];
|
c_sievehostname = [userEntry objectForKey: @"c_sievehostname"];
|
||||||
access = [[userEntry objectForKey: @"CalendarAccess"] boolValue];
|
|
||||||
if (!access)
|
enumerator = [access_types_list objectEnumerator];
|
||||||
[theCurrentUser setObject: [NSNumber numberWithBool: NO]
|
while ((access_type = [enumerator nextObject]) != nil)
|
||||||
forKey: @"CalendarAccess"];
|
{
|
||||||
access = [[userEntry objectForKey: @"MailAccess"] boolValue];
|
access = [[userEntry objectForKey: access_type] boolValue];
|
||||||
if (!access)
|
if (!access)
|
||||||
[theCurrentUser setObject: [NSNumber numberWithBool: NO]
|
[theCurrentUser setObject: [NSNumber numberWithBool: NO]
|
||||||
forKey: @"MailAccess"];
|
forKey: access_type];
|
||||||
|
}
|
||||||
|
|
||||||
// We check if it's a group
|
// We check if it's a group
|
||||||
isGroup = [userEntry objectForKey: @"isGroup"];
|
isGroup = [userEntry objectForKey: @"isGroup"];
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ $(SOGO_TOOL)_OBJC_FILES += \
|
|||||||
SOGoToolRemoveDoubles.m \
|
SOGoToolRemoveDoubles.m \
|
||||||
SOGoToolRenameUser.m \
|
SOGoToolRenameUser.m \
|
||||||
SOGoToolRestore.m \
|
SOGoToolRestore.m \
|
||||||
|
SOGoToolCreateFolder.m \
|
||||||
SOGoToolUserPreferences.m \
|
SOGoToolUserPreferences.m \
|
||||||
SOGoToolManageEAS.m
|
SOGoToolManageEAS.m
|
||||||
TOOL_NAME += $(SOGO_TOOL)
|
TOOL_NAME += $(SOGO_TOOL)
|
||||||
|
|||||||
175
Tools/SOGoToolCreateFolder.m
Normal file
175
Tools/SOGoToolCreateFolder.m
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
/* SOGoToolCreateFolder.m - this file is part of SOGo
|
||||||
|
* Implementation of create-folder command for sogo-tool
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 Javier Amor Garcia
|
||||||
|
*
|
||||||
|
* This file is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This file is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#import <Foundation/NSArray.h>
|
||||||
|
#import <Foundation/NSDictionary.h>
|
||||||
|
#import <Foundation/NSString.h>
|
||||||
|
#import <Foundation/NSException.h>
|
||||||
|
|
||||||
|
#import <SOGo/NSArray+Utilities.h>
|
||||||
|
#import <SOGo/SOGoObject.h>
|
||||||
|
|
||||||
|
#import <GDLContentStore/GCSFolderManager.h>
|
||||||
|
#import <GDLContentStore/GCSFolder.h>
|
||||||
|
|
||||||
|
#import "SOGoToolRestore.h"
|
||||||
|
|
||||||
|
@interface SOGoToolCreateFolder : SOGoToolRestore
|
||||||
|
{
|
||||||
|
NSMutableArray *foldersContents;
|
||||||
|
NSString *folderType;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation SOGoToolCreateFolder
|
||||||
|
|
||||||
|
+ (NSString *) command
|
||||||
|
{
|
||||||
|
return @"create-folder";
|
||||||
|
}
|
||||||
|
|
||||||
|
+ (NSString *) description
|
||||||
|
{
|
||||||
|
return @"create folders for a user";
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id) init
|
||||||
|
{
|
||||||
|
if ((self = [super init]))
|
||||||
|
{
|
||||||
|
foldersContents = nil;
|
||||||
|
folderType = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) dealloc
|
||||||
|
{
|
||||||
|
[foldersContents release];
|
||||||
|
[folderType release];
|
||||||
|
[super dealloc];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) usage
|
||||||
|
{
|
||||||
|
fprintf (stderr, "create-folder user type [displayname ...]\n\n"
|
||||||
|
" user the user on which the folder(s) will be created\n"
|
||||||
|
" type type of directory. Calendar or Contacts\n"
|
||||||
|
" displayname display name(s) for the created folder(s)\n\n"
|
||||||
|
"Examples: sogo-tool create-folder user1 Calendar cal1 cal2\n"
|
||||||
|
" sogo-tool create-folder user1 Contacts agenda\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) createNewFolderOfType: (NSString *) type
|
||||||
|
withContent: (NSDictionary *) content
|
||||||
|
{
|
||||||
|
NSString *folder;
|
||||||
|
NSString *guid;
|
||||||
|
GCSFolderManager *fm;
|
||||||
|
GCSFolder *gcsFolder;
|
||||||
|
BOOL rc;
|
||||||
|
|
||||||
|
guid = [SOGoObject globallyUniqueObjectId];
|
||||||
|
folder= [NSString stringWithFormat: @"/Users/%@/%@/%@",
|
||||||
|
userID, type, guid];
|
||||||
|
fm = [GCSFolderManager defaultFolderManager];
|
||||||
|
|
||||||
|
rc = [self createFolder: folder withFM: fm];
|
||||||
|
if (!rc)
|
||||||
|
{
|
||||||
|
NSLog (@"Create directory failed at path %s", folder);
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
gcsFolder = [fm folderAtPath: folder];
|
||||||
|
if (!gcsFolder)
|
||||||
|
{
|
||||||
|
NSLog (@"folder '%@' could not be created", folder);
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = [self restoreDisplayName: [content objectForKey: @"displayname"]
|
||||||
|
ofFolder: gcsFolder
|
||||||
|
withFM: fm];
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) proceed
|
||||||
|
{
|
||||||
|
BOOL rc;
|
||||||
|
NSUInteger count, i;
|
||||||
|
NSDictionary * content;
|
||||||
|
|
||||||
|
rc = YES;
|
||||||
|
count = [foldersContents count];
|
||||||
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
content = [foldersContents objectAtIndex: i];
|
||||||
|
if (![self createNewFolderOfType: folderType withContent: content])
|
||||||
|
{
|
||||||
|
rc = NO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) parseArguments
|
||||||
|
{
|
||||||
|
NSString *identifier;
|
||||||
|
NSUInteger count, i;
|
||||||
|
NSDictionary *content;
|
||||||
|
|
||||||
|
count = [arguments count];
|
||||||
|
if (count < 3)
|
||||||
|
{
|
||||||
|
[self usage];
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
identifier = [arguments objectAtIndex: 0];
|
||||||
|
if (![self fetchUserID: identifier])
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Invalid user:%s\n", [identifier cString]);
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
folderType = [arguments objectAtIndex: 1];
|
||||||
|
if (!([folderType isEqualToString: @"Contacts"] || [folderType isEqualToString: @"Calendar"]))
|
||||||
|
{
|
||||||
|
fprintf (stderr, "Invalid folder type:%s\n", [folderType cString]);
|
||||||
|
return NO;
|
||||||
|
}
|
||||||
|
|
||||||
|
foldersContents = [[NSMutableArray alloc] init];
|
||||||
|
for (i = 2; i < count; i++)
|
||||||
|
{
|
||||||
|
content = [NSDictionary dictionaryWithObject: [arguments objectAtIndex: i]
|
||||||
|
forKey: @"displayname"];
|
||||||
|
[foldersContents addObject: content];
|
||||||
|
}
|
||||||
|
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
49
Tools/SOGoToolRestore.h
Normal file
49
Tools/SOGoToolRestore.h
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/* SOGoToolRestore.h - this file is part of SOGo
|
||||||
|
* Header to allow subclassing of SOGoToolRestore class
|
||||||
|
*
|
||||||
|
* Copyright (C) 2015 Javier Amor Garcia
|
||||||
|
*
|
||||||
|
* This file is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2, or (at your option)
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This file is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; see the file COPYING. If not, write to
|
||||||
|
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
||||||
|
* Boston, MA 02111-1307, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#import "SOGoTool.h"
|
||||||
|
|
||||||
|
typedef enum SOGoToolRestoreMode {
|
||||||
|
SOGoToolRestoreFolderMode,
|
||||||
|
SOGoToolRestoreFolderDestructiveMode,
|
||||||
|
SOGoToolRestoreListFoldersMode,
|
||||||
|
SOGoToolRestorePreferencesMode
|
||||||
|
} SOGoToolRestoreMode;
|
||||||
|
|
||||||
|
@interface SOGoToolRestore : SOGoTool
|
||||||
|
{
|
||||||
|
NSString *directory;
|
||||||
|
NSString *userID;
|
||||||
|
NSString *filename;
|
||||||
|
NSString *restoreFolder;
|
||||||
|
BOOL destructive; /* destructive mode not handled */
|
||||||
|
SOGoToolRestoreMode restoreMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL) fetchUserID: (NSString *) identifier;
|
||||||
|
- (BOOL) createFolder: (NSString *) folder
|
||||||
|
withFM: (GCSFolderManager *) fm;
|
||||||
|
- (BOOL) restoreDisplayName: (NSString *) newDisplayName
|
||||||
|
ofFolder: (GCSFolder *) gcsFolder
|
||||||
|
withFM: (GCSFolderManager *) fm;
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -46,33 +46,14 @@
|
|||||||
#import <NGCards/NGVCard.h>
|
#import <NGCards/NGVCard.h>
|
||||||
#import <NGCards/NGVList.h>
|
#import <NGCards/NGVList.h>
|
||||||
|
|
||||||
#import "SOGoTool.h"
|
#import "SOGoToolRestore.h"
|
||||||
|
|
||||||
/* TODO:
|
/* TODO:
|
||||||
- respond to "--help restore"
|
- respond to "--help restore"
|
||||||
- handle database connectivity errors
|
- handle database connectivity errors
|
||||||
- handle the case where the restored folder has been deleted
|
- handle the case where the restored folder has been deleted
|
||||||
- write methods in GDLContentStore to get/update displayname
|
- write methods in GDLContentStore to get/update displayname
|
||||||
and storing roles */
|
and storing roles */
|
||||||
|
|
||||||
typedef enum SOGoToolRestoreMode {
|
|
||||||
SOGoToolRestoreFolderMode,
|
|
||||||
SOGoToolRestoreFolderDestructiveMode,
|
|
||||||
SOGoToolRestoreListFoldersMode,
|
|
||||||
SOGoToolRestorePreferencesMode
|
|
||||||
} SOGoToolRestoreMode;
|
|
||||||
|
|
||||||
@interface SOGoToolRestore : SOGoTool
|
|
||||||
{
|
|
||||||
NSString *directory;
|
|
||||||
NSString *userID;
|
|
||||||
NSString *filename;
|
|
||||||
NSString *restoreFolder;
|
|
||||||
BOOL destructive; /* destructive mode not handled */
|
|
||||||
SOGoToolRestoreMode restoreMode;
|
|
||||||
}
|
|
||||||
|
|
||||||
@end
|
|
||||||
|
|
||||||
@implementation SOGoToolRestore
|
@implementation SOGoToolRestore
|
||||||
|
|
||||||
@@ -176,8 +157,8 @@ typedef enum SOGoToolRestoreMode {
|
|||||||
SOGoSystemDefaults *sd;
|
SOGoSystemDefaults *sd;
|
||||||
SOGoUserManager *lm;
|
SOGoUserManager *lm;
|
||||||
NSDictionary *infos;
|
NSDictionary *infos;
|
||||||
NSString *uid;
|
NSString *uid = nil;
|
||||||
|
|
||||||
BOOL rc;
|
BOOL rc;
|
||||||
|
|
||||||
lm = [SOGoUserManager sharedUserManager];
|
lm = [SOGoUserManager sharedUserManager];
|
||||||
@@ -188,7 +169,7 @@ typedef enum SOGoToolRestoreMode {
|
|||||||
{
|
{
|
||||||
sd = [SOGoSystemDefaults sharedSystemDefaults];
|
sd = [SOGoSystemDefaults sharedSystemDefaults];
|
||||||
uid = [infos objectForKey: @"c_uid"];
|
uid = [infos objectForKey: @"c_uid"];
|
||||||
|
|
||||||
if ([sd enableDomainBasedUID] && [uid rangeOfString: @"@"].location == NSNotFound)
|
if ([sd enableDomainBasedUID] && [uid rangeOfString: @"@"].location == NSNotFound)
|
||||||
uid = [NSString stringWithFormat: @"%@@%@",
|
uid = [NSString stringWithFormat: @"%@@%@",
|
||||||
[infos objectForKey: @"c_uid"],
|
[infos objectForKey: @"c_uid"],
|
||||||
|
|||||||
Reference in New Issue
Block a user