Merge branch 'develop'
[pithos-ios] / Classes / OpenStackAccount.m
1 //
2 //  OpenStackAccount.m
3 //  OpenStack
4 //
5 //  Created by Mike Mayo on 10/1/10.
6 //  The OpenStack project is provided under the Apache 2.0 license.
7 //
8
9 #import "OpenStackAccount.h"
10 #import "Keychain.h"
11 #import "Provider.h"
12 #import "Archiver.h"
13 #import "OpenStackRequest.h"
14 #import "NSObject+Conveniences.h"
15 #import "AccountManager.h"
16 #import "APICallback.h"
17
18 static NSArray *accounts = nil;
19
20 @implementation OpenStackAccount
21
22 @synthesize uuid, provider, username, filesURL, manager,
23             bytesUsed, policyQuota, containers, hasBeenRefreshed, flaggedForDelete,
24             shared, sharingAccount, userCatalog;
25
26 + (void)initialize {
27     accounts = [[Archiver retrieve:@"accounts"] retain];
28     if (accounts == nil) {
29         accounts = [[NSArray alloc] init];
30         [Archiver persist:accounts key:@"accounts"];
31     }
32 }
33
34 #pragma mark - Constructors
35
36 - (id)init {
37     if ((self = [super init])) {
38         uuid = [[NSString alloc] initWithString:[OpenStackAccount stringWithUUID]];
39         
40         self.userCatalog = [NSMutableDictionary dictionary];
41         
42         manager = [[AccountManager alloc] init];
43         manager.account = self;
44     }
45     return self;
46 }
47
48 - (id)initWithCoder:(NSCoder *)coder {
49     if ((self = [super init])) {
50         self.uuid = [self decode:coder key:@"uuid"];
51         self.provider = [self decode:coder key:@"provider"];
52         self.username = [self decode:coder key:@"username"];
53         
54         self.filesURL = [self decode:coder key:@"filesURL"];
55         self.bytesUsed = [self decode:coder key:@"bytesUsed"];
56         self.policyQuota = [self decode:coder key:@"policyQuota"];
57         
58 //        containers = [self decode:coder key:@"containers"];
59         
60         self.userCatalog = [self decode:coder key:@"userCatalog"];
61         if (!userCatalog) {
62             self.userCatalog = [NSMutableDictionary dictionary];
63         }
64         
65         manager = [[AccountManager alloc] init];
66         manager.account = self;
67     }
68     return self;
69 }
70
71 #pragma mark - Serialization
72
73 - (id)copyWithZone:(NSZone *)zone {
74     OpenStackAccount *copy = [[[self class] allocWithZone:zone] init];
75     copy.uuid = self.uuid;
76     copy.provider = self.provider;
77     copy.username = self.username;
78     copy.apiKey = self.apiKey;
79     copy.authToken = self.authToken;
80     
81     copy.filesURL = self.filesURL;
82     copy.bytesUsed = self.bytesUsed;
83     copy.policyQuota = self.policyQuota;
84     
85     copy.userCatalog = [[self.userCatalog copy] autorelease];
86     
87     copy.manager = [[[AccountManager alloc] init] autorelease];
88     copy.manager.account = copy;
89     return copy;
90 }
91
92 - (void)encodeWithCoder: (NSCoder *)coder {
93     [coder encodeObject:uuid forKey:@"uuid"];
94     [coder encodeObject:provider forKey:@"provider"];
95     [coder encodeObject:username forKey:@"username"];
96     
97     [coder encodeObject:filesURL forKey:@"filesURL"];
98     [coder encodeObject:bytesUsed forKey:@"bytesUsed"];
99     [coder encodeObject:policyQuota forKey:@"policyQuota"];
100     
101 //    [coder encodeObject:containers forKey:@"containers"];
102     
103     [coder encodeObject:userCatalog forKey:@"userCatalog"];
104 }
105
106 - (id)decode:(NSCoder *)coder key:(NSString *)key {
107     @try {
108         return [coder decodeObjectForKey:key];
109     }
110     @catch (NSException *exception) {
111         return nil;
112     }
113 }
114
115 #pragma mark - Properties
116
117 - (void)setShared:(BOOL)aShared {
118     if (shared != aShared) {
119         self.containers = nil;
120     }
121     shared = aShared;
122 }
123
124 - (void)setSharingAccount:(NSString *)aSharingAccount {
125     if ((aSharingAccount && ![aSharingAccount isEqualToString:sharingAccount]) || (!aSharingAccount && sharingAccount)) {
126         self.containers = nil;
127     }
128     [sharingAccount release];
129     sharingAccount = [aSharingAccount retain];
130 }
131
132 // the API key and auth token are stored in the Keychain, so overriding the
133 // getter and setter to abstract the encryption away and make it easy to use
134
135 - (NSString *)apiKeyKeychainKey {
136     return [NSString stringWithFormat:@"%@-apiKey", self.uuid];
137 }
138
139 - (NSString *)apiKey {
140     return [Keychain getStringForKey:[self apiKeyKeychainKey]];
141 }
142
143 - (void)setApiKey:(NSString *)newAPIKey {
144     [Keychain setString:newAPIKey forKey:[self apiKeyKeychainKey]];
145 }
146
147 - (NSString *)authTokenKeychainKey {
148     return [NSString stringWithFormat:@"%@-authToken", self.uuid];
149 }
150
151 - (NSString *)authToken {
152     NSString *authToken = [Keychain getStringForKey:[self authTokenKeychainKey]];
153     if (!authToken) {
154         authToken = @"";
155     }
156     return authToken;
157 }
158
159 - (void)setAuthToken:(NSString *)newAuthToken {
160     [Keychain setString:newAuthToken forKey:[self authTokenKeychainKey]];
161 }
162
163 #pragma mark - Class Actions
164
165 + (NSArray *)accounts {
166     if (accounts == nil) {
167         accounts = [[Archiver retrieve:@"accounts"] retain];
168     }
169     return accounts;
170 }
171
172 + (void)persist:(NSArray *)accountArray {
173     accounts = [[NSArray arrayWithArray:accountArray] retain];
174     [Archiver persist:accounts key:@"accounts"];
175     [accounts release];
176     accounts = nil;
177 }
178
179 #pragma mark - Actions
180
181 - (void)persist {
182     if (!flaggedForDelete) {
183         NSMutableArray *accountArr = [NSMutableArray arrayWithArray:[OpenStackAccount accounts]];
184         
185         BOOL accountPresent = NO;
186         for (int i = 0; i < [accountArr count]; i++) {
187             OpenStackAccount *account = [accountArr objectAtIndex:i];
188             
189             if ([account.uuid isEqualToString:self.uuid]) {
190                 accountPresent = YES;
191                 [accountArr replaceObjectAtIndex:i withObject:self];
192                 break;
193             }
194         }
195         
196         if (!accountPresent) {
197             [accountArr insertObject:self atIndex:0];
198         }
199         
200         [Archiver persist:[NSArray arrayWithArray:accountArr] key:@"accounts"];
201         [accounts release];
202         accounts = nil;
203     }
204 }
205
206 - (NSArray *)pithosSortedContainers {
207     NSMutableArray *pithosSortedContainers = [NSMutableArray array];
208     if ([self.containers objectForKey:@"pithos"])
209         [pithosSortedContainers addObject:[self.containers objectForKey:@"pithos"]];
210     if ([self.containers objectForKey:@"trash"])
211         [pithosSortedContainers addObject:[self.containers objectForKey:@"trash"]];
212     
213     NSMutableDictionary *otherContainers = [NSMutableDictionary dictionaryWithDictionary:self.containers];
214     [otherContainers removeObjectForKey:@"pithos"];
215     [otherContainers removeObjectForKey:@"trash"];
216     [pithosSortedContainers addObjectsFromArray:[[otherContainers allValues] sortedArrayUsingSelector:@selector(compare:)]];
217     return pithosSortedContainers;
218 }
219
220 - (NSString *)displaynameForUUID:(NSString *)UUID safe:(BOOL)safe {
221     NSString *displayName = [userCatalog objectForKey:UUID];
222     if (safe && !displayName) {
223         return UUID;
224     } else {
225         return displayName;
226     }
227 }
228
229 - (NSString *)displaynameForUUID:(NSString *)UUID {
230     return [self displaynameForUUID:UUID safe:NO];
231 }
232
233 #pragma mark - Memory Management
234
235 - (void)dealloc {
236     [uuid release];
237     [manager release];
238     [provider release];
239     [username release];
240     [filesURL release];
241     [containers release];
242     [sharingAccount release];
243     [bytesUsed release];
244     [policyQuota release];
245     [userCatalog release];
246     
247     [super dealloc];
248 }
249
250 @end