dotfiles
Seven years worth of accumulated configuration cruft
dotfiles/scripts/.local/bin/mailaddr
Download raw file: scripts/.local/bin/mailaddr
#!/usr/bin/env python3 # Add a new email address alias to my domain name using migadu. import re import sys import requests import subprocess from bs4 import BeautifulSoup class MigaduError(Exception): pass; def get_email_and_passwd(): print("Getting username and password from keyring...") o = subprocess.run(["pass", "migadu.com"], stdout=subprocess.PIPE).stdout.decode("utf-8").split("\n") return (o[1].split(" ")[1], o[0]) def get_otp_code(): print("Getting OTP code from keyring...") return subprocess.run(["pass", "otp", "migadu.com"], stdout=subprocess.PIPE).stdout.decode("utf-8").split("\n")[0] def fetch_csrf_token_and_session_cookie(): print("Fetching signin CSRF token and initial session cookie...") r = requests.get("https://admin.migadu.com/public/login") r.raise_for_status() soup = BeautifulSoup(r.text, "html.parser") return (soup.find(id="signin_form").input.get("value"), r.cookies) def signin_passwd(email, passwd, cookies, signin_csrf_token): print("Signing in with username and password...") r = requests.post("https://admin.migadu.com/public/login", cookies=cookies, data={"user[email]": email, "user[password]": passwd, "_csrf_token": signin_csrf_token}) r.raise_for_status() soup = BeautifulSoup(r.text, "html.parser") otp_csrf_token = soup.find(id="otp_form").input.get("value") org_id = soup.find(id="otp_form_organization_id").get("value") return (otp_csrf_token, r.cookies, org_id) def signin_otp(cookies, otp_csrf_token, otp_code, org_id): print("Signing in with OTP code...") r = requests.post("https://admin.migadu.com/public/login", cookies=cookies, data={"user[otp_token]": otp_code, "user[organization_id]": org_id, "user[temporary_disable_second_factor]": "false", "_csrf_token": otp_csrf_token}) r.raise_for_status() return r.cookies def get_login_cookies(): print("Logging you in...") (email, passwd) = get_email_and_passwd() (csrf_token, cookies) = fetch_csrf_token_and_session_cookie() (csrf_token, cookies, org_id) = signin_passwd(email, passwd, cookies, csrf_token) cookies = signin_otp(cookies, csrf_token, get_otp_code(), org_id) print("Successfully logged in.") return cookies def get_alias_csrf_token(auth): print("Getting CSRF token for alias form...") r = requests.get("https://admin.migadu.com/domains/104297/aliases/new", cookies=auth) r.raise_for_status() soup = BeautifulSoup(r.text, "html.parser") return soup.find(action="/domains/104297/aliases").input.get("value") def create_mail_alias(auth, addr): alias_csrf_token = get_alias_csrf_token(auth) print("Creating alias " + addr + "@ulthar.xyz...") r = requests.post("https://admin.migadu.com/domains/104297/aliases", cookies=auth, data={"_csrf_token": alias_csrf_token, "alias[tags]": "", "alias[local_part]": addr, "alias[destinations]": "ymir"}) r.raise_for_status() error = BeautifulSoup(r.text, "html.parser").find(class_="alert alert-error") if error: print("Something's wrong, writing response to migadu_debug.html", file=sys.stderr) with open("migadu_debug.html", "w") as f: f.write(r.text) raise MigaduError(error.span.text) else: print("Created alias " + addr + "@ulthar.xyz") pass pass def main(argv): if len(argv) == 1: print("Generate email aliases: mailaddr [aliases...]", file=sys.stderr) return 1 auth = get_login_cookies() for arg in argv[1:]: has_domain = re.compile("^.*@ulthar.xyz$") addr = arg.replace("@ulthar.xyz", "", 1) if has_domain.match(arg) else arg try: create_mail_alias(auth, addr) except MigaduError as err: print("Migadu Error: " + str(err), file=sys.stderr); return -1 return 0 if __name__ == '__main__': sys.exit(main(sys.argv)) pass