mirror of
https://github.com/inverse-inc/sogo.git
synced 2026-05-21 19:35:38 +00:00
(feat) applied all changes as a patch coming from PR #180
This commit is contained in:
+175
-146
@@ -67,10 +67,12 @@ static Class NSNullK;
|
||||
|
||||
if (type)
|
||||
{
|
||||
if ([type isEqualToString: @"ldap"])
|
||||
if ([type caseInsensitiveCompare: @"ldap"] == NSOrderedSame)
|
||||
sourceClass = @"LDAPSource";
|
||||
else if ([type isEqualToString: @"sql"])
|
||||
else if ([type caseInsensitiveCompare: @"sql"] == NSOrderedSame)
|
||||
sourceClass = @"SQLSource";
|
||||
else if (NSClassFromString(type))
|
||||
sourceClass = type;
|
||||
else
|
||||
{
|
||||
[NSException raise: @"SOGoUserManagerRegistryException"
|
||||
@@ -104,65 +106,58 @@ static Class NSNullK;
|
||||
NSString *sourceID, *value, *type;
|
||||
NSMutableDictionary *metadata;
|
||||
NSObject <SOGoSource> *sogoSource;
|
||||
BOOL isAddressBook, result;
|
||||
BOOL isAddressBook;
|
||||
Class c;
|
||||
|
||||
result = NO;
|
||||
sourceID = [udSource objectForKey: @"id"];
|
||||
if ([sourceID length] > 0)
|
||||
if (!sourceID || [sourceID length] == 0)
|
||||
{
|
||||
if ([_sourcesMetadata objectForKey: sourceID])
|
||||
[self errorWithFormat: @"attempted to register a contact/user source"
|
||||
@" with duplicated id (%@)", sourceID];
|
||||
else
|
||||
{
|
||||
type = [[udSource objectForKey: @"type"] lowercaseString];
|
||||
c = NSClassFromString([_registry sourceClassForType: type]);
|
||||
sogoSource = [c sourceFromUDSource: udSource inDomain: domain];
|
||||
if (sourceID)
|
||||
[_sources setObject: sogoSource forKey: sourceID];
|
||||
else
|
||||
[self errorWithFormat: @"id field missing in an user source,"
|
||||
@" check the SOGoUserSources defaults"];
|
||||
metadata = [NSMutableDictionary dictionary];
|
||||
if (domain)
|
||||
[metadata setObject: domain forKey: @"domain"];
|
||||
value = [udSource objectForKey: @"canAuthenticate"];
|
||||
if (value)
|
||||
[metadata setObject: value forKey: @"canAuthenticate"];
|
||||
value = [udSource objectForKey: @"isAddressBook"];
|
||||
if (value)
|
||||
{
|
||||
[metadata setObject: value forKey: @"isAddressBook"];
|
||||
isAddressBook = [value boolValue];
|
||||
}
|
||||
else
|
||||
isAddressBook = NO;
|
||||
value = [udSource objectForKey: @"displayName"];
|
||||
if (value)
|
||||
[metadata setObject: value forKey: @"displayName"];
|
||||
else
|
||||
{
|
||||
if (isAddressBook)
|
||||
[self errorWithFormat: @"addressbook source '%@' has"
|
||||
@" no displayname", sourceID];
|
||||
}
|
||||
value = [udSource objectForKey: @"MailFieldNames"];
|
||||
if (value)
|
||||
[metadata setObject: value forKey: @"MailFieldNames"];
|
||||
value = [udSource objectForKey: @"SearchFieldNames"];
|
||||
if (value)
|
||||
[metadata setObject: value forKey: @"SearchFieldNames"];
|
||||
|
||||
[_sourcesMetadata setObject: metadata forKey: sourceID];
|
||||
result = YES;
|
||||
}
|
||||
[self errorWithFormat: @"attempted to register a contact/user source "
|
||||
@"without id (skipped)"];
|
||||
return NO;
|
||||
}
|
||||
if ([_sourcesMetadata objectForKey: sourceID])
|
||||
{
|
||||
[self errorWithFormat: @"attempted to register a contact/user source "
|
||||
@"with duplicated id (%@)", sourceID];
|
||||
return NO;
|
||||
}
|
||||
|
||||
type = [udSource objectForKey: @"type"];
|
||||
c = NSClassFromString([_registry sourceClassForType: type]);
|
||||
sogoSource = [c sourceFromUDSource: udSource inDomain: domain];
|
||||
[_sources setObject: sogoSource forKey: sourceID];
|
||||
|
||||
metadata = [NSMutableDictionary dictionary];
|
||||
if (domain)
|
||||
[metadata setObject: domain forKey: @"domain"];
|
||||
value = [udSource objectForKey: @"canAuthenticate"];
|
||||
if (value)
|
||||
[metadata setObject: value forKey: @"canAuthenticate"];
|
||||
value = [udSource objectForKey: @"isAddressBook"];
|
||||
if (value)
|
||||
{
|
||||
[metadata setObject: value forKey: @"isAddressBook"];
|
||||
isAddressBook = [value boolValue];
|
||||
}
|
||||
else
|
||||
[self errorWithFormat: @"attempted to register a contact/user source"
|
||||
@" without id (skipped)"];
|
||||
isAddressBook = NO;
|
||||
value = [udSource objectForKey: @"displayName"];
|
||||
if (value)
|
||||
[metadata setObject: value forKey: @"displayName"];
|
||||
else if (isAddressBook)
|
||||
[self errorWithFormat: @"addressbook source '%@' has no displayname", sourceID];
|
||||
|
||||
return result;
|
||||
value = [udSource objectForKey: @"MailFieldNames"];
|
||||
if (value)
|
||||
[metadata setObject: value forKey: @"MailFieldNames"];
|
||||
value = [udSource objectForKey: @"SearchFieldNames"];
|
||||
if (value)
|
||||
[metadata setObject: value forKey: @"SearchFieldNames"];
|
||||
|
||||
[_sourcesMetadata setObject: metadata forKey: sourceID];
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (int) _registerSourcesInDomain: (NSString *) domain
|
||||
@@ -171,11 +166,7 @@ static Class NSNullK;
|
||||
unsigned int count, max, total;
|
||||
SOGoDomainDefaults *dd;
|
||||
|
||||
if (domain)
|
||||
dd = [SOGoDomainDefaults defaultsForDomain: domain];
|
||||
else
|
||||
dd = [SOGoSystemDefaults sharedSystemDefaults];
|
||||
|
||||
dd = [SOGoDomainDefaults defaultsForDomain: domain];
|
||||
userSources = [dd userSources];
|
||||
max = [userSources count];
|
||||
total = 0;
|
||||
@@ -305,6 +296,35 @@ static Class NSNullK;
|
||||
return sourceIDs;
|
||||
}
|
||||
|
||||
- (BOOL) isDomainDefined: (NSString *) domain
|
||||
{
|
||||
NSEnumerator *allIDs;
|
||||
NSArray *ids;
|
||||
NSString *currentID, *sourceDomain;
|
||||
SOGoSystemDefaults *sd;
|
||||
|
||||
if (!domain) return NO;
|
||||
|
||||
ids = [_sources allKeys];
|
||||
if ([ids containsObject: domain])
|
||||
// FIXME check SOGoMailDomain?
|
||||
// Now source id is being considered as the domain
|
||||
return YES;
|
||||
|
||||
sd = [SOGoSystemDefaults sharedSystemDefaults];
|
||||
if ([sd enableDomainBasedUID])
|
||||
{
|
||||
allIDs = [ids objectEnumerator];
|
||||
while ((currentID = [allIDs nextObject]))
|
||||
{
|
||||
sourceDomain = [[_sources objectForKey: currentID] domain];
|
||||
if (!sourceDomain) // source that can identify any domain
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
- (NSString *) displayNameForSourceWithID: (NSString *) sourceID
|
||||
{
|
||||
NSDictionary *metadata;
|
||||
@@ -328,7 +348,6 @@ static Class NSNullK;
|
||||
{
|
||||
NSDictionary *contactInfos;
|
||||
|
||||
// NSLog (@"getEmailForUID: %@", uid);
|
||||
contactInfos = [self contactInfosForUserWithUIDorEmail: uid];
|
||||
|
||||
return [contactInfos objectForKey: @"c_email"];
|
||||
@@ -345,8 +364,7 @@ static Class NSNullK;
|
||||
if ([cn length] > 0)
|
||||
{
|
||||
if ([email length] > 0)
|
||||
fullEmail = [NSString stringWithFormat: @"%@ <%@>",
|
||||
cn, email];
|
||||
fullEmail = [NSString stringWithFormat: @"%@ <%@>", cn, email];
|
||||
else
|
||||
fullEmail = cn;
|
||||
}
|
||||
@@ -369,11 +387,7 @@ static Class NSNullK;
|
||||
login = [contactInfos objectForKey: @"c_imaplogin"];
|
||||
if (login == nil)
|
||||
{
|
||||
if ([domain length])
|
||||
dd = [SOGoDomainDefaults defaultsForDomain: domain];
|
||||
else
|
||||
dd = [SOGoSystemDefaults sharedSystemDefaults];
|
||||
|
||||
dd = [SOGoDomainDefaults defaultsForDomain: domain];
|
||||
if ([dd forceExternalLoginWithEmail])
|
||||
{
|
||||
sd = [SOGoSystemDefaults sharedSystemDefaults];
|
||||
@@ -415,16 +429,16 @@ static Class NSNullK;
|
||||
- (BOOL) _sourceChangePasswordForLogin: (NSString *) login
|
||||
inDomain: (NSString *) domain
|
||||
oldPassword: (NSString *) oldPassword
|
||||
newPassword: (NSString *) newPassword
|
||||
perr: (SOGoPasswordPolicyError *) perr
|
||||
newPassword: (NSString *) newPassword
|
||||
perr: (SOGoPasswordPolicyError *) perr
|
||||
{
|
||||
NSObject <SOGoSource> *sogoSource;
|
||||
NSEnumerator *authIDs;
|
||||
NSString *currentID;
|
||||
BOOL didChange;
|
||||
|
||||
|
||||
didChange = NO;
|
||||
|
||||
|
||||
authIDs = [[self authenticationSourceIDsInDomain: domain] objectEnumerator];
|
||||
while (!didChange && (currentID = [authIDs nextObject]))
|
||||
{
|
||||
@@ -465,7 +479,24 @@ static Class NSNullK;
|
||||
}
|
||||
|
||||
if (checkOK && *domain == nil)
|
||||
*domain = [sogoSource domain];
|
||||
{
|
||||
SOGoSystemDefaults *sd = [SOGoSystemDefaults sharedSystemDefaults];
|
||||
BOOL multidomainSource = [sd enableDomainBasedUID] &&
|
||||
[sogoSource domain] == nil;
|
||||
if (multidomainSource)
|
||||
{
|
||||
NSArray *parts = [login componentsSeparatedByString: @"@"];
|
||||
if ([parts count] != 2)
|
||||
{
|
||||
[self errorWithFormat: @"Authenticated with multidomain source "
|
||||
@"but login is not an email (%@).", login];
|
||||
return NO;
|
||||
}
|
||||
*domain = [parts objectAtIndex: 1];
|
||||
}
|
||||
else
|
||||
*domain = [sogoSource domain];
|
||||
}
|
||||
|
||||
return checkOK;
|
||||
}
|
||||
@@ -546,7 +577,7 @@ static Class NSNullK;
|
||||
delta = current_time - start_time;
|
||||
|
||||
block_time = [sd failedLoginBlockInterval];
|
||||
|
||||
|
||||
if ([[failedCount objectForKey: @"FailedCount"] intValue] >= [sd maximumFailedLoginCount] &&
|
||||
delta >= [sd maximumFailedLoginInterval] &&
|
||||
delta <= block_time )
|
||||
@@ -554,7 +585,7 @@ static Class NSNullK;
|
||||
*_perr = PolicyAccountLocked;
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
if (delta > block_time)
|
||||
{
|
||||
[[SOGoCache sharedCache] setFailedCount: 0
|
||||
@@ -638,7 +669,7 @@ static Class NSNullK;
|
||||
[[SOGoCache sharedCache] setFailedCount: ([[failedCount objectForKey: @"FailedCount"] intValue] + 1)
|
||||
forLogin: username];
|
||||
}
|
||||
|
||||
|
||||
checkOK = NO;
|
||||
}
|
||||
|
||||
@@ -649,7 +680,7 @@ static Class NSNullK;
|
||||
{
|
||||
NSObject <SOGoDNSource> *currentSource;
|
||||
NSEnumerator *sources;
|
||||
|
||||
|
||||
sources = [[_sources allValues] objectEnumerator];
|
||||
while ((currentSource = [sources nextObject]))
|
||||
if ([currentSource conformsToProtocol: @protocol(SOGoDNSource)] &&
|
||||
@@ -669,9 +700,9 @@ static Class NSNullK;
|
||||
//
|
||||
- (BOOL) changePasswordForLogin: (NSString *) login
|
||||
inDomain: (NSString *) domain
|
||||
oldPassword: (NSString *) oldPassword
|
||||
newPassword: (NSString *) newPassword
|
||||
perr: (SOGoPasswordPolicyError *) perr
|
||||
oldPassword: (NSString *) oldPassword
|
||||
newPassword: (NSString *) newPassword
|
||||
perr: (SOGoPasswordPolicyError *) perr
|
||||
{
|
||||
NSString *jsonUser, *userLogin;
|
||||
NSMutableDictionary *currentUser;
|
||||
@@ -720,21 +751,19 @@ static Class NSNullK;
|
||||
SOGoDomainDefaults *dd;
|
||||
|
||||
domain = [contact objectForKey: @"c_domain"];
|
||||
if ([domain length])
|
||||
dd = [SOGoDomainDefaults defaultsForDomain: domain];
|
||||
else
|
||||
dd = [SOGoSystemDefaults sharedSystemDefaults];
|
||||
dd = [SOGoDomainDefaults defaultsForDomain: domain];
|
||||
emails = [contact objectForKey: @"emails"];
|
||||
uid = [contact objectForKey: @"c_uid"];
|
||||
if ([uid rangeOfString: @"@"].location == NSNotFound)
|
||||
systemEmail
|
||||
= [NSString stringWithFormat: @"%@@%@", uid, [dd mailDomain]];
|
||||
else
|
||||
systemEmail = uid;
|
||||
|
||||
// We always add the system email, which will always be returned
|
||||
// by SOGoUser -systemEmail.
|
||||
[emails addObject: systemEmail];
|
||||
if ([emails count] == 0)
|
||||
{
|
||||
uid = [contact objectForKey: @"c_uid"];
|
||||
if ([uid rangeOfString: @"@"].location == NSNotFound)
|
||||
systemEmail = [NSString stringWithFormat: @"%@@%@", uid, [dd mailDomain]];
|
||||
else
|
||||
systemEmail = uid;
|
||||
// We always add the system email, which will always be returned
|
||||
// by SOGoUser -systemEmail.
|
||||
[emails addObject: systemEmail];
|
||||
}
|
||||
[contact setObject: [emails objectAtIndex: 0] forKey: @"c_email"];
|
||||
}
|
||||
|
||||
@@ -789,7 +818,7 @@ static Class NSNullK;
|
||||
while (!userEntry && (sourceID = [sogoSources nextObject]))
|
||||
{
|
||||
currentSource = [_sources objectForKey: sourceID];
|
||||
|
||||
|
||||
userEntry = [currentSource lookupContactEntryWithUIDorEmail: theUID
|
||||
inDomain: theDomain];
|
||||
if (userEntry)
|
||||
@@ -904,7 +933,7 @@ static Class NSNullK;
|
||||
[user setObject: [NSNumber numberWithBool: YES]
|
||||
forKey: @"CalendarAccess"];
|
||||
[user setObject: [NSNumber numberWithBool: NO]
|
||||
forKey: @"MailAccess"];
|
||||
forKey: @"MailAccess"];
|
||||
}
|
||||
|
||||
return user;
|
||||
@@ -933,7 +962,7 @@ static Class NSNullK;
|
||||
// The domain is probably appended to the username;
|
||||
// make sure it is a defined domain in the configuration.
|
||||
domain = [uid substringFromIndex: (r.location + r.length)];
|
||||
if ([[sd domainIds] containsObject: domain])
|
||||
if ([self isDomainDefined: domain])
|
||||
username = [uid substringToIndex: r.location];
|
||||
else
|
||||
domain = nil;
|
||||
@@ -948,7 +977,7 @@ static Class NSNullK;
|
||||
// search using the original uid.
|
||||
infos = [self contactInfosForUserWithUIDorEmail: uid
|
||||
inDomain: nil];
|
||||
|
||||
|
||||
return infos;
|
||||
}
|
||||
|
||||
@@ -977,29 +1006,29 @@ static Class NSNullK;
|
||||
if ([currentUser isKindOfClass: NSNullK])
|
||||
currentUser = nil;
|
||||
else if (!([currentUser objectForKey: @"emails"]
|
||||
&& [currentUser objectForKey: @"cn"]))
|
||||
{
|
||||
// We make sure that we either have no occurence of a cache entry or
|
||||
// that we have an occurence with only a cached password. In the
|
||||
// latter case, we update the entry with the remaining information
|
||||
// and recache the value.
|
||||
if (!currentUser ||
|
||||
&& [currentUser objectForKey: @"cn"]))
|
||||
{
|
||||
// We make sure that we either have no occurence of a cache entry or
|
||||
// that we have an occurence with only a cached password. In the
|
||||
// latter case, we update the entry with the remaining information
|
||||
// and recache the value.
|
||||
if (!currentUser ||
|
||||
([currentUser count] == 1 && [currentUser objectForKey: @"password"]) ||
|
||||
([currentUser count] == 2 && [currentUser objectForKey: @"password"] && [currentUser objectForKey: @"DomainLessLogin"]))
|
||||
{
|
||||
newUser = YES;
|
||||
newUser = YES;
|
||||
|
||||
if (!currentUser)
|
||||
currentUser = [NSMutableDictionary dictionary];
|
||||
}
|
||||
else
|
||||
newUser = NO;
|
||||
[self _fillContactInfosForUser: currentUser
|
||||
if (!currentUser)
|
||||
currentUser = [NSMutableDictionary dictionary];
|
||||
}
|
||||
else
|
||||
newUser = NO;
|
||||
[self _fillContactInfosForUser: currentUser
|
||||
withUIDorEmail: aUID
|
||||
inDomain: domain];
|
||||
if (newUser)
|
||||
{
|
||||
if ([[currentUser objectForKey: @"c_uid"] length] == 0)
|
||||
if (newUser)
|
||||
{
|
||||
if ([[currentUser objectForKey: @"c_uid"] length] == 0)
|
||||
{
|
||||
[self _retainUser: (NSDictionary *) [NSNull null]
|
||||
withLogin: cacheUid];
|
||||
@@ -1022,7 +1051,7 @@ static Class NSNullK;
|
||||
[self _retainUser: currentUser withLogin: cacheUid];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
currentUser = nil;
|
||||
@@ -1048,7 +1077,7 @@ static Class NSNullK;
|
||||
while ((sourceID = [sources nextObject]))
|
||||
{
|
||||
currentSource = [_sources objectForKey: sourceID];
|
||||
contact = [currentSource lookupContactEntry: uid];
|
||||
contact = [currentSource lookupContactEntry: uid inDomain: domain];
|
||||
if (contact)
|
||||
[contacts addObject: contact];
|
||||
}
|
||||
@@ -1077,30 +1106,30 @@ static Class NSNullK;
|
||||
{
|
||||
uid = [userEntry objectForKey: @"c_uid"];
|
||||
if ([uid length])
|
||||
{
|
||||
returnContact = [compactContacts objectForKey: uid];
|
||||
if (!returnContact)
|
||||
{
|
||||
returnContact = [NSMutableDictionary dictionary];
|
||||
[returnContact setObject: uid forKey: @"c_uid"];
|
||||
{
|
||||
returnContact = [compactContacts objectForKey: uid];
|
||||
if (!returnContact)
|
||||
{
|
||||
returnContact = [NSMutableDictionary dictionary];
|
||||
[returnContact setObject: uid forKey: @"c_uid"];
|
||||
source = [userEntry objectForKey: @"source"];
|
||||
if (source)
|
||||
[returnContact setObject: source forKey: @"source"];
|
||||
[compactContacts setObject: returnContact forKey: uid];
|
||||
}
|
||||
if (![[returnContact objectForKey: @"c_name"] length])
|
||||
[returnContact setObject: [userEntry objectForKey: @"c_name"]
|
||||
forKey: @"c_name"];
|
||||
if (![[returnContact objectForKey: @"cn"] length])
|
||||
[returnContact setObject: [userEntry objectForKey: @"c_cn"]
|
||||
forKey: @"cn"];
|
||||
emails = [returnContact objectForKey: @"emails"];
|
||||
if (!emails)
|
||||
{
|
||||
emails = [NSMutableArray array];
|
||||
[returnContact setObject: emails forKey: @"emails"];
|
||||
}
|
||||
email = [userEntry objectForKey: @"mail"];
|
||||
if (![[returnContact objectForKey: @"c_name"] length])
|
||||
[returnContact setObject: [userEntry objectForKey: @"c_name"]
|
||||
forKey: @"c_name"];
|
||||
if (![[returnContact objectForKey: @"cn"] length])
|
||||
[returnContact setObject: [userEntry objectForKey: @"c_cn"]
|
||||
forKey: @"cn"];
|
||||
emails = [returnContact objectForKey: @"emails"];
|
||||
if (!emails)
|
||||
{
|
||||
emails = [NSMutableArray array];
|
||||
[returnContact setObject: emails forKey: @"emails"];
|
||||
}
|
||||
email = [userEntry objectForKey: @"mail"];
|
||||
if ([email isKindOfClass: [NSArray class]])
|
||||
{
|
||||
allEmails = (NSArray *) email;
|
||||
@@ -1112,22 +1141,22 @@ static Class NSNullK;
|
||||
}
|
||||
}
|
||||
else if (email && ![emails containsObject: email])
|
||||
[emails addObject: email];
|
||||
email = [userEntry objectForKey: @"mozillasecondemail"];
|
||||
if (email && ![emails containsObject: email])
|
||||
[emails addObject: email];
|
||||
email = [userEntry objectForKey: @"xmozillasecondemail"];
|
||||
if (email && ![emails containsObject: email])
|
||||
[emails addObject: email];
|
||||
[emails addObject: email];
|
||||
email = [userEntry objectForKey: @"mozillasecondemail"];
|
||||
if (email && ![emails containsObject: email])
|
||||
[emails addObject: email];
|
||||
email = [userEntry objectForKey: @"xmozillasecondemail"];
|
||||
if (email && ![emails containsObject: email])
|
||||
[emails addObject: email];
|
||||
info = [userEntry objectForKey: @"c_info"];
|
||||
if ([info length] > 0
|
||||
&& ![[returnContact objectForKey: @"c_info"] length])
|
||||
[returnContact setObject: info forKey: @"c_info"];
|
||||
[self _fillContactMailRecords: returnContact];
|
||||
[self _fillContactMailRecords: returnContact];
|
||||
isGroup = [userEntry objectForKey: @"isGroup"];
|
||||
if (isGroup)
|
||||
[returnContact setObject: isGroup forKey: @"isGroup"];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
newContacts = [compactContacts allValues];
|
||||
@@ -1136,7 +1165,7 @@ static Class NSNullK;
|
||||
}
|
||||
|
||||
- (NSArray *) _fetchEntriesInSources: (NSArray *) sourcesList
|
||||
matching: (NSString *) filter
|
||||
matching: (NSString *) filter
|
||||
inDomain: (NSString *) domain
|
||||
{
|
||||
NSMutableArray *contacts;
|
||||
@@ -1150,7 +1179,7 @@ static Class NSNullK;
|
||||
{
|
||||
currentSource = [_sources objectForKey: sourceID];
|
||||
[contacts addObjectsFromArray:
|
||||
[currentSource fetchContactsMatching: filter
|
||||
[currentSource fetchContactsMatching: filter
|
||||
inDomain: domain]];
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user