Changeset 1243 for trunk


Ignore:
Timestamp:
03/15/19 16:51:32 (5 years ago)
Author:
bln4
Message:

Alterations to how mail works to work better in a cloud environment.
General code tidying and updating to work with larger changes happening to Expeditee.

Location:
trunk/src/org/expeditee/auth
Files:
3 added
6 edited
1 moved

Legend:

Unmodified
Added
Removed
  • trunk/src/org/expeditee/auth/Actions.java

    r1231 r1243  
    11package org.expeditee.auth;
    22
     3import java.io.File;
    34import java.io.FileNotFoundException;
     5import java.io.FileWriter;
    46import 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;
    512import java.security.KeyFactory;
    613import java.security.KeyPair;
     
    1017import java.security.PrivateKey;
    1118import java.security.PublicKey;
    12 import java.security.UnrecoverableEntryException;
    1319import java.security.cert.CertificateException;
    1420import java.security.spec.InvalidKeySpecException;
    1521import java.security.spec.PKCS8EncodedKeySpec;
     22import java.sql.Connection;
     23import java.sql.DriverManager;
    1624import java.sql.SQLException;
     25import java.sql.Statement;
    1726import java.util.Base64;
    1827import java.util.Collection;
     
    2231import java.util.Optional;
    2332import java.util.Random;
    24 
     33import java.util.stream.Collectors;
     34
     35import javax.crypto.BadPaddingException;
     36import javax.crypto.IllegalBlockSizeException;
     37import javax.crypto.NoSuchPaddingException;
    2538import javax.crypto.SecretKey;
    2639import javax.crypto.spec.SecretKeySpec;
    2740
     41import org.expeditee.agents.ExistingFramesetException;
     42import org.expeditee.agents.InvalidFramesetNameException;
    2843import org.expeditee.auth.Mail.MailEntry;
    2944import org.expeditee.auth.gui.MailBay;
     45import org.expeditee.auth.tags.AuthenticationTag;
     46import org.expeditee.auth.tags.Constants;
    3047import org.expeditee.core.Colour;
    3148import org.expeditee.gui.DisplayController;
     
    3451import org.expeditee.gui.MessageBay;
    3552import org.expeditee.items.Item;
     53import org.expeditee.items.PermissionPair;
    3654import org.expeditee.items.Text;
     55import org.expeditee.items.UserAppliedPermission;
     56import org.expeditee.setting.GenericSetting;
     57import org.expeditee.setting.Setting;
     58import org.expeditee.setting.TextSetting;
     59import org.expeditee.settings.Settings;
    3760import org.expeditee.settings.UserSettings;
     61import org.expeditee.settings.folders.FolderSettings;
     62import org.expeditee.settings.identity.secrets.KeyList;
    3863import org.ngikm.cryptography.CryptographyConstants;
    3964
    4065public class Actions implements CryptographyConstants {
     66               
     67        public static void SendTestMessage(String colleagueName) throws InvalidKeySpecException, NoSuchAlgorithmException, FileNotFoundException, KeyStoreException, CertificateException, ClassNotFoundException, IOException, SQLException {
     68                String time = org.expeditee.stats.Formatter.getDateTime();
     69                String sender = UserSettings.UserName.get();
     70                String topic = "Test Message";
     71                String message = "This is a test message.";
     72                Map<String, String> options = new HashMap<String, String>();
     73                options.put("Neat", "Beep");
     74                MailEntry mail = new MailEntry(time, sender, colleagueName, topic, message, options);
     75                PublicKey publicKey = Authenticator.getInstance().getPublicKey(colleagueName);
     76                Path outbox = Paths.get(FrameIO.PROFILE_PATH).resolve(sender).resolve(sender + "-credentials");
     77                Mail.sendMail(mail, publicKey, outbox);
     78        }
    4179       
    4280        /**
     
    66104       
    67105        /**
    68          * Log out of current user and navigate to authentication1
    69          */
    70         public static void AuthLogout() {
    71                 UserSettings.Authenticated.set(false);
    72                 setUser(System.getProperty("user.name"));
    73                 DisplayController.setCurrentFrame(FrameIO.LoadFrame("authentication1"), true);
    74         }
    75        
    76         /**
    77106         * Action used to created a new user account.
    78107         * Attempts to use content from text items on frame, will default to java properties if they cannot be found.
    79108         * Will fail if it cannot find content from text items on frame and all required java properties are not present.
     109         * @throws SQLException
     110         * @throws IOException
     111         * @throws ExistingFramesetException
     112         * @throws InvalidFramesetNameException
     113         * @throws ClassNotFoundException
     114         * @throws FileNotFoundException
     115         * @throws CertificateException
     116         * @throws NoSuchAlgorithmException
     117         * @throws KeyStoreException
     118         * @throws BadPaddingException
     119         * @throws IllegalBlockSizeException
     120         * @throws NoSuchPaddingException
     121         * @throws InvalidKeySpecException
     122         * @throws InvalidKeyException
    80123         * @throws Exception
    81124         */
    82         public static void AuthCreateAccount() throws Exception {
    83                 final Collection<Text> textItems = DisplayController.getCurrentFrame().getTextItems();
    84                 final Optional<Map<AuthenticationTag, String>> userdata = AuthenticationTag.fetchUserData(textItems, false, AuthenticationTag.Username, AuthenticationTag.Password, AuthenticationTag.PasswordAgain);
    85                 if (userdata.isPresent()) {
    86                         final Map<AuthenticationTag, String> userData = userdata.get();
    87                         final String password = userData.get(AuthenticationTag.Password);
    88                         final String passwordAgain = userData.get(AuthenticationTag.PasswordAgain);
    89                         if (password.compareTo(passwordAgain) == 0) {
    90                                 createAccount(userData);
    91                         } else {
    92                                 MessageBay.errorMessage("The passwords provided do not match.");
    93                         }
     125        public static void AuthCreateAccount() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, ClassNotFoundException, InvalidFramesetNameException, ExistingFramesetException, IOException, SQLException, InvalidKeyException, InvalidKeySpecException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
     126                Collection<Text> textItems = DisplayController.getCurrentFrame().getTextItems();
     127                Optional<Map<AuthenticationTag, String>> userdata =
     128                                AuthenticationTag.fetchUserData(textItems, false,
     129                                                AuthenticationTag.Username,
     130                                                AuthenticationTag.Password,
     131                                                AuthenticationTag.PasswordAgain,
     132                                                AuthenticationTag.Email,
     133                                                AuthenticationTag.EmailAgain);
     134               
     135                if (userdata.isPresent()) {
     136                        Map<AuthenticationTag, String> userData = userdata.get();
     137                       
     138                        // A profile already existing with 'username' means an account cannot be created with that username.
     139                        if (FrameIO.LoadProfile(userData.get(AuthenticationTag.Username)) != null) {
     140                                MessageBay.errorMessage(Constants.ERROR_PROFILE_NAME_PREEXISTS);
     141                                return;
     142                        }
     143                       
     144                        // The chosen username must be a valid frameset name.
     145                        if (!FrameIO.isValidFramesetName(userData.get(AuthenticationTag.Username))) {
     146                                MessageBay.errorMessage(Constants.ERROR_INVALID_USERNAME);
     147                                return;
     148                        }
     149                       
     150                        // The passwords provided must match
     151                        if (userData.get(AuthenticationTag.Password).compareTo(userData.get(AuthenticationTag.PasswordAgain)) != 0) {
     152                                MessageBay.errorMessage(Constants.ERROR_MISMATCH_PASSWORDS);
     153                                return;
     154                        }
     155                       
     156                        // The emails provided must match
     157                        if (userData.get(AuthenticationTag.Email).compareTo(userData.get(AuthenticationTag.EmailAgain)) != 0) {
     158                                MessageBay.errorMessage(Constants.ERROR_MISMATCH_EMAILS);
     159                                return;
     160                        }
     161                       
     162                        createAccount(userData);
     163                        login(userData);
     164                        Authenticator.Authenticated = true;
    94165                } else {
    95                         MessageBay.errorMessage("Please enter a username and password ( + repeated password) to create an account.");
     166                        MessageBay.errorMessage(Constants.ERROR_INSUFFICIENT_INFORMATION_PROVIDED);
    96167                }
    97168        }
     
    108179                if (userdata.isPresent()) {
    109180                        login(userdata.get());
     181                        Authenticator.Authenticated = true;
    110182                }
    111183                else {
    112                         MessageBay.errorMessage("Please enter a username and password to log in.");
     184                        MessageBay.errorMessage(Constants.ERROR_INSUFFICIENT_INFORMATION_PROVIDED);
    113185                }
    114186        }
     
    130202                final Collection<Text> textItems = DisplayController.getCurrentFrame().getTextItems();
    131203               
    132                 if (!UserSettings.Authenticated.get()) {
    133                         MessageBay.errorMessage("You must be logged in to change your password.");
     204                if (!Authenticator.Authenticated) {
     205                        MessageBay.errorMessage(Constants.ERROR_MUST_BE_LOGGED_IN);
    134206                } else {
    135207                        final Optional<Map<AuthenticationTag, String>> userdata = AuthenticationTag.fetchUserData(textItems, false, AuthenticationTag.Password, AuthenticationTag.NewPassword, AuthenticationTag.NewPasswordAgain);
     
    137209                                final Map<AuthenticationTag, String> userData = userdata.get();
    138210                                if (userData.get(AuthenticationTag.NewPassword).compareTo(userData.get(AuthenticationTag.NewPasswordAgain)) != 0) {
    139                                         MessageBay.errorMessage("The passwords provided do not match.");
     211                                        MessageBay.errorMessage(Constants.ERROR_MISMATCH_PASSWORDS);
    140212                                } else {
    141213                                        userData.put(AuthenticationTag.Username, UserSettings.UserName.get());
     
    143215                                }
    144216                        } else {
    145                                 MessageBay.errorMessage("Insufficient information provided to complete this action.");
    146                         }
    147                 }
    148         }
    149        
    150         /**
    151          * Part of the process to secure an authorised account, the AuthAssociateEmail action associates a supplied email
    152          * with the currently logged in user. 
    153          */
    154         public static void AuthAssociateEmail() {
     217                                MessageBay.errorMessage(Constants.ERROR_INSUFFICIENT_INFORMATION_PROVIDED);
     218                        }
     219                }
     220        }
     221       
     222        public static void AuthGotoAccountManagement() {
     223                if (Authenticator.Authenticated) {
     224                        DisplayController.setCurrentFrame(FrameIO.LoadFrame(Constants.FRAME_MULTIUSER1), false);
     225                } else {
     226                        DisplayController.setCurrentFrame(FrameIO.LoadFrame(Constants.FRAME_AUTHENTICATION1), false);
     227                }
     228        }
     229       
     230        public static void AuthShareFrameset() throws IOException {
    155231                Collection<Text> textItems = DisplayController.getCurrentFrame().getTextItems();
    156232               
    157                 if (!UserSettings.Authenticated.get()) {
    158                         MessageBay.errorMessage("You must be logged in to perform this action.");
    159                 } else {
    160                         Optional<Map<AuthenticationTag, String>> userdata = AuthenticationTag.fetchUserData(textItems, false, AuthenticationTag.Email);
    161                         if (userdata.isPresent()) {
    162                                 Map<AuthenticationTag, String> userData = userdata.get();
    163                                 userData.put(AuthenticationTag.Username, UserSettings.UserName.get());
    164                                 String emailRegex = "^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}$";
    165                                 if (!userData.get(AuthenticationTag.Email).toUpperCase().matches(emailRegex)) {
    166                                         MessageBay.errorMessage("Invalid email address supplied.");
    167                                 } else {
    168                                         try {
    169                                                 associateEmail(userData);
    170                                                 DisplayController.setCurrentFrame(FrameIO.LoadFrame("authentication5"), true);
    171                                         } catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | ClassNotFoundException | IOException | SQLException  e) {
    172                                                 MessageBay.errorMessage("An unknown error has occured. Details sent to standard error.");
    173                                                 e.printStackTrace();
    174                                         }
    175                                 }
    176                         } else {
    177                                 MessageBay.errorMessage("Insufficient information provided to complete this action.");
    178                         }
    179                 }
    180         }
    181        
     233                Optional<Map<AuthenticationTag, String>> userdata = AuthenticationTag.fetchUserData(textItems, false, AuthenticationTag.Frameset);
     234                if (userdata.isPresent()) {
     235                        Map<AuthenticationTag, String> userData = userdata.get();
     236                        FrameIO.SuspendCache();
     237                        Frame toShare = FrameIO.LoadFrame(userData.get(AuthenticationTag.Frameset) + 1);
     238                        FrameIO.ResumeCache();
     239                       
     240                        if (toShare == null) {
     241                                MessageBay.errorMessage(Constants.ERROR_INSUFFICIENT_INFORMATION);
     242                                return;
     243                        }
     244                       
     245                        shareFrameset(toShare);
     246                }
     247        }
     248
    182249        /**
    183250         * Navigation action for progressing the process of recruiting colleagues to assist in password recovery.
     
    185252         */
    186253        public static void AuthGotoColleagueSubmissionFrame() {
    187                 Frame destination = FrameIO.LoadFrame("authentication7");
     254                Frame destination = FrameIO.LoadFrame(Constants.FRAME_COLLEAGUE_SUBMISSION_FRAME);
    188255                DisplayController.setCurrentFrame(destination, true);
    189                 Collection<Item> toHide = getByData(destination, "ShowOnProgress");
     256                Collection<Item> toHide = getByData(destination, Constants.DATA_SHOW_ON_PROGRESS);
    190257                for (Item i: toHide) {
    191258                        i.setVisible(false);
     
    204271         * @throws InvalidKeySpecException
    205272         */
    206         public static void AuthSubmitPWColleagues() throws KeyStoreException, FileNotFoundException, NoSuchAlgorithmException, CertificateException, ClassNotFoundException, IOException, SQLException, InvalidKeySpecException {
    207                 final Frame currentFrame = DisplayController.getCurrentFrame();
     273        public static void AuthSubmitPWColleagues() throws InvalidKeySpecException, NoSuchAlgorithmException, KeyStoreException, FileNotFoundException, CertificateException, ClassNotFoundException, IOException, SQLException {
     274                Frame currentFrame = DisplayController.getCurrentFrame();
    208275                Collection<Text> textItems = currentFrame.getTextItems();
    209276               
    210                 if (!UserSettings.Authenticated.get()) {
    211                         MessageBay.errorMessage("You must be logged in to perform this action.");
    212                 } else {
    213                         Optional<Map<AuthenticationTag, String>> userdata = AuthenticationTag.fetchUserData(textItems, false, AuthenticationTag.ColleagueOne, AuthenticationTag.ColleagueTwo);
    214                         if (userdata.isPresent()) {
    215                                 Map<AuthenticationTag, String> userData = userdata.get();
     277                if (!Authenticator.Authenticated) {
     278                        MessageBay.errorMessage(Constants.ERROR_MUST_BE_LOGGED_IN);
     279                        return;
     280                }
     281               
     282                Optional<Map<AuthenticationTag, String>> userdata = AuthenticationTag.fetchUserData(textItems, false, AuthenticationTag.ColleagueOne, AuthenticationTag.ColleagueTwo);
     283                if (userdata.isPresent()) {
     284                        Map<AuthenticationTag, String> userData = userdata.get();
     285                        String colleagueOne = userData.get(AuthenticationTag.ColleagueOne);
     286                        Path colleagueOnePath = Paths.get(FrameIO.CONTACTS_PATH).resolve(colleagueOne + "-credentials");
     287                        String colleagueTwo = userData.get(AuthenticationTag.ColleagueTwo);
     288                        Path colleagueTwoPath = Paths.get(FrameIO.CONTACTS_PATH).resolve(colleagueTwo + "-credentials");
     289                        if (!colleagueOnePath.toFile().exists()) {
     290                                MessageBay.errorMessage("Your nominated colleague: " + colleagueOne + " must exist in your contacts.");
     291                        } else if (!colleagueTwoPath.toFile().exists()) {
     292                                MessageBay.errorMessage("Your nominated colleague: " + colleagueTwo + " must exist in your contacts.");
     293                        } else {
    216294                                userData.put(AuthenticationTag.Username, UserSettings.UserName.get());
    217                                 boolean succsess = submitPWColleagues(userData);
    218                                 if (succsess) {
    219                                         Collection<Item> toShow = getByData(currentFrame, "ShowOnProgress");
     295                                boolean success = submitPWColleagues(userData);
     296                                if (success) {
     297                                        Collection<Item> toShow = getByData(currentFrame, Constants.DATA_SHOW_ON_PROGRESS);
    220298                                        for (Item i: toShow) {
    221299                                                i.setVisible(true);
    222300                                        }
    223301                                        currentFrame.change();
     302                                        MessageBay.displayMessage("-------Messages sent-------");
    224303                                }
    225304                                FrameIO.SaveFrame(currentFrame);
    226305                                DisplayController.requestRefresh(false);
    227                         } else {
    228                                 MessageBay.errorMessage("Insufficient information provided to complete this action.");
    229                         }
    230                 }
    231         }
    232        
    233         public static void AuthSetupPasswordRecovery() throws KeyStoreException, FileNotFoundException, NoSuchAlgorithmException, CertificateException, ClassNotFoundException, IOException, SQLException, UnrecoverableEntryException {
    234                 if (!UserSettings.Authenticated.get()) {
    235                         MessageBay.errorMessage("You must be logged in to perform this action.");
    236                 } else if (!Authenticator.getInstance().hasRegisteredEmail(UserSettings.UserName.get())) {
    237                         Frame registerEmailFrame = FrameIO.LoadFrame("authentication4");
    238                         DisplayController.setCurrentFrame(registerEmailFrame, true);
    239                 } else if (!Authenticator.getInstance().hasRequestedColleagues(UserSettings.UserName.get()) && Authenticator.getInstance().getColleagues(UserSettings.UserName.get()) == null) {
    240                         Frame submitColleaguesFrame = FrameIO.LoadFrame("authentication5");
    241                         DisplayController.setCurrentFrame(submitColleaguesFrame, true);
    242                 } else if (Authenticator.getInstance().hasRequestedColleagues(UserSettings.UserName.get()) && Authenticator.getInstance().getColleagues(UserSettings.UserName.get()) == null) {
    243                         MessageBay.displayMessage("You have already nominated two colleagues to assist you in the process of password recovery and are awaiting their response."
    244                                         + "  You will be alerted on Expeditee startup when they have both responded.");
    245                 } else if (Authenticator.getInstance().getColleagues(UserSettings.UserName.get()) != null) {
    246                         MessageBay.displayMessage("You have completed the Password Recovery Setup process, there is nothing more to do here.");
    247                 }
    248         }
     306                        }
     307                }
     308        }
     309       
     310//      public static void AuthSetupPasswordRecovery() throws KeyStoreException, FileNotFoundException, NoSuchAlgorithmException, CertificateException, ClassNotFoundException, IOException, SQLException, UnrecoverableEntryException {
     311//              if (!UserSettings.Authenticated.get()) {
     312//                      MessageBay.errorMessage("You must be logged in to perform this action.");
     313//              } else if (!Authenticator.getInstance().hasRegisteredEmail(UserSettings.UserName.get())) {
     314//                      Frame registerEmailFrame = FrameIO.LoadFrame("authentication4");
     315//                      DisplayController.setCurrentFrame(registerEmailFrame, true);
     316//              } else if (!Authenticator.getInstance().hasRequestedColleagues(UserSettings.UserName.get()) && Authenticator.getInstance().getColleagues(UserSettings.UserName.get()) == null) {
     317//                      Frame submitColleaguesFrame = FrameIO.LoadFrame("authentication5");
     318//                      DisplayController.setCurrentFrame(submitColleaguesFrame, true);
     319//              } else if (Authenticator.getInstance().hasRequestedColleagues(UserSettings.UserName.get()) && Authenticator.getInstance().getColleagues(UserSettings.UserName.get()) == null) {
     320//                      MessageBay.displayMessage("You have already nominated two colleagues to assist you in the process of password recovery and are awaiting their response."
     321//                                      + "  You will be alerted on Expeditee startup when they have both responded.");
     322//              } else if (Authenticator.getInstance().getColleagues(UserSettings.UserName.get()) != null) {
     323//                      MessageBay.displayMessage("You have completed the Password Recovery Setup process, there is nothing more to do here.");
     324//              }
     325//      }
    249326       
    250327        public static void AuthConfirmPasswordColleagueRelationship(String colleagueName) {
     
    252329        }
    253330       
    254         public static void AuthDenyPasswordColleagueRelationship(String colleagueName) throws InvalidKeySpecException, NoSuchAlgorithmException, KeyStoreException, FileNotFoundException, CertificateException, ClassNotFoundException, IOException, SQLException {
     331        public static void AuthDenyPasswordColleagueRelationship(String colleagueName) throws InvalidKeySpecException, NoSuchAlgorithmException,
     332                KeyStoreException, FileNotFoundException, CertificateException, ClassNotFoundException, IOException, SQLException {
    255333                denyPasswordColleagueRelationship(colleagueName);
    256334        }
     
    260338        }
    261339       
     340        /**
     341         * Create a user account using the specified information in userdata.  Creates and stores user keys.
     342         * @param userdata Should contain username, password and email.
     343         */
     344        private static void createAccount(Map<AuthenticationTag, String> userdata) throws InvalidFramesetNameException, ExistingFramesetException,
     345                KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, ClassNotFoundException, IOException, SQLException {
     346                               
     347                // Track progress
     348                String message = "Creating new user account...";
     349                //Progress progress = MessageBay.displayProgress(message);
     350
     351                // Extract user details
     352                String username = userdata.get(AuthenticationTag.Username);
     353                String password = userdata.get(AuthenticationTag.Password);
     354                String email = userdata.get(AuthenticationTag.Email);
     355               
     356                System.out.println(message + "Generating Keys.");
     357
     358                // Generate keys
     359                //      Personal key
     360                Random rand = new Random();
     361                byte[] keyBytes = new byte[16];
     362                rand.nextBytes(keyBytes);
     363                SecretKey key = new SecretKeySpec(keyBytes, SymmetricAlgorithm);
     364                Authenticator.getInstance().putKey(username, password, key);
     365                String personalKey = Base64.getEncoder().encodeToString(key.getEncoded());
     366                //      Public and private keys
     367                KeyPairGenerator keyGen = KeyPairGenerator.getInstance(AsymmetricAlgorithm);
     368                keyGen.initialize(1024);
     369                KeyPair keyPair = keyGen.generateKeyPair();
     370                String publicKey = Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded());
     371                String privateKey = Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded());
     372               
     373                System.out.println(message + "Creating Profile Frameset.");
     374               
     375                // Update in memory settings
     376                UserSettings.UserName.set(username);
     377                UserSettings.ProfileName.set(username);
     378                UserSettings.setupDefaultFolders();
     379                               
     380                // Establish the initial settings for the created user.
     381                Map<String, Setting> initialSettings = new HashMap<String, Setting>();
     382                initialSettings.put(Constants.SETTINGS_AUTH_SECRETS_PERSONAL_KEY, constructTextSetting(Constants.TOOLTIP_SETTING_PERSONAL_KEY, "PersonalKey", personalKey));
     383                initialSettings.put(Constants.SETTINGS_AUTH_SECRETS_PRIVATE_KEY, constructTextSetting(Constants.TOOLTIP_SETTING_PRIVATE_KEY, "PrivateKey", privateKey));
     384                initialSettings.put(Constants.SETTINGS_AUTH_PUBLIC_KEY, constructTextSetting(Constants.TOOLTIP_SETTING_PUBLIC_KEY, "PublicKey", publicKey));
     385                initialSettings.put(Constants.SETTINGS_AUTH_EMAIL, constructGenericSetting(String.class, Constants.TOOLTIP_SETTING_EMAIL, "Email", email, username));
     386                initialSettings.put(Constants.SETTINGS_USER_SETTINGS_USER_NAME, constructGenericSetting(String.class, Constants.LABEL_USERNAME, Constants.LABEL_USERNAME, username, username));
     387                initialSettings.put(Constants.SETTINGS_USER_SETTINGS_PROFILE_NAME, constructGenericSetting(String.class, Constants.LABEL_PROFILENAME, Constants.LABEL_PROFILENAME, username, username));
     388                initialSettings.put("org.expeditee.gui.folders.FolderSettings.FrameDirs", FolderSettings.FrameDirs);
     389                initialSettings.put("org.expeditee.gui.folders.FolderSettings.ImageDirs", FolderSettings.ImageDirs);
     390                                               
     391                // Create users profile
     392                Frame profile = FrameIO.CreateNewProfile(username, initialSettings);
     393                int lastNumber = FrameIO.getLastNumber(profile.getFramesetName());
     394                for (int i = 1; i <= lastNumber; i++) {
     395                        Frame f = FrameIO.LoadFrame(profile.getFramesetName() + i);
     396                        Text titleItem = f.getTitleItem();
     397                        if (i == 1 && titleItem != null) {
     398                                titleItem.delete();
     399                                f.setBackgroundColor(new Colour(1, 1, 0.39f));
     400                        }
     401                        f.setOwner(username);
     402                        f.getAllItems().stream().forEach(item -> item.setOwner(username));
     403                        f.setChanged(true);
     404                        f.setEncryptionLabel("Profile");
     405                        Collection<Item> secretsLink = getByContent(f, "Secrets");
     406                        Collection<Item> publicKeyItem = getByContent(f, "PublicKey");
     407                        if (!secretsLink.isEmpty() && !publicKeyItem.isEmpty()) {
     408                                //Then we are on credentials frame
     409                                secretsLink.forEach(text -> text.setPermission(new PermissionPair(UserAppliedPermission.full, UserAppliedPermission.none)));
     410                                f.addToData("MultiuserCredentials");
     411                        }
     412                        Text backupPersonalKey = KeyList.PersonalKey.get();
     413                        Text tempPersonalKey = KeyList.PersonalKey.generateText();
     414                        tempPersonalKey.setData(personalKey);
     415                        KeyList.PersonalKey.setSetting(tempPersonalKey);
     416                        FrameIO.SaveFrame(f);
     417                        KeyList.PersonalKey.setSetting(backupPersonalKey);
     418                }
     419                               
     420                // Create credentials
     421                File credentialsDir = new File(profile.getFramesetPath() + username + "-credentials");
     422                credentialsDir.mkdir();
     423                //      credentials.inf file.
     424                String credentialsPath =  credentialsDir.getAbsolutePath() + File.separator + "credentials.inf";
     425                File credentialsFile = new File(credentialsPath);
     426                credentialsFile.createNewFile();
     427                FileWriter out = new FileWriter(credentialsFile);
     428                out.write(Authenticator.CREDENTIALS_FRAME + ".exp");
     429                out.flush();
     430                out.close();
     431                //      outbox
     432                Connection c = DriverManager.getConnection("jdbc:sqlite:" + credentialsDir.getAbsolutePath() + File.separator + "expmail.db");
     433                Statement createTable = c.createStatement();
     434                String sql = "CREATE TABLE EXPMAIL (" +
     435                                "TIME           TEXT                                    NOT NULL, " +
     436                                "SND            TEXT                                    NOT NULL, " +
     437                                "REC            TEXT                                    NOT NULL, " +
     438                                "MSG            TEXT                                    NOT NULL, " +
     439                                "MSG2           TEXT                                    NOT NULL, " +
     440                                "OPTS           ARRAY                                   NOT NULL, " +
     441                                "OPTSVAL        ARRAY                                   NOT NULL)";
     442                createTable.executeUpdate(sql);
     443                createTable.close();
     444                c.close();
     445               
     446                System.out.println(message + "Creating Individual Space.");
     447               
     448                // Copy private resources to personal area
     449                Path personalResources = Paths.get(FrameIO.PARENT_FOLDER).resolve("resources-" + username);
     450                personalResources.toFile().mkdir();             
     451                File[] globalResourcesToCopy = Paths.get(FrameIO.RESOURCES_PRIVATE).toFile().listFiles();
     452                for (File toCopy: globalResourcesToCopy) {
     453                        Path p = Paths.get(toCopy.getAbsolutePath());
     454                        if (!p.getFileName().toString().equals(".res") && !p.getFileName().toString().equals("about")) {
     455                                copyFileTree(p.toAbsolutePath(), personalResources.resolve(p.getFileName()));
     456                        }
     457                }
     458                File contactsDir = new File(personalResources.resolve("contacts").toAbsolutePath().toString());
     459                contactsDir.mkdir();
     460               
     461                System.out.println(message + "Done.");
     462        }
     463       
     464        private static void copyFileTree(Path source, Path target) throws IOException {
     465                Files.copy(source, target);
     466                if (source.toFile().isDirectory()) {
     467                        File[] files = source.toFile().listFiles();
     468                        for (File file: files) {
     469                                Path asPath = Paths.get(file.getAbsolutePath());
     470                                copyFileTree(asPath, target.resolve(asPath.getFileName()));
     471                        }
     472                }
     473        }
     474
     475        /*
     476         * Function used to authenticate as a specified user (via function arguments).
     477         */
     478        private static void login(Map<AuthenticationTag, String> userdata) throws NoSuchAlgorithmException, KeyStoreException, FileNotFoundException, CertificateException, ClassNotFoundException, IOException, SQLException, InvalidKeySpecException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
     479                String username = userdata.get(AuthenticationTag.Username);
     480                String password = userdata.get(AuthenticationTag.Password);
     481               
     482                SecretKey personalKey = Authenticator.getInstance().getSecretKey(username, password);
     483                if (personalKey == null) {
     484                        // Incorrect username and password
     485                        MessageBay.errorMessage("The username + password combination was incorrect.");
     486                        return;
     487                }
     488               
     489                // Load in and cache the profile frame using the personal key fetched from keystore.
     490                // Reset the personal key once finished so that setting parsing can correctly set it.
     491                FrameIO.ClearCache();
     492                Text personalKeyText = KeyList.PersonalKey.generateText();
     493                personalKeyText.setData(Base64.getEncoder().encodeToString(personalKey.getEncoded()));
     494                KeyList.PersonalKey.setSetting(personalKeyText);
     495                Frame oneFrame = FrameIO.LoadProfile(username);
     496                for (int i = 1; i <= FrameIO.getLastNumber(username); i++) {
     497                        Frame f = FrameIO.LoadFrame(oneFrame.getFramesetName() + i);
     498                        if (f.getData() != null && f.getData().contains("MultiuserCredentials")) {
     499                                Authenticator.CREDENTIALS_FRAME = f.getNumber();
     500                        }
     501                }
     502                               
     503                // Parse the settings frame to update the settings datastructure.
     504                Text fakeLink = new Text("settings");
     505                fakeLink.setLink(oneFrame.getFramesetName() + "2");
     506                Settings.parseSettings(fakeLink);
     507               
     508                // Update default folders.
     509                UserSettings.setupDefaultFolders();
     510
     511                // Check mail
     512                MailBay.clear();
     513                Authenticator.getInstance().loadMailDatabase();
     514                Text keyItem = org.expeditee.settings.identity.secrets.KeyList.PrivateKey.get();
     515                if (keyItem.getData() != null) {
     516                        String keyEncoded = keyItem.getData().get(0);
     517                        byte[] keyBytes = Base64.getDecoder().decode(keyEncoded);
     518                        PrivateKey key = KeyFactory.getInstance(AsymmetricAlgorithm).generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
     519                        List<MailEntry> mailForLoggingInUser = Mail.getEntries(UserSettings.UserName.get(), key);
     520                        for (MailEntry mail: mailForLoggingInUser) {
     521                                MailBay.addMessage(mail.timestamp, mail.message, mail.message2, mail.options);
     522                        }
     523                }
     524               
     525                Collection<Item> usernameFields = getByData(FrameIO.LoadFrame(Constants.FRAME_MULTIUSER1), "txtUsername");
     526                usernameFields.forEach(usernameField -> usernameField.setText(username));
     527                               
     528                Frame homeFrame = FrameIO.LoadFrame("home1");
     529                DisplayController.setCurrentFrame(homeFrame == null ? oneFrame : homeFrame, false);
     530        }       
     531
     532        /*
     533         * Function to share a specified frameset.
     534         * 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.
     535         */
     536        private static void shareFrameset(Frame toShare) throws IOException {   
     537                File destinationDir = new File(FrameIO.SHARED_FRAMESETS_PATH + File.separator + toShare.getFramesetName());
     538                File sourceDir = new File(toShare.getFramesetPath());
     539               
     540                if (destinationDir.exists()) {
     541                        MessageBay.errorMessage("A frameset by this name already exists.");
     542                        return;
     543                }
     544               
     545                destinationDir.mkdir();
     546                List<Path> files = Files.walk(sourceDir.toPath()).collect(Collectors.toList());
     547                Files.move(files.get(0), destinationDir.toPath(), StandardCopyOption.ATOMIC_MOVE);
     548               
     549                MessageBay.displayMessage("The frameset " + toShare.getFramesetName() + " has been moved to " + destinationDir + ".  Google Drive functionality can now be used to share it with colleagues.");
     550        }
     551       
    262552        private static void denyPasswordColleagueRelationship(String colleagueName) throws InvalidKeySpecException, NoSuchAlgorithmException, KeyStoreException, FileNotFoundException, CertificateException, ClassNotFoundException, IOException, SQLException {
     553                String time = org.expeditee.stats.Formatter.getDateTime();
    263554                String sender = UserSettings.UserName.get();
    264555                String message = "You have received a reply from " + sender + " reguarding your request for assistance.";
     
    266557                Map<String, String> options = new HashMap<String, String>();
    267558                options.put("Clear Preview Colleague Nominations", "AuthClearPWColleaguesNominated");
    268                 MailEntry mail = new MailEntry(sender, colleagueName, message, message2, options);
    269                 Mail.sendMail(mail, Authenticator.getInstance().getPublicKey(colleagueName));
    270         }
    271        
    272         private static boolean submitPWColleagues(Map<AuthenticationTag, String> userData) throws KeyStoreException, FileNotFoundException, NoSuchAlgorithmException, CertificateException, ClassNotFoundException, IOException, SQLException, InvalidKeySpecException {
    273                 // Confirm both colleagues exist
     559                MailEntry mail = new MailEntry(time, sender, colleagueName, message, message2, options);
     560                Mail.sendMail(mail, Authenticator.getInstance().getPublicKey(colleagueName), Paths.get(FrameIO.PROFILE_PATH).resolve(sender).resolve(sender + "-credentials"));
     561        }
     562       
     563        private static boolean submitPWColleagues(Map<AuthenticationTag, String> userData) throws InvalidKeySpecException, NoSuchAlgorithmException, KeyStoreException, FileNotFoundException, CertificateException, ClassNotFoundException, IOException, SQLException {
    274564                String colleagueOne = userData.get(AuthenticationTag.ColleagueOne);
    275565                String colleagueTwo = userData.get(AuthenticationTag.ColleagueTwo);
    276                 PublicKey colleagueOneKey = null;
    277                 PublicKey colleagueTwoKey = null;
    278                 if (!FrameIO.canAccessFrameset(colleagueOne) && FrameIO.canAccessFrameset(colleagueTwo)) {
    279                         MessageBay.errorMessage("At least one of the colleagues you specified does not have a Expeditee profile.");
     566                PublicKey colleagueOneKey = Authenticator.getInstance().getPublicKey(colleagueOne);
     567                PublicKey colleagueTwoKey = Authenticator.getInstance().getPublicKey(colleagueTwo);
     568                if (colleagueOneKey == null) {
     569                        MessageBay.errorMessage("Unable to get public key for colleague: " + colleagueOne);
    280570                        return false;
    281                 } else if ((colleagueOneKey = Authenticator.getInstance().getPublicKey(colleagueOne)) == null ||
    282                                 (colleagueTwoKey = Authenticator.getInstance().getPublicKey(colleagueTwo)) == null) {
    283                         MessageBay.errorMessage("At least one of the colleagues you specified is not set up to be authorised.");
     571                } else if (colleagueTwoKey == null) {
     572                        MessageBay.errorMessage("Unable to get public key for colleague: " + colleagueTwo);
    284573                        return false;
    285574                } else {
    286                         String sender = UserSettings.UserName.get();
    287                         String message = "You have received a request for cooperation from your colleague " + sender;
    288                         String message2 = "\"I would like to receive your help if I happen to forget my password.\"";
     575                        String time = org.expeditee.stats.Formatter.getDateTime();
     576                        String sender = userData.get(AuthenticationTag.Username);
     577                        String topic = "You have received a request for cooperation from your colleague " + sender;
     578                        String message = "Should " + sender + " forget their password, they would like your help recoverying it.";
    289579                        Map<String, String> arguments = new HashMap<String, String>();
    290                         arguments.put("I Agree To Assist " + sender + " If They Forget Their Password" , "AuthConfirmPasswordColleagueRelationship " + sender);
    291                         arguments.put("I Wish To Excuse Myself From This Responsibility", "AuthDenyPasswordColleagueRelationship " + sender);
    292                         MailEntry mail = new MailEntry(sender, colleagueOne, message, message2, arguments);
    293                         Mail.sendMail(mail, colleagueOneKey);
    294                         mail = new MailEntry(sender, colleagueTwo, message, message2, arguments);
    295                         Mail.sendMail(mail, colleagueTwoKey);
     580                        arguments.put("I agree to assist " + sender + " if they loose access to their account.", "AuthConfirmPasswordColleagueRelationship " + sender);
     581                        arguments.put("I wish to excuse myself from this responsibility.", "AuthDenyPasswordColleagueRelationship " + sender);
     582                        MailEntry mail = new MailEntry(time, sender, colleagueOne, topic, message, arguments);
     583                        Path outbox = Paths.get(FrameIO.PROFILE_PATH).resolve(sender).resolve(sender + "-credentials");
     584                        Mail.sendMail(mail, colleagueOneKey, outbox);
     585                        mail = new MailEntry(time, sender, colleagueTwo, topic, message, arguments);
     586                        Mail.sendMail(mail, colleagueTwoKey, outbox);
    296587                        Authenticator.getInstance().markRequestedColleagues(UserSettings.UserName.get());
    297588                        return true;
     
    299590        }
    300591
    301         /*
    302          * Function used to authenticate as a specified user (via function arguments).
    303          */
    304         private static void login(final Map<AuthenticationTag, String> userdata) throws Exception {
    305                 final String username = userdata.get(AuthenticationTag.Username);
    306                 final String password = userdata.get(AuthenticationTag.Password);
    307                
    308                 final SecretKey personalKey = Authenticator.getInstance().getSecretKey(username, password);
    309                 if (personalKey == null) {
    310                         // Incorrect username and password
    311                         MessageBay.errorMessage("The username + password combination was incorrect.");
    312                 } else {
    313                         // Proceed with login process.
    314                         org.expeditee.settings.auth.secrets.KeyList.PersonalKey.setSetting(new Text(Base64.getEncoder().encodeToString(personalKey.getEncoded())));
    315                         setUser(username);
    316                         MessageBay.displayMessage("Logged in as: " + UserSettings.UserName.get());
    317                        
    318                         // Set Public Key and private key in settings datastructure
    319                         String profileName = UserSettings.ProfileName.get();
    320                         int lastNumber = FrameIO.getLastNumber(profileName);
    321                         for (int i = 1; i <= lastNumber; i++) {
    322                                 Frame frame = FrameIO.LoadFrame(profileName + i);
    323                                 if (frame == null) {
    324                                         continue;
    325                                 }
    326                                 Collection<Item> items = frame.getAllItems();
    327                                 boolean foundPublic = false;
    328                                 boolean foundPrivate = false;
    329                                 for (Item item: items) {
    330                                         if (item.getText().compareTo("PublicKey") == 0) {
    331                                                 org.expeditee.settings.auth.KeyList.PublicKey.set((Text) item);
    332                                                 foundPublic = true;
    333                                         } else if (item.getText().compareTo("PrivateKey") == 0) {
    334                                                 org.expeditee.settings.auth.secrets.KeyList.PrivateKey.set((Text) item);
    335                                                 foundPrivate = true;
    336                                         }
    337                                 }
    338                                 if (foundPublic && foundPrivate) { break; }
    339                         }
    340                                                
    341                         // Check mail
    342                         MailBay.clear();
    343                         Authenticator.getInstance().loadMailDatabase();
    344                         Text keyItem = org.expeditee.settings.auth.secrets.KeyList.PrivateKey.get();
    345                         if (keyItem.getData() != null) {
    346                                 String keyEncoded = keyItem.getData().get(0);
    347                                 byte[] keyBytes = Base64.getDecoder().decode(keyEncoded);
    348                                 PrivateKey key = KeyFactory.getInstance(AsymmetricAlgorithm).generatePrivate(new PKCS8EncodedKeySpec(keyBytes));
    349                                 List<MailEntry> mailForLoggingInUser = Mail.getEntries(UserSettings.UserName.get(), key);
    350                                 for (MailEntry mail: mailForLoggingInUser) {
    351                                         MailBay.addMessage(mail.message, mail.message2, mail.options);
    352                                 }
    353                         }
    354                        
    355                         UserSettings.Authenticated.set(true);
    356                         // navigate to logged in profile
    357                         DisplayController.setCurrentFrame(loadProfile(username), false);
    358                 }
    359         }
    360        
    361         /*
    362          * Creates an account from specified user data.
    363          */
    364         private static void createAccount(final Map<AuthenticationTag, String> userdata) throws Exception {
    365                 String username = userdata.get(AuthenticationTag.Username);
    366                 String password = userdata.get(AuthenticationTag.Password);
    367                 if (FrameIO.LoadProfile(username) != null) {
    368                         MessageBay.errorMessage("A Expeditee profile with this username already exists, please choose another.");
    369                 } else {                               
    370                         // generate the newly created user a profile frame using the specialized default frame as a blueprint
    371                         String defaultBackup = UserSettings.DEFAULT_PROFILE_NAME;
    372                         UserSettings.DEFAULT_PROFILE_NAME = "multiusermodedefault";
    373                         Frame profile = FrameIO.CreateNewProfile(username);
    374                         UserSettings.DEFAULT_PROFILE_NAME = defaultBackup;
    375                        
    376                         // perform necessary changes to generated frame: remove default title, set background color, set custom title
    377                         profile.getTitleItem().delete();
    378                         profile.setBackgroundColor(new Colour(1, 1, 0.39f));
    379                         getByData(profile, "txtUsername").stream().forEach(i -> i.setText(username));
    380                         getByText(profile, "“If Aphroditē be the godess of love").stream().forEach(i -> i.setWidth(300));
    381                         getByText(profile, "Sleek like Aphroditē, Wise like Athēnâ.").stream().forEach(i -> i.setWidth(300));
    382                        
    383                         // update ownership
    384                         int lastNumber = FrameIO.getLastNumber(profile.getFramesetName());
    385                         for (int i = 1; i <= lastNumber; i++) {
    386                                 Frame frame = FrameIO.LoadFrame(profile.getFramesetName() + i);
    387                                 frame.setOwner(username);
    388                                 frame.setEncryptionLabel("Profile");
    389                                 Collection<Item> items = frame.getAllItems();
    390                                 for (Item item: items) {
    391                                         String newText = item.getText().replace("authadmin", username);
    392                                         item.setText(newText);
    393                                 }
    394                         }
    395                        
    396                         // generate and store personal, public and private keys
    397                         String backupUser = UserSettings.UserName.get();
    398                         setUser(username);
    399                         UserSettings.Authenticated.set(true);
    400                        
    401                         // personal key
    402                         Random rand = new Random();
    403                         byte[] keyBytes = new byte[16];
    404                         rand.nextBytes(keyBytes);
    405                         SecretKey key = new SecretKeySpec(keyBytes, SymmetricAlgorithm);
    406                         Authenticator.getInstance().putKey(username, password, key);
    407                         org.expeditee.settings.auth.secrets.KeyList.PersonalKey.setSetting(new Text(Base64.getEncoder().encodeToString(key.getEncoded())));
    408                        
    409                         // public+private key pair
    410                         KeyPairGenerator keyGen = KeyPairGenerator.getInstance(AsymmetricAlgorithm);
    411                         keyGen.initialize(1024);
    412                         KeyPair keyPair = keyGen.generateKeyPair();
    413                        
    414                         org.expeditee.settings.auth.secrets.KeyList.PrivateKey.setSetting(new Text(Base64.getEncoder().encodeToString(keyPair.getPrivate().getEncoded())));
    415                         org.expeditee.settings.auth.KeyList.PublicKey.setSetting(new Text(Base64.getEncoder().encodeToString(keyPair.getPublic().getEncoded())));
    416                        
    417                         // ensure save of keys
    418                         lastNumber = FrameIO.getLastNumber(profile.getFramesetName());
    419                         for (int i = 1; i <= lastNumber; i++) {
    420                                 Frame frame = FrameIO.LoadFrame(profile.getFramesetName() + i);
    421                                 frame.setChanged(true);
    422                                 FrameIO.SaveFrame(frame);
    423                         }
    424                         setUser(backupUser);
    425                         UserSettings.Authenticated.set(false);
    426                        
    427                         // proceed to log into new account.
    428                         login(userdata);
    429                 }
     592               
     593        private static TextSetting constructTextSetting(String tooltip, String text, String data) {
     594                return new TextSetting(tooltip, text) {
     595                        @Override
     596                        public Text generateText() {
     597                                Text t = new Text(text);
     598                                t.setData(data);
     599                                return t;
     600                        }
     601                };
     602        }
     603
     604        private static <T> GenericSetting<T> constructGenericSetting(Class<T> type, String tooltip, String name, T value, String frameset) {
     605                return new GenericSetting<T>(type, tooltip, name, value) {
     606                        @Override
     607                        public Text generateRepresentation(String name, String frameset) {
     608                                Text t = new Text(name + ": " + value);
     609                                return t;
     610                        }
     611                };
    430612        }
    431613       
     
    446628                }
    447629        }
    448        
    449         private static void associateEmail(Map<AuthenticationTag, String> userdata) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, ClassNotFoundException, IOException, SQLException {
    450                 Authenticator.getInstance().putEmail(
    451                                 userdata.get(AuthenticationTag.Username),
    452                                 userdata.get(AuthenticationTag.Email));
    453         }
    454 
    455         private static void setUser(final String username) {
    456                 UserSettings.UserName.set(username);
    457                 UserSettings.ProfileName.set(username);
    458                 UserSettings.HomeFrame.set(username + "1");
    459                 UserSettings.UserName.setDefault(username);
    460                 UserSettings.ProfileName.setDefault(username);
    461                 UserSettings.HomeFrame.setDefault(username + "1");
    462         }
    463        
    464         private static Frame loadProfile(final String username) throws Exception {
    465                 final Frame frameOne = FrameIO.LoadProfile(username);
    466                 if (frameOne != null) {
    467                         return frameOne;
    468                 } else {
    469                         final Frame profile = FrameIO.CreateNewProfile(username);
    470                         for (int i = 0; i < FrameIO.getLastNumber(profile.getFramesetName()); i++) {
    471                                 final Frame frame = FrameIO.LoadFrame(profile.getFramesetName() + i);
    472                                 final Collection<Text> textItems = frame.getTextItems();
    473                                 for (final Text t: textItems) {
    474                                         if (t.getText().startsWith("User name:")) {
    475                                                 t.setText("User name: " + UserSettings.UserName.get());
    476                                         } else if (t.getText().startsWith("Profile name:")) {
    477                                                 t.setText("Profile name: " + UserSettings.ProfileName.get());
    478                                         }
    479                                 }
    480                                 FrameIO.ForceSaveFrame(frame);
    481                         }
    482                         return profile;
    483                 }
    484         }
    485 
    486 //      public static void AuthRecoverPasswordStage1() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException {
    487 //              final Collection<Text> textItems = DisplayController.getCurrentFrame().getTextItems();
    488 //              final Optional<Text> txtUsername = textItems.stream().filter(t -> t.getData() != null && t.getData().contains("txtUsername")).findFirst();
    489 //              final Optional<Text> txtRecoveryEmail = textItems.stream().filter(t -> t.getData() != null && t.getData().contains("txtRecoveryEmail")).findFirst();
    490 //              final String username = txtUsername.isPresent() ? txtUsername.get().getText() : System.getProperty("user.name");
    491 //              final String email = txtRecoveryEmail.isPresent() ? txtRecoveryEmail.get().getText() : System.getProperty("user.recoveryemail");
    492 //              if (areAllPresent(new String[] { username, email })) {
    493 //                      // generate intergalactic number
    494 //                      final String intergalacticNumber = Authenticator.getInstance().newIntergalacticNumber(username, email);
    495 //
     630
    496631//                      // establish properties
    497632//                      final String from = "[email protected]";
     
    515650//                              };
    516651//                      });
    517 //
    518 //                      try {
     652
    519653//                              // construct email message
    520654//                              final MimeMessage message = new MimeMessage(session);
     
    526660//                              // send email message
    527661//                              Transport.send(message);
    528 //                      } catch (final MessagingException e) {
    529 //                              e.printStackTrace();
    530 //                      }
    531 //                     
    532 //                      FrameUtils.DisplayFrame("4", false, true);
    533 //              } else {
    534 //                      MessageBay.errorMessage("To recover a lost password please fill in all the provided fields.");
    535 //              }
    536 //      }
    537 //     
    538 //      public static void AuthRecoverPasswordStage2() throws NoSuchAlgorithmException, KeyStoreException, CertificateException, FileNotFoundException, IOException {
    539 //              final Collection<Text> textItems = DisplayController.getCurrentFrame().getTextItems();
    540 //              final Optional<Text> txtUsername = textItems.stream().filter(t -> t.getData() != null && t.getData().contains("txtUsername")).findFirst();
    541 //              final Optional<Text> txtRecoveryEmail = textItems.stream().filter(t -> t.getData() != null && t.getData().contains("txtRecoveryEmail")).findFirst();
    542 //              final Optional<Text> txtIntergalacticNumber = textItems.stream().filter(t -> t.getData() != null && t.getData().contains("txtIntergalacticNumber")).findFirst();
    543 //              final String username = txtUsername.isPresent() ? txtUsername.get().getText() : System.getProperty("user.name");
    544 //              final String email = txtRecoveryEmail.isPresent() ? txtRecoveryEmail.get().getText() : System.getProperty("user.recoveryemail");
    545 //              final String intergalacticNumber = txtIntergalacticNumber.isPresent() ? txtIntergalacticNumber.get().getText() : System.getProperty("user.intergalacticnumber");
    546 //              if (areAllPresent(new String[] { username, email, intergalacticNumber })) {
    547 //                      // confirm intergalactic number matches what is stored
    548 //                      final boolean intergalaticNumberMatches = Authenticator.getInstance().confirmIntergalaticNumber(username, email, intergalacticNumber);
    549 //                      if (intergalaticNumberMatches) {
    550 //                              final Frame changePasswordFrame = FrameIO.LoadFrame("5");
    551 //                              final Optional<Text> actionNewPassword = changePasswordFrame.getTextItems().stream().filter(t -> t.getAction().contains("AuthNewPassword")).findFirst();
    552 //                              if (actionNewPassword.isPresent()) {
    553 //                                      actionNewPassword.get().setData(intergalacticNumber);
    554 //                              }
    555 //                              FrameUtils.DisplayFrame("5", false, true);
    556 //                      }
    557 //              } else {
    558 //                      MessageBay.errorMessage("To recover a lost password please fill in all the provided fields.");
    559 //              }
    560 //      }
     662
    561663
    562664        public static void TickBox(final Text item) {
     
    569671       
    570672        /*
    571          *  Gets all items on a specified frame that contain the specified text.
    572          */
    573         private static Collection<Item> getByText(final Frame frame, final String text) {
    574                 final Collection<Item> allItems = frame.getAllItems();
    575                 allItems.removeIf(i -> i.getText() == null || !i.getText().contains(text));
    576                 return allItems;
    577         }
    578        
    579         /*
    580673         * Gets all items on a specified frame that contain the specified data.
    581674         */
    582         private static Collection<Item> getByData(final Frame frame, final String data) {
     675        public static Collection<Item> getByData(final Frame frame, final String data) {
    583676                final Collection<Item> allItems = frame.getAllItems();
    584677                allItems.removeIf(i -> i.getData() == null || !i.hasData(data));
    585678                return allItems;
    586679        }
     680       
     681        public static Collection<Item> getByContent(final Frame frame, final String content) {
     682                final Collection<Item> allItems = frame.getAllItems();
     683                allItems.removeIf(i -> i.getText().compareTo(content) != 0);
     684                return allItems;
     685        }
    587686}
  • trunk/src/org/expeditee/auth/Authenticator.java

    r1202 r1243  
    55import java.io.FileNotFoundException;
    66import java.io.FileOutputStream;
    7 import java.io.FileWriter;
    87import java.io.IOException;
    98import java.io.InputStream;
    10 import java.io.Writer;
     9import java.nio.file.Path;
     10import java.nio.file.Paths;
    1111import java.security.KeyFactory;
    1212import java.security.KeyStore;
     
    2222import java.sql.Connection;
    2323import java.sql.DriverManager;
     24import java.sql.PreparedStatement;
    2425import java.sql.ResultSet;
    2526import java.sql.SQLException;
    26 import java.sql.Statement;
    2727import java.util.Arrays;
    2828import java.util.Base64;
     
    3030import java.util.HashMap;
    3131import java.util.Map;
     32import java.util.Scanner;
    3233import java.util.stream.Stream;
    3334
     
    3637
    3738import org.expeditee.actions.Actions;
     39import org.expeditee.auth.tags.Constants;
    3840import org.expeditee.core.Dimension;
    3941import org.expeditee.core.Point;
     
    5052import org.expeditee.gui.FrameUtils;
    5153import org.expeditee.gui.MessageBay;
     54import org.expeditee.io.ExpReader;
     55import org.expeditee.items.Item;
    5256import org.expeditee.items.ItemUtils;
    5357import org.expeditee.items.Text;
    5458import org.expeditee.settings.Settings;
    5559import org.expeditee.settings.UserSettings;
    56 import org.expeditee.settings.auth.secrets.KeyList;
     60import org.expeditee.settings.identity.secrets.KeyList;
    5761import org.ngikm.cryptography.CryptographyConstants;
    5862
     
    6064       
    6165        // The frame number of the frame containing the current authenticated users public key.
    62         public static final int PUBLIC_KEY_FRAME = 4;
     66        public static int CREDENTIALS_FRAME = 13;
     67       
     68        public static boolean Authenticated = false;
    6369       
    6470        private final KeyStore keyStore = KeyStore.getInstance(KeystoreType);
     71               
    6572        private static final byte[] TRUE = "yes".getBytes();
    6673        private static final byte[] FALSE = "no".getBytes();
     
    8289
    8390                // draw the window
    84                 final GraphicsManager g = EcosystemManager.getGraphicsManager();
     91                GraphicsManager g = EcosystemManager.getGraphicsManager();
    8592                g.setWindowLocation(new Point(50, 50));
    8693                DisplayController.Init();
     
    98105               
    99106                // navigate to authentication frame
    100                 final Frame authFrame = FrameIO.LoadFrame("authentication1");
     107                Frame authFrame = FrameIO.LoadFrame("authentication1");
    101108                DisplayController.setCurrentFrame(authFrame, true);
    102109               
    103110                // set initial values
    104                 final Stream<Text> usernameItemsStream = authFrame.getTextItems().stream().filter(t -> t.getData() != null && t.getData().contains("txtUsername"));
    105                 final Stream<Text> passwordItemsStream = authFrame.getTextItems().stream().filter(t -> t.getData() != null && t.getData().contains("txtPassword"));
     111                Stream<Text> usernameItemsStream = authFrame.getTextItems().stream().filter(t -> t.getData() != null && t.getData().contains("txtUsername"));
     112                Stream<Text> passwordItemsStream = authFrame.getTextItems().stream().filter(t -> t.getData() != null && t.getData().contains("txtPassword"));
    106113                usernameItemsStream.forEach(txtUsername -> txtUsername.setText(System.getProperty("user.name", "")));
    107114                passwordItemsStream.forEach(txtPassword -> txtPassword.setText(System.getProperty("user.password", "")));
     
    109116                MessageBay.warningMessages(org.expeditee.actions.Actions.Init());
    110117               
    111                 // ensure database
     118                // class load database classes
    112119                Class.forName("org.sqlite.JDBC");
    113                 if (!mailDatabaseExists()) {
    114                         createMailDatabase();
    115                 }
    116         }
    117        
    118         private void createMailDatabase() throws ClassNotFoundException, SQLException {
    119                 Connection c = DriverManager.getConnection("jdbc:sqlite:" + FrameIO.PARENT_FOLDER + "/expmail.db");
    120                 Statement createTable = c.createStatement();
    121                 String sql = "CREATE TABLE EXPMAIL (" +
    122                                 "SND            TEXT                                    NOT NULL, " +
    123                                 "REC            TEXT                                    NOT NULL, " +
    124                                 "MSG            TEXT                                    NOT NULL, " +
    125                                 "MSG2           TEXT                                    NOT NULL, " +
    126                                 "OPTS           ARRAY                                   NOT NULL, " +
    127                                 "OPTSVAL        ARRAY                                   NOT NULL)";
    128                 createTable.executeUpdate(sql);
    129                 createTable.close();
    130                 c.close();
    131         }
    132        
    133         final void loadMailDatabase() throws SQLException {
    134                 Connection c = DriverManager.getConnection("jdbc:sqlite:" + FrameIO.PARENT_FOLDER + "/expmail.db");
    135                 Statement query = c.createStatement();
    136                 ResultSet results = query.executeQuery("SELECT * FROM EXPMAIL");
    137                 Mail.clear();
    138                 while (results.next()) {
    139                         String from = results.getString("snd");
    140                         String to = results.getString("rec");
    141                         String msg = results.getString("msg");
    142                         String msg2 = results.getString("msg2");
    143                         String[] opts = results.getString("opts").split(",");
     120        }
     121               
     122        private void loadKeystore()
     123                        throws IOException, NoSuchAlgorithmException, CertificateException, FileNotFoundException {
     124                final File keyStoreFile = new File(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME);
     125                if (!keyStoreFile.exists()) {
     126                        keyStore.load(null, Constants.CREDENTIALS_KEYSTORE_PASSWORD.toCharArray());
     127                } else {
     128                        try (final InputStream in = new FileInputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME)) {
     129                                keyStore.load(in, Constants.CREDENTIALS_KEYSTORE_PASSWORD.toCharArray());
     130                        }
     131                }
     132        }
     133       
     134        final void loadMailFromDirectory(Path contactDir) throws SQLException {
     135                // Load in all mail.
     136                Connection c = DriverManager.getConnection("jdbc:sqlite:" + contactDir.resolve("expmail.db"));
     137                String sql = "SELECT * FROM EXPMAIL";
     138                PreparedStatement query = c.prepareStatement(sql);
     139                ResultSet allMail = query.executeQuery();
     140
     141                // Construct all mail objects using content from database.
     142                while(allMail.next()) {
     143                        String timestamp = allMail.getString("time");
     144                        String from = allMail.getString("snd");
     145                        String to = allMail.getString("rec");
     146                        String msg = allMail.getString("msg");
     147                        String msg2 = allMail.getString("msg2");
     148                        String[] opts = allMail.getString("opts").split(",");
    144149                        opts[0] = opts[0].replace("[", "");
    145150                        opts[opts.length - 1] = opts[opts.length - 1].replace("]", "");
    146                         String[] optsVal = results.getString("optsval").split(",");
     151                        String[] optsVal = allMail.getString("optsval").split(",");
    147152                        optsVal[0] = optsVal[0].replace("[", "");
    148153                        optsVal[optsVal.length - 1] = optsVal[optsVal.length - 1].replace("]", "");
     
    155160                        }
    156161                       
    157                         Mail.addEntry(new Mail.MailEntry(from, to, msg, msg2, options));
    158                 }
    159                 results.close();
     162                        Mail.addEntry(new Mail.MailEntry(timestamp, from, to, msg, msg2, options));
     163                }
     164               
     165                // Disconnect from database.
     166                allMail.close();
    160167                query.close();
    161168                c.close();
    162169        }
    163170       
    164         private boolean mailDatabaseExists() {
    165                 final File file = new File(FrameIO.PARENT_FOLDER + "/expmail.db");
    166                 return file.exists();
    167         }
    168                
    169         private void loadKeystore()
    170                         throws IOException, NoSuchAlgorithmException, CertificateException, FileNotFoundException {
    171                 final File keyStoreFile = new File(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME);
    172                 if (!keyStoreFile.exists()) {
    173                         keyStore.load(null, "ExpediteeAuthPassword".toCharArray());
    174                 } else {
    175                         try (final InputStream in = new FileInputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME)) {
    176                                 keyStore.load(in, "ExpediteeAuthPassword".toCharArray());
     171        final void loadMailDatabase() throws SQLException {
     172                Path contactsPath = Paths.get(FrameIO.CONTACTS_PATH);
     173                File[] contacts = contactsPath.toFile().listFiles();
     174                for (int i = 0; i < contacts.length; i++) {
     175                        if (contacts[i].isDirectory()) {
     176                                Path contact = Paths.get(contacts[i].getAbsolutePath());
     177                                loadMailFromDirectory(contact);
    177178                        }
    178179                }
     
    195196                final KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(password.toCharArray());
    196197                keyStore.setEntry(label, entry, entryPassword);
    197                 keyStore.store(new FileOutputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME), "ExpediteeAuthPassword".toCharArray());
    198         }
    199        
    200         final void putEmail(String username, String email) throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, IOException {
    201                 // Establish location of email file
    202                 String emailFilePath = FrameIO.PROFILE_PATH + username + File.separator + username + ".email";
    203                 File emailFile = new File(emailFilePath);
    204                
    205                 // Delete old version if it exists.
    206                 if (emailFile.exists()) {
    207                         emailFile.delete();
    208                 }
    209                
    210                 // Write email to file
    211                 emailFile.createNewFile();
    212                 Writer w = new FileWriter(emailFile);
    213                 w.write(email);
    214                 w.flush();
    215                 w.close();
    216                
    217                 // TODO: set rights on file to be read only by 'owner' once installed on drive.
    218         }
    219        
    220         final boolean hasRegisteredEmail(String username) throws KeyStoreException {
    221                 String emailFilePath = FrameIO.PROFILE_PATH + username + File.separator + username + ".email";
    222                 File emailFile = new File(emailFilePath);
    223                 return emailFile.exists();
     198                keyStore.store(new FileOutputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME), Constants.CREDENTIALS_KEYSTORE_PASSWORD.toCharArray());
    224199        }
    225200       
     
    232207                        } else if (entry.getSecretKey().getEncoded() == TRUE) {
    233208                                keyStore.deleteEntry(email + username);
    234                                 keyStore.store(new FileOutputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME), "ExpediteeAuthPassword".toCharArray());
     209                                keyStore.store(new FileOutputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME), Constants.CREDENTIALS_KEYSTORE_PASSWORD.toCharArray());
    235210                                return true;
    236211                        } else { return false; }
     
    251226                final KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(intergalacticNumber.toCharArray());
    252227                keyStore.setEntry(email + username, entry, entryPassword);
    253                 keyStore.store(new FileOutputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME), "ExpediteeAuthPassword".toCharArray());
     228                keyStore.store(new FileOutputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME), Constants.CREDENTIALS_KEYSTORE_PASSWORD.toCharArray());
    254229               
    255230                return intergalacticNumber;
    256231        }
    257232       
    258         final PublicKey getPublicKey(String username) throws InvalidKeySpecException, NoSuchAlgorithmException {
    259                 Frame withTargetPublic = FrameIO.LoadFrame(username + Authenticator.PUBLIC_KEY_FRAME);
    260                 Collection<Text> textItems = withTargetPublic.getTextItems();
    261                 textItems.removeIf(t -> !t.getText().startsWith("PublicKey"));
    262                
    263                 if (textItems.isEmpty()) {
     233        final PublicKey getPublicKey(String username) throws InvalidKeySpecException, NoSuchAlgorithmException, FileNotFoundException {
     234                // load in frame with public key on it.
     235                String credentialsFramesetPath = FrameIO.CONTACTS_PATH + username + "-credentials" + File.separator;
     236                if (!new File(credentialsFramesetPath).exists()) {
    264237                        return null;
    265                 } else {
    266                         String keyEncoded = textItems.stream().findFirst().get().getData().get(0);
    267                         byte[] keyBytes = Base64.getDecoder().decode(keyEncoded);
    268                         PublicKey key = KeyFactory.getInstance(AsymmetricAlgorithm).generatePublic(new X509EncodedKeySpec(keyBytes));
    269                         return key;
    270                 }
     238                }
     239                Scanner in = new Scanner(new File(credentialsFramesetPath + "credentials.inf"));
     240                String credentialsFrameNumber = in.nextLine().replace(ExpReader.EXTENTION, "");
     241                in.close();
     242                Frame frame = FrameIO.LoadFrame(username + "-credentials" + credentialsFrameNumber, FrameIO.CONTACTS_PATH);
     243                if (frame == null) {
     244                        return null;
     245                }
     246               
     247                // obtain public key from frame
     248                Collection<Item> canditates = org.expeditee.auth.Actions.getByContent(frame, "PublicKey");
     249                String keyEncoded = "";
     250                for (Item i: canditates) {
     251                        if (i.getData() != null) {
     252                                keyEncoded = i.getData().get(0);
     253                        }
     254                }
     255                if (keyEncoded.isEmpty()) {
     256                        return null;
     257                }
     258                byte[] keyBytes = Base64.getDecoder().decode(keyEncoded);
     259                return KeyFactory.getInstance(AsymmetricAlgorithm).generatePublic(new X509EncodedKeySpec(keyBytes));
    271260        }
    272261       
     
    275264                KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(KeyList.PersonalKey.get().getText().toCharArray());
    276265                keyStore.setEntry(username + "colleaguesRequested", entry, entryPassword);
    277                 keyStore.store(new FileOutputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME), "ExpediteeAuthPassword".toCharArray());
     266                keyStore.store(new FileOutputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME), Constants.CREDENTIALS_KEYSTORE_PASSWORD.toCharArray());
    278267        }
    279268       
     
    282271                KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(KeyList.PersonalKey.get().getText().toCharArray());
    283272                keyStore.setEntry(username + "colleaguesRequested", entry, entryPassword);
    284                 keyStore.store(new FileOutputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME), "ExpediteeAuthPassword".toCharArray());
     273                keyStore.store(new FileOutputStream(FrameIO.PARENT_FOLDER + KEYSTOREFILENAME), Constants.CREDENTIALS_KEYSTORE_PASSWORD.toCharArray());
    285274        }
    286275       
     
    296285        }
    297286       
    298         final void putColleagues(String username, String[] colleagues) throws KeyStoreException {
    299                 String alias = username + "colleagues";
    300                 final SecretKeySpec secretKeySpec = new SecretKeySpec((colleagues[0] + System.getProperty("line.separator") + colleagues[1]).getBytes(), SymmetricAlgorithm);
    301                 KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(secretKeySpec);
    302                 KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(KeyList.PersonalKey.get().getText().toCharArray());
    303                 keyStore.setEntry(alias, entry, entryPassword);
    304         }
    305        
    306         final String[] getColleagues(String username) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableEntryException {
    307                 String alias = username + "colleagues";
    308                 if (!keyStore.containsAlias(alias)) {
    309                         return null;
    310                 } else {
    311                         KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(KeyList.PersonalKey.get().getText().toCharArray());
    312                         KeyStore.SecretKeyEntry entry = (SecretKeyEntry) keyStore.getEntry(alias, entryPassword);
    313                         byte[] colleaguesEncoded = entry.getSecretKey().getEncoded();
    314                         String colleagues = new String(colleaguesEncoded);
    315                         return colleagues.split(System.getProperty("line.separator"));
    316                 }
    317         }
     287//      final void putColleagues(String username, String[] colleagues) throws KeyStoreException {
     288//              String alias = username + "colleagues";
     289//              final SecretKeySpec secretKeySpec = new SecretKeySpec((colleagues[0] + System.getProperty("line.separator") + colleagues[1]).getBytes(), SymmetricAlgorithm);
     290//              KeyStore.SecretKeyEntry entry = new KeyStore.SecretKeyEntry(secretKeySpec);
     291//              KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(KeyList.PersonalKey.get().getText().toCharArray());
     292//              keyStore.setEntry(alias, entry, entryPassword);
     293//      }
     294//     
     295//      final String[] getColleagues(String username) throws KeyStoreException, NoSuchAlgorithmException, UnrecoverableEntryException {
     296//              String alias = username + "colleagues";
     297//              if (!keyStore.containsAlias(alias)) {
     298//                      return null;
     299//              } else {
     300//                      KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(KeyList.PersonalKey.get().getText().toCharArray());
     301//                      KeyStore.SecretKeyEntry entry = (SecretKeyEntry) keyStore.getEntry(alias, entryPassword);
     302//                      byte[] colleaguesEncoded = entry.getSecretKey().getEncoded();
     303//                      String colleagues = new String(colleaguesEncoded);
     304//                      return colleagues.split(System.getProperty("line.separator"));
     305//              }
     306//      }
    318307       
    319308        private static void setInputManagerWindowRoutines()     {
  • trunk/src/org/expeditee/auth/EncryptedExpReader.java

    r1227 r1243  
    2323import org.expeditee.io.ExpReader;
    2424import org.expeditee.items.Text;
    25 import org.expeditee.settings.auth.secrets.KeyList;
     25import org.expeditee.settings.identity.secrets.KeyList;
    2626import org.ngikm.cryptography.CryptographyConstants;
    2727
     
    3131        static final String ENCRYPTED_EXP_FLAG = "EncryptedExp";
    3232        private SecretKey personalKey;
    33         //private List<SecretKey> multiKey;
    3433        private boolean accessDenied = false;
    35         //private boolean usePersonalKey;
    3634
    3735        public EncryptedExpReader(final String frameName) throws UnsupportedEncodingException {
     
    4947                try {
    5048                        BufferedReader reader = new EncryptedLineReader(new BufferedReader(new FileReader(fullpath)));
    51                         //if (usePersonalKey) {
    52                         //      reader = new EncryptedProfileLineReader(new BufferedReader(new FileReader(fullpath)));
    53                         //} else {
    54                         //      reader = new EncryptedLineReader(new BufferedReader(new FileReader(fullpath)));
    55                         //}
    5649                        String next = "";
    5750                        // First read the header lines until we get the version number
     
    7669                Reader in = new InputStreamReader(new FileInputStream(fullPath), "UTF-8");
    7770                return readFrame(new EncryptedLineReader(in));
    78                 //if (usePersonalKey) {
    79                 //      return readFrame(new EncryptedProfileLineReader(new BufferedReader(in)));
    80                 //} else {
    81                 //      return readFrame(new EncryptedLineReader(new BufferedReader(in)));
    82                 //}
    8371        }
    8472       
  • trunk/src/org/expeditee/auth/EncryptedExpWriter.java

    r1227 r1243  
    66import java.util.Arrays;
    77import java.util.Base64;
     8import java.util.List;
    89
    910import javax.crypto.BadPaddingException;
     
    1617import org.expeditee.io.ExpWriter;
    1718import org.expeditee.items.Text;
    18 import org.expeditee.settings.auth.secrets.KeyList;
     19import org.expeditee.settings.identity.secrets.KeyList;
    1920import org.ngikm.cryptography.CryptographyConstants;
    2021
     
    2829                        // obtain personal key
    2930                        Text text = KeyList.PersonalKey.get();
    30                         byte[] keyBytes = Base64.getDecoder().decode(text.getData().get(0));
    31                         key = new SecretKeySpec(keyBytes, SymmetricAlgorithm);
     31                        List<String> data = text.getData();
     32                        if (data != null && !data.isEmpty()) {
     33                                byte[] keyBytes = Base64.getDecoder().decode(data.get(0));
     34                                key = new SecretKeySpec(keyBytes, SymmetricAlgorithm);
     35                        }
    3236                        label = "Profile";
    3337                } else {
  • trunk/src/org/expeditee/auth/Mail.java

    r1202 r1243  
    11package org.expeditee.auth;
    22
     3import java.nio.file.Path;
    34import java.security.InvalidKeyException;
    45import java.security.NoSuchAlgorithmException;
     
    2122import javax.crypto.NoSuchPaddingException;
    2223
    23 import org.expeditee.gui.FrameIO;
    2424import org.ngikm.cryptography.CryptographyConstants;
    2525
     
    3939        }
    4040       
    41         public static void sendMail(MailEntry mail, PublicKey key) {
     41        public static void sendMail(MailEntry mail, PublicKey key, Path outbox) {
    4242                try {
    4343                        Cipher cipher = Cipher.getInstance(AsymmetricAlgorithm + AsymmetricAlgorithmParameters);
    4444                       
    4545                        // encrypt the necessary parts of the message
     46                        cipher.init(Cipher.ENCRYPT_MODE, key);
     47                        String time = Base64.getEncoder().encodeToString(cipher.doFinal(mail.timestamp.getBytes()));
    4648                        cipher.init(Cipher.ENCRYPT_MODE, key);
    4749                        String sender = Base64.getEncoder().encodeToString(cipher.doFinal(mail.sender.getBytes()));
     
    6365                       
    6466                        // write to mail database
    65                         Connection c = DriverManager.getConnection("jdbc:sqlite:" + FrameIO.PARENT_FOLDER + "/expmail.db");
    66                         String sql = "INSERT INTO EXPMAIL (SND,REC,MSG,MSG2,OPTS,OPTSVAL) VALUES (?, ?, ?, ?, ?, ?);";
     67                        Connection c = DriverManager.getConnection("jdbc:sqlite:" + outbox.resolve("expmail.db"));
     68                        String sql = "INSERT INTO EXPMAIL (TIME,SND,REC,MSG,MSG2,OPTS,OPTSVAL) VALUES (?, ?, ?, ?, ?, ?, ?);";
    6769                        PreparedStatement statement = c.prepareStatement(sql);
    68                         statement.setString(1, sender);
    69                         statement.setString(2, rec);
    70                         statement.setString(3, message);
    71                         statement.setString(4, message2);
     70                        statement.setString(1, time);
     71                        statement.setString(2, sender);
     72                        statement.setString(3, rec);
     73                        statement.setString(4, message);
     74                        statement.setString(5, message2);
    7275                        String opts = Arrays.toString(options.keySet().toArray());
    73                         statement.setString(5, opts);
     76                        statement.setString(6, opts);
    7477                        String optsval = Arrays.toString(options.values().toArray());
    75                         statement.setString(6, optsval);
     78                        statement.setString(7, optsval);
    7679                        statement.execute();
    7780                        statement.close();
     
    105108                       
    106109                        // add an unencrypted version of the message to the return list
    107                         if (receiverDecrypted.compareTo(name) == 0) {
     110                        if (receiverDecrypted.compareToIgnoreCase(name) == 0) {
     111                                c.init(Cipher.DECRYPT_MODE, key);
     112                                String timestamp = new String(c.doFinal(Base64.getDecoder().decode(mail.timestamp)));
    108113                                c.init(Cipher.DECRYPT_MODE, key);
    109114                                String sender = new String(c.doFinal(Base64.getDecoder().decode(mail.sender)));
     
    123128                               
    124129                                //String arguments = new String(c.doFinal(Base64.getDecoder().decode(mail.args)));
    125                                 filtered.add(new MailEntry(sender, receiverDecrypted, message, message2, options));
     130                                filtered.add(new MailEntry(timestamp, sender, receiverDecrypted, message, message2, options));
    126131                        }
    127132                }
     
    134139         */
    135140        public static class MailEntry {
     141                public String timestamp;
    136142                public String sender;
    137143                public String receiver;
     
    140146                public Map<String, String> options;
    141147               
    142                 public MailEntry(String sender, String rec, String message, String message2, Map<String, String> options) {
     148                public MailEntry(String timestamp, String sender, String rec, String message, String message2, Map<String, String> options) {
     149                        this.timestamp = timestamp;
    143150                        this.sender = sender;
    144151                        this.receiver = rec;
  • trunk/src/org/expeditee/auth/gui/MailBay.java

    r1203 r1243  
    8888         * @return
    8989         */
    90         public synchronized static Text addMessage(String message, String message2, Map<String, String> options) {
     90        public synchronized static Text addMessage(String timestamp, String message, String message2, Map<String, String> options) {
    9191                // Invalidate whole area
    9292                DisplayController.invalidateArea(DisplayController.getMessageBayPaintArea());
     
    113113                _previewMessages.add(t);
    114114                _messages.add(t);
     115                _creator.addText(timestamp, Colour.BLACK, null, null, false);
    115116                for (Text line: mail.getMessage()) {
    116117                        _creator.addItem(line.copy(), false);
  • trunk/src/org/expeditee/auth/tags/AuthenticationTag.java

    r1242 r1243  
    1 package org.expeditee.auth;
     1package org.expeditee.auth.tags;
    22
    33import java.util.Collection;
     
    1515        NewPasswordAgain ("txtNewPasswordAgain", System.getProperty("user.new.password.again")),
    1616        Email ("txtEmail", System.getProperty("user.email")),
     17        EmailAgain ("txtEmailAgain", System.getProperty("user.email.again")),
    1718        ColleagueOne ("txtColleagueOne", System.getProperty("user.colleague.one")),
    18         ColleagueTwo ("txtColleagueTwo", System.getProperty("user.colleague.two"));
     19        ColleagueTwo ("txtColleagueTwo", System.getProperty("user.colleague.two")),
     20        Frameset ("txtFrameset", System.getProperty("user.toshare.frameset"));
    1921       
    2022        public String val;
    2123        public String def;
    2224
    23         private AuthenticationTag(final String tag, final String def) {
     25        private AuthenticationTag(String tag, String def) {
    2426                this.val = tag;
    2527                this.def = def;         
     
    3335                                // use the canditate if it exists
    3436                                if (canditate.hasData(tag.val)) {
    35                                         fetchedData.put(tag, canditate.getText());
     37                                        if (tag.val.equals("txtUsername")) {
     38                                                fetchedData.put(tag, canditate.getText().toLowerCase());
     39                                        } else {
     40                                                fetchedData.put(tag, canditate.getText());
     41                                        }
    3642                                        break;
    3743                                }
Note: See TracChangeset for help on using the changeset viewer.