OSDN Git Service

Change authentication from userid/password to oauth
authorRandy Baumgarte <randy@fbn.cx>
Fri, 25 May 2012 11:13:02 +0000 (07:13 -0400)
committerRandy Baumgarte <randy@fbn.cx>
Sun, 27 May 2012 20:49:16 +0000 (16:49 -0400)
14 files changed:
build.xml
nixnote-osx
nixnote.bat
nixnote.sh
src/cx/fbn/nevernote/Global.java
src/cx/fbn/nevernote/NeverNote.java
src/cx/fbn/nevernote/dialog/ConfigConnectionPage.java
src/cx/fbn/nevernote/dialog/ConfigDialog.java
src/cx/fbn/nevernote/dialog/LoginDialog.java [deleted file]
src/cx/fbn/nevernote/oauth/NNOAuthNetworkAccessManager.java [new file with mode: 0644]
src/cx/fbn/nevernote/oauth/OAuthTokenizer.java [new file with mode: 0644]
src/cx/fbn/nevernote/oauth/OAuthWindow.java [new file with mode: 0644]
src/cx/fbn/nevernote/threads/SyncRunner.java
src/cx/fbn/nevernote/utilities/AESEncrypter.java

index 5ea02bb..2dca043 100644 (file)
--- a/build.xml
+++ b/build.xml
       <pathelement location="${lib.dir}/poi-ooxml-3.7.jar"/>
       <pathelement location="${lib.dir}/poi-ooxml-schemas-3.7-20101029.jar"/>
       <pathelement location="${lib.dir}/poi-scratchpad-3.7-20101029.jar"/>
+      <pathelement location="${lib.dir}/scribe-1.3.0.jar"/>
       <pathelement location="${lib.dir}/tika.jar"/>
       <pathelement location="${lib.dir}/xmlbeans-2.3.0.jar"/>
       <pathelement location="${lib.dir}/xsdlib-20060615.jar"/>
index 490674a..18a1cd9 100644 (file)
@@ -106,6 +106,7 @@ NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/poi-3.7-20101029.jar
 NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/poi-ooxml-3.7.jar
 NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/poi-ooxml-schemas-3.7-20101029.jar
 NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/poi-scratchpad-3.7-20101029.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/scribe-1.3.0.jar
 NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/tika.jar
 NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/xmlbeans-2.3.0.jar
 NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/xsdlib-20060615.jar
index 09ba1a3..c2a79f0 100644 (file)
@@ -99,6 +99,7 @@ set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\poi-3.7-20101029.jar
 set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\poi-ooxml-3.7.jar\r
 set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\poi-ooxml-schemas-3.7-20101029.jar\r
 set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\poi-scratchpad-3.7-20101029.jar\r
+set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\scribe-1.3.0.jar\r
 set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\tika.jar\r
 set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\xmlbeans-2.3.0.jar\r
 set NN_CLASSPATH=%NN_CLASSPATH%;%NIXNOTE%lib\xsdlib-20060615.jar\r
index c0f46b2..eefa460 100755 (executable)
@@ -96,6 +96,7 @@ NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/jazzy.jar
 NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/jtidy-r938.jar
 NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/libthrift.jar
 NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/log4j-1.2.14.jar
+NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/scribe-1.3.0.jar
 NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/pdfbox-app-1.6.0.jar
 NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/poi-3.7-20101029.jar
 NN_CLASSPATH=$NN_CLASSPATH:$NIXNOTE/lib/poi-ooxml-3.7.jar
index dfe7259..2079f5b 100644 (file)
@@ -66,7 +66,7 @@ public class Global {
        public static String version = "1.2";\r
        public static String[] validVersions = {"1.2", "1.1", "1.0", "0.99", "0.98", "0.97", "0.96"};\r
     public static String username = ""; \r
-    public static String password = "";     \r
+    //public static String password = "";     \r
     \r
 \r
     // Each thread has an ID.  This is used primarily to check the status\r
@@ -606,31 +606,6 @@ public class Global {
                        settings.setValue("automaticLogin", "false");\r
                settings.endGroup();\r
     }\r
-    \r
-    // Should it save the Evernote password?\r
-    public static boolean rememberPassword() {\r
-       try {\r
-                       settings.beginGroup("General");\r
-                       String text = (String)settings.value("rememberPassword", "false");\r
-                       settings.endGroup();\r
-                       if (text.equalsIgnoreCase("true"))\r
-                               return true;\r
-                       else\r
-                               return false;   \r
-               } catch (java.lang.ClassCastException e) {\r
-                       Boolean value = (Boolean) settings.value("rememberPassword", false);\r
-                       settings.endGroup();\r
-                       return value;\r
-               }\r
-    }\r
-    public static void setRememberPassword(boolean val) {\r
-               settings.beginGroup("General");\r
-               if (val)\r
-                       settings.setValue("rememberPassword", "true");\r
-               else\r
-                       settings.setValue("rememberPassword", "false");\r
-               settings.endGroup();\r
-    }\r
 \r
     // Get/set the Evernote server Url.  \r
     public static void setServer(String server) {\r
index e710b15..af83947 100644 (file)
@@ -21,6 +21,7 @@ import java.awt.Desktop;
 import java.io.File;
 import java.io.FileInputStream;
 import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
 import java.net.Authenticator;
 import java.net.PasswordAuthentication;
 import java.security.MessageDigest;
@@ -148,7 +149,6 @@ import cx.fbn.nevernote.dialog.DatabaseStatus;
 import cx.fbn.nevernote.dialog.FindDialog;
 import cx.fbn.nevernote.dialog.IgnoreSync;
 import cx.fbn.nevernote.dialog.LogFileDialog;
-import cx.fbn.nevernote.dialog.LoginDialog;
 import cx.fbn.nevernote.dialog.NotebookArchive;
 import cx.fbn.nevernote.dialog.NotebookEdit;
 import cx.fbn.nevernote.dialog.OnlineNoteHistory;
@@ -180,6 +180,8 @@ import cx.fbn.nevernote.gui.TagTreeWidget;
 import cx.fbn.nevernote.gui.Thumbnailer;
 import cx.fbn.nevernote.gui.TrashTreeWidget;
 import cx.fbn.nevernote.gui.controls.QuotaProgressBar;
+import cx.fbn.nevernote.oauth.OAuthTokenizer;
+import cx.fbn.nevernote.oauth.OAuthWindow;
 import cx.fbn.nevernote.sql.DatabaseConnection;
 import cx.fbn.nevernote.sql.WatchFolderRecord;
 import cx.fbn.nevernote.threads.IndexRunner;
@@ -2752,7 +2754,7 @@ public class NeverNote extends QMainWindow{
                                                tr("About NixNote"),
                                                tr("<h4><center><b>NixNote</b></center></h4><hr><center>Version ")
                                                //+Global.version
-                                               +"1.2.120404"
+                                               +"1.2.120508"
                                                +tr("<hr>"
                                                                +"Open Source Evernote Client.<br><br>" 
                                                                +"Licensed under GPL v2.  <br><hr><br>"
@@ -3381,8 +3383,10 @@ public class NeverNote extends QMainWindow{
        }
        // Do a manual connect/disconnect
     private void remoteConnect() {
+       
        logger.log(logger.HIGH, "Entering NeverNote.remoteConnect");
 
+       // If we are already connected, we just disconnect
        if (Global.isConnected) {
                Global.isConnected = false;
                syncRunner.enDisconnect();
@@ -3391,13 +3395,15 @@ public class NeverNote extends QMainWindow{
                return;
        }
        
+       OAuthTokenizer tokenizer = new OAuthTokenizer();
        AESEncrypter aes = new AESEncrypter();
        try {
-                       aes.decrypt(new FileInputStream(Global.getFileManager().getHomeDirFile("secure.txt")));
+                       aes.decrypt(new FileInputStream(Global.getFileManager().getHomeDirFile("oauth.txt")));
                } catch (FileNotFoundException e) {
                        // File not found, so we'll just get empty strings anyway. 
                }
-
+       
+               
                if (Global.getProxyValue("url").equals("")) {
                        System.setProperty("http.proxyHost","") ;
                        System.setProperty("http.proxyPort", "") ;
@@ -3424,43 +3430,54 @@ public class NeverNote extends QMainWindow{
                syncRunner.userStoreUrl = Global.userStoreUrl;
                syncRunner.noteStoreUrl = Global.noteStoreUrl;
                syncRunner.noteStoreUrlBase = Global.noteStoreUrlBase;
-
-               String userid = aes.getUserid();
-               String password = aes.getPassword();
-               if (!userid.equals("") && !password.equals("")) {
-               Global.username = userid;
-               Global.password = password;
-                       syncRunner.username = Global.username;
-                       syncRunner.password = Global.password;
+               
+               
+               
+               String authString = aes.getString();
+               if (!authString.equals("")) {
+                       tokenizer.tokenize(authString);
+                       syncRunner.authToken = tokenizer.oauth_token;
                syncRunner.enConnect();
                }               
 
                Global.isConnected = syncRunner.isConnected;
                
                if (!Global.isConnected) {
-                       // Show the login dialog box
-                       if (!Global.automaticLogin() || userid.equals("")|| password.equals("")) {
-                               LoginDialog login = new LoginDialog();
-                               login.exec();
-               
-                               if (!login.okPressed()) {
-                                       return;
-                               }
-        
-                               Global.username = login.getUserid();
-                               Global.password = login.getPassword();
+               OAuthWindow window = new OAuthWindow(logger);
+               if (window.error) {
+                       setMessage(window.errorMessage);
+                       return;
+               }
+               window.exec();
+               if (window.error) {
+                       setMessage(window.errorMessage);
+                       return;
+                       }
+               tokenizer.tokenize(window.response);
+               if (tokenizer.oauth_token.equals("")) {
+                       setMessage(tr("Invalid authorization token received."));
+                       return;
+               }
+               aes.setString(window.response);
+               try {
+                               aes.encrypt(new FileOutputStream(Global.getFileManager().getHomeDirFile("oauth.txt")));
+                       } catch (FileNotFoundException e) {
+                               // TODO Auto-generated catch block
+                               e.printStackTrace();
                        }
-                       syncRunner.username = Global.username;
-                       syncRunner.password = Global.password;
+               syncRunner.authToken = tokenizer.oauth_token;
                        syncRunner.enConnect();
                        Global.isConnected = syncRunner.isConnected;
                }
-               
+               Global.username = syncRunner.username;
+                       
                if (!Global.isConnected)
                        return;
                setupOnlineMenu();
                setupConnectMenuOptions();
                logger.log(logger.HIGH, "Leaving NeverNote.remoteConnect");
+
+
     }
     private void setupConnectMenuOptions() {
        logger.log(logger.HIGH, "entering NeverNote.setupConnectMenuOptions");
index 8ec11d6..563a1a2 100644 (file)
@@ -45,9 +45,7 @@ import cx.fbn.nevernote.Global;
 import cx.fbn.nevernote.utilities.SyncTimes;\r
 \r
 public class ConfigConnectionPage extends QWidget {\r
-       private final QLineEdit useridEdit;\r
-       private final QLineEdit passwordEdit;\r
-       private final QCheckBox rememberPassword;\r
+\r
        private final QCheckBox autoLogin;\r
        private final QComboBox syncInterval;\r
        private final SyncTimes syncTimes;\r
@@ -63,22 +61,11 @@ public class ConfigConnectionPage extends QWidget {
                \r
                // Userid settings\r
                QGroupBox useridGroup = new QGroupBox(tr("Connection"));\r
-               QLabel useridLabel = new QLabel(tr("Userid"));\r
-               QLabel passwordLabel = new QLabel(tr("Password"));\r
-\r
-               \r
-               useridEdit = new QLineEdit();\r
-               useridEdit.setText(Global.username);\r
-               \r
-               passwordEdit = new QLineEdit();\r
-               passwordEdit.setText(Global.password);\r
-               passwordEdit.setEchoMode(QLineEdit.EchoMode.Password);\r
                \r
                syncInterval = new QComboBox(this);\r
                syncTimes = new SyncTimes();\r
                syncInterval.addItems(syncTimes.stringValues());\r
                \r
-               rememberPassword = new QCheckBox("Remember Userid & Password");\r
                autoLogin = new QCheckBox("Automatic Connect");\r
                synchronizeDeletedContents = new QCheckBox("Synchronze Deleted Note Content");\r
                synchronizeOnClose = new QCheckBox("Synchronize On Shutdown (only if connected)");\r
@@ -113,13 +100,8 @@ public class ConfigConnectionPage extends QWidget {
                \r
                \r
                QFormLayout useridLayout = new QFormLayout();\r
-               useridLayout.addWidget(useridLabel);\r
-               useridLayout.addWidget(useridEdit);             \r
-               useridLayout.addWidget(passwordLabel);\r
-               useridLayout.addWidget(passwordEdit);\r
                useridLayout.addWidget(new QLabel(tr("Syncronization Interval")));\r
                useridLayout.addWidget(syncInterval);\r
-               useridLayout.addWidget(rememberPassword);\r
                useridLayout.addWidget(autoLogin);\r
                useridLayout.addWidget(synchronizeOnClose);\r
                useridLayout.addWidget(synchronizeDeletedContents);\r
@@ -147,39 +129,6 @@ public class ConfigConnectionPage extends QWidget {
        }\r
 \r
        \r
-       //*****************************************\r
-       //* Userid get/set methods \r
-       //*****************************************\r
-       public void setUserid(String id) {\r
-               useridEdit.setText(id);\r
-       }\r
-       public String getUserid() {\r
-               return useridEdit.text();\r
-       }\r
-       \r
-\r
-       //*****************************************\r
-       //* Password get/set methods \r
-       //*****************************************\r
-       public void setPassword(String id) {\r
-               passwordEdit.setText(id);\r
-       }\r
-       public String getPassword() {\r
-               return passwordEdit.text();\r
-       }\r
-       \r
-\r
-       //*******************************************\r
-       //* Remember Password get/set\r
-       //*******************************************\r
-       public void setRememberPassword(boolean val) {\r
-               rememberPassword.setChecked(val);\r
-       }\r
-       public boolean getRememberPassword() {\r
-               return rememberPassword.isChecked();\r
-       }\r
-       \r
-       \r
        \r
        \r
        //*******************************************\r
index d59f402..5e7e7bb 100644 (file)
 \r
 package cx.fbn.nevernote.dialog;\r
 \r
-import java.io.FileInputStream;\r
-import java.io.FileNotFoundException;\r
-import java.io.FileOutputStream;\r
-\r
 import com.swabunga.spell.engine.Configuration;\r
 import com.trolltech.qt.core.QSize;\r
 import com.trolltech.qt.core.Qt.AlignmentFlag;\r
@@ -47,7 +43,6 @@ import com.trolltech.qt.gui.QVBoxLayout;
 import com.trolltech.qt.gui.QWidget;\r
 \r
 import cx.fbn.nevernote.Global;\r
-import cx.fbn.nevernote.utilities.AESEncrypter;\r
 public class ConfigDialog extends QDialog {\r
        private final QListWidget                               contentsWidget;\r
        private final ConfigFontPage                    fontPage;\r
@@ -116,8 +111,7 @@ public class ConfigDialog extends QDialog {
        public void okPushed() {\r
                Global.setServer(debugPage.getServer());\r
                Global.setEnableThumbnails(debugPage.getEnableThumbnails());\r
-               AESEncrypter aes = new AESEncrypter();\r
-               aes.setUserid(connectionPage.getUserid().trim());\r
+\r
                \r
                if (debugPage.getDisableUploads())\r
                        Global.disableUploads = true;\r
@@ -157,10 +151,6 @@ public class ConfigDialog extends QDialog {
                Global.setAutoSaveInterval(appearancePage.getAutoSaveInterval());\r
                                                \r
                Global.setAutomaticLogin(connectionPage.getAutomaticLogin());\r
-               Global.setRememberPassword(connectionPage.getRememberPassword());\r
-               if (connectionPage.getRememberPassword()) {     \r
-                       aes.setPassword(connectionPage.getPassword());\r
-               }\r
                Global.setProxyValue("url", connectionPage.getProxyUrl());\r
                Global.setProxyValue("port", connectionPage.getProxyPort());\r
                Global.setProxyValue("userid", connectionPage.getProxyUserid());\r
@@ -181,14 +171,6 @@ public class ConfigDialog extends QDialog {
                Global.setIncludeTagChildren(appearancePage.getIncludeTagChildren());\r
                Global.setDisplayRightToLeft(appearancePage.getDisplayRightToLeft());\r
                \r
-       FileOutputStream out = null;\r
-               try {\r
-                       out = new FileOutputStream(Global.getFileManager().getHomeDirFile("secure.txt"));\r
-               } catch (FileNotFoundException e) {\r
-                       // if it isn't found we'll write it.\r
-               }\r
-               if (out != null)\r
-                       aes.encrypt(out);\r
                Global.userStoreUrl = "https://"+debugPage.getServer()+"/edam/user";\r
                Global.setWordRegex(indexPage.getRegex());\r
                Global.setRecognitionWeight(indexPage.getRecognitionWeight());\r
@@ -312,26 +294,9 @@ public class ConfigDialog extends QDialog {
                debugPage.setEnableThumbnails(Global.enableThumbnails());\r
 //             if (Global.getUpdateSequenceNumber() > 0)\r
                        debugPage.serverCombo.setEnabled(false);\r
-               \r
-               if (Global.username.equalsIgnoreCase("") || Global.password.equalsIgnoreCase("")) {\r
-               AESEncrypter aes = new AESEncrypter();\r
-               try {\r
-                               aes.decrypt(new FileInputStream(Global.getFileManager().getHomeDirFile("secure.txt")));\r
-                       } catch (FileNotFoundException e) {\r
-                               // File not found, so we'll just get empty strings anyway. \r
-                       }\r
-                       String userid = aes.getUserid();\r
-                       String password = aes.getPassword();\r
-                       if (!userid.equals("") && !password.equals("")) {\r
-                       Global.username = userid;\r
-                       Global.password = password;\r
-                       }                                       \r
-               }\r
+\r
                appearancePage.setAutoSaveInterval(Global.getAutoSaveInterval());\r
-               connectionPage.setUserid(Global.username);\r
-               connectionPage.setPassword(Global.password);\r
                connectionPage.setAutomaticLogin(Global.automaticLogin());\r
-               connectionPage.setRememberPassword(Global.rememberPassword());\r
                appearancePage.setMimicEvernote(Global.getMimicEvernoteInterface());\r
                appearancePage.setShowTrayIcon(Global.showTrayIcon());\r
                connectionPage.setSynchronizeOnClose(Global.synchronizeOnClose());\r
diff --git a/src/cx/fbn/nevernote/dialog/LoginDialog.java b/src/cx/fbn/nevernote/dialog/LoginDialog.java
deleted file mode 100644 (file)
index 238e96e..0000000
+++ /dev/null
@@ -1,121 +0,0 @@
-/*\r
- * This file is part of NixNote \r
- * Copyright 2009 Randy Baumgarte\r
- * \r
- * This file may be licensed under the terms of of the\r
- * GNU General Public License Version 2 (the ``GPL'').\r
- *\r
- * Software distributed under the License is distributed\r
- * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either\r
- * express or implied. See the GPL for the specific language\r
- * governing rights and limitations.\r
- *\r
- * You should have received a copy of the GPL along with this\r
- * program. If not, go to http://www.gnu.org/licenses/gpl.html\r
- * or write to the Free Software Foundation, Inc.,\r
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.\r
- *\r
-*/\r
-\r
-package cx.fbn.nevernote.dialog;\r
-\r
-//**********************************************\r
-//**********************************************\r
-//* Login to Evernote\r
-//**********************************************\r
-//**********************************************\r
-\r
-import com.trolltech.qt.gui.QDialog;\r
-import com.trolltech.qt.gui.QGridLayout;\r
-import com.trolltech.qt.gui.QIcon;\r
-import com.trolltech.qt.gui.QLabel;\r
-import com.trolltech.qt.gui.QLineEdit;\r
-import com.trolltech.qt.gui.QPushButton;\r
-\r
-import cx.fbn.nevernote.Global;\r
-\r
-public class LoginDialog extends QDialog {\r
-\r
-       private boolean         okPressed;\r
-       private final QLineEdit userid;\r
-       private final QLineEdit password;\r
-       private final QPushButton ok;\r
-       private final String iconPath = new String("classpath:cx/fbn/nevernote/icons/");\r
-       \r
-       // Constructor\r
-       public LoginDialog() {\r
-               okPressed = false;\r
-               setWindowTitle(tr("NixNote Login"));\r
-               setWindowIcon(new QIcon(iconPath+"password.png"));\r
-               QGridLayout grid = new QGridLayout();\r
-               setLayout(grid);\r
-               QGridLayout passwordGrid = new QGridLayout();\r
-               QGridLayout buttonGrid = new QGridLayout();\r
-               \r
-               String useridValue = Global.username;\r
-               String passwordValue = Global.password;\r
-               \r
-               userid = new QLineEdit(useridValue);\r
-               password = new QLineEdit(passwordValue);\r
-               password.setEchoMode(QLineEdit.EchoMode.Password);\r
-               \r
-               userid.textChanged.connect(this, "validateInput()");\r
-               password.textChanged.connect(this, "validateInput()");\r
-               \r
-               passwordGrid.addWidget(new QLabel(tr("Userid")), 1,1);\r
-               passwordGrid.addWidget(userid, 1, 2);\r
-               passwordGrid.addWidget(new QLabel(tr("Password")), 2,1);\r
-               passwordGrid.addWidget(password, 2, 2);\r
-               passwordGrid.setContentsMargins(10, 10,  -10, -10);\r
-               grid.addLayout(passwordGrid,1,1);\r
-               \r
-               ok = new QPushButton(tr("OK"));\r
-               ok.clicked.connect(this, "okButtonPressed()");\r
-               QPushButton cancel = new QPushButton(tr("Cancel"));\r
-               cancel.clicked.connect(this, "cancelButtonPressed()");\r
-               buttonGrid.addWidget(ok, 1, 1);\r
-               buttonGrid.addWidget(cancel, 1,2);\r
-               grid.addLayout(buttonGrid,2,1);\r
-       }\r
-       \r
-       // The OK button was pressed\r
-       @SuppressWarnings("unused")\r
-       private void okButtonPressed() {\r
-               okPressed = true;\r
-               close();\r
-       }\r
-       \r
-       // The CANCEL button was pressed\r
-       @SuppressWarnings("unused")\r
-       private void cancelButtonPressed() {\r
-               okPressed = false;\r
-               close();\r
-       }\r
-       \r
-       // Get the userid from the field\r
-       public String getUserid() {\r
-               return userid.text();\r
-       }\r
-       \r
-       // Get the password \r
-       public String getPassword() {\r
-               return password.text();\r
-       }\r
-       \r
-       // Check if the OK button was pressed\r
-       public boolean okPressed() {\r
-               return okPressed;\r
-       }\r
-       \r
-       // Validate user input\r
-       public void validateInput() {\r
-               ok.setEnabled(true);\r
-               if (userid.text().trim().equals("")) {\r
-                       ok.setEnabled(false);\r
-                       return;\r
-               }               if (password.text().trim().equals("")) {\r
-                       ok.setEnabled(false);\r
-                       return;\r
-               }\r
-       }\r
-}\r
diff --git a/src/cx/fbn/nevernote/oauth/NNOAuthNetworkAccessManager.java b/src/cx/fbn/nevernote/oauth/NNOAuthNetworkAccessManager.java
new file mode 100644 (file)
index 0000000..b8c889e
--- /dev/null
@@ -0,0 +1,65 @@
+
+/*
+ * This file is part of NixNote 
+ * Copyright 2012 Randy Baumgarte
+ * 
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/* This class is used to listen to inbound network requests.  It 
+ * examines all of them to look for the OAuth reply.  This reply
+ * is what we need to get access to Evernote.
+ */
+
+package cx.fbn.nevernote.oauth;
+
+import com.trolltech.qt.core.QIODevice;
+import com.trolltech.qt.core.QObject;
+import com.trolltech.qt.network.QNetworkAccessManager;
+import com.trolltech.qt.network.QNetworkReply;
+import com.trolltech.qt.network.QNetworkRequest;
+
+import cx.fbn.nevernote.utilities.ApplicationLogger;
+
+public class NNOAuthNetworkAccessManager extends QNetworkAccessManager {
+       public Signal1<String> tokenFound;
+       private ApplicationLogger logger;
+
+       public NNOAuthNetworkAccessManager(ApplicationLogger l){
+               super();
+               tokenFound = new Signal1<String>();
+               logger = l;
+       }
+
+       public NNOAuthNetworkAccessManager(QObject qObject){
+               super(qObject);
+               tokenFound = new Signal1<String>();
+       }
+
+       @Override
+       protected QNetworkReply createRequest(Operation op,
+                       QNetworkRequest request, QIODevice outgoingData) {
+
+               logger.log(logger.EXTREME,"NNOAuthNetworkAccessManager URL request scheme: " 
+                               +request.url().scheme() + " " + request.url().toString());
+               String searchReq = "nnoauth?oauth_token=";
+               int pos = request.url().toString().indexOf(searchReq);
+               if (pos>0) {
+                       String token = request.url().toString().substring(pos+searchReq.length());
+                       tokenFound.emit(token);
+               }
+               return super.createRequest(op, request, outgoingData);
+       }               
+}
\ No newline at end of file
diff --git a/src/cx/fbn/nevernote/oauth/OAuthTokenizer.java b/src/cx/fbn/nevernote/oauth/OAuthTokenizer.java
new file mode 100644 (file)
index 0000000..505857e
--- /dev/null
@@ -0,0 +1,96 @@
+
+/*
+  * This file is part of NixNote 
+ * Copyright 2012 Randy Baumgarte
+ * 
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+*/
+
+
+
+/* This class is used to parse out the OAuth reply from Evernote */
+
+package cx.fbn.nevernote.oauth;
+
+import java.util.ArrayList;
+
+public class OAuthTokenizer {
+
+         public String oauth_token;
+         public String edam_shard;
+         public String edam_userId;
+         public String edam_expires;
+         public String edam_noteStoreUrl;
+         public String edam_webApiUrlPrefix;
+         
+         public OAuthTokenizer() {
+                 oauth_token = new String();
+                 edam_shard = new String();
+                 edam_userId = new String();
+                 edam_expires = new String();
+                 edam_noteStoreUrl = new String();
+                 edam_webApiUrlPrefix = new String();
+         }
+       
+         public void tokenize(String decoded) {
+               ArrayList<String> tokens = new ArrayList<String>();
+               for (;decoded!=null && decoded.length()>0;) {
+                       int i=decoded.indexOf("&");
+                       if (i>0) {
+                               tokens.add(decoded.substring(0,i));
+                               decoded=decoded.substring(i+1);
+                       } else {
+                               tokens.add(decoded);
+                               decoded="";
+                       }
+               }
+               System.out.println("Tokens found:" +tokens.size());
+               String oauth_tokenString = "oauth_token=";
+               String edam_shardString = "edam_shard=";
+               String edam_userIdString = "edam_userid=";
+               String edam_expiresString = "edam_expires=";
+               String edam_noteStoreUrlString ="edam_notestoreurl=";
+               String edam_webApiUrlPrefixString = "edam_webapiurlprefix=";
+               oauth_token = "";
+               edam_shard = "";
+               edam_userId = "";
+               edam_expires = "";
+               edam_noteStoreUrl = "";
+               edam_webApiUrlPrefix = "";
+               
+               for (int i=0; i<tokens.size(); i++) {
+                       String token = tokens.get(i);
+                       if (token.toLowerCase().startsWith(oauth_tokenString)) {
+                               oauth_token = token.substring(oauth_tokenString.length());
+                       }
+                       if (token.toLowerCase().startsWith(edam_shardString)) {
+                               edam_shard = token.substring(edam_shardString.length());
+                       }
+                       if (token.toLowerCase().startsWith(edam_userIdString)) {
+                               edam_userId = token.substring(edam_userIdString.length());
+                       }
+                       if (token.toLowerCase().startsWith(edam_expiresString)) {
+                               edam_expires = token.substring(edam_expiresString.length());
+                       }
+                       if (token.toLowerCase().startsWith(edam_noteStoreUrlString)) {
+                               edam_noteStoreUrl = token.substring(edam_noteStoreUrlString.length());
+                       }
+                       if (token.toLowerCase().startsWith(edam_webApiUrlPrefixString)) {
+                               edam_webApiUrlPrefix = token.substring(edam_webApiUrlPrefixString.length());
+                       }
+               }
+
+       }
+}
diff --git a/src/cx/fbn/nevernote/oauth/OAuthWindow.java b/src/cx/fbn/nevernote/oauth/OAuthWindow.java
new file mode 100644 (file)
index 0000000..e033482
--- /dev/null
@@ -0,0 +1,166 @@
+
+/*
+  * This file is part of NixNote 
+ * Copyright 2012 Randy Baumgarte
+ * 
+ * This file may be licensed under the terms of of the
+ * GNU General Public License Version 2 (the ``GPL'').
+ *
+ * Software distributed under the License is distributed
+ * on an ``AS IS'' basis, WITHOUT WARRANTY OF ANY KIND, either
+ * express or implied. See the GPL for the specific language
+ * governing rights and limitations.
+ *
+ * You should have received a copy of the GPL along with this
+ * program. If not, go to http://www.gnu.org/licenses/gpl.html
+ * or write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+*/
+
+
+/* This method is used to present the user with the web view of Evernote
+ * that they need to grant permission to Nixnote.
+ */
+
+
+package cx.fbn.nevernote.oauth;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+
+import com.trolltech.qt.core.QUrl;
+import com.trolltech.qt.gui.QDialog;
+import com.trolltech.qt.gui.QGridLayout;
+import com.trolltech.qt.gui.QIcon;
+import com.trolltech.qt.network.QSslSocket;
+import com.trolltech.qt.webkit.QWebView;
+
+import cx.fbn.nevernote.Global;
+import cx.fbn.nevernote.utilities.ApplicationLogger;
+
+public class OAuthWindow extends QDialog {
+       private final static String consumerKey = "baumgarr"; 
+       private final static String consumerSecret = "60d4cdedb074b0ac";
+       public String response;
+
+       private final String temporaryCredUrl;    
+       private final String permanentCredUrl;
+
+
+       static final String urlBase = "https://"+Global.getServer();
+
+       public boolean error;
+       public String errorMessage;
+
+       static final String requestTokenUrl = urlBase + "/oauth";
+       static final String accessTokenUrl = urlBase + "/oauth";
+       static final String authorizationUrlBase = urlBase + "/OAuth.action";
+       private final String iconPath = new String("classpath:cx/fbn/nevernote/");
+       private final QWebView tempPage;
+       private final QWebView authPage;
+       private final QGridLayout grid;
+       private NNOAuthNetworkAccessManager manager;
+
+       static final String callbackUrl = "index.jsp?action=callbackReturn";
+       private final ApplicationLogger logger;
+
+
+       // Constructor.
+       public OAuthWindow(ApplicationLogger l) {
+               logger = l;
+               int millis = (int) System.currentTimeMillis();
+               int time = millis / 1000;
+
+
+               // Create the URLs needed for authentication with Evernote
+               temporaryCredUrl = "https://"+Global.getServer() + "/oauth?oauth_consumer_key=" +consumerKey + "&oauth_signature=" +
+                               consumerSecret + "%26&oauth_signature_method=PLAINTEXT&oauth_timestamp="+String.valueOf(time)+
+                               "&oauth_nonce="+String.valueOf(millis) +"&oauth_callback=nnoauth";
+
+               permanentCredUrl = "https://"+Global.getServer() + "/oauth?oauth_consumer_key=" +consumerKey + "&oauth_signature=" +
+                               consumerSecret + "%26&oauth_signature_method=PLAINTEXT&oauth_timestamp="+String.valueOf(time)+
+                               "&oauth_nonce="+String.valueOf(millis) +"&oauth_token=";
+
+
+               // Build the window
+               setWindowTitle(tr("Please Grant Nixnote Access"));
+               setWindowIcon(new QIcon(iconPath+"icons/password.png"));
+               grid = new QGridLayout();
+               setLayout(grid);
+               tempPage = new QWebView();
+               authPage = new QWebView();
+               grid.addWidget(authPage);
+               tempPage.loadFinished.connect(this, "temporaryCredentialsReceived()");
+
+               error = false;
+               errorMessage = "";
+               
+               // Check that SSL sockets are supported
+               logger.log(logger.MEDIUM, "SSL Sockets Supported: " +QSslSocket.supportsSsl());
+               if (!QSslSocket.supportsSsl()) {
+                       errorMessage = new String(tr("SSL Support not found.  Aborting connection"));
+                       error = true;
+               }
+               
+               // Load the temporary URL to start the authentication procesess.  When 
+               // finished, this QWebView will contain the URL to start the
+               // authentication process.
+               QUrl tu = new QUrl(temporaryCredUrl);
+               tempPage.load(tu);
+       }
+
+       
+       // This method is triggered when the temporary credentials are received from Evernote
+       public void temporaryCredentialsReceived() {
+               logger.log(logger.MEDIUM, "Temporary Credentials Received");
+               String contents = tempPage.page().mainFrame().toPlainText();
+               logger.log(logger.MEDIUM, "Temporary Credentials:" +contents);
+               int index = contents.indexOf("&oauth_token_secret");
+               contents = contents.substring(0,index);
+               QUrl accessUrl = new QUrl(urlBase+"/OAuth.action?" +contents);
+               manager = new NNOAuthNetworkAccessManager(logger);
+               authPage.page().setNetworkAccessManager(manager);
+               manager.tokenFound.connect(this, "tokenFound(String)");
+
+               authPage.load(accessUrl);  
+               grid.addWidget(authPage);
+       }
+
+       // This method is signaled when NNOAuthNetworkAccessManager finds an OAuth token
+       // in the network request.
+       public void tokenFound(String token) {
+               logger.log(logger.MEDIUM, "*** TOKEN *** " +token);
+               if (token.indexOf("auth_verifier") <= 0) {
+                       errorMessage = new String(tr("Error receiving authorization"));
+                       error = true;
+                       this.close();
+               }
+               tempPage.disconnect();
+               tempPage.loadFinished.connect(this, "permanentCredentialsReceived()");
+               logger.log(logger.HIGH,"Permanent URL: " +permanentCredUrl+token);
+               tempPage.load(new QUrl(permanentCredUrl+token));
+       }
+
+       
+       // This method is used when the permanent credentials are finally
+       // received to grant access to Evernote.
+       public void permanentCredentialsReceived() {
+               String contents = tempPage.page().mainFrame().toPlainText();
+               if (contents.startsWith("oauth_token=S%3D")) {
+                       logger.log(logger.HIGH, "Permanent Credentials:" +contents);
+                       String decoded;
+                       try {
+                               response = "";
+                               decoded = URLDecoder.decode(contents,"UTF-8");
+                               logger.log(logger.HIGH, "Decoded URL:"+decoded);
+                               response = decoded;
+                       } catch (UnsupportedEncodingException e) {
+                               e.printStackTrace();
+                       }
+
+                       this.close();
+               }
+       }
+
+}
index 7526577..d01faf6 100644 (file)
@@ -123,15 +123,15 @@ public class SyncRunner extends QObject implements Runnable {
            public volatile String username = ""; \r
            public volatile String password = ""; \r
                public volatile String userStoreUrl;\r
-           private final static String consumerKey = "baumgarte"; \r
-           private final static String consumerSecret = "eb8b5740e17cb55f";\r
+//         private final static String consumerKey = "baumgarte"; \r
+//         private final static String consumerSecret = "eb8b5740e17cb55f";\r
            public String noteStoreUrlBase;\r
            private THttpClient userStoreTrans;\r
            private TBinaryProtocol userStoreProt;\r
-           private AuthenticationResult authResult;\r
+           //private AuthenticationResult authResult;\r
            private AuthenticationResult linkedAuthResult;\r
            private User user; \r
-           private long authTimeRemaining;\r
+//         private long authTimeRemaining;\r
            public long authRefreshTime;\r
            public long failedRefreshes = 0;\r
            public  THttpClient noteStoreTrans;\r
@@ -205,10 +205,10 @@ public class SyncRunner extends QObject implements Runnable {
                                }\r
                                idle=false;\r
                                error=false;\r
-                               if (authRefreshNeeded == true || !isConnected) {\r
-                                       logger.log(logger.EXTREME, "Refreshing connection");\r
-                                       refreshConnection();\r
-                               }\r
+//                             if (authRefreshNeeded == true || !isConnected) {\r
+//                                     logger.log(logger.EXTREME, "Refreshing connection");\r
+//                                     refreshConnection();\r
+//                             }\r
                                if (syncNeeded) {\r
                                        logger.log(logger.EXTREME, "SyncNeeded is true");\r
                                        refreshNeeded=false;\r
@@ -471,9 +471,9 @@ public class SyncRunner extends QObject implements Runnable {
                boolean error = false;\r
                for (int i=0; i<expunged.size() && keepRunning; i++) {\r
 \r
-                       if (authRefreshNeeded)\r
-                               if (!refreshConnection())\r
-                                       return;\r
+//                     if (authRefreshNeeded)\r
+//                             if (!refreshConnection())\r
+//                                     return;\r
 \r
                        try {\r
                                if (expunged.get(i).type.equalsIgnoreCase("TAG")) {\r
@@ -536,9 +536,9 @@ public class SyncRunner extends QObject implements Runnable {
                // Sync the local notebooks with Evernote's\r
                for (int i=0; i<notes.size() && keepRunning; i++) {\r
                        \r
-                       if (authRefreshNeeded)\r
-                               if (!refreshConnection())\r
-                                       return;\r
+//                     if (authRefreshNeeded)\r
+//                             if (!refreshConnection())\r
+//                                     return;\r
                        \r
                        Note enNote = notes.get(i);\r
                        try {\r
@@ -603,9 +603,9 @@ public class SyncRunner extends QObject implements Runnable {
                logger.log(logger.HIGH, "Entering SyncRunner.syncNotes");\r
                status.message.emit(tr("Sending local notes."));\r
 \r
-               if (authRefreshNeeded)\r
-                       if (!refreshConnection())\r
-                               return;\r
+//             if (authRefreshNeeded)\r
+//                     if (!refreshConnection())\r
+//                             return;\r
                        \r
                if (enNote.isActive()) {\r
                        try {\r
@@ -706,9 +706,9 @@ public class SyncRunner extends QObject implements Runnable {
                // Sync the local notebooks with Evernote's\r
                for (int i=0; i<notebooks.size() && keepRunning; i++) {\r
                        \r
-                       if (authRefreshNeeded)\r
-                               if (!refreshConnection())\r
-                                       return;\r
+//                     if (authRefreshNeeded)\r
+//                             if (!refreshConnection())\r
+//                                     return;\r
                        \r
                        Notebook enNotebook = notebooks.get(i);\r
                        try {\r
@@ -808,9 +808,9 @@ public class SyncRunner extends QObject implements Runnable {
                \r
                while(enTag!=null && loopCount < maxCount) {\r
                        loopCount++;\r
-                       if (authRefreshNeeded)\r
-                               if (!refreshConnection())\r
-                                       return;\r
+//                     if (authRefreshNeeded)\r
+//                             if (!refreshConnection())\r
+//                                     return;\r
 \r
                        try {\r
                                if (enTag.getUpdateSequenceNum() > 0) {\r
@@ -944,9 +944,9 @@ public class SyncRunner extends QObject implements Runnable {
                logger.log(logger.EXTREME, "Beginning to send saved searches");\r
                for (int i=0; i<searches.size() &&  keepRunning; i++) {\r
                        \r
-                       if (authRefreshNeeded)\r
-                               if (!refreshConnection())\r
-                                       return;\r
+//                     if (authRefreshNeeded)\r
+//                             if (!refreshConnection())\r
+//                                     return;\r
                        \r
                        SavedSearch enSearch = searches.get(i);\r
                        try {\r
@@ -1025,9 +1025,9 @@ public class SyncRunner extends QObject implements Runnable {
                \r
                while(more &&  keepRunning) {\r
                        \r
-                       if (authRefreshNeeded)\r
-                               if (!refreshConnection())\r
-                                       return;\r
+//                     if (authRefreshNeeded)\r
+//                             if (!refreshConnection())\r
+//                                     return;\r
                        \r
                        int sequence = updateSequenceNumber;\r
                        try {\r
@@ -1516,9 +1516,10 @@ public class SyncRunner extends QObject implements Runnable {
            userStore = new UserStore.Client(userStoreProt, userStoreProt);\r
            syncSignal.saveUserStore.emit(userStore);\r
            try {\r
-                       authResult = userStore.authenticate(username, password, consumerKey, consumerSecret);\r
+                       //authResult = userStore.authenticate(username, password, consumerKey, consumerSecret);\r
+               user = userStore.getUser(authToken);\r
                } catch (EDAMUserException e) {\r
-                       QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, "Error", "Incorrect username/password");\r
+                       QMessageBox mb = new QMessageBox(QMessageBox.Icon.Critical, "Error", "Invalid Authorization");\r
                        mb.exec();\r
                        isConnected = false;\r
                        return false;\r
@@ -1547,9 +1548,9 @@ public class SyncRunner extends QObject implements Runnable {
                System.err.println("Incomatible EDAM client protocol version"); \r
                isConnected = false;\r
            }\r
-           if (authResult != null) {\r
-               user = authResult.getUser(); \r
-               authToken = authResult.getAuthenticationToken(); \r
+           //if (authResult != null) {\r
+               //user = authResult.getUser(); \r
+               //authToken = authResult.getAuthenticationToken(); \r
                noteStoreUrl = noteStoreUrlBase + user.getShardId();\r
                syncSignal.saveAuthToken.emit(authToken);\r
                syncSignal.saveNoteStore.emit(localNoteStore);\r
@@ -1568,9 +1569,9 @@ public class SyncRunner extends QObject implements Runnable {
                localNoteStore = \r
                        new NoteStore.Client(noteStoreProt, noteStoreProt); \r
                isConnected = true;\r
-               authTimeRemaining = authResult.getExpiration() - authResult.getCurrentTime();\r
-               authRefreshTime = authTimeRemaining / 2;\r
-           }\r
+               //authTimeRemaining = authResult.getExpiration() - authResult.getCurrentTime();\r
+               //authRefreshTime = authTimeRemaining / 2;\r
+           //}\r
            \r
                // Get user information\r
                try {\r
@@ -1590,8 +1591,11 @@ public class SyncRunner extends QObject implements Runnable {
     public void enDisconnect() {\r
        isConnected = false;\r
     }\r
+    \r
+    /*\r
     // Refresh the connection\r
     private synchronized boolean refreshConnection() {\r
+       \r
                logger.log(logger.EXTREME, "Entering SyncRunner.refreshConnection()");\r
 //        Calendar cal = Calendar.getInstance();\r
                \r
@@ -1669,6 +1673,8 @@ public class SyncRunner extends QObject implements Runnable {
                return true;\r
     }\r
     \r
+    */\r
+    \r
        public synchronized boolean addWork(String request) {\r
                if (workQueue.offer(request))\r
                        return true;\r
index 0d39afe..18ec06d 100644 (file)
@@ -35,8 +35,7 @@ import javax.crypto.spec.SecretKeySpec;
 public class AESEncrypter\r
 {\r
        private Cipher cipher;\r
-       private String password;\r
-       private String userid;\r
+       private String string;\r
        private final SecretKeySpec skeySpec;\r
        private final AlgorithmParameterSpec paramSpec;\r
        \r
@@ -44,8 +43,7 @@ public class AESEncrypter
        {\r
                String key = "x331aq5wDQ8xO81v";\r
                skeySpec = new SecretKeySpec(key.getBytes(), "AES");\r
-               password = new String("");\r
-               userid = new String("");\r
+               string = new String("");\r
                \r
                // Create an 8-byte initialization vector\r
                byte[] iv = new byte[]\r
@@ -63,18 +61,11 @@ public class AESEncrypter
                        e.printStackTrace();\r
                }\r
        }\r
-               \r
-       public void setPassword(String s) {\r
-               password = s;\r
-       }\r
-       public String getPassword() {\r
-               return password;\r
-       }\r
-       public void setUserid(String s) {\r
-               userid = s;\r
+       public void setString(String s) {\r
+               string = s;\r
        }\r
-       public String getUserid() {\r
-               return userid;\r
+       public String getString() {\r
+               return string;\r
        }\r
        \r
        public void encrypt(OutputStream out)\r
@@ -86,7 +77,7 @@ public class AESEncrypter
 \r
 //                     String u = new String(userid +" " +password);\r
                        StringBuffer u = new StringBuffer(1024);\r
-                       u.append("Userid:" +userid+ " " +password);\r
+                       u.append(string);\r
                        for (int i=u.length(); i<128; i++)\r
                                u.append('\0');\r
 \r
@@ -113,14 +104,7 @@ public class AESEncrypter
                        in = new CipherInputStream(in, cipher);\r
                        if (in.read(buf) >= 0)\r
                        {\r
-                               String line = new String(buf);\r
-                               int offset = line.indexOf(" ");\r
-                               if (offset > 0) {\r
-                                       userid = line.substring(line.indexOf(":")+1, offset);\r
-                                       password = line.substring(offset+1);\r
-                                       password = password.trim();\r
-                               }\r
-                               \r
+                               string = new String(buf);       \r
                        }\r
                        in.close();\r
                } catch (java.io.IOException e) {\r