dyndns: be able to unsubscribe using the key + domain and i18n string consistency

This commit is contained in:
Alexandre Aubin 2023-04-11 19:40:30 +02:00
parent e2da51b9a3
commit cbef40798c
3 changed files with 47 additions and 32 deletions

View file

@ -91,7 +91,8 @@
"ask_new_path": "New path",
"ask_password": "Password",
"ask_dyndns_recovery_password_explain": "Please pick a recovery password for your DynDNS domain, in case you need to reset it later.",
"ask_dyndns_recovery_password": "DynDNS recovey passwory",
"ask_dyndns_recovery_password": "DynDNS recovery password",
"ask_dyndns_recovery_password_explain_during_unsubscribe": "Please enter the recovery password for this DynDNS domain.",
"ask_user_domain": "Domain to use for the user's email address and XMPP account",
"backup_abstract_method": "This backup method has yet to be implemented",
"backup_actually_backuping": "Creating a backup archive from the collected files...",
@ -404,12 +405,12 @@
"dyndns_no_recovery_password": "No recovery password specified! In case you loose control of this domain, you will need to contact an administrator in the YunoHost team!",
"dyndns_added_password": "Remember your recovery password, you can use it to delete this domain record.",
"dyndns_provider_unreachable": "Unable to reach DynDNS provider {provider}: either your YunoHost is not correctly connected to the internet or the dynette server is down.",
"dyndns_registered": "DynDNS domain registered",
"dyndns_registration_failed": "Could not register DynDNS domain: {error}",
"dyndns_unregistration_failed": "Could not unregister DynDNS domain: {error}",
"dyndns_unregistered": "DynDNS domain successfully unregistered",
"dyndns_unsubscribe_wrong_password": "Invalid password",
"dyndns_unsubscribe_wrong_domain": "Domain is not registered",
"dyndns_subscribed": "DynDNS domain subscribed",
"dyndns_subscribe_failed": "Could not subscribe DynDNS domain: {error}",
"dyndns_unsubscribe_failed": "Could not unsubscribe DynDNS domain: {error}",
"dyndns_unsubscribed": "DynDNS domain unsubscribed",
"dyndns_unsubscribe_denied": "Failed to unsubscribe domain: invalid credentials",
"dyndns_unsubscribe_already_unsubscribed": "Domain is already unsubscribed",
"dyndns_unavailable": "The domain '{domain}' is unavailable.",
"extracting": "Extracting...",
"field_invalid": "Invalid field '{}'",

View file

@ -663,9 +663,8 @@ domain:
subscribe:
action_help: Subscribe to a DynDNS service
arguments:
-d:
full: --domain
help: Full domain to subscribe with
domain:
help: Domain to subscribe to the DynDNS service
extra:
pattern: *pattern_domain
-p:
@ -681,9 +680,8 @@ domain:
unsubscribe:
action_help: Unsubscribe from a DynDNS service
arguments:
-d:
full: --domain
help: Full domain to unsubscribe with
domain:
help: Domain to unsubscribe from the DynDNS service
extra:
pattern: *pattern_domain
required: True

View file

@ -165,14 +165,14 @@ def dyndns_subscribe(operation_logger, domain=None, recovery_password=None):
)
except Exception as e:
rm(key_file, force=True)
raise YunohostError("dyndns_registration_failed", error=str(e))
raise YunohostError("dyndns_subscribe_failed", error=str(e))
if r.status_code != 201:
rm(key_file, force=True)
try:
error = json.loads(r.text)["error"]
except Exception:
error = f'Server error, code: {r.status_code}. (Message: "{r.text}")'
raise YunohostError("dyndns_registration_failed", error=error)
raise YunohostError("dyndns_subscribe_failed", error=error)
# Yunohost regen conf will add the dyndns cron job if a key exists
# in /etc/yunohost/dyndns
@ -187,7 +187,7 @@ def dyndns_subscribe(operation_logger, domain=None, recovery_password=None):
subprocess.check_call(["bash", "-c", cmd.format(t="2 min")])
subprocess.check_call(["bash", "-c", cmd.format(t="4 min")])
logger.success(m18n.n("dyndns_registered"))
logger.success(m18n.n("dyndns_subscribed"))
@is_unit_operation(exclude=["recovery_password"])
@ -202,23 +202,37 @@ def dyndns_unsubscribe(operation_logger, domain, recovery_password=None):
import requests # lazy loading this module for performance reasons
# FIXME : it should be possible to unsubscribe the domain just using the key file ...
# Unsubscribe the domain using the key if available
keys = glob.glob(f"/etc/yunohost/dyndns/K{domain}.+*.key")
if keys:
key = keys[0]
with open(key) as f:
key = f.readline().strip().split(" ", 6)[-1]
base64key = base64.b64encode(key.encode()).decode()
credential = {"key": base64key}
else:
# Ensure sufficiently complex password
if Moulinette.interface.type == "cli" and not recovery_password:
logger.warning(m18n.n("ask_dyndns_recovery_password_explain_during_unsubscribe"))
recovery_password = Moulinette.prompt(
m18n.n("ask_dyndns_recovery_password"),
is_password=True
)
if not recovery_password:
logger.error(f"Cannot unsubscribe the domain {domain}: no credential provided")
return
secret = str(domain) + ":" + str(recovery_password).strip()
credential = {"recovery_password": hashlib.sha256(secret.encode('utf-8')).hexdigest()}
operation_logger.start()
# Send delete request
try:
secret = str(domain) + ":" + str(recovery_password).strip()
r = requests.delete(
f"https://{DYNDNS_PROVIDER}/domains/{domain}",
data={"recovery_password": hashlib.sha256(secret.encode('utf-8')).hexdigest()},
data=credential,
timeout=30,
)
except Exception as e:
@ -230,12 +244,14 @@ def dyndns_unsubscribe(operation_logger, domain, recovery_password=None):
# Yunohost regen conf will add the dyndns cron job if a key exists
# in /etc/yunohost/dyndns
regen_conf(["yunohost"])
elif r.status_code == 403: # Wrong password
raise YunohostError("dyndns_unsubscribe_wrong_password")
elif r.status_code == 404: # Invalid domain
raise YunohostError("dyndns_unsubscribe_wrong_domain")
elif r.status_code == 403:
raise YunohostError("dyndns_unsubscribe_denied")
elif r.status_code == 409:
raise YunohostError("dyndns_unsubscribe_already_unsubscribed")
else:
raise YunohostError("dyndns_unsubscribe_failed", error=f"The server returned code {r.status_code}")
logger.success(m18n.n("dyndns_unregistered"))
logger.success(m18n.n("dyndns_unsubscribed"))
def dyndns_list():