1/*
2 Connection Parameters abstraction
3
4 Copyright 2013 Thincast Technologies GmbH, Author: Dorian Johnson
5
6 This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
7 If a copy of the MPL was not distributed with this file, You can obtain one at
8 http://mozilla.org/MPL/2.0/.
9 */
10
11#import "ConnectionParams.h"
12#import "GlobalDefaults.h"
13#import "EncryptionController.h"
14#import "Utils.h"
15#import "TSXAdditions.h"
16
17@interface ConnectionParams (Private)
18- (id)initWithConnectionParams:(ConnectionParams *)params;
19@end
20
21@implementation ConnectionParams
22
23// Designated initializer.
24- (id)initWithDictionary:(NSDictionary *)dict
25{
26	if (!(self = [super init]))
27		return nil;
28
29	_connection_params = [dict mutableDeepCopy];
30
31	[self decryptPasswordForKey:@"password"];
32	[self decryptPasswordForKey:@"tsg_password"];
33
34	return self;
35}
36
37- (void)decryptPasswordForKey:(NSString *)key
38{
39	if ([[_connection_params objectForKey:key] isKindOfClass:[NSData class]])
40	{
41		NSString *plaintext_password = [[[EncryptionController sharedEncryptionController]
42		    decryptor] decryptString:[_connection_params objectForKey:key]];
43		[self setValue:plaintext_password forKey:key];
44	}
45}
46
47- (id)initWithBaseDefaultParameters
48{
49	return [self initWithDictionary:[[NSUserDefaults standardUserDefaults]
50	                                    dictionaryForKey:@"TSXDefaultComputerBookmarkSettings"]];
51}
52
53- (id)init
54{
55	return [self initWithDictionary:[NSDictionary dictionary]];
56}
57
58- (id)initWithConnectionParams:(ConnectionParams *)params
59{
60	return [self initWithDictionary:params->_connection_params];
61}
62- (void)dealloc
63{
64	[_connection_params release];
65	_connection_params = nil;
66	[super dealloc];
67}
68
69- (id)copyWithZone:(NSZone *)zone
70{
71	return [[ConnectionParams alloc] initWithDictionary:_connection_params];
72}
73
74- (NSString *)description
75{
76	return [NSString stringWithFormat:@"ConnectionParams: %@", [_connection_params description]];
77}
78
79#pragma mark -
80#pragma mark NSCoder
81
82- (id)initWithCoder:(NSCoder *)decoder
83{
84	if ([decoder containsValueForKey:@"connectionParams"])
85		return [self initWithDictionary:[decoder decodeObjectForKey:@"connectionParams"]];
86
87	return [self init];
88}
89
90- (void)encodeWithCoder:(NSCoder *)coder
91{
92	NSSet *unserializable_keys = [NSSet setWithObjects:@"view", nil];
93	NSMutableDictionary *serializable_params =
94	    [[NSMutableDictionary alloc] initWithCapacity:[_connection_params count]];
95
96	for (NSString *k in _connection_params)
97		if (([k characterAtIndex:0] != '_') && ![unserializable_keys containsObject:k])
98			[serializable_params setObject:[_connection_params objectForKey:k] forKey:k];
99
100	if ([serializable_params objectForKey:@"password"] != nil)
101		[self serializeDecryptedForKey:@"password" forParams:serializable_params];
102	if ([serializable_params objectForKey:@"tsg_password"] != nil)
103		[self serializeDecryptedForKey:@"tsg_password" forParams:serializable_params];
104
105	[coder encodeObject:serializable_params forKey:@"connectionParams"];
106	[serializable_params release];
107}
108
109- (void)serializeDecryptedForKey:(NSString *)key forParams:(NSMutableDictionary *)params
110{
111	NSData *encrypted_password = [[[EncryptionController sharedEncryptionController] encryptor]
112	    encryptString:[params objectForKey:key]];
113
114	if (encrypted_password)
115		[params setObject:encrypted_password forKey:key];
116	else
117		[params removeObjectForKey:key];
118}
119
120#pragma mark -
121#pragma mark NSKeyValueCoding
122
123- (void)setValue:(id)value forKey:(NSString *)key
124{
125	[self willChangeValueForKey:key];
126
127	if (value == nil)
128		[self setNilValueForKey:key];
129	else
130		[_connection_params setValue:value forKey:key];
131
132	[self didChangeValueForKey:key];
133}
134
135- (void)setValue:(id)value forKeyPath:(NSString *)key
136{
137	[self willChangeValueForKey:key];
138
139	if (value == nil)
140		[self setNilValueForKey:key];
141	else
142		[_connection_params setValue:value forKeyPath:key];
143
144	[self didChangeValueForKey:key];
145}
146
147- (void)setNilValueForKey:(NSString *)key
148{
149	[_connection_params removeObjectForKey:key];
150}
151
152- (id)valueForKey:(NSString *)key
153{
154	return [_connection_params valueForKey:key];
155}
156
157- (NSArray *)allKeys
158{
159	return [_connection_params allKeys];
160}
161
162#pragma mark -
163#pragma mark KV convenience
164
165- (BOOL)hasValueForKey:(NSString *)key
166{
167	return [_connection_params objectForKey:key] != nil;
168}
169
170- (void)setInt:(int)integer forKey:(NSString *)key
171{
172	[self setValue:[NSNumber numberWithInteger:integer] forKey:key];
173}
174- (int)intForKey:(NSString *)key
175{
176	return [[self valueForKey:key] intValue];
177}
178
179- (void)setBool:(BOOL)v forKey:(NSString *)key
180{
181	[self setValue:[NSNumber numberWithBool:v] forKey:key];
182}
183- (BOOL)boolForKey:(NSString *)key
184{
185	return [[_connection_params objectForKey:key] boolValue];
186}
187
188- (const char *)UTF8StringForKey:(NSString *)key
189{
190	id val = [self valueForKey:key];
191	const char *str;
192
193	if ([val respondsToSelector:@selector(UTF8String)] && (str = [val UTF8String]))
194		return str;
195
196	return "";
197}
198
199- (NSString *)StringForKey:(NSString *)key
200{
201	return [self valueForKey:key];
202}
203
204- (BOOL)hasValueForKeyPath:(NSString *)key
205{
206	return [_connection_params valueForKeyPath:key] != nil;
207}
208
209- (void)setInt:(int)integer forKeyPath:(NSString *)key
210{
211	[self setValue:[NSNumber numberWithInteger:integer] forKeyPath:key];
212}
213- (int)intForKeyPath:(NSString *)key
214{
215	return [[self valueForKeyPath:key] intValue];
216}
217
218- (void)setBool:(BOOL)v forKeyPath:(NSString *)key
219{
220	[self setValue:[NSNumber numberWithBool:v] forKeyPath:key];
221}
222
223- (BOOL)boolForKeyPath:(NSString *)key
224{
225	return [[self valueForKeyPath:key] boolValue];
226}
227
228- (const char *)UTF8StringForKeyPath:(NSString *)key
229{
230	id val = [self valueForKeyPath:key];
231	const char *str;
232
233	if ([val respondsToSelector:@selector(UTF8String)] && (str = [val UTF8String]))
234		return str;
235
236	return "";
237}
238
239- (NSString *)StringForKeyPath:(NSString *)key
240{
241	return [self valueForKeyPath:key];
242}
243
244- (int)intForKey:(NSString *)key with3GEnabled:(BOOL)enabled
245{
246	if (enabled && [self boolForKey:@"enable_3g_settings"])
247		return [self intForKeyPath:[NSString stringWithFormat:@"settings_3g.%@", key]];
248	return [self intForKeyPath:key];
249}
250
251- (BOOL)boolForKey:(NSString *)key with3GEnabled:(BOOL)enabled
252{
253	if (enabled && [self boolForKey:@"enable_3g_settings"])
254		return [self boolForKeyPath:[NSString stringWithFormat:@"settings_3g.%@", key]];
255	return [self boolForKeyPath:key];
256}
257
258@end
259