Source/ESOTRPreferences.m
author Tyler Funnell <tyler.funnell@gmail.com>
Sun Mar 21 00:06:56 2010 -0400 (2010-03-21)
changeset 3159 ed57eaa7f328
parent 1109 092c44a2cfbb
child 3576 1190bca3e731
permissions -rw-r--r--
Change "Generate" to "Regenerate" in Preferences. Fixes #1128
     1 /* 
     2  * Adium is the legal property of its developers, whose names are listed in the copyright file included
     3  * with this source distribution.
     4  * 
     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.
     8  * 
     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.
    12  * 
    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.
    15  */
    16 
    17 #import "ESOTRPreferences.h"
    18 #import <Adium/AIAccountControllerProtocol.h>
    19 #import <AIUtilities/AIImageAdditions.h>
    20 #import <AIUtilities/AIPopUpButtonAdditions.h>
    21 #import <Adium/AIAccount.h>
    22 #import <Adium/AIService.h>
    23 
    24 #import "OTRCommon.h"
    25 
    26 #import "AdiumOTREncryption.h"
    27 
    28 /* Adium OTR headers */
    29 #import "ESOTRFingerprintDetailsWindowController.h"
    30 
    31 @interface ESOTRPreferences ()
    32 - (void)tableViewSelectionDidChange:(NSNotification *)aNotification;
    33 @end
    34 
    35 @implementation ESOTRPreferences
    36 
    37 //Preference pane properties
    38 - (NSString *)label
    39 {
    40     return AILocalizedString(@"Encryption",nil);
    41 }
    42 - (NSString *)nibName
    43 {
    44     return @"OTRPrefs";
    45 }
    46 - (NSImage *)image
    47 {
    48 	return [NSImage imageNamed:@"Lock_Locked State" forClass:[adium class]];
    49 }
    50 
    51 - (void)viewDidLoad
    52 {
    53 	viewIsOpen = YES;
    54 
    55 	//Account Menu
    56 	accountMenu = [[AIAccountMenu accountMenuWithDelegate:self
    57 											  submenuType:AIAccountNoSubmenu
    58 										   showTitleVerbs:NO] retain];
    59 	
    60 	//Fingerprints
    61 	[tableView_fingerprints setDelegate:self];
    62 	[tableView_fingerprints setDataSource:self];
    63 	[tableView_fingerprints setTarget:self];
    64 	[tableView_fingerprints setDoubleAction:@selector(showFingerprint:)];
    65 	[self updateFingerprintsList];
    66 	
    67 	[self updatePrivateKeyList];
    68 
    69 	[textField_privateKey setSelectable:YES];
    70 
    71 	[self tableViewSelectionDidChange:nil];		
    72 }
    73 
    74 - (void)viewWillClose
    75 {
    76 	viewIsOpen = NO;
    77 	[fingerprintDictArray release]; fingerprintDictArray = nil;
    78 	[accountMenu release]; accountMenu = nil;
    79 	
    80 	[[NSNotificationCenter defaultCenter] removeObserver:self
    81 										  name:Account_ListChanged
    82 										object:nil];
    83 }
    84 
    85 /*!
    86  * @brief Deallocate
    87  */
    88 - (void)dealloc
    89 {
    90 	[fingerprintDictArray release]; fingerprintDictArray = nil;
    91 	[[NSNotificationCenter defaultCenter] removeObserver:self];
    92 
    93 	[super dealloc];
    94 }
    95 
    96 /*!
    97  * @brief Update the fingerprint display
    98  *
    99  * Called by the OTR adapter when -otr informs us the fingerprint list changed
   100  */
   101 - (void)updateFingerprintsList
   102 {
   103 	OtrlUserState   otrg_plugin_userstate = otrg_get_userstate();
   104 
   105 	if (viewIsOpen && otrg_plugin_userstate) {
   106 		ConnContext		*context;
   107 		Fingerprint		*fingerprint;
   108 
   109 		[fingerprintDictArray release];
   110 		fingerprintDictArray = [[NSMutableArray alloc] init];
   111 		
   112 		for (context = otrg_plugin_userstate->context_root; context != NULL;
   113 			 context = context->next) {
   114 
   115 			fingerprint = context->fingerprint_root.next;
   116 			/* If there's no fingerprint, don't add it to the known
   117 				* fingerprints list */
   118 			while (fingerprint) {
   119 				char			hash[45];
   120 				NSDictionary	*fingerprintDict;
   121 				NSString		*UID;
   122 				NSString		*state, *fingerprintString;
   123 
   124 				UID = [NSString stringWithUTF8String:context->username];
   125 				
   126 				if (context->msgstate == OTRL_MSGSTATE_ENCRYPTED &&
   127 					context->active_fingerprint != fingerprint) {
   128 					state = AILocalizedString(@"Unused","Word to describe an encryption fingerprint which is not currently being used");
   129 				} else {
   130 					TrustLevel trustLevel = otrg_plugin_context_to_trust(context);
   131 					
   132 					switch (trustLevel) {
   133 						case TRUST_NOT_PRIVATE:
   134 							state = AILocalizedString(@"Not private",nil);
   135 							break;
   136 						case TRUST_UNVERIFIED:
   137 							state = AILocalizedString(@"Unverified",nil);
   138 							break;
   139 						case TRUST_PRIVATE:
   140 							state = AILocalizedString(@"Private",nil);
   141 							break;
   142 						case TRUST_FINISHED:
   143 							state = AILocalizedString(@"Finished",nil);
   144 							break;
   145 						default:
   146 							state = @"";
   147 							break;
   148 					}
   149 				}
   150 				
   151 				otrl_privkey_hash_to_human(hash, fingerprint->fingerprint);
   152 				fingerprintString = [NSString stringWithUTF8String:hash];
   153 				
   154 				AIAccount *account = [adium.accountController accountWithInternalObjectID:[NSString stringWithUTF8String:context->accountname]];
   155 
   156 				fingerprintDict = [NSDictionary dictionaryWithObjectsAndKeys:
   157 					UID, @"UID",
   158 					state, @"Status",
   159 					fingerprintString, @"FingerprintString",
   160 					[NSValue valueWithPointer:fingerprint], @"FingerprintValue",
   161 					account, @"AIAccount",
   162 					nil];
   163 
   164 				[fingerprintDictArray addObject:fingerprintDict];
   165 
   166 				fingerprint = fingerprint->next;
   167 			}
   168 		}
   169 		
   170 		[tableView_fingerprints reloadData];
   171 	}
   172 }
   173 
   174 /*!
   175  * @brief Update the key list
   176  *
   177  * Called by the OTR adapter when -otr informs us the private key list changed
   178  */
   179 - (void)updatePrivateKeyList
   180 {
   181 	if (viewIsOpen) {
   182 		NSString		*fingerprintString = nil;
   183 		AIAccount		*account = ([popUp_accounts numberOfItems] ? [[popUp_accounts selectedItem] representedObject] : nil);
   184 		
   185 		if (account) {
   186 			const char		*accountname = [account.internalObjectID UTF8String];
   187 			const char		*protocol = [account.service.serviceCodeUniqueID UTF8String];
   188 			char			*fingerprint;
   189 			OtrlUserState	otrg_plugin_userstate;
   190 			
   191 			if ((otrg_plugin_userstate = otrg_get_userstate())){
   192 				char fingerprint_buf[45];
   193 				fingerprint = otrl_privkey_fingerprint(otrg_plugin_userstate,
   194 													   fingerprint_buf, accountname, protocol);
   195 				
   196 				if (fingerprint) {
   197 					[button_generate setTitle:AILocalizedString(@"Regenerate", nil)];
   198 					fingerprintString = [NSString stringWithFormat:AILocalizedString(@"Fingerprint: %.80s",nil), fingerprint];
   199 				} else {
   200 					[button_generate setTitle:AILocalizedString(@"Generate", nil)];
   201 					fingerprintString = AILocalizedString(@"No private key present", "Message to show in the Encryption OTR preferences when an account is selected which does not have a private key");
   202 				}
   203 			}
   204 		}
   205 
   206 		[textField_privateKey setStringValue:(fingerprintString ?
   207 											  fingerprintString :
   208 											  @"")];
   209 	}	
   210 }
   211 
   212 /*!
   213  * @brief Generate a new private key for the currently selected account
   214  */
   215 - (IBAction)generate:(id)sender
   216 {
   217 	AIAccount	*account = ([popUp_accounts numberOfItems] ? [[popUp_accounts selectedItem] representedObject] : nil);
   218 	
   219 	otrg_plugin_create_privkey([account.internalObjectID UTF8String],
   220 							   [account.service.serviceCodeUniqueID UTF8String]);
   221 }
   222 
   223 /*!
   224  * @brief Show the fingerprint for the contact selected in the fingerprints NSTableView
   225  */
   226 - (IBAction)showFingerprint:(id)sender
   227 {
   228 	NSInteger selectedRow = [tableView_fingerprints selectedRow];
   229 	if (selectedRow != -1) {
   230 		NSDictionary	*fingerprintDict = [fingerprintDictArray objectAtIndex:selectedRow];
   231 		[ESOTRFingerprintDetailsWindowController showDetailsForFingerprintDict:fingerprintDict];
   232 	}
   233 }
   234 
   235 //Fingerprint tableview ------------------------------------------------------------------------------------------------
   236 #pragma mark Fingerprint tableview
   237 - (NSInteger)numberOfRowsInTableView:(NSTableView *)aTableView
   238 {
   239 	return [fingerprintDictArray count];
   240 }
   241 
   242 - (id)tableView:(NSTableView *)aTableView objectValueForTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
   243 {
   244 	if ((rowIndex >= 0) && (rowIndex < [fingerprintDictArray count])) {
   245 		NSString		*identifier = [aTableColumn identifier];
   246 		NSDictionary	*fingerprintDict = [fingerprintDictArray objectAtIndex:rowIndex];
   247 		
   248 		if ([identifier isEqualToString:@"UID"]) {
   249 			return [fingerprintDict objectForKey:@"UID"];
   250 			
   251 		} else if ([identifier isEqualToString:@"Status"]) {
   252 			return [fingerprintDict objectForKey:@"Status"];
   253 			
   254 		}
   255 	}
   256 
   257 	return @"";
   258 }
   259 
   260 - (void)tableView:(NSTableView *)aTableView willDisplayCell:(id)aCell forTableColumn:(NSTableColumn *)aTableColumn row:(NSInteger)rowIndex
   261 {
   262 	
   263 }
   264 
   265 - (void)tableViewSelectionDidChange:(NSNotification *)aNotification
   266 {
   267 	NSInteger selectedRow = [tableView_fingerprints selectedRow];
   268 	[button_showFingerprint setEnabled:(selectedRow != -1)];
   269 }
   270 
   271 
   272 //Account menu ---------------------------------------------------------------------------------------------------------
   273 #pragma mark Account menu
   274 /*!
   275  * @brief Account menu delegate
   276  */ 
   277 - (void)accountMenu:(AIAccountMenu *)inAccountMenu didRebuildMenuItems:(NSArray *)menuItems {
   278 	[popUp_accounts setMenu:[inAccountMenu menu]];
   279 
   280 	BOOL hasItems = ([[popUp_accounts menu] numberOfItems] > 0);
   281 	[popUp_accounts setEnabled:hasItems];
   282 	[button_generate setEnabled:hasItems];
   283 }
   284 
   285 - (void)accountMenu:(AIAccountMenu *)inAccountMenu didSelectAccount:(AIAccount *)inAccount {
   286 	[self updatePrivateKeyList];
   287 }
   288 
   289 - (NSControlSize)controlSizeForAccountMenu:(AIAccountMenu *)inAccountMenu
   290 {
   291 	return NSSmallControlSize;
   292 }
   293 
   294 @end