Browse Source

added checks to the cloudflare if the domain can be created; code refactoring - moved calls to cloudflare to seperate file

master
Kristjan 4 years ago
parent
commit
f45aadaafe
  1. 44
      lnbits/extensions/subdomains/cloudflare.py
  2. 28
      lnbits/extensions/subdomains/tasks.py
  3. 26
      lnbits/extensions/subdomains/views_api.py

44
lnbits/extensions/subdomains/cloudflare.py

@ -0,0 +1,44 @@
from lnbits.extensions.subdomains.models import Domains
import httpx, json
async def cloudflare_create_subdomain(domain: Domains, subdomain: str, record_type: str, ip: str):
# Call to cloudflare sort of a dry-run - if success delete the domain and wait for payment
### SEND REQUEST TO CLOUDFLARE
url = "https://api.cloudflare.com/client/v4/zones/" + domain.cf_zone_id + "/dns_records"
header = {"Authorization": "Bearer " + domain.cf_token, "Content-Type": "application/json"}
aRecord = subdomain + "." + domain.domain
cf_response = ""
async with httpx.AsyncClient() as client:
try:
r = await client.post(
url,
headers=header,
json={
"type": record_type,
"name": aRecord,
"content": ip,
"ttl": 0,
"proxed": False,
},
timeout=40,
)
cf_response = json.loads(r.text)
except AssertionError:
cf_response = "Error occured"
return cf_response
async def cloudflare_deletesubdomain(domain: Domains, domain_id: str):
url = "https://api.cloudflare.com/client/v4/zones/" + domain.cf_zone_id + "/dns_records"
header = {"Authorization": "Bearer " + domain.cf_token, "Content-Type": "application/json"}
async with httpx.AsyncClient() as client:
try:
r = await client.delete(
url + "/" + domain_id,
headers=header,
timeout=40,
)
cf_response = r.text
except AssertionError:
cf_response = "Error occured"

28
lnbits/extensions/subdomains/tasks.py

@ -1,7 +1,6 @@
from http import HTTPStatus
from quart.json import jsonify
import trio # type: ignore
import json
import httpx
from .crud import get_domain, set_subdomain_paid
@ -9,6 +8,7 @@ from lnbits.core.crud import get_user, get_wallet
from lnbits.core import db as core_db
from lnbits.core.models import Payment
from lnbits.tasks import register_invoice_listener
from .cloudflare import cloudflare_create_subdomain
async def register_listeners():
@ -31,28 +31,10 @@ async def on_invoice_paid(payment: Payment) -> None:
subdomain = await set_subdomain_paid(payment_hash=payment.payment_hash)
domain = await get_domain(subdomain.domain)
### SEND REQUEST TO CLOUDFLARE
url = "https://api.cloudflare.com/client/v4/zones/" + domain.cf_zone_id + "/dns_records"
header = {"Authorization": "Bearer " + domain.cf_token, "Content-Type": "application/json"}
aRecord = subdomain.subdomain + "." + subdomain.domain_name
cf_response = ""
async with httpx.AsyncClient() as client:
try:
r = await client.post(
url,
headers=header,
json={
"type": subdomain.record_type,
"name": aRecord,
"content": subdomain.ip,
"ttl": 0,
"proxed": False,
},
timeout=40,
)
cf_response = r.text
except AssertionError:
cf_response = "Error occured"
### Create subdomain
cf_response = cloudflare_create_subdomain(
domain=domain, subdomain=subdomain.subdomain, record_type=subdomain.record_type, ip=subdomain.ip
)
### Use webhook to notify about cloudflare registration
if domain.webhook:

26
lnbits/extensions/subdomains/views_api.py

@ -2,7 +2,9 @@ import re
from quart import g, jsonify, request
from http import HTTPStatus
from lnbits.core import crud
import json
import httpx
from lnbits.core.crud import get_user, get_wallet
from lnbits.core.services import create_invoice, check_invoice_status
from lnbits.decorators import api_check_wallet_key, api_validate_post_request
@ -21,6 +23,7 @@ from .crud import (
delete_domain,
get_subdomainBySubdomain,
)
from .cloudflare import cloudflare_create_subdomain, cloudflare_deletesubdomain
# domainS
@ -113,32 +116,45 @@ async def api_subdomains():
async def api_subdomain_make_subdomain(domain_id):
domain = await get_domain(domain_id)
# If the request is coming for the non-existant domain
if not domain:
return jsonify({"message": "LNsubdomain does not exist."}), HTTPStatus.NOT_FOUND
# regex if IP is address
if not isvalidIPAddress(g.data["ip"]):
return jsonify({"message": g.data["ip"] + " Not a valid IP address"}), HTTPStatus.BAD_REQUEST
# regex for checking if domain is valid
if not isValidDomain(g.data["subdomain"] + "." + domain.domain):
return (
jsonify({"message": g.data["subdomain"] + "." + domain.domain + " bad domain name"}),
HTTPStatus.BAD_REQUEST,
)
## If domain already exist in our database reject it
if await get_subdomainBySubdomain(g.data["subdomain"]) is not None:
return (
jsonify({"message": g.data["subdomain"] + "." + domain.domain + " domain already taken"}),
HTTPStatus.BAD_REQUEST,
)
## If record_type is not one of the allowed ones reject the request
if g.data["record_type"] not in domain.allowed_record_types:
return jsonify({"message": g.data["record_type"] + "Not a valid record"}), HTTPStatus.BAD_REQUEST
## Dry run cloudflare... (create and if create is sucessful delete it)
cf_response = await cloudflare_create_subdomain(
domain=domain, subdomain=g.data["subdomain"], record_type=g.data["record_type"], ip=g.data["ip"]
)
if cf_response["success"] == True:
cloudflare_deletesubdomain(domain=domain, domain_id=cf_response["result"]["id"])
else:
return (
jsonify({"message": "Problem with cloudflare: " + cf_response["errors"][0]["message"]}),
HTTPStatus.BAD_REQUEST,
)
subdomain = g.data["subdomain"]
duration = g.data["duration"]
## ALL OK - create an invoice and return it to the user
sats = g.data["sats"]
payment_hash, payment_request = await create_invoice(
wallet_id=domain.wallet,
amount=sats,
memo=f"subdomain {subdomain}.{domain.domain} for {sats} sats for {duration} days",
memo=f"subdomain {g.data['subdomain']}.{domain.domain} for {sats} sats for {g.data['duration']} days",
extra={"tag": "lnsubdomain"},
)

Loading…
Cancel
Save