source: trunk/src/org/expeditee/auth/Actions.java@ 1250

Last change on this file since 1250 was 1250, checked in by bln4, 5 years ago
File size: 31.9 KB
Line 
1package org.expeditee.auth;
2
3import java.io.File;
4import java.io.FileNotFoundException;
5import java.io.FileWriter;
6import java.io.IOException;
7import java.nio.file.Files;
8import java.nio.file.Path;
9import java.nio.file.Paths;
10import java.nio.file.StandardCopyOption;
11import java.security.InvalidKeyException;
12import java.security.KeyFactory;
13import java.security.KeyPair;
14import java.security.KeyPairGenerator;
15import java.security.KeyStoreException;
16import java.security.NoSuchAlgorithmException;
17import java.security.PrivateKey;
18import java.security.PublicKey;
19import java.security.cert.CertificateException;
20import java.security.spec.InvalidKeySpecException;
21import java.security.spec.PKCS8EncodedKeySpec;
22import java.sql.Connection;
23import java.sql.DriverManager;
24import java.sql.SQLException;
25import java.sql.Statement;
26import java.util.Base64;
27import java.util.Collection;
28import java.util.HashMap;
29import java.util.List;
30import java.util.Map;
31import java.util.Optional;
32import java.util.Random;
33import java.util.stream.Collectors;
34
35import javax.crypto.BadPaddingException;
36import javax.crypto.IllegalBlockSizeException;
37import javax.crypto.NoSuchPaddingException;
38import javax.crypto.SecretKey;
39import javax.crypto.spec.SecretKeySpec;
40
41import org.apollo.io.AudioPathManager;
42import org.expeditee.agents.ExistingFramesetException;
43import org.expeditee.agents.InvalidFramesetNameException;
44import org.expeditee.auth.Mail.MailEntry;
45import org.expeditee.auth.gui.MailBay;
46import org.expeditee.auth.tags.AuthenticationTag;
47import org.expeditee.auth.tags.Constants;
48import org.expeditee.core.Colour;
49import org.expeditee.gui.DisplayController;
50import org.expeditee.gui.Frame;
51import org.expeditee.gui.FrameIO;
52import org.expeditee.gui.MessageBay;
53import org.expeditee.items.Item;
54import org.expeditee.items.PermissionPair;
55import org.expeditee.items.Text;
56import org.expeditee.items.UserAppliedPermission;
57import org.expeditee.setting.GenericSetting;
58import org.expeditee.setting.Setting;
59import org.expeditee.setting.TextSetting;
60import org.expeditee.settings.Settings;
61import org.expeditee.settings.UserSettings;
62import org.expeditee.settings.folders.FolderSettings;
63import org.expeditee.settings.identity.secrets.KeyList;
64import org.ngikm.cryptography.CryptographyConstants;
65
66public class Actions implements CryptographyConstants {
67
68 public static void SendTestMessage(String colleagueName) throws InvalidKeySpecException, NoSuchAlgorithmException, FileNotFoundException, KeyStoreException, CertificateException, ClassNotFoundException, IOException, SQLException {
69 String time = org.expeditee.stats.Formatter.getDateTime();
70 String sender = UserSettings.UserName.get();
71 String topic = "Test Message";
72 String message = "This is a test message.";
73 Map<String, String> options = new HashMap<String, String>();
74 options.put("Neat", "Beep");
75 MailEntry mail = new MailEntry(time, sender, colleagueName, topic, message, options);
76 PublicKey publicKey = Authenticator.getInstance().getPublicKey(colleagueName);
77 Path outbox = Paths.get(FrameIO.PROFILE_PATH).resolve(sender).resolve(sender + "-credentials");
78 Mail.sendMail(mail, publicKey, outbox);
79 }
80
81 /**
82 * Display Expeditee Mail
83 * @throws IOException
84 * @throws SQLException
85 * @throws ClassNotFoundException
86 * @throws CertificateException
87 * @throws NoSuchAlgorithmException
88 * @throws FileNotFoundException
89 * @throws KeyStoreException
90 */
91 public static void MailMode() throws KeyStoreException, FileNotFoundException, NoSuchAlgorithmException, CertificateException, ClassNotFoundException, SQLException, IOException {
92 if (!DisplayController.isMailMode()) {
93 Mail.clear();
94 Authenticator.getInstance().loadMailDatabase();
95 }
96 DisplayController.ToggleMailMode();
97 }
98
99 /**
100 * Action used to navigate the authorised user back to their desktop.
101 */
102 public static void AuthGoToDesktop() {
103 DisplayController.setCurrentFrame(FrameIO.LoadFrame(UserSettings.HomeFrame.get()), true);
104 }
105
106 /**
107 * Action used to created a new user account.
108 * Attempts to use content from text items on frame, will default to java properties if they cannot be found.
109 * Will fail if it cannot find content from text items on frame and all required java properties are not present.
110 * @throws SQLException
111 * @throws IOException
112 * @throws ExistingFramesetException
113 * @throws InvalidFramesetNameException
114 * @throws ClassNotFoundException
115 * @throws FileNotFoundException
116 * @throws CertificateException
117 * @throws NoSuchAlgorithmException
118 * @throws KeyStoreException
119 * @throws BadPaddingException
120 * @throws IllegalBlockSizeException
121 * @throws NoSuchPaddingException
122 * @throws InvalidKeySpecException
123 * @throws InvalidKeyException
124 * @throws Exception
125 */
126 public static void AuthCreateAccount() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, ClassNotFoundException, InvalidFramesetNameException, ExistingFramesetException, IOException, SQLException, InvalidKeyException, InvalidKeySpecException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
127 Collection<Text> textItems = DisplayController.getCurrentFrame().getTextItems();
128 Optional<Map<AuthenticationTag, String>> userdata =
129 AuthenticationTag.fetchUserData(textItems, false,
130 AuthenticationTag.Username,
131 AuthenticationTag.Password,
132 AuthenticationTag.PasswordAgain,
133 AuthenticationTag.Email,
134 AuthenticationTag.EmailAgain);
135
136 if (userdata.isPresent()) {
137 Map<AuthenticationTag, String> userData = userdata.get();
138
139 // A profile already existing with 'username' means an account cannot be created with that username.
140 if (FrameIO.LoadProfile(userData.get(AuthenticationTag.Username)) != null) {
141 MessageBay.errorMessage(Constants.ERROR_PROFILE_NAME_PREEXISTS);
142 return;
143 }
144
145 // The chosen username must be a valid frameset name.
146 if (!FrameIO.isValidFramesetName(userData.get(AuthenticationTag.Username))) {
147 MessageBay.errorMessage(Constants.ERROR_INVALID_USERNAME);
148 return;
149 }
150
151 // The passwords provided must match
152 if (userData.get(AuthenticationTag.Password).compareTo(userData.get(AuthenticationTag.PasswordAgain)) != 0) {
153 MessageBay.errorMessage(Constants.ERROR_MISMATCH_PASSWORDS);
154 return;
155 }
156
157 // The emails provided must match
158 if (userData.get(AuthenticationTag.Email).compareTo(userData.get(AuthenticationTag.EmailAgain)) != 0) {
159 MessageBay.errorMessage(Constants.ERROR_MISMATCH_EMAILS);
160 return;
161 }
162
163 createAccount(userData);
164 login(userData);
165 Authenticator.Authenticated = true;
166 } else {
167 MessageBay.errorMessage(Constants.ERROR_INSUFFICIENT_INFORMATION_PROVIDED);
168 }
169 }
170
171 /**
172 * Action used to start authentication as a specified user.
173 * Attempts to use content from text items on frame, will default to java properties if they cannot be found.
174 * Will fail if it cannot find content from text items on frame and all required java properties are not present.
175 * @throws Exception
176 */
177 public static void AuthLogin() throws Exception {
178 final Collection<Text> textItems = DisplayController.getCurrentFrame().getTextItems();
179 final Optional<Map<AuthenticationTag, String>> userdata = AuthenticationTag.fetchUserData(textItems, false, AuthenticationTag.Username, AuthenticationTag.Password);
180 if (userdata.isPresent()) {
181 login(userdata.get());
182 Authenticator.Authenticated = true;
183 }
184 else {
185 MessageBay.errorMessage(Constants.ERROR_INSUFFICIENT_INFORMATION_PROVIDED);
186 }
187 }
188
189 /**
190 * Action used to change the currently authenticated users password.
191 * Attempts to use content from text items on frame, will default to java properties if they cannot be found.
192 * Will fail if it cannot find content from text items on frame and all required java properties are not present.
193 * Will fail if no user is currently logged in.
194 * @throws IOException
195 * @throws CertificateException
196 * @throws FileNotFoundException
197 * @throws KeyStoreException
198 * @throws NoSuchAlgorithmException
199 * @throws SQLException
200 * @throws ClassNotFoundException
201 */
202 public static void AuthChangePassword() throws NoSuchAlgorithmException, KeyStoreException, FileNotFoundException, CertificateException, IOException, ClassNotFoundException, SQLException {
203 final Collection<Text> textItems = DisplayController.getCurrentFrame().getTextItems();
204
205 if (!Authenticator.Authenticated) {
206 MessageBay.errorMessage(Constants.ERROR_MUST_BE_LOGGED_IN);
207 } else {
208 final Optional<Map<AuthenticationTag, String>> userdata = AuthenticationTag.fetchUserData(textItems, false, AuthenticationTag.Password, AuthenticationTag.NewPassword, AuthenticationTag.NewPasswordAgain);
209 if (userdata.isPresent()) {
210 final Map<AuthenticationTag, String> userData = userdata.get();
211 if (userData.get(AuthenticationTag.NewPassword).compareTo(userData.get(AuthenticationTag.NewPasswordAgain)) != 0) {
212 MessageBay.errorMessage(Constants.ERROR_MISMATCH_PASSWORDS);
213 } else {
214 userData.put(AuthenticationTag.Username, UserSettings.UserName.get());
215 changePassword(userData);
216 }
217 } else {
218 MessageBay.errorMessage(Constants.ERROR_INSUFFICIENT_INFORMATION_PROVIDED);
219 }
220 }
221 }
222
223 public static void AuthGotoAccountManagement() {
224 if (Authenticator.Authenticated) {
225 DisplayController.setCurrentFrame(FrameIO.LoadFrame(Constants.FRAME_MULTIUSER1), false);
226 } else {
227 DisplayController.setCurrentFrame(FrameIO.LoadFrame(Constants.FRAME_AUTHENTICATION1), false);
228 }
229 }
230
231 public static void AuthShareFrameset() throws IOException {
232 Collection<Text> textItems = DisplayController.getCurrentFrame().getTextItems();
233
234 Optional<Map<AuthenticationTag, String>> userdata = AuthenticationTag.fetchUserData(textItems, false, AuthenticationTag.Frameset);
235 if (userdata.isPresent()) {
236 Map<AuthenticationTag, String> userData = userdata.get();
237 FrameIO.SuspendCache();
238 Frame toShare = FrameIO.LoadFrame(userData.get(AuthenticationTag.Frameset) + 1);
239 FrameIO.ResumeCache();
240
241 if (toShare == null) {
242 MessageBay.errorMessage(Constants.ERROR_INSUFFICIENT_INFORMATION);
243 return;
244 }
245
246 shareFrameset(toShare);
247 }
248 }
249
250 /**
251 * Navigation action for progressing the process of recruiting colleagues to assist in password recovery.
252 * Hides certain content that AuthSubmitPWCollegues goes onto show if it does not fail.
253 */
254 public static void AuthGotoColleagueSubmissionFrame() {
255 Frame destination = FrameIO.LoadFrame(Constants.FRAME_COLLEAGUE_SUBMISSION_FRAME);
256 DisplayController.setCurrentFrame(destination, true);
257 Collection<Item> toHide = getByData(destination, Constants.DATA_SHOW_ON_PROGRESS);
258 for (Item i: toHide) {
259 i.setVisible(false);
260 }
261 }
262
263 /**
264 * Action used to start the process of formalising the password recovery process.
265 * @throws SQLException
266 * @throws IOException
267 * @throws ClassNotFoundException
268 * @throws CertificateException
269 * @throws NoSuchAlgorithmException
270 * @throws FileNotFoundException
271 * @throws KeyStoreException
272 * @throws InvalidKeySpecException
273 */
274 public static void AuthSubmitPWColleagues() throws InvalidKeySpecException, NoSuchAlgorithmException, KeyStoreException, FileNotFoundException, CertificateException, ClassNotFoundException, IOException, SQLException {
275 Frame currentFrame = DisplayController.getCurrentFrame();
276 Collection<Text> textItems = currentFrame.getTextItems();
277
278 if (!Authenticator.Authenticated) {
279 MessageBay.errorMessage(Constants.ERROR_MUST_BE_LOGGED_IN);
280 return;
281 }
282
283 Optional<Map<AuthenticationTag, String>> userdata = AuthenticationTag.fetchUserData(textItems, false, AuthenticationTag.ColleagueOne, AuthenticationTag.ColleagueTwo);
284 if (userdata.isPresent()) {
285 Map<AuthenticationTag, String> userData = userdata.get();
286 String colleagueOne = userData.get(AuthenticationTag.ColleagueOne);
287 Path colleagueOnePath = Paths.get(FrameIO.CONTACTS_PATH).resolve(colleagueOne + "-credentials");
288 String colleagueTwo = userData.get(AuthenticationTag.ColleagueTwo);
289 Path colleagueTwoPath = Paths.get(FrameIO.CONTACTS_PATH).resolve(colleagueTwo + "-credentials");
290 if (!colleagueOnePath.toFile().exists()) {
291 MessageBay.errorMessage("Your nominated colleague: " + colleagueOne + " must exist in your contacts.");
292 } else if (!colleagueTwoPath.toFile().exists()) {
293 MessageBay.errorMessage("Your nominated colleague: " + colleagueTwo + " must exist in your contacts.");
294 } else {
295 userData.put(AuthenticationTag.Username, UserSettings.UserName.get());
296 boolean success = submitPWColleagues(userData);
297 if (success) {
298 Collection<Item> toShow = getByData(currentFrame, Constants.DATA_SHOW_ON_PROGRESS);
299 for (Item i: toShow) {
300 i.setVisible(true);
301 }
302 currentFrame.change();
303 MessageBay.displayMessage("-------Messages sent-------");
304 }
305 FrameIO.SaveFrame(currentFrame);
306 DisplayController.requestRefresh(false);
307 }
308 }
309 }
310
311// public static void AuthSetupPasswordRecovery() throws KeyStoreException, FileNotFoundException, NoSuchAlgorithmException, CertificateException, ClassNotFoundException, IOException, SQLException, UnrecoverableEntryException {
312// if (!UserSettings.Authenticated.get()) {
313// MessageBay.errorMessage("You must be logged in to perform this action.");
314// } else if (!Authenticator.getInstance().hasRegisteredEmail(UserSettings.UserName.get())) {
315// Frame registerEmailFrame = FrameIO.LoadFrame("authentication4");
316// DisplayController.setCurrentFrame(registerEmailFrame, true);
317// } else if (!Authenticator.getInstance().hasRequestedColleagues(UserSettings.UserName.get()) && Authenticator.getInstance().getColleagues(UserSettings.UserName.get()) == null) {
318// Frame submitColleaguesFrame = FrameIO.LoadFrame("authentication5");
319// DisplayController.setCurrentFrame(submitColleaguesFrame, true);
320// } else if (Authenticator.getInstance().hasRequestedColleagues(UserSettings.UserName.get()) && Authenticator.getInstance().getColleagues(UserSettings.UserName.get()) == null) {
321// MessageBay.displayMessage("You have already nominated two colleagues to assist you in the process of password recovery and are awaiting their response."
322// + " You will be alerted on Expeditee startup when they have both responded.");
323// } else if (Authenticator.getInstance().getColleagues(UserSettings.UserName.get()) != null) {
324// MessageBay.displayMessage("You have completed the Password Recovery Setup process, there is nothing more to do here.");
325// }
326// }
327
328 public static void AuthConfirmPasswordColleagueRelationship(String colleagueName) {
329
330 }
331
332 public static void AuthDenyPasswordColleagueRelationship(String colleagueName) throws InvalidKeySpecException, NoSuchAlgorithmException,
333 KeyStoreException, FileNotFoundException, CertificateException, ClassNotFoundException, IOException, SQLException {
334 denyPasswordColleagueRelationship(colleagueName);
335 }
336
337 public static void AuthClearPWColleaguesNominated() {
338
339 }
340
341 /**
342 * Create a user account using the specified information in userdata. Creates and stores user keys.
343 * @param userdata Should contain username, password and email.
344 */
345 private static void createAccount(Map<AuthenticationTag, String> userdata) throws InvalidFramesetNameException, ExistingFramesetException,
346 KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, ClassNotFoundException, IOException, SQLException {
347
348 // Track progress
349 String message = "Creating new user account...";
350 //Progress progress = MessageBay.displayProgress(message);
351
352 // Extract user details
353 String username = userdata.get(AuthenticationTag.Username);
354 String password = userdata.get(AuthenticationTag.Password);
355 String email = userdata.get(AuthenticationTag.Email);
356
357 System.out.println(message + "Generating Keys.");
358
359 // Generate keys
360 // Personal key
361 Random rand = new Random();
362 byte[] keyBytes = new byte[16];
363 rand.nextBytes(keyBytes);
364 SecretKey key = new SecretKeySpec(keyBytes, SymmetricAlgorithm);
365 Authenticator.getInstance().putKey(username, password, key);
366 String personalKey = Base64.getEncoder().encodeToString(key.getEncoded());
367 // Public and private keys
368 KeyPairGenerator keyGen = KeyPairGenerator.getInstance(AsymmetricAlgorithm);
369 keyGen.initialize(1024);
370 KeyPair keyPair = keyGen.generateKeyPair();
371 String publicKey = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());
372 String privateKey = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded());
373
374 System.out.println(message + "Creating Profile Frameset.");
375
376 // Update in memory settings
377 System.setProperty("user.name", username);
378 UserSettings.UserName.set(username);
379 UserSettings.ProfileName.set(username);
380 UserSettings.setupDefaultFolders();
381
382 // Establish the initial settings for the created user.
383 Map<String, Setting> initialSettings = new HashMap<String, Setting>();
384 initialSettings.put(Constants.SETTINGS_AUTH_SECRETS_PERSONAL_KEY, constructTextSetting(Constants.TOOLTIP_SETTING_PERSONAL_KEY, "PersonalKey", personalKey));
385 initialSettings.put(Constants.SETTINGS_AUTH_SECRETS_PRIVATE_KEY, constructTextSetting(Constants.TOOLTIP_SETTING_PRIVATE_KEY, "PrivateKey", privateKey));
386 initialSettings.put(Constants.SETTINGS_AUTH_PUBLIC_KEY, constructTextSetting(Constants.TOOLTIP_SETTING_PUBLIC_KEY, "PublicKey", publicKey));
387 initialSettings.put(Constants.SETTINGS_AUTH_EMAIL, constructGenericSetting(String.class, Constants.TOOLTIP_SETTING_EMAIL, "Email", email, username));
388 initialSettings.put(Constants.SETTINGS_USER_SETTINGS_USER_NAME, constructGenericSetting(String.class, Constants.LABEL_USERNAME, Constants.LABEL_USERNAME, username, username));
389 initialSettings.put(Constants.SETTINGS_USER_SETTINGS_PROFILE_NAME, constructGenericSetting(String.class, Constants.LABEL_PROFILENAME, Constants.LABEL_PROFILENAME, username, username));
390 initialSettings.put("org.expeditee.gui.folders.FolderSettings.FrameDirs", FolderSettings.FrameDirs);
391 initialSettings.put("org.expeditee.gui.folders.FolderSettings.ImageDirs", FolderSettings.ImageDirs);
392 initialSettings.put("org.expeditee.gui.folders.FolderSettings.AudioDirs", FolderSettings.AudioDirs);
393
394 // Create users profile
395 Frame profile = FrameIO.CreateNewProfile(username, initialSettings);
396 int lastNumber = FrameIO.getLastNumber(profile.getFramesetName());
397 for (int i = 1; i <= lastNumber; i++) {
398 Frame f = FrameIO.LoadFrame(profile.getFramesetName() + i);
399 Text titleItem = f.getTitleItem();
400 if (i == 1 && titleItem != null) {
401 titleItem.delete();
402 f.setBackgroundColor(new Colour(1, 1, 0.39f));
403 }
404 f.setOwner(username);
405 f.getAllItems().stream().forEach(item -> item.setOwner(username));
406 f.setChanged(true);
407 f.setEncryptionLabel("Profile");
408 Collection<Item> secretsLink = getByContent(f, "Secrets");
409 Collection<Item> publicKeyItem = getByContent(f, "PublicKey");
410 if (!secretsLink.isEmpty() && !publicKeyItem.isEmpty()) {
411 //Then we are on credentials frame
412 secretsLink.forEach(text -> text.setPermission(new PermissionPair(UserAppliedPermission.full, UserAppliedPermission.none)));
413 f.addToData("MultiuserCredentials");
414 }
415 Text backupPersonalKey = KeyList.PersonalKey.get();
416 Text tempPersonalKey = KeyList.PersonalKey.generateText();
417 tempPersonalKey.setData(personalKey);
418 KeyList.PersonalKey.setSetting(tempPersonalKey);
419 FrameIO.SaveFrame(f);
420 KeyList.PersonalKey.setSetting(backupPersonalKey);
421 }
422
423 // Create credentials
424 File credentialsDir = new File(profile.getFramesetPath() + username + "-credentials");
425 credentialsDir.mkdir();
426 // credentials.inf file.
427 String credentialsPath = credentialsDir.getAbsolutePath() + File.separator + "credentials.inf";
428 File credentialsFile = new File(credentialsPath);
429 credentialsFile.createNewFile();
430 FileWriter out = new FileWriter(credentialsFile);
431 out.write(Authenticator.CREDENTIALS_FRAME + ".exp");
432 out.flush();
433 out.close();
434 // outbox
435 Connection c = DriverManager.getConnection("jdbc:sqlite:" + credentialsDir.getAbsolutePath() + File.separator + "expmail.db");
436 Statement createTable = c.createStatement();
437 String sql = "CREATE TABLE EXPMAIL (" +
438 "TIME TEXT NOT NULL, " +
439 "SND TEXT NOT NULL, " +
440 "REC TEXT NOT NULL, " +
441 "MSG TEXT NOT NULL, " +
442 "MSG2 TEXT NOT NULL, " +
443 "OPTS ARRAY NOT NULL, " +
444 "OPTSVAL ARRAY NOT NULL)";
445 createTable.executeUpdate(sql);
446 createTable.close();
447 c.close();
448
449 System.out.println(message + "Creating Individual Space.");
450
451 // Copy private resources to personal area
452 Path personalResources = FrameIO.setupPersonalResources(username);
453
454 File contactsDir = new File(personalResources.resolve("contacts").toAbsolutePath().toString());
455 contactsDir.mkdir();
456
457 System.err.println("**** Hardwired call in Apollo's AuthioPathManager");
458 AudioPathManager.activateAndScanAudioDir(); // ****
459
460 System.out.println(message + "Done.");
461 }
462
463
464
465 /*
466 * Function used to authenticate as a specified user (via function arguments).
467 */
468 private static void login(Map<AuthenticationTag, String> userdata) throws NoSuchAlgorithmException, KeyStoreException, FileNotFoundException, CertificateException, ClassNotFoundException, IOException, SQLException, InvalidKeySpecException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
469 String username = userdata.get(AuthenticationTag.Username);
470 String password = userdata.get(AuthenticationTag.Password);
471
472 SecretKey personalKey = Authenticator.getInstance().getSecretKey(username, password);
473 if (personalKey == null) {
474 // Incorrect username and password
475 MessageBay.errorMessage("The username + password combination was incorrect.");
476 return;
477 }
478
479 // **** DB
480 // Have not been able to test the following as auth + login not currently working
481 // 'out of the box'
482
483 // Currently causing a concurrent modification setting related to InputManager.distributeGesture (preGesture)
484
485 // initialize Apollo
486// EcosystemManager.getMiscManager().runOnGIOThread(new BlockingRunnable() {
487// public void execute() {
488// ApolloSystem.initialize();
489// }
490// });
491
492
493 // Load in and cache the profile frame using the personal key fetched from keystore.
494 // Reset the personal key once finished so that setting parsing can correctly set it.
495 FrameIO.ClearCache();
496 Text personalKeyText = KeyList.PersonalKey.generateText();
497 personalKeyText.setData(Base64.getEncoder().encodeToString(personalKey.getEncoded()));
498 KeyList.PersonalKey.setSetting(personalKeyText);
499 Frame oneFrame = FrameIO.LoadProfile(username);
500 for (int i = 1; i <= FrameIO.getLastNumber(username); i++) {
501 Frame f = FrameIO.LoadFrame(oneFrame.getFramesetName() + i);
502 if (f.getData() != null && f.getData().contains("MultiuserCredentials")) {
503 Authenticator.CREDENTIALS_FRAME = f.getNumber();
504 }
505 }
506
507 // Parse the settings frame to update the settings datastructure.
508 Text fakeLink = new Text("settings");
509 fakeLink.setLink(oneFrame.getFramesetName() + "2");
510 Settings.parseSettings(fakeLink);
511
512 // Update default folders.
513 UserSettings.setupDefaultFolders();
514
515 // Check mail
516 MailBay.clear();
517 Authenticator.getInstance().loadMailDatabase();
518 Text keyItem = org.expeditee.settings.identity.secrets.KeyList.PrivateKey.get();
519 if (keyItem.getData() != null) {
520 String keyEncoded = keyItem.getData().get(0);
521 byte[] keyBytes = Base64.getDecoder().decode(keyEncoded);
522 PrivateKey key = KeyFactory.getInstance(AsymmetricAlgorithm).generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
523 List<MailEntry> mailForLoggingInUser = Mail.getEntries(UserSettings.UserName.get(), key);
524 for (MailEntry mail: mailForLoggingInUser) {
525 MailBay.addMessage(mail.timestamp, mail.message, mail.message2, mail.options);
526 }
527 }
528
529 Collection<Item> usernameFields = getByData(FrameIO.LoadFrame(Constants.FRAME_MULTIUSER1), "txtUsername");
530 usernameFields.forEach(usernameField -> usernameField.setText(username));
531
532 Frame homeFrame = FrameIO.LoadFrame("home1");
533 DisplayController.setCurrentFrame(homeFrame == null ? oneFrame : homeFrame, false);
534 }
535
536 /*
537 * Function to share a specified frameset.
538 * Currently, this moves the frameset to the 'Shared By Me' directory and then relies on the user to use Google Drive functionality to share it appropriately.
539 */
540 private static void shareFrameset(Frame toShare) throws IOException {
541 File destinationDir = new File(FrameIO.SHARED_FRAMESETS_PATH + File.separator + toShare.getFramesetName());
542 File sourceDir = new File(toShare.getFramesetPath());
543
544 if (destinationDir.exists()) {
545 MessageBay.errorMessage("A frameset by this name already exists.");
546 return;
547 }
548
549 destinationDir.mkdir();
550 List<Path> files = Files.walk(sourceDir.toPath()).collect(Collectors.toList());
551 Files.move(files.get(0), destinationDir.toPath(), StandardCopyOption.ATOMIC_MOVE);
552
553 MessageBay.displayMessage("The frameset " + toShare.getFramesetName() + " has been moved to " + destinationDir + ". Google Drive functionality can now be used to share it with colleagues.");
554 }
555
556 private static void denyPasswordColleagueRelationship(String colleagueName) throws InvalidKeySpecException, NoSuchAlgorithmException, KeyStoreException, FileNotFoundException, CertificateException, ClassNotFoundException, IOException, SQLException {
557 String time = org.expeditee.stats.Formatter.getDateTime();
558 String sender = UserSettings.UserName.get();
559 String message = "You have received a reply from " + sender + " reguarding your request for assistance.";
560 String message2 = "Unfortunately " + sender + " has indicated that they are unable to help you with your potential password recovery.";
561 Map<String, String> options = new HashMap<String, String>();
562 options.put("Clear Preview Colleague Nominations", "AuthClearPWColleaguesNominated");
563 MailEntry mail = new MailEntry(time, sender, colleagueName, message, message2, options);
564 Mail.sendMail(mail, Authenticator.getInstance().getPublicKey(colleagueName), Paths.get(FrameIO.PROFILE_PATH).resolve(sender).resolve(sender + "-credentials"));
565 }
566
567 private static boolean submitPWColleagues(Map<AuthenticationTag, String> userData) throws InvalidKeySpecException, NoSuchAlgorithmException, KeyStoreException, FileNotFoundException, CertificateException, ClassNotFoundException, IOException, SQLException {
568 String colleagueOne = userData.get(AuthenticationTag.ColleagueOne);
569 String colleagueTwo = userData.get(AuthenticationTag.ColleagueTwo);
570 PublicKey colleagueOneKey = Authenticator.getInstance().getPublicKey(colleagueOne);
571 PublicKey colleagueTwoKey = Authenticator.getInstance().getPublicKey(colleagueTwo);
572 if (colleagueOneKey == null) {
573 MessageBay.errorMessage("Unable to get public key for colleague: " + colleagueOne);
574 return false;
575 } else if (colleagueTwoKey == null) {
576 MessageBay.errorMessage("Unable to get public key for colleague: " + colleagueTwo);
577 return false;
578 } else {
579 String time = org.expeditee.stats.Formatter.getDateTime();
580 String sender = userData.get(AuthenticationTag.Username);
581 String topic = "You have received a request for cooperation from your colleague " + sender;
582 String message = "Should " + sender + " forget their password, they would like your help recoverying it.";
583 Map<String, String> arguments = new HashMap<String, String>();
584 arguments.put("I agree to assist " + sender + " if they loose access to their account.", "AuthConfirmPasswordColleagueRelationship " + sender);
585 arguments.put("I wish to excuse myself from this responsibility.", "AuthDenyPasswordColleagueRelationship " + sender);
586 MailEntry mail = new MailEntry(time, sender, colleagueOne, topic, message, arguments);
587 Path outbox = Paths.get(FrameIO.PROFILE_PATH).resolve(sender).resolve(sender + "-credentials");
588 Mail.sendMail(mail, colleagueOneKey, outbox);
589 mail = new MailEntry(time, sender, colleagueTwo, topic, message, arguments);
590 Mail.sendMail(mail, colleagueTwoKey, outbox);
591 Authenticator.getInstance().markRequestedColleagues(UserSettings.UserName.get());
592 return true;
593 }
594 }
595
596
597 private static TextSetting constructTextSetting(String tooltip, String text, String data) {
598 return new TextSetting(tooltip, text) {
599 @Override
600 public Text generateText() {
601 Text t = new Text(text);
602 t.setData(data);
603 return t;
604 }
605 };
606 }
607
608 private static <T> GenericSetting<T> constructGenericSetting(Class<T> type, String tooltip, String name, T value, String frameset) {
609 return new GenericSetting<T>(type, tooltip, name, value) {
610 @Override
611 public Text generateRepresentation(String name, String frameset) {
612 Text t = new Text(name + ": " + value);
613 return t;
614 }
615 };
616 }
617
618 /*
619 * Changes the recorded password for a user in the key store.
620 */
621 private static void changePassword(final Map<AuthenticationTag, String> userdata) throws NoSuchAlgorithmException, KeyStoreException, FileNotFoundException, CertificateException, IOException, ClassNotFoundException, SQLException {
622 final String username = userdata.get(AuthenticationTag.Username);
623 final String password = userdata.get(AuthenticationTag.Password);
624 final String newpassword = userdata.get(AuthenticationTag.NewPassword);
625
626 final SecretKey key = Authenticator.getInstance().getSecretKey(username, password);
627 if (key == null) {
628 MessageBay.errorMessage("The username + existing password combination was incorrect.");
629 } else {
630 Authenticator.getInstance().putKey(username, newpassword, key);
631 MessageBay.displayMessage("Password changed successfully.");
632 }
633 }
634
635// // establish properties
636// final String from = "[email protected]";
637// final Properties properties = System.getProperties();
638//
639// properties.setProperty("mail.transport.protocol", "smtp");
640// properties.setProperty("mail.smtp.host", "smtp.gmail.com");
641// properties.setProperty("mail.smtp.port", "465");
642// properties.setProperty("mail.smtp.starttls.enable", "true");
643// properties.setProperty("mail.smtp.auth", "true");
644// properties.setProperty("mail.smtp.debug", "true");
645// properties.setProperty("mail.smtp.auth", "true");
646// properties.setProperty("mail.smtp.socketFactory.port", "465");
647// properties.setProperty("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
648// properties.setProperty("mail.smtp.socketFactory.fallback", "false");
649//
650// final Session session = Session.getDefaultInstance(properties, new javax.mail.Authenticator() {
651// @Override
652// protected PasswordAuthentication getPasswordAuthentication() {
653// return new PasswordAuthentication("noreply.expeditee", "intergalacticnumber");
654// };
655// });
656
657// // construct email message
658// final MimeMessage message = new MimeMessage(session);
659// message.setFrom(new InternetAddress(from));
660// message.addRecipient(Message.RecipientType.TO, new InternetAddress(email));
661// message.setSubject("Expeditee Password Recovery");
662// message.setText(intergalacticNumber);
663//
664// // send email message
665// Transport.send(message);
666
667
668 public static void TickBox(final Text item) {
669 if (item.getBackgroundColor() != Colour.RED) {
670 item.setBackgroundColor(Colour.RED);
671 } else {
672 item.setBackgroundColor(Colour.GREEN);
673 }
674 }
675
676 /*
677 * Gets all items on a specified frame that contain the specified data.
678 */
679 public static Collection<Item> getByData(final Frame frame, final String data) {
680 final Collection<Item> allItems = frame.getAllItems();
681 allItems.removeIf(i -> i.getData() == null || !i.hasData(data));
682 return allItems;
683 }
684
685 public static Collection<Item> getByContent(final Frame frame, final String content) {
686 final Collection<Item> allItems = frame.getAllItems();
687 allItems.removeIf(i -> i.getText().compareTo(content) != 0);
688 return allItems;
689 }
690}
Note: See TracBrowser for help on using the repository browser.