From b13888737145537812933ad241324aadb184227a Mon Sep 17 00:00:00 2001 From: Jeena Paradies Date: Sun, 18 Nov 2012 02:20:35 +0100 Subject: [PATCH] fixed authentication in Linux, showing Timeline now --- Linux/Helper.py | 72 ++++++++++++++++++++-------- Linux/QtTest.py | 24 +++++++++- Linux/Tentia.py | 66 ++++++++++++++++---------- Linux/Windows.py | 76 +++++++++++++++++------------- Mac/publish/Appcast.xml | 6 +-- WebKit/scripts/controller/Oauth.js | 2 + WebKit/scripts/helper/Paths.js | 4 +- WebKit/scripts/main.js | 31 ++++++++++++ 8 files changed, 196 insertions(+), 85 deletions(-) diff --git a/Linux/Helper.py b/Linux/Helper.py index e4978d6..2e41a67 100644 --- a/Linux/Helper.py +++ b/Linux/Helper.py @@ -1,38 +1,70 @@ from PyQt4 import QtCore, QtGui, QtWebKit +from PyQt4.QtCore import QTimer, QVariant, SIGNAL +from PyQt4.QtGui import * +from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply +from PyQt4.QtWebKit import QWebView + class WebPage(QtWebKit.QWebPage): - def __init__(self, parent): + def __init__(self, parent=0, app=None): super(QtWebKit.QWebPage, self).__init__(parent) + self.app = app def javaScriptConsoleMessage(self, message, lineNumber, sourceId): print str(message) + " on line: " + str(lineNumber) + " Source: " + str(sourceId) -class WebViewCreator(QtGui.QWidget): - def __init__(self, app, delegate): + def checkRequest(self, request): + print request + +class WebViewCreator(QtWebKit.QWebView): + def __init__(self, app, local=True): QtGui.QWidget.__init__(self) self.app = app - self.delegate = delegate + self.is_local = local + self.setPage(WebPage(self, self.app)) + + def load_local(self, callback=None): + self.page().settings().setAttribute(QtWebKit.QWebSettings.LocalContentCanAccessRemoteUrls, True) + self.loadFinished.connect(lambda ok: self.load_finished(ok, callback)) - self.view = QtWebKit.QWebView(self) - self.view.loadFinished.connect(self.load_finished) - - self.page = WebPage(self) - self.view.setPage(self.page) - self.page.settings().setAttribute(QtWebKit.QWebSettings.LocalContentCanAccessRemoteUrls, True) - - layout = QtGui.QVBoxLayout(self) - layout.addWidget(self.view) - - frame = self.view.page().mainFrame() + frame = self.page().mainFrame() frame.addToJavaScriptWindowObject("controller", self.app.controller) - frame.addToJavaScriptWindowObject("console", self.app.console) + frame.addToJavaScriptWindowObject("__console", self.app.console) url = self.app.resources_uri() + "/index.html" - self.view.load(QtCore.QUrl(url)) + self.load(QtCore.QUrl(url)) + def load_url(self, url, callback=None): + self.loadFinished.connect(lambda ok: self.load_finished(ok, callback)) + self.load(QtCore.QUrl(url)) - def load_finished(self, ok): - self.view.page().mainFrame().evaluateJavaScript("var OS_TYPE = 'linux';") - self.delegate.load_finished(ok) + def load_finished(self, ok, callback=None): + if self.is_local: + self.page().mainFrame().evaluateJavaScript("var OS_TYPE = 'linux';") + + if callback: + callback(ok) + +class NetworkAccessManager(QNetworkAccessManager): + + def __init__(self, old_manager, tentia_callback): + QNetworkAccessManager.__init__(self) + + self.tentia_callback = tentia_callback + + self.old_manager = old_manager + self.setCache(old_manager.cache()) + self.setCookieJar(old_manager.cookieJar()) + self.setProxy(old_manager.proxy()) + self.setProxyFactory(old_manager.proxyFactory()) + + def createRequest(self, operation, request, data): + if request.url().scheme() != "tentia": + return QNetworkAccessManager.createRequest(self, operation, request, data) + else: + self.tentia_callback(request.url()) + return QNetworkAccessManager.createRequest(self, QNetworkAccessManager.GetOperation, QNetworkRequest(QtCore.QUrl())) + + \ No newline at end of file diff --git a/Linux/QtTest.py b/Linux/QtTest.py index 6291940..2800e47 100644 --- a/Linux/QtTest.py +++ b/Linux/QtTest.py @@ -1,4 +1,4 @@ -import sys +import sys, urllib from PyQt4 import QtCore, QtGui, QtWebKit """Html snippet.""" @@ -28,6 +28,20 @@ class StupidClass(QtCore.QObject): """Python interpreter version property.""" pyVersion = QtCore.pyqtProperty(str, fget=_pyVersion) +def isBasicAuth(url): + url_opener = urllib.URLopener() + + try: + url_opener.open(url) + except IOError, error_code: + if error_code[0] == "http error" : + if error_code[1] == 401: + return True + else: + return False + + return False + def main(): app = QtGui.QApplication(sys.argv) @@ -36,7 +50,13 @@ def main(): webView = QtWebKit.QWebView() # Make myObj exposed as JavaScript object named 'pyObj' webView.page().mainFrame().addToJavaScriptWindowObject("pyObj", myObj) - webView.setHtml(html) + + url = "http://lala.home.jeena.net:3002/admin" + if isBasicAuth(url): + print "Basic Auth" + else: + webView.load(QtCore.QUrl(url)) + #webView.setHtml(html) window = QtGui.QMainWindow() window.setCentralWidget(webView) diff --git a/Linux/Tentia.py b/Linux/Tentia.py index b4f97cd..32e90e1 100755 --- a/Linux/Tentia.py +++ b/Linux/Tentia.py @@ -1,27 +1,25 @@ #!/usr/bin/env python import os, sys, pickle -from PyQt4 import QtCore, QtGui -import Windows +from PyQt4 import QtCore, QtGui, QtWebKit +import Windows, Helper class Tentia: def __init__(self): self.app = QtGui.QApplication(sys.argv) - self.controller = Controller() + self.controller = Controller(self) self.console = Console() - self.setup_url_handler() - self.setup_windows() - self.preferences.show() - self.app.exec_() - - def quit(self, sender): - print "quit" - - def setup_windows(self): self.preferences = Windows.Preferences(self) - #self.timeline = Windows.Timeline(self) - #self.mentions = Windows.Timeline(self, action="mentions", title="Mentions") + self.preferences.show() + + self.timeline = Windows.Timeline(self) + self.mentions = Windows.Timeline(self, "mentions", "Mentions") + + if self.controller.stringForKey("user_access_token") != "": + self.logged_in_successfully(True) + + self.app.exec_() def resources_path(self): return os.path.abspath(os.path.join(os.path.dirname(__file__), '..')) @@ -33,17 +31,31 @@ class Tentia: self.controller.setStringForKey(entity, "entity") self.oauth_implementation = Windows.Oauth(self) - def setup_url_handler(self): - QtGui.QDesktopServices.setUrlHandler("tentia://", self.reciveURI) + def authentification_succeded(self): + self.preferences.active(False) + self.preferences.hide() + self.init_web_views() - def reciveURI(uri): - print uri + def init_web_views(self): + self.timeline.show() + self.mentions.show() + + def logged_in_successfully(self, success): + self.preferences.active(False) + if success: + self.preferences.hide() + self.timeline = Windows.Timeline(self) + self.timeline.show() + else: + print "not logged in" class Controller(QtCore.QObject): - def __init__(self): + def __init__(self, app): QtCore.QObject.__init__(self) + self.app = app + self.config_path = os.path.expanduser('~/.tentia.cfg') if os.access(self.config_path, os.R_OK): with open(self.config_path, 'r') as f: @@ -73,9 +85,10 @@ class Controller(QtCore.QObject): @QtCore.pyqtSlot(str) def openURL(self, url): - print url - print QtCore.QUrl(url) - QtGui.QDesktopServices.openUrl(QtCore.QUrl(url)); + self.app.oauth_implementation.handle_authentication(str(url)) + + def loggedIn(self): + self.app.authentification_succeded() class Console(QtCore.QObject): @@ -84,13 +97,18 @@ class Console(QtCore.QObject): def log(self, string): print ": " + string + @QtCore.pyqtSlot(str) + def error(self, string): + print ": " + string + @QtCore.pyqtSlot(str) def warn(self, string): print ": " + string @QtCore.pyqtSlot(str) - def error(self, string): - print ": " + string + def notice(self, string): + print ": " + string + if __name__ == "__main__": diff --git a/Linux/Windows.py b/Linux/Windows.py index a5f0236..03de3a1 100644 --- a/Linux/Windows.py +++ b/Linux/Windows.py @@ -1,5 +1,5 @@ from PyQt4 import QtCore, QtGui, QtWebKit -import Helper +import Helper, urllib class Preferences: @@ -76,26 +76,14 @@ class Preferences: class Timeline: - def __init__(self, app, action="home_timeline", title="Tentia"): + def __init__(self, app, action="timeline", title="Tentia"): self.app = app self.action = action self.title = title - self.window = gtk.Window() - self.window.connect("delete-event", self.quit) - self.window.set_title(self.title) - self.window.set_position(gtk.WIN_POS_CENTER) - self.window.set_size_request(390, 650) - - scroller = gtk.ScrolledWindow() - self.window.add(scroller) - - self.web_view = webkit.WebView() - scroller.add(self.web_view) - - def quit(self, widget, foo): - self.window.hide() - self.app.quit(self) + self.window = Helper.WebViewCreator(self.app) + self.window.setWindowTitle(title) + self.window.load_local(self.load_finished) def show(self): self.window.show() @@ -103,32 +91,52 @@ class Timeline: def hide(self): self.window.hide() - def init_web_view(self): - self.web_view.connect("load-finished", self.load_finished) - self.web_view.open(self.app.resources_path() + "index.html") - def load_finished(self, widget): - delay = 1 - if self.action == "mentions": - delay = 1000 + script = "function HostAppGo() { start('" + self.action + "'); }" + self.window.page().mainFrame().evaluateJavaScript(script) - script = "setTimeout(\ - function() {\ - tentia_instance = new Core('" + self.action + "');\ - document.getElementsByTagName('body')[0].appendChild(tentia_instance.body);\ - setTimeout(function(){ loadPlugin(controller.pluginURL()) }, 1); }, " + delay + "\ - );" - - self.web_view.execute_script(script) class Oauth: def __init__(self, app): self.app = app - self.window = Helper.WebViewCreator(self.app, self) + self.core = Helper.WebViewCreator(self.app) + self.core.load_local(self.load_finished) def load_finished(self, ok): if ok: script = "function HostAppGo() { start('oauth'); }" - self.window.view.page().mainFrame().evaluateJavaScript(script) + self.core.page().mainFrame().evaluateJavaScript(script) + def handle_authentication(self, url): + self.auth_view = Helper.WebViewCreator(self.app) + self.auth_view.setWindowTitle("Authentification") + + old_manager = self.auth_view.page().networkAccessManager() + new_manager = Helper.NetworkAccessManager(old_manager, self.tentia_callback) + self.auth_view.page().setNetworkAccessManager(new_manager) + + self.auth_view.show() + + if self.is_basic_auth(url): + print "Basic auth" + else: + self.auth_view.load_url(url) + + + def is_basic_auth(self, url): + url_opener = urllib.URLopener() + + try: + url_opener.open(url) + except IOError, error_code: + if error_code[0] == "http error" : + if error_code[1] == 401: + return True + + return False + + def tentia_callback(self, url): + script = "tentia_instance.requestAccessToken('" + url.toString() + "');" + print script + self.core.page().mainFrame().evaluateJavaScript(script) diff --git a/Mac/publish/Appcast.xml b/Mac/publish/Appcast.xml index 5507cbc..844bb76 100755 --- a/Mac/publish/Appcast.xml +++ b/Mac/publish/Appcast.xml @@ -9,12 +9,12 @@ Version 0.2.4 10.5.0 http://jabs.nu/Tentia/download/ReleaseNotes.html - Sat, 17 Nov 2012 20:43:06 +0100 + Sat, 17 Nov 2012 20:45:22 +0100 + sparkle:dsaSignature="MC0CFCvZgr1pcB0bW0IQ8E7ffqs0SjvpAhUAioix/kjwYUqGqchCTDN6EjncmSE=" /> diff --git a/WebKit/scripts/controller/Oauth.js b/WebKit/scripts/controller/Oauth.js index 0c7fc48..6160085 100644 --- a/WebKit/scripts/controller/Oauth.js +++ b/WebKit/scripts/controller/Oauth.js @@ -103,6 +103,7 @@ function(HostApp, Paths, Hmac) { Oauth.prototype.requestAccessToken = function(responseBody) { // /oauthtoken?code=51d0115b04d1ed94001dde751c5b360f&state=aQfH1VEohYsQr86qqyv + var urlVars = Paths.getUrlVars(responseBody); if(this.state && this.state != "" && urlVars["state"] == this.state) { @@ -145,6 +146,7 @@ function(HostApp, Paths, Hmac) { HostApp.setStringForKey(access["token_type"], "user_token_type"); HostApp.loggedIn(); + console.log("D") } Oauth.prototype.logout = function() { diff --git a/WebKit/scripts/helper/Paths.js b/WebKit/scripts/helper/Paths.js index fd2ef0c..b3978d6 100644 --- a/WebKit/scripts/helper/Paths.js +++ b/WebKit/scripts/helper/Paths.js @@ -55,7 +55,7 @@ function(jQuery, HostApp, Hmac) { data: data, processData: false, error: function(xhr, ajaxOptions, thrownError) { - alert("getURL " + xhr.statusText + " " + http_method + " (" + url + "): '" + xhr.responseText + "'"); + console.error("getURL " + xhr.statusText + " " + http_method + " (" + url + "): '" + xhr.responseText + "'"); } }); } @@ -86,7 +86,7 @@ function(jQuery, HostApp, Hmac) { } }, error: function(xhr, ajaxOptions, thrownError) { - alert("findProfileURL " + xhr.statusText + " (" + entity + "): " + xhr.responseText); + console.error("findProfileURL " + xhr.statusText + " (" + entity + "): " + xhr.responseText); if (errorCallback) errorCallback(xhr.statusText + " - " + xhr.responseText) } }); diff --git a/WebKit/scripts/main.js b/WebKit/scripts/main.js index 71447d8..0505dc5 100644 --- a/WebKit/scripts/main.js +++ b/WebKit/scripts/main.js @@ -55,6 +55,37 @@ String.prototype.endsWith = function(suffix) { return this.match(suffix+"$") == suffix; }; +var console = { + log: function(s) { + if (OS_TYPE == "mac") { + alert(s) + } else { + __console.log(s); + } + }, + error: function(s) { + if (OS_TYPE == "mac") { + alert("ERROR: " + s); + } else { + __console.error(s); + } + }, + warning: function (s) { + if (OS_TYPE == "mac") { + alert("WARNING: " + s); + } else { + __console.warning(s); + } + } + notice: function(s) { + if (OS_TYPE == "mac") { + alert("NOTICE: " + s); + } else { + __console.notice(s); + } + } +}; + function loadPlugin(url) { var plugin = document.createElement("script"); plugin.type = "text/javascript";