blob: f83bc78c5bbff26d49e9c3a5e88af6da9a40649c [file] [log] [blame]
Alexandre Lision745e4d62015-03-22 20:03:10 -04001/*
Alexandre Lision9fe374b2016-01-06 10:17:31 -05002 * Copyright (C) 2015-2016 Savoir-faire Linux Inc.
Alexandre Lision745e4d62015-03-22 20:03:10 -04003 * Author: Alexandre Lision <alexandre.lision@savoirfairelinux.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Alexandre Lision745e4d62015-03-22 20:03:10 -040018 */
19#import "RingWizardWC.h"
20
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -040021//Qt
22#import <QUrl>
23
24//LRC
Alexandre Lision745e4d62015-03-22 20:03:10 -040025#import <accountmodel.h>
26#import <protocolmodel.h>
27#import <QItemSelectionModel>
28#import <account.h>
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -040029#import <certificate.h>
Alexandre Lision745e4d62015-03-22 20:03:10 -040030
31#import "AppDelegate.h"
Alexandre Lision34607032016-02-08 16:16:49 -050032#import "Constants.h"
33#import "views/NSColor+RingTheme.h"
Alexandre Lision745e4d62015-03-22 20:03:10 -040034
Alexandre Lision08abfac2015-09-22 12:20:51 -040035@implementation RingWizardWC {
Alexandre Lision33942092016-02-03 12:19:09 -050036 __unsafe_unretained IBOutlet NSTextField* nicknameField;
37 __unsafe_unretained IBOutlet NSProgressIndicator* progressBar;
38 __unsafe_unretained IBOutlet NSTextField* indicationLabel;
39 __unsafe_unretained IBOutlet NSButton* createButton;
40 __unsafe_unretained IBOutlet NSButton* showCustomCertsButton;
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -040041 IBOutlet NSView *securityContainer;
42
Alexandre Lision34607032016-02-08 16:16:49 -050043 __unsafe_unretained IBOutlet NSButton* shareButton;
Alexandre Lision33942092016-02-03 12:19:09 -050044 __unsafe_unretained IBOutlet NSSecureTextField* passwordField;
45 __unsafe_unretained IBOutlet NSView* pvkContainer;
46 __unsafe_unretained IBOutlet NSPathControl* certificatePathControl;
47 __unsafe_unretained IBOutlet NSPathControl* caListPathControl;
48 __unsafe_unretained IBOutlet NSPathControl* pvkPathControl;
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -040049 BOOL isExpanded;
Alexandre Lision08abfac2015-09-22 12:20:51 -040050 Account* accountToCreate;
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -040051}
52
Alexandre Lision08abfac2015-09-22 12:20:51 -040053NSInteger const PVK_PASSWORD_TAG = 0;
54NSInteger const NICKNAME_TAG = 1;
Alexandre Lision745e4d62015-03-22 20:03:10 -040055
56- (void)windowDidLoad {
57 [super windowDidLoad];
58
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -040059 [passwordField setTag:PVK_PASSWORD_TAG];
Alexandre Lision33942092016-02-03 12:19:09 -050060 [nicknameField setTag:NICKNAME_TAG];
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -040061
62 isExpanded = false;
Alexandre Lision34607032016-02-08 16:16:49 -050063 [self.window setBackgroundColor:[NSColor ringGreyHighlight]];
64
65 AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
Alexandre Lision76d59692016-01-20 18:06:05 -050066
67 if(![appDelegate checkForRingAccount]) {
Alexandre Lision34607032016-02-08 16:16:49 -050068 accountToCreate = AccountModel::instance().add(QString::fromNSString(NSFullUserName()), Account::Protocol::RING);
Alexandre Lision33942092016-02-03 12:19:09 -050069 [nicknameField setStringValue:NSFullUserName()];
Alexandre Lision34607032016-02-08 16:16:49 -050070 [self controlTextDidChange:[NSNotification notificationWithName:@"PlaceHolder" object:nicknameField]];
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -040071 } else {
Alexandre Lision922380d2015-09-15 10:25:17 -040072 [indicationLabel setStringValue:NSLocalizedString(@"Ring is already ready to work",
73 @"Display message to user")];
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -040074 auto accList = AccountModel::instance().getAccountsByProtocol(Account::Protocol::RING);
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -040075 [self displayHash:accList[0]->username().toNSString()];
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -040076 }
77
78 [caListPathControl setDelegate:self];
79 [certificatePathControl setDelegate:self];
80 [pvkPathControl setDelegate:self];
Alexandre Lision745e4d62015-03-22 20:03:10 -040081}
82
Alexandre Lision745e4d62015-03-22 20:03:10 -040083- (void) displayHash:(NSString* ) hash
84{
Alexandre Lision33942092016-02-03 12:19:09 -050085 [nicknameField setFrameSize:NSMakeSize(400, nicknameField.frame.size.height)];
86 [nicknameField setStringValue:hash];
87 [nicknameField setEditable:NO];
88 [nicknameField setHidden:NO];
Alexandre Lision745e4d62015-03-22 20:03:10 -040089
Alexandre Lision08abfac2015-09-22 12:20:51 -040090 [showCustomCertsButton setHidden:YES];
91
Alexandre Lision34607032016-02-08 16:16:49 -050092 [shareButton setHidden:NO];
93 [shareButton sendActionOn:NSLeftMouseDownMask];
Alexandre Lision745e4d62015-03-22 20:03:10 -040094
95 NSSharingService* emailSharingService = [NSSharingService sharingServiceNamed:NSSharingServiceNameComposeEmail];
96
Alexandre Lision34607032016-02-08 16:16:49 -050097 [createButton setTitle:NSLocalizedString(@"Continue",
98 @"Continue button")];
99 [createButton setAction:@selector(goToApp:)];
100}
Alexandre Lision08abfac2015-09-22 12:20:51 -0400101
Alexandre Lision34607032016-02-08 16:16:49 -0500102- (IBAction)shareRingID:(id)sender {
103 NSSharingServicePicker* sharingServicePicker = [[NSSharingServicePicker alloc] initWithItems:[NSArray arrayWithObject:[nicknameField stringValue]]];
104 [sharingServicePicker showRelativeToRect:[sender bounds]
105 ofView:sender
106 preferredEdge:NSMinYEdge];
Alexandre Lision745e4d62015-03-22 20:03:10 -0400107}
108
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -0400109- (IBAction)createRingAccount:(id)sender
110{
Alexandre Lision33942092016-02-03 12:19:09 -0500111 [nicknameField setHidden:YES];
Alexandre Lision745e4d62015-03-22 20:03:10 -0400112 [progressBar setHidden:NO];
Alexandre Lision34607032016-02-08 16:16:49 -0500113 [createButton setHidden:YES];
114 [progressBar startAnimation:nil];
Alexandre Lision922380d2015-09-15 10:25:17 -0400115 [indicationLabel setStringValue:NSLocalizedString(@"Just a moment...",
116 @"Indication for user")];
Alexandre Lision745e4d62015-03-22 20:03:10 -0400117
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400118 QModelIndex qIdx = AccountModel::instance().protocolModel()->selectionModel()->currentIndex();
Alexandre Lision745e4d62015-03-22 20:03:10 -0400119
120 [self setCallback];
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -0400121 if (isExpanded) {
122 // retract panel
123 [self chooseOwnCertificates:nil];
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -0400124 }
Alexandre Lision08abfac2015-09-22 12:20:51 -0400125 [showCustomCertsButton setHidden:YES];
Alexandre Lision745e4d62015-03-22 20:03:10 -0400126
Alexandre Lision08abfac2015-09-22 12:20:51 -0400127 [self performSelector:@selector(saveAccount) withObject:nil afterDelay:1];
Alexandre Lision34607032016-02-08 16:16:49 -0500128 [self registerDefaultPreferences];
Alexandre Lision41981972015-06-04 13:27:33 -0400129}
130
131/**
Alexandre Lision34607032016-02-08 16:16:49 -0500132 * Set default values for preferences
Alexandre Lision41981972015-06-04 13:27:33 -0400133 */
Alexandre Lision34607032016-02-08 16:16:49 -0500134- (void) registerDefaultPreferences
Alexandre Lision41981972015-06-04 13:27:33 -0400135{
Alexandre Lision34607032016-02-08 16:16:49 -0500136 // enable AutoStartup
Alexandre Lision41981972015-06-04 13:27:33 -0400137 LSSharedFileListRef loginItemsRef = LSSharedFileListCreate(NULL, kLSSharedFileListSessionLoginItems, NULL);
138 if (loginItemsRef == nil) return;
Alexandre Lision81c97212015-06-17 15:51:53 -0400139 CFURLRef appUrl = (__bridge CFURLRef)[NSURL fileURLWithPath:[[NSBundle mainBundle] bundlePath]];
Alexandre Lision41981972015-06-04 13:27:33 -0400140 LSSharedFileListItemRef itemRef = LSSharedFileListInsertItemURL(loginItemsRef, kLSSharedFileListItemLast, NULL, NULL, appUrl, NULL, NULL);
141 if (itemRef) CFRelease(itemRef);
Alexandre Lision34607032016-02-08 16:16:49 -0500142
143 // enable Notifications
144 [[NSUserDefaults standardUserDefaults] setBool:YES forKey:Preferences::Notifications];
Alexandre Lision745e4d62015-03-22 20:03:10 -0400145}
146
147- (void) saveAccount
148{
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -0400149 accountToCreate->setUpnpEnabled(YES); // Always active upnp
150 accountToCreate << Account::EditAction::SAVE;
Alexandre Lision745e4d62015-03-22 20:03:10 -0400151}
152
153- (void) setCallback
154{
Alexandre Lisiond3aa3ad2015-10-23 14:28:41 -0400155 QObject::connect(&AccountModel::instance(),
Alexandre Lision745e4d62015-03-22 20:03:10 -0400156 &AccountModel::accountStateChanged,
157 [=](Account *account, const Account::RegistrationState state) {
Alexandre Lision1abdf582016-02-09 14:21:19 -0500158 [self.window close];
159 AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
160 [appDelegate showMainWindow];
Alexandre Lision745e4d62015-03-22 20:03:10 -0400161 });
162}
163
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -0400164- (IBAction)chooseOwnCertificates:(NSButton*)sender
165{
166 if (isExpanded) {
167 [securityContainer removeFromSuperview];
168 NSRect frame = [self.window frame];
169 frame.size = CGSizeMake(securityContainer.frame.size.width, frame.size.height - securityContainer.frame.size.height);
170 frame.origin.y = frame.origin.y + securityContainer.frame.size.height;
171 [self.window setFrame:frame display:YES animate:YES];
172 isExpanded = false;
173 [sender setImage:[NSImage imageNamed:@"NSAddTemplate"]];
174 } else {
175 NSRect frame = [self.window frame];
176 frame.size = CGSizeMake(securityContainer.frame.size.width, frame.size.height + securityContainer.frame.size.height);
177 frame.origin.y = frame.origin.y - securityContainer.frame.size.height;
178 [self.window setFrame:frame display:YES animate:YES];
179
180 [securityContainer setFrameOrigin:CGPointMake(0, 50)];
181 [self.window.contentView addSubview:securityContainer];
182 isExpanded = true;
183 [sender setImage:[NSImage imageNamed:@"NSRemoveTemplate"]];
184 }
185}
186
187- (IBAction)goToApp:(id)sender
188{
Alexandre Lision745e4d62015-03-22 20:03:10 -0400189 [self.window close];
Alexandre Lision34607032016-02-08 16:16:49 -0500190 AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
Alexandre Lision745e4d62015-03-22 20:03:10 -0400191 [appDelegate showMainWindow];
192}
193
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -0400194#pragma mark - NSPathControl delegate methods
Alexandre Lision745e4d62015-03-22 20:03:10 -0400195
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -0400196- (IBAction)caListPathControlSingleClick:(id)sender
Alexandre Lision745e4d62015-03-22 20:03:10 -0400197{
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -0400198 NSURL* fileURL;
199 if ([sender isKindOfClass:[NSMenuItem class]]) {
200 fileURL = nil;
201 } else {
202 fileURL = [[sender clickedPathComponentCell] URL];
203 }
204 [self->caListPathControl setURL:fileURL];
205 accountToCreate->setTlsCaListCertificate([[fileURL path] UTF8String]);
206
207}
208
209- (IBAction)certificatePathControlSingleClick:(id)sender
210{
211 NSURL* fileURL;
212 if ([sender isKindOfClass:[NSMenuItem class]]) {
213 fileURL = nil;
214 } else {
215 fileURL = [[sender clickedPathComponentCell] URL];
216 }
217 [self->certificatePathControl setURL:fileURL];
218 accountToCreate->setTlsCertificate([[fileURL path] UTF8String]);
219
220 auto cert = accountToCreate->tlsCertificate();
221
222 if (cert) {
223 [pvkContainer setHidden:!cert->requirePrivateKey()];
224 } else {
225 [pvkContainer setHidden:YES];
226 }
227
228}
229
230- (IBAction)pvkFilePathControlSingleClick:(id)sender
231{
232 NSURL* fileURL;
233 if ([sender isKindOfClass:[NSMenuItem class]]) {
234 fileURL = nil;
235 } else {
236 fileURL = [[sender clickedPathComponentCell] URL];
237 }
238 [self->pvkPathControl setURL:fileURL];
239 accountToCreate->setTlsPrivateKey([[fileURL path] UTF8String]);
240
241 if(accountToCreate->tlsCertificate()->requirePrivateKeyPassword()) {
242 [passwordField setHidden:NO];
243 } else {
244 [passwordField setHidden:YES];
245 }
246}
247
248/*
249 Delegate method of NSPathControl to determine how the NSOpenPanel will look/behave.
250 */
251- (void)pathControl:(NSPathControl *)pathControl willDisplayOpenPanel:(NSOpenPanel *)openPanel
252{
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -0400253 [openPanel setAllowsMultipleSelection:NO];
254 [openPanel setCanChooseDirectories:NO];
255 [openPanel setCanChooseFiles:YES];
256 [openPanel setResolvesAliases:YES];
257
258 if(pathControl == caListPathControl) {
259 [openPanel setTitle:NSLocalizedString(@"Choose a CA list", @"Open panel title")];
260 } else if (pathControl == certificatePathControl) {
261 [openPanel setTitle:NSLocalizedString(@"Choose a certificate", @"Open panel title")];
262 } else {
263 [openPanel setTitle:NSLocalizedString(@"Choose a private key file", @"Open panel title")];
264 }
265
266 [openPanel setPrompt:NSLocalizedString(@"Choose", @"Open panel prompt for 'Choose a file'")];
267 [openPanel setDelegate:self];
268}
269
270- (void)pathControl:(NSPathControl *)pathControl willPopUpMenu:(NSMenu *)menu
271{
272 NSMenuItem *item;
273 if(pathControl == caListPathControl) {
Alexandre Lision7f01b072015-09-15 14:57:05 -0400274 item = [menu addItemWithTitle:NSLocalizedString(@"Remove value", @"Contextual menu entry")
275 action:@selector(caListPathControlSingleClick:) keyEquivalent:@""];
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -0400276 } else if (pathControl == certificatePathControl) {
Alexandre Lision7f01b072015-09-15 14:57:05 -0400277 item = [menu addItemWithTitle:NSLocalizedString(@"Remove value", @"Contextual menu entry")
278 action:@selector(certificatePathControlSingleClick:) keyEquivalent:@""];
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -0400279 } else {
Alexandre Lision7f01b072015-09-15 14:57:05 -0400280 item = [menu addItemWithTitle:NSLocalizedString(@"Remove value", @"Contextual menu entry")
281 action:@selector(pvkFilePathControlSingleClick:) keyEquivalent:@""];
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -0400282 }
283 [item setTarget:self]; // or whatever target you want
284}
285
286#pragma mark - NSOpenSavePanelDelegate delegate methods
287
288- (BOOL)panel:(id)sender validateURL:(NSURL *)url error:(NSError **)outError
289{
Alexandre Lision745e4d62015-03-22 20:03:10 -0400290 return YES;
291}
292
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -0400293#pragma mark - NSTextFieldDelegate methods
294
295-(void)controlTextDidChange:(NSNotification *)notif
Alexandre Lision745e4d62015-03-22 20:03:10 -0400296{
Alexandre Lision33942092016-02-03 12:19:09 -0500297 NSTextField* textField = [notif object];
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -0400298 if (textField.tag == PVK_PASSWORD_TAG) {
299 accountToCreate->setTlsPassword([textField.stringValue UTF8String]);
300 return;
301 }
302
303 // else it is NICKNAME_TAG field
Alexandre Lision34607032016-02-08 16:16:49 -0500304 NSString* alias = textField.stringValue;
305 if ([alias isEqualToString:@""]) {
306 alias = NSLocalizedString(@"Unknown", @"Name used when user leave field empty");
307 }
308 accountToCreate->setAlias([alias UTF8String]);
309 accountToCreate->setDisplayName([alias UTF8String]);
Alexandre Lision745e4d62015-03-22 20:03:10 -0400310}
311
Alexandre Lisionb3f7ed62015-08-17 11:53:13 -0400312# pragma NSWindowDelegate methods
Alexandre Lision745e4d62015-03-22 20:03:10 -0400313
314- (void)windowWillClose:(NSNotification *)notification
315{
Alexandre Lision34607032016-02-08 16:16:49 -0500316 AppDelegate* appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
Alexandre Lision76d59692016-01-20 18:06:05 -0500317 if ([appDelegate checkForRingAccount]) {
318 [appDelegate showMainWindow];
319 }
Alexandre Lision745e4d62015-03-22 20:03:10 -0400320}
321
322@end