diff --git a/configure.d/10-core.sh b/configure.d/10-core.sh index 1aba499..a25081c 100755 --- a/configure.d/10-core.sh +++ b/configure.d/10-core.sh @@ -541,15 +541,24 @@ failed() { [ -n "$3" ] && FIXES+=("$3") FIX_TITLES+=("$1") } -# Test an Online Accounts account: <provider> <identity> <setup> <fix> +# Test an Online Accounts account, and that none of what CoreDesktop set it up +# for is turned off in Settings: +# <title> <provider> <identity> <setup> <fix> <enable> test_account() { - local error + local error off works=1 if ! "$GOA_ACCOUNT" exists "$2" "$3" 2> /dev/null; then failed "$1" "not set up" "$4" - elif error="$("$GOA_ACCOUNT" check "$2" "$3" 2>&1)"; then - passed "$1" - else + return + fi + if ! error="$("$GOA_ACCOUNT" check "$2" "$3" 2>&1)"; then failed "$1" "can't sign in" "$5" "$error" + works=0 + fi + off="$("$GOA_ACCOUNT" disabled "$2" "$3" 2> /dev/null)" + if [ -n "$off" ]; then + failed "$1" "turned off in Settings: $off" "$6" + elif [ $works -eq 1 ]; then + passed "$1" fi } @@ -615,8 +624,8 @@ test_core() { failed "Superpanel" "can't reach https://superpanel.$CORE_DOMAIN" fi test_account "Nextcloud in Online Accounts" owncloud "$CORE_USER@nextcloud.$CORE_DOMAIN" \ - setup_nextcloud fix_nextcloud - test_account "Email in Online Accounts" imap_smtp "$CORE_EMAIL" setup_email fix_email + setup_nextcloud fix_nextcloud enable_nextcloud + test_account "Email in Online Accounts" imap_smtp "$CORE_EMAIL" setup_email fix_email enable_email test_files [ "$CORE_DOMAIN" = "$MAIN_DOMAIN" ] && element_installed && test_element backup_on "$CORE_DOMAIN" && test_backups @@ -631,6 +640,16 @@ fix_nextcloud() { echo "Nextcloud in Online Accounts has a new app password." } +enable_nextcloud() { + "$GOA_ACCOUNT" enable owncloud "$CORE_USER@nextcloud.$CORE_DOMAIN" || return 1 + echo "Turned Nextcloud's calendar, contacts and files back on." +} + +enable_email() { + "$GOA_ACCOUNT" enable imap_smtp "$CORE_EMAIL" || return 1 + echo "Turned email back on." +} + # Email gets your Core password. If the mail server still says no, its # settings may have changed, so add it again with the server's settings now. fix_email() { diff --git a/configure.d/lib/goa-account b/configure.d/lib/goa-account index dbfac08..f784660 100755 --- a/configure.d/lib/goa-account +++ b/configure.d/lib/goa-account @@ -13,6 +13,8 @@ Usage: goa-account add < account.json goa-account update <provider> <presentation-identity> < credentials.json goa-account check <provider> <presentation-identity> + goa-account disabled <provider> <presentation-identity> + goa-account enable <provider> <presentation-identity> goa-account remove <provider> <presentation-identity> account.json: @@ -22,6 +24,8 @@ account.json: credentials.json is the account's "credentials", e.g. {"password": "..."}. check signs in with what's saved, and fails if the server says no. update exits with 3 if it saved the password but the server didn't accept it. +disabled prints the features CoreDesktop uses that are turned off in Settings, +e.g. "Calendar, Files", and enable turns them back on. """ import json @@ -40,6 +44,10 @@ BUS_NAME = "org.gnome.OnlineAccounts" SCHEMA = Secret.Schema.new("org.gnome.OnlineAccounts", Secret.SchemaFlags.DONT_MATCH_NAME, {"goa-identity": Secret.SchemaAttributeType.STRING}) +# The features CoreDesktop sets each kind of account up for. Every account has +# a <feature>Disabled property for each feature, used or not. +FEATURES = {"owncloud": ["Calendar", "Contacts", "Files"], "imap_smtp": ["Mail"]} + def call(bus, path, interface, method, parameters, reply_type): return bus.call_sync(BUS_NAME, path, interface, method, parameters, @@ -127,6 +135,25 @@ def check(bus, provider, presentation_identity): ensure_credentials(bus, path) +def disabled(bus, provider, presentation_identity): + found = find_accounts(bus, provider, presentation_identity) + if not found: + raise LookupError(f"there's no {provider} account for {presentation_identity}") + return [feature for feature in FEATURES.get(provider, []) + if any(account.get(f"{feature}Disabled") for _, account in found)] + + +# Settings turns a feature off or on by setting its property +def enable(bus, provider, presentation_identity): + for path, account in find_accounts(bus, provider, presentation_identity): + for feature in FEATURES.get(provider, []): + if account.get(f"{feature}Disabled"): + call(bus, path, "org.freedesktop.DBus.Properties", "Set", + GLib.Variant("(ssv)", ("org.gnome.OnlineAccounts.Account", + f"{feature}Disabled", GLib.Variant("b", False))), + "()") + + def remove(bus, provider, presentation_identity): for path in find(bus, provider, presentation_identity): call(bus, path, "org.gnome.OnlineAccounts.Account", "Remove", None, "()") @@ -147,6 +174,12 @@ def main(): if len(sys.argv) == 4 and sys.argv[1] == "check": check(bus, sys.argv[2], sys.argv[3]) return 0 + if len(sys.argv) == 4 and sys.argv[1] == "disabled": + print(", ".join(disabled(bus, sys.argv[2], sys.argv[3]))) + return 0 + if len(sys.argv) == 4 and sys.argv[1] == "enable": + enable(bus, sys.argv[2], sys.argv[3]) + return 0 if len(sys.argv) == 4 and sys.argv[1] == "remove": remove(bus, sys.argv[2], sys.argv[3]) return 0