fix the fail2ban issues and other things
shellcheck / shellcheck (push) Successful in 11s

This commit is contained in:
2026-10-31 08:10:05 -06:00
parent 17c1ba10f7
commit 6770150b11
19 changed files with 580 additions and 51 deletions
+61
View File
@@ -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