Patch from brion to add an SSL option for StatusNet accounts. Fixes #13077.
2 * Adium is the legal property of its developers, whose names are listed in the copyright file included
3 * with this source distribution.
5 * This program is free software; you can redistribute it and/or modify it under the terms of the GNU
6 * General Public License as published by the Free Software Foundation; either version 2 of the License,
7 * or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
10 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
11 * Public License for more details.
13 * You should have received a copy of the GNU General Public License along with this program; if not,
14 * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 #import "AITwitterAccount.h"
18 #import "AITwitterAccountViewController.h"
19 #import <AIUtilities/AIMenuAdditions.h>
20 #import <Adium/AIAccountControllerProtocol.h>
22 #import "AITwitterAccountOAuthSetup.h"
24 #define BUTTON_TEXT_ALLOW_ACCESS AILocalizedString(@"Allow Adium access", nil)
26 @interface AITwitterAccountViewController()
27 - (void)completedOAuthSetup;
28 - (void)setStatusText:(NSString *)text withColor:(NSColor *)color buttonEnabled:(BOOL)enabled buttonText:(NSString *)buttonText;
31 @implementation AITwitterAccountViewController
34 * @brief We have no privacy settings.
36 - (NSView *)privacyView
42 * @brief Use the Twitter account view.
46 return @"AITwitterAccountView";
51 NSMenu *intervalMenu = [[[NSMenu alloc] init] autorelease];
53 [intervalMenu addItemWithTitle:AILocalizedString(@"never", "Update tweets: never")
57 representedObject:[NSNumber numberWithInt:0]];
59 [intervalMenu addItemWithTitle:AILocalizedString(@"every 2 minutes", "Update tweets: every 2 minutes")
63 representedObject:[NSNumber numberWithInt:2]];
65 [intervalMenu addItemWithTitle:AILocalizedString(@"every 5 minutes", "Update tweets: every 5 minutes")
69 representedObject:[NSNumber numberWithInt:5]];
71 [intervalMenu addItemWithTitle:AILocalizedString(@"every 10 minutes", "Update tweets every: 10 minutes")
75 representedObject:[NSNumber numberWithInt:10]];
77 [intervalMenu addItemWithTitle:AILocalizedString(@"every 15 minutes", "Update tweets every: 15 minutes")
81 representedObject:[NSNumber numberWithInt:15]];
83 [intervalMenu addItemWithTitle:AILocalizedString(@"every half-hour", "Update tweets every: half-hour")
87 representedObject:[NSNumber numberWithInt:30]];
89 [intervalMenu addItemWithTitle:AILocalizedString(@"every hour", "Update tweets every hour")
93 representedObject:[NSNumber numberWithInt:60]];
95 [intervalMenu setAutoenablesItems:YES];
97 [popUp_updateInterval setMenu:intervalMenu];
99 [self setStatusText:@"" withColor:nil buttonEnabled:YES buttonText:BUTTON_TEXT_ALLOW_ACCESS];
104 [OAuthSetup release]; OAuthSetup = nil;
109 * @brief A preference was changed
111 * Don't save here; merely update controls as necessary.
113 - (IBAction)changedPreference:(id)sender
115 [checkBox_updateGlobalIncludeReplies setEnabled:[checkBox_updateGlobalStatus state]];
117 if(sender == button_OAuthStart) {
118 if (OAuthSetupStep == AIOAuthStepRequestToken) {
119 OAuthSetup.verifier = textField_OAuthVerifier.stringValue;
120 textField_OAuthVerifier.stringValue = @"";
122 [OAuthSetup fetchAccessToken];
124 [OAuthSetup release];
126 OAuthSetup = [[AITwitterAccountOAuthSetup alloc] initWithDelegate:self
127 forAccount:(AITwitterAccount *)account];
129 [OAuthSetup beginSetup];
135 * @brief Configure the account view
137 - (void)configureForAccount:(AIAccount *)inAccount
139 [super configureForAccount:inAccount];
143 AITwitterAccount *twitterAccount = (AITwitterAccount *)account;
145 if (twitterAccount.useOAuth) {
146 [tabView_authenticationType selectTabViewItem:tabViewItem_OAuth];
148 if ([account.lastDisconnectionError isEqualToString:TWITTER_OAUTH_NOT_AUTHORIZED]) {
149 [self setStatusText:TWITTER_OAUTH_NOT_AUTHORIZED
150 withColor:[NSColor redColor]
152 buttonText:BUTTON_TEXT_ALLOW_ACCESS];
154 } else if (account.UID && [[adium.accountController passwordForAccount:account] length]) {
155 [self setStatusText:AILocalizedString(@"Adium currently has access to your account.", nil)
158 buttonText:BUTTON_TEXT_ALLOW_ACCESS];
160 [self setStatusText:nil
163 buttonText:BUTTON_TEXT_ALLOW_ACCESS];
166 [tabView_authenticationType selectTabViewItem:tabViewItem_basicAuthentication];
169 [textField_OAuthVerifier setHidden:YES];
173 NSNumber *updateInterval = [account preferenceForKey:TWITTER_PREFERENCE_UPDATE_INTERVAL group:TWITTER_PREFERENCE_GROUP_UPDATES];
174 [popUp_updateInterval selectItemAtIndex:[[popUp_updateInterval menu] indexOfItemWithRepresentedObject:updateInterval]];
176 BOOL updateAfterSend = [[account preferenceForKey:TWITTER_PREFERENCE_UPDATE_AFTER_SEND group:TWITTER_PREFERENCE_GROUP_UPDATES] boolValue];
177 [checkBox_updateAfterSend setState:updateAfterSend];
179 BOOL updateGlobal = [[account preferenceForKey:TWITTER_PREFERENCE_UPDATE_GLOBAL group:TWITTER_PREFERENCE_GROUP_UPDATES] boolValue];
180 [checkBox_updateGlobalStatus setState:updateGlobal];
182 BOOL updateGlobalIncludesReplies = [[account preferenceForKey:TWITTER_PREFERENCE_UPDATE_GLOBAL_REPLIES group:TWITTER_PREFERENCE_GROUP_UPDATES] boolValue];
183 [checkBox_updateGlobalIncludeReplies setState:updateGlobalIncludesReplies];
185 [checkBox_updateGlobalIncludeReplies setEnabled:[checkBox_updateGlobalStatus state]];
187 BOOL showRetweet = [[account preferenceForKey:TWITTER_PREFERENCE_RETWEET_SPAM group:TWITTER_PREFERENCE_GROUP_UPDATES] boolValue];
188 [checkBox_retweet setState:showRetweet];
190 BOOL loadContacts = [[account preferenceForKey:TWITTER_PREFERENCE_LOAD_CONTACTS group:TWITTER_PREFERENCE_GROUP_UPDATES] boolValue];
191 [checkBox_loadContacts setState:loadContacts];
195 textField_name.stringValue = [account valueForProperty:@"Profile Name"] ?: @"";
196 textField_url.stringValue = [account valueForProperty:@"Profile URL"] ?: @"";
197 textField_location.stringValue = [account valueForProperty:@"Profile Location"] ?: @"";
198 textField_description.stringValue = [account valueForProperty:@"Profile Description"] ?: @"";
200 [textField_name setEnabled:account.online];
201 [textField_url setEnabled:account.online];
202 [textField_location setEnabled:account.online];
203 [textField_description setEnabled:account.online];
205 textField_APIpath.stringValue = @"";
207 [textField_connectHost setEnabled:NO];
208 [textField_APIpath setEnabled:NO];
209 [checkBox_useSSL setEnabled:NO];
213 * @brief The Update Interval combo box was changed.
215 - (void)saveConfiguration
217 [super saveConfiguration];
219 [OAuthSetup release]; OAuthSetup = nil;
221 [account setPreference:popUp_updateInterval.selectedItem.representedObject
222 forKey:TWITTER_PREFERENCE_UPDATE_INTERVAL
223 group:TWITTER_PREFERENCE_GROUP_UPDATES];
225 [account setPreference:[NSNumber numberWithBool:[checkBox_updateAfterSend state]]
226 forKey:TWITTER_PREFERENCE_UPDATE_AFTER_SEND
227 group:TWITTER_PREFERENCE_GROUP_UPDATES];
229 [account setPreference:[NSNumber numberWithBool:[checkBox_updateGlobalStatus state]]
230 forKey:TWITTER_PREFERENCE_UPDATE_GLOBAL
231 group:TWITTER_PREFERENCE_GROUP_UPDATES];
233 [account setPreference:[NSNumber numberWithBool:[checkBox_updateGlobalIncludeReplies state]]
234 forKey:TWITTER_PREFERENCE_UPDATE_GLOBAL_REPLIES
235 group:TWITTER_PREFERENCE_GROUP_UPDATES];
237 [account setPreference:[NSNumber numberWithBool:[checkBox_retweet state]]
238 forKey:TWITTER_PREFERENCE_RETWEET_SPAM
239 group:TWITTER_PREFERENCE_GROUP_UPDATES];
241 [account setPreference:[NSNumber numberWithBool:[checkBox_loadContacts state]]
242 forKey:TWITTER_PREFERENCE_LOAD_CONTACTS
243 group:TWITTER_PREFERENCE_GROUP_UPDATES];
245 if (account.online) {
246 [(AITwitterAccount *)account setProfileName:(textField_name.isEnabled ? textField_name.stringValue : nil)
247 url:(textField_url.isEnabled ? textField_url.stringValue : nil)
248 location:(textField_location.isEnabled ? textField_location.stringValue : nil)
249 description:(textField_description.isEnabled ? textField_description.stringValue : nil)];
253 #pragma mark OAuth status text
254 - (void)setStatusText:(NSString *)text withColor:(NSColor *)color buttonEnabled:(BOOL)enabled buttonText:(NSString *)buttonText
256 textField_OAuthStatus.stringValue = text ?: @"";
257 textField_OAuthStatus.textColor = color ?: [NSColor controlTextColor];
259 [button_OAuthStart setEnabled:enabled];
262 button_OAuthStart.title = buttonText;
263 [button_OAuthStart sizeToFit];
264 [button_OAuthStart setFrameOrigin:NSMakePoint(NSMidX(button_OAuthStart.superview.frame) - NSWidth(button_OAuthStart.frame)/2.0,
265 NSMinY(button_OAuthStart.frame))];
269 #pragma mark OAuth setup delegate
271 - (void)OAuthSetup:(AITwitterAccountOAuthSetup *)setup
272 changedToStep:(AIOAuthSetupStep)setupStep
273 withToken:(OAToken *)token
274 responseBody:(NSString *)responseBody
276 AILogWithSignature(@"Step %u", setupStep);
278 OAuthSetupStep = setupStep;
280 switch (OAuthSetupStep) {
281 case AIOAuthStepStart:
282 case AIOAuthStepVerifyingRequest:
283 // Just starting or verifying a token, fetching a request token
284 [self setStatusText:@""
289 [textField_OAuthVerifier setHidden:YES];
290 [progressIndicator setHidden:NO];
291 [progressIndicator startAnimation:nil];
295 case AIOAuthStepRequestToken:
296 // We have a request token, ask user to authorize.
297 [[NSWorkspace sharedWorkspace] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@?oauth_token=%@",
298 ((AITwitterAccount *)account).tokenAuthorizeURL,
301 [self setStatusText:AILocalizedString(@"You must allow Adium access to your account in the browser window which just opened. When you have done so, enter the PIN code in the field above.", nil)
304 buttonText:AILocalizedString(@"I've allowed Adium access", nil)];
306 [textField_OAuthVerifier setHidden:NO];
307 [progressIndicator setHidden:YES];
308 [progressIndicator stopAnimation:nil];
312 case AIOAuthStepAccessToken:
313 // We have an access token, hoorah!
314 textField_password.stringValue = responseBody;
316 [self setStatusText:AILocalizedString(@"Success! Adium now has access to your account. Click OK below.", nil)
321 [textField_OAuthVerifier setHidden:YES];
322 [progressIndicator setHidden:YES];
323 [progressIndicator stopAnimation:nil];
325 [account setLastDisconnectionError:nil];
326 [account setValue:[NSNumber numberWithBool:YES] forProperty:@"Reconnect After Edit" notify:NotifyNever];
328 [self completedOAuthSetup];
332 case AIOAuthStepFailure:
333 // Failed in some way. sad. :(
335 [self setStatusText:AILocalizedString(@"An error occured while trying to gain access. Please try again.", nil)
336 withColor:[NSColor redColor]
338 buttonText:BUTTON_TEXT_ALLOW_ACCESS];
340 [textField_OAuthVerifier setHidden:YES];
341 [progressIndicator setHidden:YES];
342 [progressIndicator stopAnimation:nil];
344 [self completedOAuthSetup];
350 - (void)completedOAuthSetup
352 [OAuthSetup release]; OAuthSetup = nil;
353 OAuthSetupStep = AIOAuthStepFailure;