rework config login and add update NPM function
This commit is contained in:
parent
5e8f1ee46d
commit
0f1080b196
2
.vscode/launch.json
vendored
2
.vscode/launch.json
vendored
@ -17,7 +17,7 @@
|
||||
"FLASK_APP": "ktvmanager.main:create_app",
|
||||
"FLASK_ENV": "development",
|
||||
"PYTHONPATH": "${workspaceFolder}",
|
||||
"FLASK_RUN_PORT": "5001"
|
||||
"FLASK_RUN_PORT": "5002"
|
||||
},
|
||||
"args": [
|
||||
"run",
|
||||
|
21
generate_vapid_keys.py
Normal file
21
generate_vapid_keys.py
Normal file
@ -0,0 +1,21 @@
|
||||
from py_vapid import Vapid
|
||||
import os
|
||||
|
||||
vapid = Vapid()
|
||||
vapid.generate_keys()
|
||||
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
|
||||
private_key = vapid.private_key.private_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PrivateFormat.PKCS8,
|
||||
encryption_algorithm=serialization.NoEncryption()
|
||||
).decode('utf-8')
|
||||
|
||||
public_key = vapid.public_key.public_bytes(
|
||||
encoding=serialization.Encoding.PEM,
|
||||
format=serialization.PublicFormat.SubjectPublicKeyInfo
|
||||
).decode('utf-8')
|
||||
|
||||
print(f"VAPID_PRIVATE_KEY='{private_key}'")
|
||||
print(f"VAPID_PUBLIC_KEY='{public_key}'")
|
72
host_9_config.txt
Normal file
72
host_9_config.txt
Normal file
@ -0,0 +1,72 @@
|
||||
location ~ ^/Mongoose(.*)$ {
|
||||
return 302 http://m3u.sstv.one:81/$1$is_args$args;
|
||||
}
|
||||
location ~ ^/Blazin(.*)$ {
|
||||
return 302 http://blazin.dns-cloud.net:8080/$1$is_args$args;
|
||||
}
|
||||
location ~ ^/Insanity(.*)$ {
|
||||
return 302 https://biglicks.win:443/$1$is_args$args;
|
||||
}
|
||||
location ~ ^/Badger(.*)$ {
|
||||
return 302 http://hurricanetv.kiev.ua:80/$1$is_args$args;
|
||||
}
|
||||
location ~ ^/Gunslinger(.*)$ {
|
||||
return 302 http://jabawalkies.club:8080/$1$is_args$args;
|
||||
}
|
||||
location ~ ^/KDB(.*)$ {
|
||||
return 302 http://finger-ya-bum-hole.site/$1$is_args$args;
|
||||
}
|
||||
location ~ ^/Graphite(.*)$ {
|
||||
return 302 http://sarahgraphite.liveme.vip:80/$1$is_args$args;
|
||||
}
|
||||
location ~ ^/old-Premium(.*)$ {
|
||||
return 302 https://kwikfitfitter.life:443/$1$is_args$args;
|
||||
}
|
||||
location ~ ^/Gold(.*)$ {
|
||||
return 302 http://server1.elitehosting.gq:8090/$1$is_args$args;
|
||||
}
|
||||
location ~ ^/Bravado(.*)$ {
|
||||
return 302 http://le.thund.re/$1$is_args$args;
|
||||
}
|
||||
location ~ ^/Titan(.*)$ {
|
||||
return 302 http://maximumorg.xyz:80/$1$is_args$args;
|
||||
}
|
||||
location ~ ^/Wolfie(.*)$ {
|
||||
return 302 http://deviltv.fun:8080/$1$is_args$args;
|
||||
}
|
||||
location ~ ^/DiamondBack(.*)$ {
|
||||
return 302 http://pro-media.live:2052/$1$is_args$args;
|
||||
}
|
||||
location ~ ^/Halo(.*)$ {
|
||||
return 302 http://i-like-turtles.org:8080/$1$is_args$args;
|
||||
}
|
||||
location ~ ^/Nitro(.*)$ {
|
||||
return 302 http://mr-beans-streams.xyz$1$is_args$args;
|
||||
}
|
||||
location ~ ^/Insanity(.*)$ {
|
||||
return 302 https://biglicks.win:443/$1$is_args$args;
|
||||
}
|
||||
location ~ ^/Bonsai(.*)$ {
|
||||
return 302 http://crazyservertimes.pro/$1$is_args$args;
|
||||
}
|
||||
location ~ ^/New-Prem(.*)$ {
|
||||
return 302 http://hello.exodus-2.xyz:8080/$1$is_args$args;
|
||||
}
|
||||
location ~ ^/Crystal(.*)$ {
|
||||
return 302 https://line.ottcst.com/$1$is_args$args;
|
||||
}
|
||||
location ~ ^/VIP(.*)$ {
|
||||
return 302 https://1visions.co.uk:443/$1$is_args$args;
|
||||
}
|
||||
location ~ ^/WILD(.*)$ {
|
||||
return 302 http://wildversion.com:8080/$1$is_args$args;
|
||||
}
|
||||
location ~ ^/STEST(.*)$ {
|
||||
return 302 http://notwhatyourlookingfor.ru/$1$is_args$args;
|
||||
}
|
||||
location ~ ^/SPARE(.*)$ {
|
||||
return 302 http://moontv.co.uk/$1$is_args$args;
|
||||
}
|
||||
location ~ ^/QUARTZ(.*)$ {
|
||||
return 302 http://anyholeisagoal.ru/$1$is_args$args;
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
from functools import wraps
|
||||
from flask import request, jsonify, Blueprint, Response
|
||||
from typing import Callable, Any, Tuple, Dict
|
||||
from .database import get_user_id_from_username
|
||||
|
||||
|
||||
auth_blueprint = Blueprint("auth", __name__)
|
||||
@ -57,4 +58,5 @@ def check_login(username: str, password: str) -> Response:
|
||||
Returns:
|
||||
A Flask JSON response indicating success.
|
||||
"""
|
||||
return jsonify({"auth": "Success"})
|
||||
user_id = get_user_id_from_username(username)
|
||||
return jsonify({"auth": "Success", "user_id": user_id, "username": username})
|
@ -114,6 +114,17 @@ def get_stream_names() -> Response:
|
||||
return jsonify(stream_names)
|
||||
|
||||
|
||||
def get_all_stream_urls() -> Response:
|
||||
"""Retrieves all stream names and URLs from the database.
|
||||
|
||||
Returns:
|
||||
A Flask JSON response containing a list of stream names and URLs.
|
||||
"""
|
||||
query = "SELECT DISTINCT SUBSTRING_INDEX(stream, ' ', 1) AS streamName, streamURL FROM userAccounts"
|
||||
results = _execute_query(query)
|
||||
return jsonify(results)
|
||||
|
||||
|
||||
def single_check() -> Response | Tuple[Response, int]:
|
||||
"""
|
||||
Performs a check on a single account provided in the request JSON.
|
||||
|
157
npm_config_modifier.py
Normal file
157
npm_config_modifier.py
Normal file
@ -0,0 +1,157 @@
|
||||
import requests
|
||||
import json
|
||||
import argparse
|
||||
import mysql.connector
|
||||
import re
|
||||
import os
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
class NginxProxyManager:
|
||||
def __init__(self, host, email, password):
|
||||
self.host = host
|
||||
self.email = email
|
||||
self.password = password
|
||||
self.token = None
|
||||
|
||||
def login(self):
|
||||
url = f"{self.host}/api/tokens"
|
||||
payload = {
|
||||
"identity": self.email,
|
||||
"secret": self.password
|
||||
}
|
||||
headers = {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
response = requests.post(url, headers=headers, data=json.dumps(payload))
|
||||
if response.status_code == 200:
|
||||
self.token = response.json()["token"]
|
||||
print("Login successful.")
|
||||
else:
|
||||
print(f"Failed to login: {response.text}")
|
||||
exit(1)
|
||||
|
||||
def get_proxy_hosts(self):
|
||||
if not self.token:
|
||||
self.login()
|
||||
|
||||
url = f"{self.host}/api/nginx/proxy-hosts"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.token}"
|
||||
}
|
||||
response = requests.get(url, headers=headers)
|
||||
if response.status_code == 200:
|
||||
return response.json()
|
||||
else:
|
||||
print(f"Failed to get proxy hosts: {response.text}")
|
||||
return []
|
||||
|
||||
def get_proxy_host(self, host_id):
|
||||
if not self.token:
|
||||
self.login()
|
||||
|
||||
url = f"{self.host}/api/nginx/proxy-hosts/{host_id}"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.token}"
|
||||
}
|
||||
response = requests.get(url, headers=headers)
|
||||
if response.status_code == 200:
|
||||
return response.json()
|
||||
else:
|
||||
print(f"Failed to get proxy host {host_id}: {response.text}")
|
||||
return None
|
||||
|
||||
def update_proxy_host_config(self, host_id, config):
|
||||
if not self.token:
|
||||
self.login()
|
||||
|
||||
url = f"{self.host}/api/nginx/proxy-hosts/{host_id}"
|
||||
payload = {
|
||||
"advanced_config": config
|
||||
}
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.token}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
response = requests.put(url, headers=headers, data=json.dumps(payload))
|
||||
if response.status_code == 200:
|
||||
print(f"Successfully updated proxy host {host_id}")
|
||||
else:
|
||||
print(f"Failed to update proxy host {host_id}: {response.text}")
|
||||
|
||||
def get_streams_from_db(db_host, db_user, db_pass, db_name, db_port):
|
||||
try:
|
||||
conn = mysql.connector.connect(
|
||||
host=db_host,
|
||||
user=db_user,
|
||||
password=db_pass,
|
||||
database=db_name,
|
||||
port=db_port
|
||||
)
|
||||
cursor = conn.cursor(dictionary=True)
|
||||
cursor.execute("SELECT streamName, streamURL FROM streams")
|
||||
streams = cursor.fetchall()
|
||||
cursor.close()
|
||||
conn.close()
|
||||
return streams
|
||||
except mysql.connector.Error as err:
|
||||
print(f"Error connecting to database: {err}")
|
||||
return []
|
||||
|
||||
def update_config_with_streams(config, streams):
|
||||
for stream in streams:
|
||||
stream_name = stream['streamName']
|
||||
stream_url = stream['streamURL']
|
||||
# Use a more specific regex to avoid replacing parts of other URLs
|
||||
pattern = re.compile(f'(location ~ \^/{re.escape(stream_name)}\(\.\*\)\$ {{\s*return 302 )([^;]+)(;\\s*}})')
|
||||
config = pattern.sub(f'\\1{stream_url}/$1$is_args$args\\3', config)
|
||||
return config
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Modify Nginx Proxy Manager custom configuration.")
|
||||
parser.add_argument("--list-hosts", action="store_true", help="List all proxy hosts")
|
||||
parser.add_argument("--host-id", type=int, help="The ID of the proxy host to modify")
|
||||
parser.add_argument("--config-file", type=str, help="Path to the file containing the new advanced configuration")
|
||||
parser.add_argument("--download-config", type=str, help="Path to save the current advanced configuration")
|
||||
parser.add_argument("--update-from-db", action="store_true", help="Update the configuration from the database")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
npm_host = os.getenv("NPM_HOST")
|
||||
npm_email = os.getenv("NPM_EMAIL")
|
||||
npm_password = os.getenv("NPM_PASSWORD")
|
||||
db_host = os.getenv("DBHOST")
|
||||
db_user = os.getenv("DBUSER")
|
||||
db_pass = os.getenv("DBPASS")
|
||||
db_name = os.getenv("DATABASE")
|
||||
db_port = os.getenv("DBPORT")
|
||||
|
||||
npm = NginxProxyManager(npm_host, npm_email, npm_password)
|
||||
npm.login()
|
||||
|
||||
if args.list_hosts:
|
||||
hosts = npm.get_proxy_hosts()
|
||||
for host in hosts:
|
||||
print(f"ID: {host['id']}, Domains: {', '.join(host['domain_names'])}")
|
||||
|
||||
if args.host_id and args.download_config:
|
||||
host = npm.get_proxy_host(args.host_id)
|
||||
if host:
|
||||
with open(args.download_config, 'w') as f:
|
||||
f.write(host.get('advanced_config', ''))
|
||||
print(f"Configuration for host {args.host_id} downloaded to {args.download_config}")
|
||||
|
||||
if args.host_id and args.config_file:
|
||||
with open(args.config_file, 'r') as f:
|
||||
config = f.read()
|
||||
npm.update_proxy_host_config(args.host_id, config)
|
||||
|
||||
if args.host_id and args.update_from_db:
|
||||
host = npm.get_proxy_host(args.host_id)
|
||||
if host:
|
||||
current_config = host.get('advanced_config', '')
|
||||
streams = get_streams_from_db(db_host, db_user, db_pass, db_name, db_port)
|
||||
if streams:
|
||||
new_config = update_config_with_streams(current_config, streams)
|
||||
npm.update_proxy_host_config(args.host_id, new_config)
|
@ -8,6 +8,7 @@ from ktvmanager.lib.database import (
|
||||
get_user_id_from_username,
|
||||
save_push_subscription,
|
||||
get_push_subscriptions,
|
||||
get_all_stream_urls,
|
||||
)
|
||||
from ktvmanager.lib.get_urls import get_latest_urls_from_dns
|
||||
from ktvmanager.lib.auth import requires_basic_auth, check_login
|
||||
@ -71,6 +72,21 @@ def get_user_accounts_streams_route(username: str, password: str) -> Response:
|
||||
return jsonify(get_latest_urls_from_dns())
|
||||
|
||||
|
||||
@api_blueprint.route("/get_all_stream_urls")
|
||||
@requires_basic_auth
|
||||
def get_all_stream_urls_route(username: str, password: str) -> Response:
|
||||
"""Retrieves all stream names and URLs.
|
||||
|
||||
Args:
|
||||
username: The username of the user.
|
||||
password: The password of the user (used for authentication).
|
||||
|
||||
Returns:
|
||||
A Flask JSON response containing the list of stream names and URLs.
|
||||
"""
|
||||
return get_all_stream_urls()
|
||||
|
||||
|
||||
@api_blueprint.route("/singleCheck", methods=["POST"])
|
||||
@requires_basic_auth
|
||||
def single_check_route(username: str, password: str) -> Response:
|
||||
|
Loading…
x
Reference in New Issue
Block a user