set User-Agent when accessing external resources (#2100)

* set User-Agent when accessing external resources

* refactor User-Agent into settings.user_agent
This commit is contained in:
Pavol Rusnak
2023-11-30 13:54:07 +01:00
committed by GitHub
parent 992e3bfb9a
commit 62b0e3fe89
16 changed files with 70 additions and 43 deletions

View File

@@ -385,7 +385,8 @@ async def redeem_lnurl_withdraw(
res = {}
async with httpx.AsyncClient() as client:
headers = {"User-Agent": settings.user_agent}
async with httpx.AsyncClient(headers=headers) as client:
lnurl = decode_lnurl(lnurl_request)
r = await client.get(str(lnurl))
res = r.json()
@@ -419,7 +420,8 @@ async def redeem_lnurl_withdraw(
except Exception:
pass
async with httpx.AsyncClient() as client:
headers = {"User-Agent": settings.user_agent}
async with httpx.AsyncClient(headers=headers) as client:
try:
await client.get(res["callback"], params=params)
except Exception:
@@ -482,7 +484,8 @@ async def perform_lnurlauth(
sig = key.sign_digest_deterministic(k1, sigencode=encode_strict_der)
async with httpx.AsyncClient() as client:
headers = {"User-Agent": settings.user_agent}
async with httpx.AsyncClient(headers=headers) as client:
assert key.verifying_key, "LNURLauth verifying_key does not exist"
r = await client.get(
callback,

View File

@@ -120,7 +120,8 @@ async def wait_for_paid_invoices(invoice_paid_queue: asyncio.Queue):
# dispatch balance_notify
url = await get_balance_notify(payment.wallet_id)
if url:
async with httpx.AsyncClient() as client:
headers = {"User-Agent": settings.user_agent}
async with httpx.AsyncClient(headers=headers) as client:
try:
r = await client.post(url, timeout=4)
await mark_webhook_sent(payment, r.status_code)
@@ -152,7 +153,8 @@ async def dispatch_webhook(payment: Payment):
if not payment.webhook:
return await mark_webhook_sent(payment, -1)
async with httpx.AsyncClient() as client:
headers = {"User-Agent": settings.user_agent}
async with httpx.AsyncClient(headers=headers) as client:
data = payment.dict()
try:
r = await client.post(payment.webhook, json=data, timeout=40)

View File

@@ -297,7 +297,8 @@ async def api_payments_create_invoice(data: CreateInvoice, wallet: Wallet):
if data.lnurl_balance_check is not None:
await save_balance_check(wallet.id, data.lnurl_balance_check)
async with httpx.AsyncClient() as client:
headers = {"User-Agent": settings.user_agent}
async with httpx.AsyncClient(headers=headers) as client:
try:
r = await client.get(
data.lnurl_callback,
@@ -412,7 +413,8 @@ async def api_payments_pay_lnurl(
):
domain = urlparse(data.callback).netloc
async with httpx.AsyncClient() as client:
headers = {"User-Agent": settings.user_agent}
async with httpx.AsyncClient(headers=headers) as client:
try:
r = await client.get(
data.callback,
@@ -594,7 +596,8 @@ async def api_lnurlscan(code: str, wallet: WalletTypeInfo = Depends(get_key_type
assert lnurlauth_key.verifying_key
params.update(pubkey=lnurlauth_key.verifying_key.to_string("compressed").hex())
else:
async with httpx.AsyncClient(follow_redirects=True) as client:
headers = {"User-Agent": settings.user_agent}
async with httpx.AsyncClient(headers=headers, follow_redirects=True) as client:
r = await client.get(url, timeout=5)
r.raise_for_status()
if r.is_error:

View File

@@ -179,7 +179,8 @@ class NodeRank(BaseModel):
)
async def api_get_1ml_stats(node: Node = Depends(require_node)) -> Optional[NodeRank]:
node_id = await node.get_id()
async with httpx.AsyncClient() as client:
headers = {"User-Agent": settings.user_agent}
async with httpx.AsyncClient(headers=headers) as client:
r = await client.get(url=f"https://1ml.com/node/{node_id}/json", timeout=15)
try:
r.raise_for_status()

View File

@@ -144,16 +144,11 @@ async def fetch_github_release_config(
async def github_api_get(url: str, error_msg: Optional[str]) -> Any:
async with httpx.AsyncClient() as client:
headers = (
{"Authorization": "Bearer " + settings.lnbits_ext_github_token}
if settings.lnbits_ext_github_token
else None
)
resp = await client.get(
url,
headers=headers,
)
headers = {"User-Agent": settings.user_agent}
if settings.lnbits_ext_github_token:
headers["Authorization"] = f"Bearer {settings.lnbits_ext_github_token}"
async with httpx.AsyncClient(headers=headers) as client:
resp = await client.get(url)
if resp.status_code != 200:
logger.warning(f"{error_msg} ({url}): {resp.text}")
resp.raise_for_status()

View File

@@ -297,6 +297,7 @@ class EnvSettings(LNbitsSettings):
lnbits_extensions_path: str = Field(default="lnbits")
super_user: str = Field(default="")
version: str = Field(default="0.0.0")
user_agent: str = Field(default="")
enable_log_to_file: bool = Field(default=True)
log_rotation: str = Field(default="100 MB")
log_retention: str = Field(default="3 months")
@@ -432,6 +433,9 @@ settings.lnbits_path = str(path.dirname(path.realpath(__file__)))
settings.version = importlib.metadata.version("lnbits")
if not settings.user_agent:
settings.user_agent = f"LNbits/{settings.version}"
# printing environment variable for debugging
if not settings.lnbits_admin_ui:
logger.debug("Environment Settings:")

View File

@@ -4,6 +4,7 @@ from typing import Callable, NamedTuple
import httpx
from loguru import logger
from lnbits.settings import settings
from lnbits.utils.cache import cache
currencies = {
@@ -246,7 +247,8 @@ async def btc_price(currency: str) -> float:
async def fetch_price(provider: Provider):
url = provider.api_url.format(**replacements)
try:
async with httpx.AsyncClient() as client:
headers = {"User-Agent": settings.user_agent}
async with httpx.AsyncClient(headers=headers) as client:
r = await client.get(url, timeout=0.5)
r.raise_for_status()
data = r.json()

View File

@@ -28,7 +28,7 @@ class AlbyWallet(Wallet):
self.endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint
self.auth = {
"Authorization": "Bearer " + settings.alby_access_token,
"User-Agent": f"LNbits/{settings.version}",
"User-Agent": settings.user_agent,
}
self.client = httpx.AsyncClient(base_url=self.endpoint, headers=self.auth)

View File

@@ -38,14 +38,15 @@ class CoreLightningRestWallet(Wallet):
self.url = (
f"https://{self.url}" if not self.url.startswith("http") else self.url
)
self.auth = {
headers = {
"macaroon": self.macaroon,
"encodingtype": "hex",
"accept": "application/json",
"User-Agent": settings.user_agent,
}
self.cert = settings.corelightning_rest_cert or False
self.client = httpx.AsyncClient(verify=self.cert, headers=self.auth)
self.client = httpx.AsyncClient(verify=self.cert, headers=headers)
self.last_pay_index = 0
self.statuses = {
"paid": True,

View File

@@ -40,8 +40,11 @@ class EclairWallet(Wallet):
encodedAuth = base64.b64encode(f":{passw}".encode())
auth = str(encodedAuth, "utf-8")
self.auth = {"Authorization": f"Basic {auth}"}
self.client = httpx.AsyncClient(base_url=self.url, headers=self.auth)
self.headers = {
"Authorization": f"Basic {auth}",
"User-Agent": settings.user_agent,
}
self.client = httpx.AsyncClient(base_url=self.url, headers=self.headers)
async def cleanup(self):
try:
@@ -214,7 +217,7 @@ class EclairWallet(Wallet):
try:
async with connect(
self.ws_url,
extra_headers=[("Authorization", self.auth["Authorization"])],
extra_headers=[("Authorization", self.headers["Authorization"])],
) as ws:
while True:
message = await ws.recv()

View File

@@ -28,8 +28,8 @@ class LNbitsWallet(Wallet):
)
if not self.endpoint or not key:
raise Exception("cannot initialize lnbits wallet")
self.key = {"X-Api-Key": key}
self.client = httpx.AsyncClient(base_url=self.endpoint, headers=self.key)
self.headers = {"X-Api-Key": key, "User-Agent": settings.user_agent}
self.client = httpx.AsyncClient(base_url=self.endpoint, headers=self.headers)
async def cleanup(self):
try:
@@ -136,7 +136,9 @@ class LNbitsWallet(Wallet):
while True:
try:
async with httpx.AsyncClient(timeout=None, headers=self.key) as client:
async with httpx.AsyncClient(
timeout=None, headers=self.headers
) as client:
del client.headers[
"accept-encoding"
] # we have to disable compression for SSEs

View File

@@ -67,9 +67,12 @@ class LndRestWallet(Wallet):
# even on startup
self.cert = cert or True
self.auth = {"Grpc-Metadata-macaroon": self.macaroon}
headers = {
"Grpc-Metadata-macaroon": self.macaroon,
"User-Agent": settings.user_agent,
}
self.client = httpx.AsyncClient(
base_url=self.endpoint, headers=self.auth, verify=self.cert
base_url=self.endpoint, headers=headers, verify=self.cert
)
async def cleanup(self):

View File

@@ -28,8 +28,11 @@ class LNPayWallet(Wallet):
self.wallet_key = wallet_key
self.endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint
self.auth = {"X-Api-Key": settings.lnpay_api_key}
self.client = httpx.AsyncClient(base_url=self.endpoint, headers=self.auth)
headers = {
"X-Api-Key": settings.lnpay_api_key,
"User-Agent": settings.user_agent,
}
self.client = httpx.AsyncClient(base_url=self.endpoint, headers=headers)
async def cleanup(self):
try:

View File

@@ -29,8 +29,11 @@ class LnTipsWallet(Wallet):
if not endpoint or not key:
raise Exception("cannot initialize lntxbod")
self.endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint
self.auth = {"Authorization": f"Basic {key}"}
self.client = httpx.AsyncClient(base_url=self.endpoint, headers=self.auth)
headers = {
"Authorization": f"Basic {key}",
"User-Agent": settings.user_agent,
}
self.client = httpx.AsyncClient(base_url=self.endpoint, headers=headers)
async def cleanup(self):
try:

View File

@@ -21,17 +21,20 @@ class OpenNodeWallet(Wallet):
def __init__(self):
endpoint = settings.opennode_api_endpoint
key = (
self.key = (
settings.opennode_key
or settings.opennode_admin_key
or settings.opennode_invoice_key
)
if not endpoint or not key:
if not endpoint or not self.key:
raise Exception("cannot initialize opennode")
self.endpoint = endpoint[:-1] if endpoint.endswith("/") else endpoint
self.auth = {"Authorization": key}
self.client = httpx.AsyncClient(base_url=self.endpoint, headers=self.auth)
headers = {
"Authorization": self.key,
"User-Agent": settings.user_agent,
}
self.client = httpx.AsyncClient(base_url=self.endpoint, headers=headers)
async def cleanup(self):
try:
@@ -142,7 +145,7 @@ class OpenNodeWallet(Wallet):
# raise HTTPException(status_code=HTTPStatus.NO_CONTENT)
# charge_id = data["id"]
# x = hmac.new(self.auth["Authorization"].encode("ascii"), digestmod="sha256")
# x = hmac.new(self.key.encode("ascii"), digestmod="sha256")
# x.update(charge_id.encode("ascii"))
# if x.hexdigest() != data["hashed_order"]:
# logger.error("invalid webhook, not from opennode")

View File

@@ -32,9 +32,8 @@ class SparkWallet(Wallet):
self.url = settings.spark_url.replace("/rpc", "")
self.token = settings.spark_token
assert self.token, "spark wallet token does not exist"
self.client = httpx.AsyncClient(
base_url=self.url, headers={"X-Access": self.token}
)
headers = {"X-Access": self.token, "User-Agent": settings.user_agent}
self.client = httpx.AsyncClient(base_url=self.url, headers=headers)
async def cleanup(self):
try: