summaryrefslogtreecommitdiff
path: root/src/Application.vala
diff options
context:
space:
mode:
Diffstat (limited to 'src/Application.vala')
-rw-r--r--src/Application.vala109
1 files changed, 106 insertions, 3 deletions
diff --git a/src/Application.vala b/src/Application.vala
index 59bae36..d9edcaf 100644
--- a/src/Application.vala
+++ b/src/Application.vala
@@ -4,7 +4,75 @@
* (version 2.1 or later). See the COPYING file in this distribution.
*/
+[DBus(name = "org.gnome.Shotwell.Authenticate")]
+public interface AuthenticationReceiver : Object {
+ public abstract void callback(string url) throws DBusError, IOError;
+}
+
+[DBus(name = "org.gnome.Shotwell.Authenticate")]
+internal class AuthenticatorReceiverApp : Gtk.Application, AuthenticationReceiver {
+ private Gee.HashMap<string, Spit.Publishing.AuthenticatedCallback>
+ pending_auth_requests = new Gee.HashMap<string, Spit.Publishing.AuthenticatedCallback>();
+
+ public AuthenticatorReceiverApp() {
+ Object(application_id: "org.gnome.Shotwell", flags: GLib.ApplicationFlags.HANDLES_OPEN |
+ GLib.ApplicationFlags.HANDLES_COMMAND_LINE);
+ }
+ public override bool dbus_register(DBusConnection connection, string object_path) throws Error {
+ try {
+ connection.register_object(object_path, this);
+ } catch (IOError e) {
+ warning("Failed to register authentication helper on session connection: %s", e.message);
+ }
+ return true;
+ }
+
+
+ internal void register_auth_callback(string cookie, Spit.Publishing.AuthenticatedCallback cb) {
+ pending_auth_requests[cookie] = cb;
+ }
+
+ internal void unregister_auth_callback(string cookie) {
+ pending_auth_requests.unset(cookie);
+ }
+
+ public void callback(string callback_url) throws DBusError, IOError {
+ try {
+ var uri = Uri.parse(callback_url, UriFlags.NONE);
+ debug("Got authentication callback uri: %s", callback_url);
+ // See if something is waiting for a pending authentication
+ var query = uri.get_query();
+ if (query == null || query == "") {
+ debug("Callback does not have parameters. Not accepting");
+
+ return;
+ }
+ var uri_params = Uri.parse_params(uri.get_query());
+ if ("sw_auth_cookie" in uri_params) {
+ var cookie = uri_params["sw_auth_cookie"];
+ if (pending_auth_requests.has_key(cookie)) {
+ pending_auth_requests[cookie].authenticated(uri_params);
+ LibraryWindow.get_app().present();
+ } else {
+ debug("No call-back registered for cookie %s, probably user cancelled", cookie);
+ }
+ } else if (uri.get_scheme().has_prefix("com.googleusercontent.apps")) {
+ if (pending_auth_requests.has_key(uri.get_scheme())) {
+ pending_auth_requests[uri.get_scheme()].authenticated(uri_params);
+ } else {
+ debug("No call-back registered for cookie %s, probably user cancelled", uri.get_scheme());
+ }
+ }
+ } catch (Error error) {
+ warning("Got invalid authentication call-back: %s", callback_url);
+ }
+ }
+}
+
public class Application {
+ public interface AuthCallback : Object {
+ public abstract void authenticated(HashTable<string, string> params);
+ }
private static Application instance = null;
private Gtk.Application system_app = null;
private int system_app_run_retval = 0;
@@ -36,20 +104,21 @@ public class Application {
private bool running = false;
private bool exiting_fired = false;
+ Gee.HashMap<string, AuthCallback> pending_auth_requests = new Gee.HashMap<string, AuthCallback>();
+
private Application(bool is_direct) {
if (is_direct) {
// we allow multiple instances of ourself in direct mode, so DON'T
// attempt to be unique. We don't request any command-line handling
// here because this is processed elsewhere, and we don't need to handle
// command lines from remote instances, since we don't care about them.
- system_app = new Gtk.Application("org.gnome.Shotwell-direct", GLib.ApplicationFlags.HANDLES_OPEN |
+ system_app = new Gtk.Application("org.gnome.Shotwell-Viewer", GLib.ApplicationFlags.HANDLES_OPEN |
GLib.ApplicationFlags.NON_UNIQUE);
} else {
// we've been invoked in library mode; set up for uniqueness and handling
// of incoming command lines from remote instances (needed for getting
// storage device and camera mounts).
- system_app = new Gtk.Application("org.gnome.Shotwell", GLib.ApplicationFlags.HANDLES_OPEN |
- GLib.ApplicationFlags.HANDLES_COMMAND_LINE);
+ system_app = new AuthenticatorReceiverApp();
}
// GLib will assert if we don't do this...
@@ -63,12 +132,46 @@ public class Application {
if (!direct) {
system_app.command_line.connect(on_command_line);
+ var action = new SimpleAction("authenticated", VariantType.STRING);
+ system_app.add_action(action);
+ action.activate.connect((a, p) => {
+ try {
+ var uri = Uri.parse(p.get_string(), UriFlags.NONE);
+ debug("Got authentication callback uri: %s", p.get_string());
+ // See if something is waiting for a pending authentication
+ var uri_params = Uri.parse_params(uri.get_query());
+ if ("sw_auth_cookie" in uri_params) {
+ var cookie = uri_params["sw_auth_cookie"];
+ if (pending_auth_requests.has_key(cookie)) {
+ pending_auth_requests[cookie].authenticated(uri_params);
+ } else {
+ debug("No call-back registered for cookie %s, probably user cancelled", cookie);
+ }
+ }
+ } catch (Error error) {
+ warning("Got invalid authentication call-back: %s", p.get_string());
+ }
+ });
}
system_app.activate.connect(on_activated);
system_app.startup.connect(on_activated);
}
+ public static void register_auth_callback(string cookie, Spit.Publishing.AuthenticatedCallback cb) {
+ var instance = get_instance();
+ if (!instance.direct) {
+ ((AuthenticatorReceiverApp)instance.system_app).register_auth_callback(cookie, cb);
+ }
+ }
+
+ public static void unregister_auth_callback(string cookie) {
+ var instance = get_instance();
+ if (!instance.direct) {
+ ((AuthenticatorReceiverApp)instance.system_app).unregister_auth_callback(cookie);
+ }
+ }
+
public static double get_scale() {
var instance = get_instance().system_app;
unowned GLib.List<Gtk.Window> windows = instance.get_windows();