#!/usr/bin/env python3
# Manual Authentication Hook for Let's Encrypt DNS-01 challenge for domains
# registered with Namecheap.
# 
# Copyright (C) 2021 Simon Aldrich
# 
# Use of this script is at your own risk and the author is in no way liable
# for any harm caused by its use.
# 
# Example usage:
#   sudo certbot certonly \
#     --non-interactive \
#     --manual \
#     --manual-public-ip-logging-ok \
#     -d <domain> \
#     --email <email@address> \ 
#     --manual-auth-hook <path/to/this/script>

import os
import time

# https://github.com/Bemmu/PyNamecheap
# pip3 install PyNamecheap
import namecheap

# Set to your Namecheap API credentials and IP address
username = ''
api_key = ''
ip_address = ''

# Get Domain and Validation string from environment variables
# - https://certbot.eff.org/docs/using.html#hooks
certbot_domain = os.getenv('CERTBOT_DOMAIN')
certbot_validation = os.getenv('CERTBOT_VALIDATION')
certbot_record = {'Type': 'TXT', 
                  'Name': '_acme-challenge',
                  'Address': certbot_validation,
                  'TTL': '300'}

# Connect to Namecheap API
api = namecheap.Api(username, api_key, username, ip_address, sandbox=False)

# Remove any existing _acme-challenge record
hosts = api.domains_dns_getHosts(certbot_domain)
for record in hosts:
    if record['Type'] == certbot_record['Type'] and record['Name'] == certbot_record['Name']:
        # Preserve existing record (for TTL etc)
        certbot_record = record
        print('Deleting: {}'.format(record))
        api.domains_dns_delHost(certbot_domain, record)
        certbot_record['Address'] = certbot_validation
        print('Sleeping after delete')
        time.sleep(20)
        break

# Add new record
print('Adding: {}'.format(record))
api.domains_dns_addHost(certbot_domain, certbot_record)
print('Sleeping after add')
time.sleep(20)
