From 17bc5999ce9ee774afd82d8ede33f5a9be61a4af Mon Sep 17 00:00:00 2001 From: Vivien Kraus Date: Sun, 14 Nov 2021 15:39:45 +0000 Subject: Gui: bind the settings. --- configure.ac | 1 + po/POTFILES.in | 3 +- src/client/Disfluid-0.h | 18 ++++++ src/client/libwebidoidc-client.c | 45 ++++++++++---- src/ui/Makefile.am | 7 ++- src/ui/main.vala | 13 ++-- src/ui/settings.vala | 125 +++++++++++++++++++++++++++++++++++++++ 7 files changed, 192 insertions(+), 20 deletions(-) create mode 100644 src/ui/settings.vala diff --git a/configure.ac b/configure.ac index e7dc5ce..7a03048 100644 --- a/configure.ac +++ b/configure.ac @@ -44,6 +44,7 @@ PKG_CHECK_MODULES([HOGWEED], [hogweed]) PKG_CHECK_MODULES([GUILE], [guile-$GUILE_EFFECTIVE_VERSION]) PKG_CHECK_MODULES([GLIB], [glib-2.0]) PKG_CHECK_MODULES([GOBJECT], [gobject-2.0]) +PKG_CHECK_MODULES([GIO], [gio-2.0]) GUILE_MODULE_REQUIRED([json]) GUILE_MODULE_REQUIRED([rdf rdf]) GUILE_MODULE_REQUIRED([turtle tordf]) diff --git a/po/POTFILES.in b/po/POTFILES.in index 4837f5d..ca0ce2d 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -97,4 +97,5 @@ src/ui/loading-page.glade src/ui/main-window.glade src/ui/new-page.glade src/ui/updated-page.glade -src/ui/main.vala \ No newline at end of file +src/ui/main.vala +src/ui/settings.vala \ No newline at end of file diff --git a/src/client/Disfluid-0.h b/src/client/Disfluid-0.h index b4833c4..5c7adb7 100644 --- a/src/client/Disfluid-0.h +++ b/src/client/Disfluid-0.h @@ -82,6 +82,15 @@ void disfluid_api_make_client (const DisfluidApi * api, */ void disfluid_client_free (DisfluidClient * client); +/** + * disfluid_client_copy: + * @client: the client to copy. + * @api: the API. + * @copy: (out) (transfer full): the copy. + */ +void disfluid_client_copy (const DisfluidClient * client, + const DisfluidApi * api, DisfluidClient ** copy); + /** * disfluid_client_get_id: * @client: the client whose ID to lookup. @@ -163,6 +172,15 @@ void disfluid_api_make_account_full (const DisfluidApi * api, */ void disfluid_account_free (DisfluidAccount * account); +/** + * disfluid_account_copy: + * @account: the account to copy. + * @api: the API. + * @copy: (out) (transfer full): the copy. + */ +void disfluid_account_copy (const DisfluidAccount * account, + const DisfluidApi * api, DisfluidAccount ** copy); + /** * disfluid_account_get_subject: * @account: the account whose subject to lookup. diff --git a/src/client/libwebidoidc-client.c b/src/client/libwebidoidc-client.c index 4937135..f31c100 100644 --- a/src/client/libwebidoidc-client.c +++ b/src/client/libwebidoidc-client.c @@ -107,9 +107,8 @@ disfluid_api_make_client (const struct DisfluidApi *api, { scm_jwk = scm_from_utf8_string (jwk); } - SCM object = - scm_call_3 (api->scm_make_client, scm_client_id, scm_redirect_uri, - scm_jwk); + SCM object = scm_call_3 (api->scm_make_client, scm_client_id, scm_jwk, + scm_redirect_uri); scm_dynwind_begin (0); *client = scm_malloc (sizeof (struct DisfluidClient)); scm_dynwind_unwind_handler (free, *client, 0); @@ -127,6 +126,17 @@ disfluid_client_free (struct DisfluidClient *client) free (client); } +void +disfluid_client_copy (const DisfluidClient * client, const DisfluidApi * api, + DisfluidClient ** copy) +{ + scm_dynwind_begin (0); + *copy = scm_malloc (sizeof (struct DisfluidClient)); + scm_dynwind_unwind_handler (free, *copy, 0); + (*copy)->object = scm_gc_protect_object (client->object); + scm_dynwind_end (); +} + static size_t copy_scm_string (SCM string, size_t start, size_t max, char *dest) { @@ -188,15 +198,15 @@ struct DisfluidAccount }; void -disfluid_api_make_account (const struct DisfluidApi *api, - struct DisfluidAccount **account, - const char *subject, - const char *issuer, - const char *key_pair, - const char *id_token_header, - const char *id_token, - const char *access_token, - const char *refresh_token) +disfluid_api_make_account_full (const struct DisfluidApi *api, + struct DisfluidAccount **account, + const char *subject, + const char *issuer, + const char *key_pair, + const char *id_token_header, + const char *id_token, + const char *access_token, + const char *refresh_token) { SCM scm_subject = scm_from_utf8_string (subject); SCM scm_issuer = scm_from_utf8_string (issuer); @@ -223,6 +233,17 @@ disfluid_api_make_account (const struct DisfluidApi *api, } } +void +disfluid_account_copy (const DisfluidAccount * account, + const DisfluidApi * api, DisfluidAccount ** copy) +{ + scm_dynwind_begin (0); + *copy = scm_malloc (sizeof (struct DisfluidAccount)); + scm_dynwind_unwind_handler (free, *copy, 0); + (*copy)->object = scm_gc_protect_object (account->object); + scm_dynwind_end (); +} + void disfluid_account_free (struct DisfluidAccount *account) { diff --git a/src/ui/Makefile.am b/src/ui/Makefile.am index 94e96d2..e66cfe6 100644 --- a/src/ui/Makefile.am +++ b/src/ui/Makefile.am @@ -30,16 +30,21 @@ dist_uipkgdata_DATA = \ libexec_PROGRAMS += %reldir%/disfluid-gui +AM_VALAFLAGS += --pkg=gio-2.0 + %canon_reldir%_disfluid_gui_SOURCES = \ - %reldir%/main.vala + %reldir%/main.vala \ + %reldir%/settings.vala %canon_reldir%_disfluid_gui_CFLAGS = \ $(AM_CFLAGS) \ $(GLIB_CFLAGS) \ $(GOBJECT_CFLAGS) \ + $(GIO_CFLAGS) \ -include config.h %canon_reldir%_disfluid_gui_LDADD = \ $(GLIB_LIBS) \ $(GOBJECT_LIBS) \ + $(GIO_LIBS) \ $(lib_LTLIBRARIES) diff --git a/src/ui/main.vala b/src/ui/main.vala index e15710d..a0acd6d 100644 --- a/src/ui/main.vala +++ b/src/ui/main.vala @@ -19,12 +19,13 @@ namespace Disfluid { public static int main (string[] args) { int return_code = 1; Disfluid.Api.init ((api) => { - foreach (var arg in args) { - stdout.printf ("%s\n", arg); - } - return_code = 0; - return null; - }); + var settings = new Disfluid.Settings (api); + foreach (var arg in args) { + stdout.printf ("%s\n", arg); + } + return_code = 0; + return null; + }); return return_code; } } diff --git a/src/ui/settings.vala b/src/ui/settings.vala new file mode 100644 index 0000000..435737f --- /dev/null +++ b/src/ui/settings.vala @@ -0,0 +1,125 @@ +// disfluid, implementation of the Solid specification +// Copyright (C) 2021 Vivien Kraus + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. + +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +namespace Disfluid { + class Settings: GLib.Object { + public Account? main_account; + public Account[] other_accounts; + public Client client; + private static string? detect_empty (string str) { + if (str == "") { + return null; + } + return str; + } + private static Account? get_account (Disfluid.Api api, GLib.Settings settings) { + Account ret; + var subject = detect_empty (settings.get_string ("subject")); + var issuer = detect_empty (settings.get_string ("issuer")); + var key_pair = detect_empty (settings.get_string ("key-pair")); + if (subject != null && issuer != null && key_pair != null) { + api.make_account_full (out ret, + subject, + issuer, + key_pair, + detect_empty (settings.get_string ("id-token-header")), + detect_empty (settings.get_string ("id-token")), + detect_empty (settings.get_string ("access-token")), + detect_empty (settings.get_string ("refresh-token"))); + return ret; + } + return null; + } + private static void set_account (Disfluid.Api api, GLib.Settings settings, Account? acct) { + var subject = new char[acct.get_subject (api, 0, new char[0])]; + acct.get_subject (api, 0, subject); + var issuer = new char[acct.get_issuer (api, 0, new char[0])]; + acct.get_issuer (api, 0, issuer); + var key_pair = new char[acct.get_key_pair (api, 0, new char[0])]; + acct.get_key_pair (api, 0, key_pair); + var id_token_header = new char[acct.get_id_token_header (api, 0, new char[0])]; + acct.get_id_token_header (api, 0, id_token_header); + var id_token = new char[acct.get_id_token (api, 0, new char[0])]; + acct.get_id_token (api, 0, id_token); + var access_token = new char[acct.get_access_token (api, 0, new char[0])]; + acct.get_access_token (api, 0, access_token); + var refresh_token = new char[acct.get_refresh_token (api, 0, new char[0])]; + acct.get_refresh_token (api, 0, refresh_token); + settings.set_string ("subject", (string) subject); + settings.set_string ("issuer", (string) issuer); + settings.set_string ("key-pair", (string) key_pair); + settings.set_string ("id-token-header", (string) id_token_header); + settings.set_string ("id-token", (string) id_token); + settings.set_string ("access-token", (string) access_token); + settings.set_string ("refresh-token", (string) refresh_token); + } + public Settings (Disfluid.Api api) { + var settings = new GLib.Settings ("eu.planete_kraus.Disfluid"); + var client_settings = settings.get_child ("client"); + var main_account_settings = settings.get_child ("main-account"); + var other_accounts_settings = new GLib.Settings[10]; + for (int i = 0 ; i < other_accounts_settings.length; i++) { + var name = "other-account-%d".printf (i + 1); + other_accounts_settings[i] = settings.get_child (name); + } + api.make_client (out client, + client_settings.get_string ("client-id"), + client_settings.get_string ("redirect-uri"), + client_settings.get_string ("key-pair")); + client_settings.changed.connect ((key) => { + api.make_client (out this.client, + client_settings.get_string ("client-id"), + client_settings.get_string ("redirect-uri"), + client_settings.get_string ("key-pair")); + }); + this.notify["client"].connect (() => { + var client_id = new char[this.client.get_id (api, 0, new char[0])]; + this.client.get_id (api, 0, client_id); + client_settings.set_string ("client-id", (string) client_id); + var redirect_uri = new char[this.client.get_redirect_uri (api, 0, new char[0])]; + this.client.get_redirect_uri (api, 0, redirect_uri); + client_settings.set_string ("redirect-uri", (string) redirect_uri); + var key_pair = new char[this.client.get_key_pair (api, 0, new char[0])]; + this.client.get_key_pair (api, 0, key_pair); + client_settings.set_string ("key-pair", (string) key_pair); + }); + main_account = get_account (api, main_account_settings); + this.notify["main-account"].connect (() => { + set_account (api, main_account_settings, this.main_account); + }); + var all_other_accounts = new Disfluid.Account[other_accounts_settings.length]; + var account_index = 0; + foreach (var s in other_accounts_settings) { + var acc = get_account (api, s); + if (acc != null) { + acc.copy (api, out all_other_accounts[account_index++]); + } + } + other_accounts = new Account[account_index]; + for (int i = 0; i < account_index; i++) { + all_other_accounts[i].copy (api, out other_accounts[i]); + } + this.notify["other-accounts"].connect (() => { + var settings_index = 0; + foreach (unowned Disfluid.Account account in other_accounts) { + set_account (api, + other_accounts_settings[settings_index++], + account); + } + }); + } + } +} \ No newline at end of file -- cgit v1.2.3