#import "ASIPithosAccount.h"
#import "ASIPithosContainer.h"
#import "ASIDownloadCache.h"
+#import "PithosAccount.h"
#import "PithosUtilities.h"
#import "PithosActivityFacility.h"
static NSImage *sharedIcon = nil;
@implementation PithosAccountNode
-@synthesize pithos, pithosAccount;
+@synthesize pithos, pithosAccount, translatedGroups;
+ (void)initialize {
if (self == [PithosAccountNode class])
}
#pragma mark -
+#pragma mark Internal
+
+- (void)updateGroups {
+ if (!pithosAccount) {
+ self.translatedGroups = [NSMutableDictionary dictionary];
+ } else if (pithosAccountManager) {
+ NSMutableSet *UUIDs = [NSMutableSet set];
+ for (NSString *groupName in pithosAccount.groups) {
+ [UUIDs addObjectsFromArray:[pithosAccount.groups objectForKey:groupName]];
+ }
+ [UUIDs removeObject:@""];
+ [UUIDs removeObject:@"*"];
+ if (UUIDs.count) {
+ [pithosAccountManager updateUserCatalogForForDisplaynames:nil UUIDs:[UUIDs allObjects]];
+ }
+
+ NSMutableDictionary *newTranslatedGroups = [NSMutableDictionary dictionaryWithCapacity:pithosAccount.groups.count];
+ for (NSString *groupName in pithosAccount.groups) {
+ NSMutableArray *groupUsers = [NSMutableArray array];
+ for (NSString *UUID in [pithosAccount.groups objectForKey:groupName]) {
+ [groupUsers addObject:[pithosAccountManager displaynameForUUID:UUID safe:YES]];
+ }
+ [newTranslatedGroups setObject:groupUsers forKey:groupName];
+ }
+ self.translatedGroups = newTranslatedGroups;
+ } else {
+ self.translatedGroups = [pithosAccount.groups copy];
+ }
+}
+
+#pragma mark -
#pragma mark Properties
- (void)setPithos:(ASIPithos *)aPithos {
}
}
+- (void)setPithosAccount:(ASIPithosAccount *)aPithosAccount {
+ if (![pithosAccount isEqualTo:aPithosAccount]) {
+ pithosAccount = aPithosAccount;
+ [self updateGroups];
+ }
+}
+
- (NSString *)url {
if (url == nil)
url = [[NSString alloc] initWithFormat:@"%@%@",
}
- (NSString *)displayName {
- if (displayName == nil)
- return [NSString stringWithString:(sharingAccount ? sharingAccount : @"account")];
+ if (displayName == nil) {
+ if (!sharingAccount) {
+ return @"account";
+ } else if (pithosAccountManager) {
+ return [pithosAccountManager displaynameForUUID:sharingAccount safe:YES];
+ } else {
+ return [sharingAccount copy];
+ }
+ }
return [displayName copy];
}
} else {
newChildren = nil;
accountRequest = nil;
- containers = nil;
forcedRefresh = NO;
@synchronized(self) {
freshness = PithosNodeStateRefreshNeeded;
if (accountRequest.responseStatusCode == 200) {
self.pithosAccount = [accountRequest account];
+ NSMutableArray *containers = [accountRequest.userInfo objectForKey:@"containers"];
NSArray *someContainers = [accountRequest containers];
if (containers == nil) {
- containers = [[NSMutableArray alloc] initWithArray:someContainers];
+ containers = [NSMutableArray arrayWithArray:someContainers];
} else {
[containers addObjectsFromArray:someContainers];
}
node.shared = shared;
node.sharingAccount = sharingAccount;
node.inheritChildrenUpdatedNotificationName = inheritChildrenUpdatedNotificationName;
+ node.pithosAccountManager = pithosAccountManager;
if (children) {
NSUInteger oldIndex = [children indexOfObject:node];
if (oldIndex != NSNotFound) {
}
// Else cache was used and all results were fetched during this request, so existing children can be reused
accountRequest = nil;
- containers = nil;
forcedRefresh = NO;
@synchronized(self) {
freshness = PithosNodeStateRefreshFinished;
[NSNumber numberWithInteger:NSOperationQueuePriorityVeryHigh], @"priority",
[NSNumber numberWithUnsignedInteger:10], @"retries",
NSStringFromSelector(@selector(accountRequestFinished:)), @"didFinishSelector",
- NSStringFromSelector(@selector(accountRequestFailed:)), @"didFailSelector",
+ NSStringFromSelector(@selector(accountRequestFailed:)), @"didFailSelector",
+ containers, @"containers",
nil];
[[PithosUtilities prepareRequest:accountRequest priority:NSOperationQueuePriorityVeryHigh] startAsynchronous];
}
} else if (accountRequest.responseStatusCode == 304) {
// Account is not modified, so existing children can be reused
accountRequest = nil;
- containers = nil;
forcedRefresh = NO;
@synchronized(self) {
freshness = PithosNodeStateRefreshFinished;
- (void)applyInfo {
@synchronized(self) {
if (applyMetadataAccountRequest == nil) {
- NSMutableDictionary *groups = pithosAccount.groups;
- if ([groups count] == 0)
- groups = [NSMutableDictionary dictionaryWithObject:@"" forKey:@"group"];
- applyMetadataAccountRequest = [ASIPithosAccountRequest updateAccountMetadataRequestWithPithos:pithos
+ NSMutableDictionary *groups = [NSMutableDictionary dictionary];
+ if (translatedGroups.count) {
+ for (NSString *groupName in translatedGroups) {
+ if (!groupName.length ||
+ [groupName rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@" -_~,;"]].location != NSNotFound) {
+ NSAlert *alert = [[NSAlert alloc] init];
+ [alert setMessageText:@"Invalid Input"];
+ [alert setInformativeText:@"Group names cannot be empty or contain ' ', '-', '_', '~', ',' or ';'."];
+ [alert addButtonWithTitle:@"OK"];
+ [alert runModal];
+ return;
+ }
+ }
+ if (pithosAccountManager) {
+ NSMutableSet *allGroupUsers = [NSMutableSet set];
+ for (NSMutableArray *groupUsers in [translatedGroups objectEnumerator]) {
+ [allGroupUsers addObjectsFromArray:groupUsers];
+ }
+ [allGroupUsers removeObject:@""];
+ [allGroupUsers removeObject:@"*"];
+ if (allGroupUsers.count) {
+ ASIPithosRequest *userCatalogRequest = [pithosAccountManager updateUserCatalogForForDisplaynames:[allGroupUsers allObjects]
+ UUIDs:nil];
+ if (userCatalogRequest.error || ((userCatalogRequest.responseStatusCode != 200) && (userCatalogRequest.responseStatusCode != 404))) {
+ return;
+ } else if (userCatalogRequest.responseStatusCode == 200) {
+ // Check if all users exist.
+ NSDictionary *displaynameCatalog = [userCatalogRequest displaynameCatalog];
+ NSMutableArray *inexistentGroupUsers = [NSMutableArray array];
+ for (NSString *groupUser in allGroupUsers) {
+ if (![displaynameCatalog objectForKey:groupUser]) {
+ [inexistentGroupUsers addObject:groupUser];
+ }
+ }
+ if (!inexistentGroupUsers.count) {
+ // Create groups.
+ for (NSString *groupName in translatedGroups) {
+ NSMutableArray *groupUsers = [NSMutableArray array];
+ for (NSString *groupUser in [translatedGroups objectForKey:groupName]) {
+ [groupUsers addObject:([groupUser isEqualToString:@"*"] ?
+ @"*" : [displaynameCatalog objectForKey:groupUser])];
+ }
+ [groups setObject:groupUsers forKey:groupName];
+ }
+ } else {
+ NSAlert *alert = [[NSAlert alloc] init];
+ if (inexistentGroupUsers.count == 1) {
+ [alert setMessageText:@"Invalid User"];
+ [alert setInformativeText:[NSString stringWithFormat:@"User '%@' doesn't exist.", [inexistentGroupUsers objectAtIndex:0]]];
+ } else {
+ [alert setMessageText:@"Invalid Users"];
+ [alert setInformativeText:[NSString stringWithFormat:@"Users '%@' don't exist.", [inexistentGroupUsers componentsJoinedByString:@"', '"]]];
+ }
+ [alert addButtonWithTitle:@"OK"];
+ [alert runModal];
+ return;
+ }
+ } else {
+ // 404. Since we don't translate to UUIDs, check for invalid chars.
+ BOOL valid = YES;
+ for (NSString *groupUser in allGroupUsers) {
+ if ([groupUser rangeOfCharacterFromSet:[NSCharacterSet characterSetWithCharactersInString:@" ~,;:"]].location != NSNotFound) {
+ valid = NO;
+ break;
+ }
+ }
+ if (valid) {
+ [groups addEntriesFromDictionary:translatedGroups];
+ } else {
+ NSAlert *alert = [[NSAlert alloc] init];
+ [alert setMessageText:@"Invalid Input"];
+ [alert setInformativeText:@"Users cannot contain ' ', '~', ',', ';' or ':'."];
+ [alert addButtonWithTitle:@"OK"];
+ [alert runModal];
+ return;
+ }
+ }
+ } else {
+ for (NSString *groupName in translatedGroups) {
+ if ([[translatedGroups objectForKey:groupName] containsObject:@"*"]) {
+ [groups setObject:[NSMutableArray arrayWithObject:@"*"] forKey:groupName];
+ }
+ }
+ if (!groups.count) {
+ [groups setObject:[NSArray arrayWithObject:@""] forKey:@"group"];
+ }
+ }
+ } else {
+ [groups addEntriesFromDictionary:translatedGroups];
+ }
+ } else {
+ [groups setObject:[NSArray arrayWithObject:@""] forKey:@"group"];
+ }
+
+ applyMetadataAccountRequest = [ASIPithosAccountRequest updateAccountMetadataRequestWithPithos:pithos
groups:groups
metadata:pithosAccount.metadata
update:NO];