Urls
This commit is contained in:
parent
f27aa04d02
commit
afea7d9923
3 changed files with 170 additions and 18 deletions
62
API/main.py
62
API/main.py
|
|
@ -1,9 +1,9 @@
|
||||||
from fastapi import FastAPI, HTTPException, status
|
from fastapi import FastAPI, HTTPException, Query, status
|
||||||
from pydantic import BaseModel, EmailStr
|
from pydantic import BaseModel, EmailStr
|
||||||
import utils
|
import utils
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
db = utils.DataBase("")
|
methods = utils.API("")
|
||||||
|
|
||||||
class RegisterBody(BaseModel) :
|
class RegisterBody(BaseModel) :
|
||||||
email : EmailStr
|
email : EmailStr
|
||||||
|
|
@ -13,10 +13,14 @@ class LoginBody(BaseModel) :
|
||||||
email : EmailStr
|
email : EmailStr
|
||||||
password : str
|
password : str
|
||||||
|
|
||||||
|
class UrlsBody(BaseModel) :
|
||||||
|
urls_name : str
|
||||||
|
email : EmailStr
|
||||||
|
password : str
|
||||||
|
|
||||||
@app.post("/registration", status_code=status.HTTP_201_CREATED)
|
@app.post("/registration", status_code=status.HTTP_201_CREATED)
|
||||||
def registration(body: RegisterBody) :
|
def registration(body: RegisterBody) :
|
||||||
result = db.registration(body.email, body.password)
|
result = methods.registration(body.email, body.password)
|
||||||
if result["code"] == 1:
|
if result["code"] == 1:
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
|
@ -26,11 +30,59 @@ def registration(body: RegisterBody) :
|
||||||
|
|
||||||
@app.post("/login", status_code=status.HTTP_200_OK)
|
@app.post("/login", status_code=status.HTTP_200_OK)
|
||||||
def login(body: LoginBody) :
|
def login(body: LoginBody) :
|
||||||
answer = db.login(body.email, body.password)
|
answer = methods.login(body.email, body.password)
|
||||||
if answer["code"] == 1 :
|
if answer["code"] == 1 :
|
||||||
raise HTTPException(
|
raise HTTPException(
|
||||||
status_code=status.HTTP_400_BAD_REQUEST,
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
detail="Incorrect email or password."
|
detail="Incorrect email or password."
|
||||||
)
|
)
|
||||||
else :
|
else :
|
||||||
return answer["data"]
|
return answer["data"]
|
||||||
|
|
||||||
|
@app.post("/add_url", status_code=status.HTTP_200_OK)
|
||||||
|
def add_url(body: UrlsBody) :
|
||||||
|
answer = methods.add_url(body.email, body.password, body.urls_name)
|
||||||
|
if answer["code"] == 1 :
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="Incorrect email or password."
|
||||||
|
)
|
||||||
|
elif answer["code"] == 2 :
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="The url already exists."
|
||||||
|
)
|
||||||
|
else :
|
||||||
|
return answer["data"]
|
||||||
|
|
||||||
|
@app.get("/get_url", status_code=status.HTTP_200_OK)
|
||||||
|
def get_url(email: EmailStr = Query(...), password: str = Query(...), urls_name: str = Query(...)) :
|
||||||
|
answer = methods.get_url(email, password, urls_name)
|
||||||
|
if answer["code"] == 1 :
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="Incorrect email or password."
|
||||||
|
)
|
||||||
|
elif answer["code"] == 2 :
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="The url does not exist"
|
||||||
|
)
|
||||||
|
else :
|
||||||
|
return answer["data"]
|
||||||
|
|
||||||
|
@app.delete("/del_url", status_code=status.HTTP_200_OK)
|
||||||
|
def del_url(email: EmailStr = Query(...), password: str = Query(...), urls_name: str = Query(...)) :
|
||||||
|
answer = methods.del_url(email, password, urls_name)
|
||||||
|
if answer["code"] == 1 :
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="Incorrect email or password."
|
||||||
|
)
|
||||||
|
elif answer["code"] == 2 :
|
||||||
|
raise HTTPException(
|
||||||
|
status_code=status.HTTP_400_BAD_REQUEST,
|
||||||
|
detail="The url does not exist"
|
||||||
|
)
|
||||||
|
else :
|
||||||
|
return answer["data"]
|
||||||
|
|
|
||||||
123
API/utils.py
123
API/utils.py
|
|
@ -1,36 +1,42 @@
|
||||||
import sqlite3
|
import sqlite3
|
||||||
import pandas
|
import pandas
|
||||||
|
import py3xui
|
||||||
import datetime
|
import datetime
|
||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
|
import uuid
|
||||||
|
|
||||||
class DataBase :
|
class API :
|
||||||
def __init__(self, path: str) :
|
def __init__(self, path: str, host: str, username: str, passwd: str, inbaund_id: int, inbaund_url: str, inbaund_port: str) :
|
||||||
self.con = sqlite3.connect(path)
|
self.con = sqlite3.connect(path)
|
||||||
self.cur = self.con.cursor()
|
self.cur = self.con.cursor()
|
||||||
|
|
||||||
self.cur.execute("""
|
self.cur.execute("""
|
||||||
CREATE TABLE IF NOT EXISTS users (
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
email TEXT NOT NULL UNIQUE,
|
email TEXT NOT NULL UNIQUE,
|
||||||
pass_hash TEXT NOT NULL,
|
pass_hash TEXT NOT NULL,
|
||||||
register TEXT NOT NULL,
|
register TEXT NOT NULL,
|
||||||
urls TEXT DEFAULT "",
|
urls TEXT DEFAULT "[]" NOT NULL,
|
||||||
payment TEXT DEFAULT ""
|
payment TEXT DEFAULT ""
|
||||||
)
|
)
|
||||||
""")
|
""")
|
||||||
|
|
||||||
self.con.commit()
|
self.con.commit()
|
||||||
|
|
||||||
|
self.x_ui = py3xui.Api(host, username, passwd)
|
||||||
|
self.x_ui.login()
|
||||||
|
self.inbaund_id = inbaund_id
|
||||||
|
self.inbaund_url = inbaund_url
|
||||||
|
self.inbaund_port = inbaund_port
|
||||||
|
|
||||||
def read_table(self, sql_command: str, params=None) -> dict :
|
def read_table(self, sql_command: str, params=None) -> dict :
|
||||||
if params == None :
|
if params == None :
|
||||||
params = ()
|
params = ()
|
||||||
return json.loads(pandas.read_sql(sql_command, self.con, params=params).to_json())
|
return json.loads(pandas.read_sql(sql_command, self.con, params=params).to_json())
|
||||||
|
|
||||||
def get_hash(text: str) :
|
def get_hash(text: str) -> str:
|
||||||
return hashlib.sha256(text.encode()).hexdigest()
|
return hashlib.sha256(text.encode()).hexdigest()
|
||||||
|
|
||||||
def registration(self, email: str, passwd: str) :
|
def registration(self, email: str, passwd: str) -> dict :
|
||||||
"""
|
"""
|
||||||
0 - Success
|
0 - Success
|
||||||
1 - Email is busy
|
1 - Email is busy
|
||||||
|
|
@ -48,19 +54,112 @@ class DataBase :
|
||||||
SELECT id FROM users
|
SELECT id FROM users
|
||||||
WHERE email = ?
|
WHERE email = ?
|
||||||
""", (email))
|
""", (email))
|
||||||
return {"code": 0, "data": {"id": data["id"]["0"], "email": email}}
|
return {"code": 0, "data": {"id": int(data["id"]["0"]), "email": email}}
|
||||||
|
|
||||||
def login(self, email: str, passwd: str) :
|
def login(self, email: str, passwd: str) -> dict :
|
||||||
"""
|
"""
|
||||||
0 - Success
|
0 - Success
|
||||||
1 - Incorrect email or password
|
1 - Incorrect email or password
|
||||||
"""
|
"""
|
||||||
data = self.read_table("""
|
data = self.read_table("""
|
||||||
SELECT id, urls, payment FROM users
|
SELECT id, urls FROM users
|
||||||
WHERE email = ? AND pass_hash = ?
|
WHERE email = ? AND pass_hash = ?
|
||||||
""", (email, self.get_hash(passwd)))
|
""", (email, self.get_hash(passwd)))
|
||||||
if data["id"] == {} :
|
if data["id"] == {} :
|
||||||
return {"code": 1}
|
return {"code": 1}
|
||||||
else :
|
return {"code": 0, "data": {"id": int(data["id"]["0"]), "email": email, "urls": json.loads(data["urls"]["0"])}}
|
||||||
return {"code": 0, "data": {"id": data["id"]["0"], "email": email, "urls": data["urls"]["0"], "payment": data["payment"]["0"]}}
|
|
||||||
|
|
||||||
|
def add_url(self, email: str, passwd: str, url_name: str) -> dict :
|
||||||
|
"""
|
||||||
|
0 - Success
|
||||||
|
1 - Incorrect email or password
|
||||||
|
2 - The url already exists
|
||||||
|
"""
|
||||||
|
data = self.read_table("""
|
||||||
|
SELECT id, urls FROM users
|
||||||
|
WHERE email = ? AND pass_hash = ?
|
||||||
|
""", (email, self.get_hash(passwd)))
|
||||||
|
if data["id"] == {} :
|
||||||
|
return {"code": 1}
|
||||||
|
urls = json.loads(data["urls"]["0"])
|
||||||
|
if url_name in urls :
|
||||||
|
return {"code": 2}
|
||||||
|
|
||||||
|
uid = str(uuid.uuid4())
|
||||||
|
new_client = py3xui.Client(id=uid, email=f"{email}-{url_name}", enable=True, flow="xtls-rprx-vision")
|
||||||
|
self.x_ui.client.add(self.inbaund_id, new_client)
|
||||||
|
|
||||||
|
inbound = py3xui.Inbound(id=self.inbaund_id)
|
||||||
|
pbk = inbound.stream_settings.reality_settings.get("settings").get("publicKey")
|
||||||
|
wn = inbound.stream_settings.reality_settings.get("serverNames")[0]
|
||||||
|
short_id = inbound.stream_settings.reality_settings.get("shortIds")[0]
|
||||||
|
url = f"vless://{uid}@{self.inbaund_url}:{self.inbaund_port}?security=reality&pbk={pbk}&fp=random&sni={wn}&sid={short_id}&spx=%2F&flow=xtls-rprx-vision#SpectralVPN-{url_name}"
|
||||||
|
|
||||||
|
urls.append(url_name)
|
||||||
|
|
||||||
|
self.cur.execute("""
|
||||||
|
UPDATE users SET
|
||||||
|
urls = ?
|
||||||
|
WHERE id = ?
|
||||||
|
""", (json.dumps(urls), int(data["id"]["0"])))
|
||||||
|
data = self.read_table("""
|
||||||
|
SELECT id, urls FROM users
|
||||||
|
WHERE email = ? AND pass_hash = ?
|
||||||
|
""", (email, self.get_hash(passwd)))
|
||||||
|
|
||||||
|
return {"code": 0, "data": {"id": int(data["id"]["0"]), "email": email, "urls": json.loads(data["urls"]["0"]), "url": url}}
|
||||||
|
|
||||||
|
def get_url(self, email: str, passwd: str, url_name: str) -> dict :
|
||||||
|
"""
|
||||||
|
0 - Success
|
||||||
|
1 - Incorrect email or password
|
||||||
|
2 - The url does not exist
|
||||||
|
"""
|
||||||
|
data = self.read_table("""
|
||||||
|
SELECT id, urls FROM users
|
||||||
|
WHERE email = ? AND pass_hash = ?
|
||||||
|
""", (email, self.get_hash(passwd)))
|
||||||
|
if data["id"] == {} :
|
||||||
|
return {"code": 1}
|
||||||
|
urls = json.loads(data["urls"]["0"])
|
||||||
|
if not url_name in urls :
|
||||||
|
return {"code": 2}
|
||||||
|
|
||||||
|
uid = self.x_ui.client.get_by_email(f"{email}-{url_name}").uuid
|
||||||
|
inbound = py3xui.Inbound(id=self.inbaund_id)
|
||||||
|
pbk = inbound.stream_settings.reality_settings.get("settings").get("publicKey")
|
||||||
|
wn = inbound.stream_settings.reality_settings.get("serverNames")[0]
|
||||||
|
short_id = inbound.stream_settings.reality_settings.get("shortIds")[0]
|
||||||
|
url = f"vless://{uid}@{self.inbaund_url}:{self.inbaund_port}?security=reality&pbk={pbk}&fp=random&sni={wn}&sid={short_id}&spx=%2F&flow=xtls-rprx-vision#SpectralVPN-{url_name}"
|
||||||
|
|
||||||
|
return {"code": 0, "data": {"id": int(data["id"]["0"]), "email": email, "urls": urls, "url": url}}
|
||||||
|
|
||||||
|
def del_url(self, email: str, passwd: str, url_name: str) -> dict :
|
||||||
|
"""
|
||||||
|
0 - Success
|
||||||
|
1 - Incorrect email or password
|
||||||
|
2 - The url does not exist
|
||||||
|
"""
|
||||||
|
data = self.read_table("""
|
||||||
|
SELECT id, urls FROM users
|
||||||
|
WHERE email = ? AND pass_hash = ?
|
||||||
|
""", (email, self.get_hash(passwd)))
|
||||||
|
if data["id"] == {} :
|
||||||
|
return {"code": 1}
|
||||||
|
urls = json.loads(data["urls"]["0"])
|
||||||
|
if not url_name in urls :
|
||||||
|
return {"code": 2}
|
||||||
|
|
||||||
|
uid = self.x_ui.client.get_by_email(f"{email}-{url_name}").uuid
|
||||||
|
self.x_ui.client.delete(self.inbaund_id, uid)
|
||||||
|
urls.remove(url_name)
|
||||||
|
self.cur.execute("""
|
||||||
|
UPDATE users SET
|
||||||
|
urls = ?
|
||||||
|
WHERE id = ?
|
||||||
|
""", (json.dumps(urls), int(data["id"]["0"])))
|
||||||
|
data = self.read_table("""
|
||||||
|
SELECT id, urls FROM users
|
||||||
|
WHERE email = ? AND pass_hash = ?
|
||||||
|
""", (email, self.get_hash(passwd)))
|
||||||
|
return {"code": 0, "data": {"id": int(data["id"]["0"]), "email": email, "urls": urls}}
|
||||||
|
|
@ -1,2 +1,3 @@
|
||||||
fastapi[all]
|
fastapi[all]
|
||||||
pandas
|
pandas
|
||||||
|
py3xui
|
||||||
Loading…
Add table
Add a link
Reference in a new issue