From 1244b85093be028d51e4a8fab05cbd6df62e2146 Mon Sep 17 00:00:00 2001 From: Ville Nummela Date: Fri, 6 Oct 2023 14:08:29 +0300 Subject: [PATCH 1/2] Login via amber web authorization Signed-off-by: Ville Nummela --- qml/pages/LoginPage.qml | 160 ++++++++------------------------------- rpm/harbour-tooterb.spec | 1 + 2 files changed, 31 insertions(+), 130 deletions(-) diff --git a/qml/pages/LoginPage.qml b/qml/pages/LoginPage.qml index 4df27d5..8e9bdcf 100644 --- a/qml/pages/LoginPage.qml +++ b/qml/pages/LoginPage.qml @@ -1,34 +1,14 @@ import QtQuick 2.0 import Sailfish.Silica 1.0 -import Sailfish.WebView 1.0 -import Sailfish.WebEngine 1.0 -import io.thp.pyotherside 1.5 +import Amber.Web.Authorization 1.0 import "../lib/API.js" as Logic + + Page { property bool debug: false - // Python connections and signals, callable from QML side - // This is not ideal but keeps the page from erroring out on redirect - Python { - id: py - Component.onCompleted: { - addImportPath(Qt.resolvedUrl('../lib/')); - importModule('server', function () {}); - - setHandler('finished', function(newvalue) { - if(debug) console.debug(newvalue) - }); - startDownload(); - } - function startDownload() { - call('server.downloader.serve', function() {}); - if (debug) console.debug("called") - - } - } - id: loginPage // The effective value will be restricted by ApplicationWindow.allowedOrientations allowedOrientations: Orientation.All @@ -50,6 +30,28 @@ Page { text: qsTr("Instance") } + OAuth2Ac { + id: mastodonOAuth + authorizationEndpoint: instance.text + "/oauth/authorize" + tokenEndpoint: instance.text + "/oauth/token" + scopes: ["read", "write", "follow"] + redirectListener.port: 7538 + + onErrorOccurred: console.log("Mastodon OAuth2 Error: " + error.code + " = " + error.message + " : " + error.httpCode) + + onReceivedAuthorizationCode: { + console.log("Got auth code, about to request token.") + } + + onReceivedAccessToken: { + console.log("Got access token: " + token.access_token) + Logic.conf["api_user_token"] = token.access_token + Logic.conf["login"] = true; + Logic.api.setConfig("api_user_token", Logic.conf["api_user_token"]) + pageStack.replace(Qt.resolvedUrl("MainPage.qml"), {}) + } + } + TextField { id: instance focus: true @@ -63,7 +65,7 @@ Page { EnterKey.onClicked: { Logic.api = Logic.mastodonAPI({ instance: instance.text, api_user_token: "" }); Logic.api.registerApplication("Tooter", - 'http://localhost:8000/index.html', // redirect uri, we will need this later on + "http://127.0.0.1:7538", ["read", "write", "follow"], //scopes "https://github.com/poetaster/harbour-tooter#readme", //website on the login screen function(data) { @@ -73,25 +75,15 @@ Page { conf.instance = instance.text; conf.login = false; - /*conf['login'] = false; - conf['mastodon_client_id'] = data['mastodon_client_id']; - conf['mastodon_client_secret'] = data['mastodon_client_secret']; - conf['mastodon_client_redirect_uri'] = data['mastodon_client_redirect_uri']; - delete Logic.conf;*/ Logic.conf = conf; if(debug) console.log(JSON.stringify(conf)) if(debug) console.log(JSON.stringify(Logic.conf)) // we got our application - // our user to it! - var url = Logic.api.generateAuthLink(Logic.conf["client_id"], - Logic.conf["redirect_uri"], - "code", // oauth method - ["read", "write", "follow"] //scopes - ); - if(debug) console.log(url) - webView.url = url - webView.visible = true + mastodonOAuth.clientId = conf["client_id"] + mastodonOAuth.clientSecret = conf["client_secret"]; + + mastodonOAuth.authorizeInBrowser() } ); } @@ -114,96 +106,4 @@ Page { } } } - WebView { - id: webView - - /* This will probably be required from 4.4 on. */ - Component.onCompleted: { - WebEngineSettings.setPreference("security.disable_cors_checks", true, WebEngineSettings.BoolPref) - WebEngineSettings.setPreference("security.fileuri.strict_origin_policy", false, WebEngineSettings.BoolPref) - } - onViewInitialized: { - //webview.loadFrameScript(Qt.resolvedUrl("../html/framescript.js")); - //webview.addMessageListener("webview:action"); - //webview.runJavaScript("return latlon('" + lat + "','" + lon + "')"); - } - - onRecvAsyncMessage: { - if(debug) console.log('async changed: ' + url) - if(debug) console.debug(message) - switch (message) { - case "embed:contentOrientationChanged": - break - case "webview:action": - break - } - } - visible: false - //opacity: 0 - anchors.fill: parent - /*{ - top: parent.top - left: parent.left - right: parent.right - bottom: parent.bottom - }*/ - - onLoadingChanged: { - if(debug) console.log('loading changed: ' + url) - if ( - (url+"").substr(0, 38) === 'http://localhost:8000/index.html?code=' || - (url+"").substr(0, 39) === 'https://localhost:8000/index.html?code=' - ) { - visible = false; - - var vars = {}; - (url+"").replace(/[?&]+([^=&]+)=([^&]*)/gi, function(m,key,value) { vars[key] = value;}); /* found on https://html-online.com/articles/get-url-parameters-javascript/ */ - - var authCode = vars["code"]; - - if(debug) console.log(authCode) - - Logic.api.getAccessTokenFromAuthCode( - Logic.conf["client_id"], - Logic.conf["client_secret"], - Logic.conf["redirect_uri"], - authCode, - function(data) { - // AAAND DATA CONTAINS OUR TOKEN! - if(debug) console.log(data) - data = JSON.parse(data) - if(debug) console.log(JSON.stringify(data)) - if(debug) console.log(JSON.stringify(data.access_token)) - Logic.conf["api_user_token"] = data.access_token - Logic.conf["login"] = true; - Logic.api.setConfig("api_user_token", Logic.conf["api_user_token"]) - pageStack.replace(Qt.resolvedUrl("MainPage.qml"), {}) - } - ) - } - - - /*switch (loadRequest.status) - { - case WebView.LoadSucceededStatus: - opacity = 1 - break - case WebView.LoadFailedStatus: - //opacity = 0 - break - default: - //opacity = 0 - break - }*/ - } - - FadeAnimation on opacity {} - - PullDownMenu { - MenuItem { - text: qsTr("Reload") - onClicked: webView.reload() - } - } - } } diff --git a/rpm/harbour-tooterb.spec b/rpm/harbour-tooterb.spec index b674bc1..ae277b4 100644 --- a/rpm/harbour-tooterb.spec +++ b/rpm/harbour-tooterb.spec @@ -23,6 +23,7 @@ Requires: sailfishsilica-qt5 >= 0.10.9 Requires: nemo-qml-plugin-configuration-qt5 Requires: nemo-qml-plugin-notifications-qt5 Requires: pyotherside-qml-plugin-python3-qt5 +Requires: amber-web-authorization BuildRequires: qt5-qttools-linguist BuildRequires: pkgconfig(sailfishapp) >= 1.0.2 From 1550be76f02b36ce46966288f216933cd958d88c Mon Sep 17 00:00:00 2001 From: Ville Nummela Date: Fri, 6 Oct 2023 16:40:19 +0300 Subject: [PATCH 2/2] Remove python webserver As Amber Web Authorization framework already provides callback webserver, python implementation is no longer needed. Signed-off-by: Ville Nummela --- harbour-tooterb.pro | 2 -- qml/lib/index.html | 26 ------------------------ qml/lib/server.py | 43 ---------------------------------------- rpm/harbour-tooterb.spec | 1 - 4 files changed, 72 deletions(-) delete mode 100644 qml/lib/index.html delete mode 100644 qml/lib/server.py diff --git a/harbour-tooterb.pro b/harbour-tooterb.pro index f31f4d4..12f593c 100644 --- a/harbour-tooterb.pro +++ b/harbour-tooterb.pro @@ -74,8 +74,6 @@ DISTFILES += qml/harbour-tooterb.qml \ qml/pages/LoginPage.qml \ qml/pages/Browser.qml \ qml/lib/API.js \ - qml/lib/server.py \ - qml/lib/index.html \ qml/images/icon-s-following \ qml/images/icon-s-bookmark \ qml/images/icon-m-bookmark \ diff --git a/qml/lib/index.html b/qml/lib/index.html deleted file mode 100644 index 1e3f3a1..0000000 --- a/qml/lib/index.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - -

Login Complete

- - diff --git a/qml/lib/server.py b/qml/lib/server.py deleted file mode 100644 index 716658b..0000000 --- a/qml/lib/server.py +++ /dev/null @@ -1,43 +0,0 @@ -# -*- coding: utf-8 -*- - -# POETASTER -import sys -sys.path.append('/usr/share/harbour-tooterb/qml') -sys.path.append('/usr/share/harbour-tooterb/qml/lib') -sys.path.append('/usr/share/harbour-tooterb/qml/pages') - -# POETASTER - -import pyotherside -import threading -import time -import random -import os -import http.server -import socketserver - -PORT = 8000 -directory = '/usr/share/harbour-tooterb/qml/lib' -Handler = http.server.SimpleHTTPRequestHandler -os.chdir(directory) - -def serveMe(): - with socketserver.TCPServer(("", PORT), Handler) as httpd: - print("serving at port", PORT) - pyotherside.send('finished', PORT) - httpd.serve_forever() - -class Downloader: - def __init__(self): - # Set bgthread to a finished thread so we never - # have to check if it is None. - self.bgthread = threading.Thread() - self.bgthread.start() - - def serve(self): - if self.bgthread.is_alive(): - return - self.bgthread = threading.Thread(target=serveMe) - self.bgthread.start() - -downloader = Downloader() diff --git a/rpm/harbour-tooterb.spec b/rpm/harbour-tooterb.spec index ae277b4..4b54440 100644 --- a/rpm/harbour-tooterb.spec +++ b/rpm/harbour-tooterb.spec @@ -22,7 +22,6 @@ Source0: %{name}-%{version}.tar.bz2 Requires: sailfishsilica-qt5 >= 0.10.9 Requires: nemo-qml-plugin-configuration-qt5 Requires: nemo-qml-plugin-notifications-qt5 -Requires: pyotherside-qml-plugin-python3-qt5 Requires: amber-web-authorization BuildRequires: qt5-qttools-linguist