This commit is contained in:
@@ -15,6 +15,9 @@ Usage:
|
||||
goa-account check <provider> <presentation-identity>
|
||||
goa-account disabled <provider> <presentation-identity>
|
||||
goa-account enable <provider> <presentation-identity>
|
||||
goa-account attention <provider> <presentation-identity>
|
||||
goa-account pause <provider> <presentation-identity>
|
||||
goa-account paused <provider> <presentation-identity>
|
||||
goa-account remove <provider> <presentation-identity>
|
||||
|
||||
account.json:
|
||||
@@ -26,6 +29,18 @@ 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.
|
||||
|
||||
attention exits 0 if Online Accounts found that the server no longer takes
|
||||
the saved password (it then shows the account as needing attention). It
|
||||
doesn't sign in, so it doesn't add to the server's count of failed logins.
|
||||
Online Accounts 3.58 only finds this for Nextcloud: a mail server refusing the
|
||||
password is reported as a general failure (see system/email-watch).
|
||||
|
||||
pause empties the account's saved password, keeping its place in the keyring.
|
||||
Online Accounts signs in again whenever the network changes, and Evolution
|
||||
whenever it fetches mail; with no password neither tries, so a mail server
|
||||
with fail2ban doesn't block this computer for repeated wrong passwords.
|
||||
update puts a password back, which ends the pause. paused exits 0 if paused.
|
||||
"""
|
||||
|
||||
import json
|
||||
@@ -112,6 +127,45 @@ def store_credentials(provider, account_id, credentials):
|
||||
secret, None)
|
||||
|
||||
|
||||
# The account's saved credentials, e.g. {"imap-password": "..."}
|
||||
def lookup_credentials(provider, account_id):
|
||||
items = Secret.password_search_sync(
|
||||
None, {"xdg:schema": "org.gnome.OnlineAccounts"},
|
||||
Secret.SearchFlags.ALL | Secret.SearchFlags.UNLOCK | Secret.SearchFlags.LOAD_SECRETS, None)
|
||||
for item in items:
|
||||
identity = item.get_attributes().get("goa-identity", "")
|
||||
if identity.startswith(f"{provider}:gen") and identity.endswith(f":{account_id}"):
|
||||
return GLib.Variant.parse(None, item.get_secret().get_text(), None, None).unpack()
|
||||
raise LookupError(f"there's no saved password for {account_id} in the keyring")
|
||||
|
||||
|
||||
# The credential each kind of account signs in with
|
||||
PASSWORD_KEYS = {"owncloud": "password", "imap_smtp": "imap-password"}
|
||||
|
||||
|
||||
def attention(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 any(account.get("AttentionNeeded") for _, account in found)
|
||||
|
||||
|
||||
def pause(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}")
|
||||
for _, account in found:
|
||||
store_credentials(provider, account["Id"], {})
|
||||
|
||||
|
||||
def paused(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 any(PASSWORD_KEYS[provider] not in lookup_credentials(provider, account["Id"])
|
||||
for _, account in found)
|
||||
|
||||
|
||||
def update(bus, provider, presentation_identity, credentials):
|
||||
found = find_accounts(bus, provider, presentation_identity)
|
||||
if not found:
|
||||
@@ -180,6 +234,13 @@ def main():
|
||||
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] == "attention":
|
||||
return 0 if attention(bus, sys.argv[2], sys.argv[3]) else 1
|
||||
if len(sys.argv) == 4 and sys.argv[1] == "pause":
|
||||
pause(bus, sys.argv[2], sys.argv[3])
|
||||
return 0
|
||||
if len(sys.argv) == 4 and sys.argv[1] == "paused":
|
||||
return 0 if paused(bus, sys.argv[2], sys.argv[3]) else 1
|
||||
if len(sys.argv) == 4 and sys.argv[1] == "remove":
|
||||
remove(bus, sys.argv[2], sys.argv[3])
|
||||
return 0
|
||||
|
||||
Reference in New Issue
Block a user