Changeset 1277


Ignore:
Timestamp:
04/02/19 15:22:06 (5 years ago)
Author:
bln4
Message:

Changes have been made to how mail is stored. Each user now has a location in their deaddrops folder (found inside their resources folder) that acts as an exchange location for each of their partnerships. Mail databases now belong in there.

Initial functionality to support the culling of already processed messages from the mail database has been implemented with more to follow.

Location:
trunk/src/org/expeditee
Files:
5 edited

Legend:

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

    r1271 r1277  
    2121import java.security.spec.InvalidKeySpecException;
    2222import java.security.spec.PKCS8EncodedKeySpec;
    23 import java.sql.Connection;
    24 import java.sql.DriverManager;
    2523import java.sql.SQLException;
    26 import java.sql.Statement;
     24import java.text.ParseException;
    2725import java.util.Base64;
    2826import java.util.Collection;
     
    7977                options.put("Neat", "Beep");
    8078                MailEntry mail = new MailEntry(time, sender, colleagueName, topic, message, options);
    81                 PublicKey publicKey = Authenticator.getInstance().getPublicKey(colleagueName);
    82                 Path outbox = Paths.get(FrameIO.PROFILE_PATH).resolve(sender).resolve(sender + "-credentials");
    83                 Mail.sendMail(mail, publicKey, outbox);
     79                Mail.sendMail(mail, colleagueName);
    8480        }
    8581        private static String userbackup = "authadmin";
     
    9995         * @throws FileNotFoundException
    10096         * @throws KeyStoreException
    101          */
    102         public static void MailMode() throws KeyStoreException, FileNotFoundException, NoSuchAlgorithmException, CertificateException, ClassNotFoundException, SQLException, IOException {
     97         * @throws ParseException
     98         */
     99        public static void MailMode() throws KeyStoreException, FileNotFoundException, NoSuchAlgorithmException, CertificateException, ClassNotFoundException, SQLException, IOException, ParseException {
    103100                if (!DisplayController.isMailMode()) {
    104101                        Mail.clear();
     
    133130         * @throws InvalidKeySpecException
    134131         * @throws InvalidKeyException
     132         * @throws ParseException
    135133         * @throws Exception
    136134         */
    137         public static void AuthCreateAccount() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, ClassNotFoundException, InvalidFramesetNameException, ExistingFramesetException, IOException, SQLException, InvalidKeyException, InvalidKeySpecException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
     135        public static void AuthCreateAccount() throws KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, ClassNotFoundException, InvalidFramesetNameException, ExistingFramesetException, IOException, SQLException, InvalidKeyException, InvalidKeySpecException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, ParseException {
    138136                Collection<Text> textItems = DisplayController.getCurrentFrame().getTextItems();
    139137                Optional<Map<AuthenticationTag, String>> userdata =
     
    192190                        login(userdata.get());
    193191                        Authenticator.Authenticated = true;
    194                 }
    195                 else {
     192                } else {
    196193                        MessageBay.errorMessage(Constants.ERROR_INSUFFICIENT_INFORMATION_PROVIDED);
    197194                }
     
    355352         */
    356353        private static void createAccount(Map<AuthenticationTag, String> userdata) throws InvalidFramesetNameException, ExistingFramesetException,
    357                 KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, ClassNotFoundException, IOException, SQLException {
    358                                
     354                KeyStoreException, NoSuchAlgorithmException, CertificateException, FileNotFoundException, ClassNotFoundException, IOException, SQLException {                   
    359355                // Track progress
    360356                String message = "Creating new user account...";
    361                 //Progress progress = MessageBay.displayProgress(message);
    362357
    363358                // Extract user details
     
    469464                Path destinationFile = destinationDirectory.resolve(Authenticator.CREDENTIALS_FRAME + ExpReader.EXTENTION);
    470465                FrameIO.migrateFrame(credentialsFrame, destinationFile);
    471                 //      outbox
    472                 Connection c = DriverManager.getConnection("jdbc:sqlite:" + credentialsDir.getAbsolutePath() + File.separator + "expmail.db");
    473                 Statement createTable = c.createStatement();
    474                 String sql = "CREATE TABLE EXPMAIL (" +
    475                                 "TIME           TEXT                                    NOT NULL, " +
    476                                 "SND            TEXT                                    NOT NULL, " +
    477                                 "REC            TEXT                                    NOT NULL, " +
    478                                 "MSG            TEXT                                    NOT NULL, " +
    479                                 "MSG2           TEXT                                    NOT NULL, " +
    480                                 "OPTS           ARRAY                                   NOT NULL, " +
    481                                 "OPTSVAL        ARRAY                                   NOT NULL)";
    482                 createTable.executeUpdate(sql);
    483                 createTable.close();
    484                 c.close();
    485466               
    486467                System.out.println(message + "Creating Individual Space.");
     
    492473                contactsDir.mkdir();
    493474               
     475                System.out.println(message + "Creating Space For Dead Drops");
     476               
     477                File deadDropsDir = new File(personalResources.resolve("deaddrops").toAbsolutePath().toString());
     478                deadDropsDir.mkdir();
     479               
    494480                System.err.println("**** Hardwired call in Apollo's AuthioPathManager");
    495481                AudioPathManager.activateAndScanAudioDir(); // ****
     
    497483                System.out.println(message + "Done.");
    498484        }
    499        
    500        
    501485
    502486        /*
    503487         * Function used to authenticate as a specified user (via function arguments).
    504488         */
    505         private static void login(Map<AuthenticationTag, String> userdata) throws NoSuchAlgorithmException, KeyStoreException, FileNotFoundException, CertificateException, ClassNotFoundException, IOException, SQLException, InvalidKeySpecException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
     489        private static void login(Map<AuthenticationTag, String> userdata) throws NoSuchAlgorithmException, KeyStoreException, FileNotFoundException, CertificateException, ClassNotFoundException, IOException, SQLException, InvalidKeySpecException, InvalidKeyException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, ParseException {
    506490                String username = userdata.get(AuthenticationTag.Username);
    507491                String password = userdata.get(AuthenticationTag.Password);
     
    539523                        personalKeyText.setData(Base64.getEncoder().encodeToString(personalKey.getEncoded()));
    540524                        KeyList.PersonalKey.setSetting(personalKeyText);
     525                        UserSettings.UserName.set(username);
    541526                        oneFrame = FrameIO.LoadProfile(username);
    542527                        for (int i = 1; i <= FrameIO.getLastNumber(username); i++) {
     
    608593                options.put("Clear Preview Colleague Nominations", "AuthClearPWColleaguesNominated");
    609594                MailEntry mail = new MailEntry(time, sender, colleagueName, message, message2, options);
    610                 Mail.sendMail(mail, Authenticator.getInstance().getPublicKey(colleagueName), Paths.get(FrameIO.PROFILE_PATH).resolve(sender).resolve(sender + "-credentials"));
     595                Mail.sendMail(mail, colleagueName);
    611596        }
    612597       
     
    631616                        arguments.put("I wish to excuse myself from this responsibility.", "AuthDenyPasswordColleagueRelationship " + sender);
    632617                        MailEntry mail = new MailEntry(time, sender, colleagueOne, topic, message, arguments);
    633                         Path outbox = Paths.get(FrameIO.PROFILE_PATH).resolve(sender).resolve(sender + "-credentials");
    634                         Mail.sendMail(mail, colleagueOneKey, outbox);
     618                        Mail.sendMail(mail, colleagueOne);
    635619                        mail = new MailEntry(time, sender, colleagueTwo, topic, message, arguments);
    636                         Mail.sendMail(mail, colleagueTwoKey, outbox);
     620                        Mail.sendMail(mail, colleagueTwo);
    637621                        Authenticator.getInstance().markRequestedColleagues(UserSettings.UserName.get());
    638622                        return true;
  • trunk/src/org/expeditee/auth/Authenticator.java

    r1270 r1277  
    22
    33import java.io.File;
     4import java.io.FileFilter;
    45import java.io.FileInputStream;
    56import java.io.FileNotFoundException;
    67import java.io.FileOutputStream;
     8import java.io.FileWriter;
    79import java.io.IOException;
    810import java.io.InputStream;
     
    2527import java.sql.ResultSet;
    2628import java.sql.SQLException;
     29import java.text.ParseException;
     30import java.text.SimpleDateFormat;
     31import java.util.ArrayList;
    2732import java.util.Arrays;
    2833import java.util.Base64;
    2934import java.util.Collection;
     35import java.util.Date;
    3036import java.util.HashMap;
     37import java.util.List;
    3138import java.util.Map;
    3239import java.util.Scanner;
     
    5966import org.expeditee.settings.UserSettings;
    6067import org.expeditee.settings.identity.secrets.KeyList;
     68import org.expeditee.stats.Formatter;
    6169import org.ngikm.cryptography.CryptographyConstants;
    6270
     
    172180        }
    173181       
    174         final void loadMailFromDirectory(Path contactDir) throws SQLException {
     182        final void loadMailFromFile(Path dbFile) throws SQLException {
    175183                // Load in all mail.
    176                 Connection c = DriverManager.getConnection("jdbc:sqlite:" + contactDir.resolve("expmail.db"));
     184                Connection c = DriverManager.getConnection("jdbc:sqlite:" + dbFile.toAbsolutePath().toString());
    177185                String sql = "SELECT * FROM EXPMAIL";
    178186                PreparedStatement query = c.prepareStatement(sql);
     
    209217        }
    210218       
    211         final void loadMailDatabase() throws SQLException {
    212                 Path contactsPath = Paths.get(FrameIO.CONTACTS_PATH);
    213                 File[] contacts = contactsPath.toFile().listFiles();
    214                 for (int i = 0; i < contacts.length; i++) {
    215                         if (contacts[i].isDirectory()) {
    216                                 Path contact = Paths.get(contacts[i].getAbsolutePath());
    217                                 loadMailFromDirectory(contact);
    218                         }
    219                 }
    220         }
    221        
     219        final void loadMailDatabase() throws SQLException, FileNotFoundException, ParseException {
     220                Path deadDropPath = Paths.get(FrameIO.DEAD_DROPS_PATH);
     221                for (File connectionDir: deadDropPath.toFile().listFiles()) {
     222                        if (connectionDir.isDirectory()) {
     223                                Path deaddropforcontactPath = Paths.get(connectionDir.getAbsolutePath());
     224                                Path dbFile = deaddropforcontactPath.resolve(UserSettings.UserName.get() + ".db");
     225                                if (dbFile.toFile().exists()) {
     226                                        loadMailFromFile(dbFile);
     227                                }
     228                                Path timestamp = deaddropforcontactPath.resolve(UserSettings.UserName.get() + ".last-accessed");
     229                                try(FileWriter out = new FileWriter(timestamp.toFile())) {
     230                                        out.write(Formatter.getDateTime() + System.getProperty("line.separator"));
     231                                } catch (IOException e) {
     232                                        e.printStackTrace();
     233                                }
     234                                clearOldMailFromDatabase(deaddropforcontactPath);
     235                        }
     236                }
     237        }
     238       
     239        private void clearOldMailFromDatabase(Path directory) throws FileNotFoundException, ParseException, SQLException {
     240                File[] files = directory.toFile().listFiles(new FileFilter() {
     241                        @Override
     242                        public boolean accept(File file) {
     243                                return !file.getName().startsWith(UserSettings.UserName.get());
     244                        }
     245                });
     246               
     247                File dbFile = null;
     248                File lastAccessedFile = null;
     249                for (File file: files) {
     250                        if (file.getName().endsWith(".db")) {
     251                                dbFile = file;
     252                        } else {
     253                                lastAccessedFile = file;
     254                        }
     255                }
     256               
     257                if (dbFile == null || lastAccessedFile == null) {
     258                        System.err.println("Failed to clear old messages from database file.");
     259                        return; // Not the end of the world if we cannot clear out old messages.
     260                }
     261               
     262                SimpleDateFormat format = new SimpleDateFormat("ddMMMyyyy[HH:mm]");
     263                Date timestamp = null;
     264                try(Scanner in = new Scanner(lastAccessedFile)) {
     265                        timestamp = format.parse(in.nextLine());
     266                }
     267               
     268                Connection c = DriverManager.getConnection("jdbc:sqlite:" + dbFile.getAbsolutePath());
     269                String sql = "SELECT * FROM EXPMAIL";
     270                PreparedStatement query = c.prepareStatement(sql);
     271                ResultSet allMail = query.executeQuery();
     272                List<String> oldTimestamps = new ArrayList<String>();
     273               
     274                while (allMail.next()) {
     275                        String time = allMail.getString("time");
     276                        Date messageTimestamp = format.parse(time);
     277                        if (timestamp.after(messageTimestamp)) {
     278                                oldTimestamps.add(time);
     279                        }
     280                }
     281               
     282                System.err.println("Found " + oldTimestamps.size() + " messages to delete.");
     283                // TODO delete the messages from database.
     284        }
     285         
    222286        final SecretKey getSecretKey(final String label, final String password) throws NoSuchAlgorithmException, KeyStoreException {   
    223287               
    224288                char[] password_ca = password.toCharArray();
    225                 //final KeyStore.ProtectionParameter entryPassword = new KeyStore.PasswordProtection(password_ca);
    226289               
    227290                SecretKey secret_key;
    228291                try {
    229                         //SecretKeyEntry entry = (SecretKeyEntry) keyStore.getEntry(label, entryPassword);
    230                         //secret_key = entry.getSecretKey();
    231292                        secret_key = (SecretKey) keyStore.getKey(label, password_ca);                   
    232293                } catch (final UnrecoverableEntryException e) {
  • trunk/src/org/expeditee/auth/Mail.java

    r1243 r1277  
    11package org.expeditee.auth;
    22
     3import java.io.File;
     4import java.io.IOException;
    35import java.nio.file.Path;
     6import java.nio.file.Paths;
    47import java.security.InvalidKeyException;
     8import java.security.KeyStoreException;
    59import java.security.NoSuchAlgorithmException;
    610import java.security.PrivateKey;
    711import java.security.PublicKey;
     12import java.security.cert.CertificateException;
     13import java.security.spec.InvalidKeySpecException;
    814import java.sql.Connection;
    915import java.sql.DriverManager;
    1016import java.sql.PreparedStatement;
    1117import java.sql.SQLException;
     18import java.sql.Statement;
    1219import java.util.ArrayList;
    1320import java.util.Arrays;
     
    2229import javax.crypto.NoSuchPaddingException;
    2330
     31import org.expeditee.gui.FrameIO;
    2432import org.ngikm.cryptography.CryptographyConstants;
    2533
     
    3947        }
    4048       
    41         public static void sendMail(MailEntry mail, PublicKey key, Path outbox) {
     49        public static void sendMail(MailEntry mail, String colleagueName) {
     50                // Ensure dead drop area is set up.
     51                Path databaseFileDirPath = Paths.get(FrameIO.DEAD_DROPS_PATH).resolve(colleagueName);
     52                Path databaseFilePath = databaseFileDirPath.resolve(colleagueName + ".db");
     53                File databaseFile = databaseFilePath.toFile();
     54                if (!databaseFile.exists()) {
     55                        databaseFileDirPath.toFile().mkdirs();
     56                        String sql =
     57                                        "CREATE TABLE EXPMAIL (" +
     58                                        "TIME           TEXT                                    NOT NULL, " +
     59                                        "SND            TEXT                                    NOT NULL, " +
     60                                        "REC            TEXT                                    NOT NULL, " +
     61                                        "MSG            TEXT                                    NOT NULL, " +
     62                                        "MSG2           TEXT                                    NOT NULL, " +
     63                                        "OPTS           ARRAY                                   NOT NULL, " +
     64                                        "OPTSVAL        ARRAY                                   NOT NULL)";
     65                        try {
     66                                Connection c = DriverManager.getConnection("jdbc:sqlite:" + databaseFile.getAbsolutePath());
     67                                Statement createTable = c.createStatement();
     68                                createTable.executeUpdate(sql);
     69                                createTable.close();
     70                                c.close();
     71                        } catch (SQLException e) {
     72                                System.err.println("Error while creating database file.");
     73                                e.printStackTrace();
     74                        }
     75                }
     76               
     77                // Obtain public key
     78                PublicKey publicKey = null;
     79                try {
     80                        publicKey = Authenticator.getInstance().getPublicKey(colleagueName);
     81                } catch (InvalidKeySpecException | NoSuchAlgorithmException | KeyStoreException | CertificateException
     82                                | ClassNotFoundException | IOException | SQLException e) {
     83                        System.err.println("Error while sending message.  Unable to obtain public key for colleague " + 
     84                                colleagueName + ".  Exception message: " + e.getMessage());
     85                        return;
     86                }
     87               
     88                // Check we got public key
     89                if (publicKey == null) {
     90                        System.err.println("Error while sending message.  Unable to obtain public key for colleague.  Have you exchanged contact details?");
     91                        return;
     92                }
     93               
     94                // Send message
     95                sendMail(mail, publicKey, databaseFilePath);
     96        }
     97       
     98        private static void sendMail(MailEntry mail, PublicKey key, Path databaseFile) {
    4299                try {
    43100                        Cipher cipher = Cipher.getInstance(AsymmetricAlgorithm + AsymmetricAlgorithmParameters);
    44101                       
    45102                        // 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()));
     103                        //cipher.init(Cipher.ENCRYPT_MODE, key);
     104                        //String time = Base64.getEncoder().encodeToString(cipher.doFinal(mail.timestamp.getBytes()));
    48105                        cipher.init(Cipher.ENCRYPT_MODE, key);
    49106                        String sender = Base64.getEncoder().encodeToString(cipher.doFinal(mail.sender.getBytes()));
     
    65122                       
    66123                        // write to mail database
    67                         Connection c = DriverManager.getConnection("jdbc:sqlite:" + outbox.resolve("expmail.db"));
     124                        Connection c = DriverManager.getConnection("jdbc:sqlite:" + databaseFile);
    68125                        String sql = "INSERT INTO EXPMAIL (TIME,SND,REC,MSG,MSG2,OPTS,OPTSVAL) VALUES (?, ?, ?, ?, ?, ?, ?);";
    69126                        PreparedStatement statement = c.prepareStatement(sql);
    70                         statement.setString(1, time);
     127                        statement.setString(1, mail.timestamp);
    71128                        statement.setString(2, sender);
    72129                        statement.setString(3, rec);
     
    110167                        if (receiverDecrypted.compareToIgnoreCase(name) == 0) {
    111168                                c.init(Cipher.DECRYPT_MODE, key);
    112                                 String timestamp = new String(c.doFinal(Base64.getDecoder().decode(mail.timestamp)));
    113                                 c.init(Cipher.DECRYPT_MODE, key);
    114169                                String sender = new String(c.doFinal(Base64.getDecoder().decode(mail.sender)));
    115170                                c.init(Cipher.DECRYPT_MODE, key);
     
    128183                               
    129184                                //String arguments = new String(c.doFinal(Base64.getDecoder().decode(mail.args)));
    130                                 filtered.add(new MailEntry(timestamp, sender, receiverDecrypted, message, message2, options));
     185                                filtered.add(new MailEntry(mail.timestamp, sender, receiverDecrypted, message, message2, options));
    131186                        }
    132187                }
  • trunk/src/org/expeditee/gui/FrameIO.java

    r1274 r1277  
    116116        public static String HELP_PRIVATE_PATH;
    117117        public static String HELP_PATH;
     118        public static String DEAD_DROPS_PATH;
    118119
    119120        // Paths that appear to be unused.
     
    139140                PUBLIC_PATH = PARENT_FOLDER + "public" + File.separator;
    140141                TRASH_PATH = PARENT_FOLDER + "trash" + File.separator;
    141                 //MESSAGES_PATH = PARENT_FOLDER + "messages" + File.separator;
    142142                HELP_PATH = PARENT_FOLDER + "documentation" + File.separator;
    143143                PROFILE_PATH = PARENT_FOLDER + "profiles" + File.separator;
     
    162162                        AUDIO_PATH = PARENT_FOLDER + "audio" + File.separator;
    163163                        FRAME_PATH = PARENT_FOLDER + "framesets" + File.separator;
     164                        DEAD_DROPS_PATH = PARENT_FOLDER + "deaddrops" + File.separator;
    164165                }
    165166               
     
    199200                        MESSAGES_PATH = resourcesPrivateIndividualPath + "messages" + File.separator;
    200201                        MAIL_PATH = resourcesPrivateIndividualPath + "mail" + File.separator;
     202                        DEAD_DROPS_PATH = resourcesPrivateIndividualPath + "deaddrops" + File.separator;
    201203                }
    202204                       
  • trunk/src/org/expeditee/settings/UserSettings.java

    r1272 r1277  
    259259                        FolderSettings.FrameDirs.addAbsoluteDir(FrameIO.PUBLIC_PATH);
    260260                        FolderSettings.FrameDirs.addAbsoluteDir(FrameIO.HELP_PRIVATE_PATH);
     261                        FolderSettings.FrameDirs.addAbsoluteDir(FrameIO.MAIL_PATH);
    261262                        FolderSettings.FrameDirs.setDefault(FolderSettings.FrameDirs.get());
    262263                                               
     
    271272                        FolderSettings.AudioDirs.addAbsoluteDir(FrameIO.AUDIO_PATH);
    272273                        FolderSettings.AudioDirs.setDefault(FolderSettings.AudioDirs.get());
    273                        
    274274                } else {
    275275                        FolderSettings.FrameDirs.addAbsoluteDir(FrameIO.FRAME_PATH);
Note: See TracChangeset for help on using the changeset viewer.