This commit is contained in:
Tiago vasconcelos 2022-07-05 16:25:02 +01:00 committed by dni ⚡
parent 929d174ba4
commit 8e0baf7b2d
6 changed files with 56 additions and 31 deletions

View File

@ -7,6 +7,7 @@ db = Database("ext_admin")
admin_ext: APIRouter = APIRouter(prefix="/admin", tags=["admin"]) admin_ext: APIRouter = APIRouter(prefix="/admin", tags=["admin"])
def admin_renderer(): def admin_renderer():
return template_renderer(["lnbits/extensions/admin/templates"]) return template_renderer(["lnbits/extensions/admin/templates"])

View File

@ -11,13 +11,13 @@ from .models import Admin, Funding
async def update_wallet_balance(wallet_id: str, amount: int) -> str: async def update_wallet_balance(wallet_id: str, amount: int) -> str:
temp_id = f"temp_{urlsafe_short_hash()}" temp_id = f"temp_{urlsafe_short_hash()}"
internal_id = f"internal_{urlsafe_short_hash()}" internal_id = f"internal_{urlsafe_short_hash()}"
payment = await create_payment( payment = await create_payment(
wallet_id=wallet_id, wallet_id=wallet_id,
checking_id=internal_id, checking_id=internal_id,
payment_request="admin_internal", payment_request="admin_internal",
payment_hash="admin_internal", payment_hash="admin_internal",
amount=amount*1000, amount=amount * 1000,
memo="Admin top up", memo="Admin top up",
pending=False, pending=False,
) )
@ -25,6 +25,7 @@ async def update_wallet_balance(wallet_id: str, amount: int) -> str:
await internal_invoice_queue.put(internal_id) await internal_invoice_queue.put(internal_id)
return payment return payment
async def update_admin(user: str, **kwargs) -> Admin: async def update_admin(user: str, **kwargs) -> Admin:
q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()]) q = ", ".join([f"{field[0]} = ?" for field in kwargs.items()])
# print("UPDATE", q) # print("UPDATE", q)
@ -35,23 +36,37 @@ async def update_admin(user: str, **kwargs) -> Admin:
assert row, "Newly updated settings couldn't be retrieved" assert row, "Newly updated settings couldn't be retrieved"
return Admin(**row) if row else None return Admin(**row) if row else None
async def get_admin() -> Admin: async def get_admin() -> Admin:
row = await db.fetchone("SELECT * FROM admin.admin") row = await db.fetchone("SELECT * FROM admin.admin")
return Admin(**row) if row else None return Admin(**row) if row else None
async def update_funding(data: Funding) -> Funding: async def update_funding(data: Funding) -> Funding:
await db.execute( await db.execute(
""" """
UPDATE admin.funding UPDATE admin.funding
SET backend_wallet = ?, endpoint = ?, port = ?, read_key = ?, invoice_key = ?, admin_key = ?, cert = ?, balance = ?, selected = ? SET backend_wallet = ?, endpoint = ?, port = ?, read_key = ?, invoice_key = ?, admin_key = ?, cert = ?, balance = ?, selected = ?
WHERE id = ? WHERE id = ?
""", """,
(data.backend_wallet, data.endpoint, data.port, data.read_key, data.invoice_key, data.admin_key, data.cert, data.balance, data.selected, data.id,), (
data.backend_wallet,
data.endpoint,
data.port,
data.read_key,
data.invoice_key,
data.admin_key,
data.cert,
data.balance,
data.selected,
data.id,
),
) )
row = await db.fetchone('SELECT * FROM admin.funding WHERE "id" = ?', (data.id,)) row = await db.fetchone('SELECT * FROM admin.funding WHERE "id" = ?', (data.id,))
assert row, "Newly updated settings couldn't be retrieved" assert row, "Newly updated settings couldn't be retrieved"
return Funding(**row) if row else None return Funding(**row) if row else None
async def get_funding() -> List[Funding]: async def get_funding() -> List[Funding]:
rows = await db.fetchall("SELECT * FROM admin.funding") rows = await db.fetchall("SELECT * FROM admin.funding")

View File

@ -7,19 +7,21 @@ from lnbits.helpers import urlsafe_short_hash
async def get_admin_user(): async def get_admin_user():
if(conf.admin_users[0]): if conf.admin_users[0]:
return conf.admin_users[0] return conf.admin_users[0]
from lnbits.core.crud import create_account, get_user from lnbits.core.crud import create_account, get_user
print("Seems like there's no admin users yet. Let's create an account for you!") print("Seems like there's no admin users yet. Let's create an account for you!")
account = await create_account() account = await create_account()
user = account.id user = account.id
assert user, "Newly created user couldn't be retrieved" assert user, "Newly created user couldn't be retrieved"
print(f"Your newly created account/user id is: {user}. This will be the Super Admin user.") print(
f"Your newly created account/user id is: {user}. This will be the Super Admin user."
)
conf.admin_users.insert(0, user) conf.admin_users.insert(0, user)
return user return user
async def m001_create_admin_table(db): async def m001_create_admin_table(db):
# users/server # users/server
user = await get_admin_user() user = await get_admin_user()
@ -28,7 +30,7 @@ async def m001_create_admin_table(db):
admin_ext = ",".join(conf.admin_ext) admin_ext = ",".join(conf.admin_ext)
disabled_ext = ",".join(conf.disabled_ext) disabled_ext = ",".join(conf.disabled_ext)
funding_source = conf.funding_source funding_source = conf.funding_source
#operational # operational
data_folder = conf.data_folder data_folder = conf.data_folder
database_url = conf.database_url database_url = conf.database_url
force_https = conf.force_https force_https = conf.force_https

View File

@ -28,6 +28,7 @@ class UpdateAdminSettings(BaseModel):
custom_logo: str = Query(None) custom_logo: str = Query(None)
ad_space: str = Query(None) ad_space: str = Query(None)
class Admin(BaseModel): class Admin(BaseModel):
# users # users
user: str user: str
@ -59,6 +60,7 @@ class Admin(BaseModel):
data = dict(row) data = dict(row)
return cls(**data) return cls(**data)
class Funding(BaseModel): class Funding(BaseModel):
id: str id: str
backend_wallet: str backend_wallet: str

View File

@ -16,19 +16,21 @@ from .crud import get_admin, get_funding
templates = Jinja2Templates(directory="templates") templates = Jinja2Templates(directory="templates")
@admin_ext.get("/", response_class=HTMLResponse) @admin_ext.get("/", response_class=HTMLResponse)
async def index(request: Request, user: User = Depends(check_user_exists)): async def index(request: Request, user: User = Depends(check_user_exists)):
admin = await get_admin() admin = await get_admin()
funding = [f.dict() for f in await get_funding()] funding = [f.dict() for f in await get_funding()]
error, balance = await g().WALLET.status() error, balance = await g().WALLET.status()
return admin_renderer().TemplateResponse( return admin_renderer().TemplateResponse(
"admin/index.html", { "admin/index.html",
{
"request": request, "request": request,
"user": user.dict(), "user": user.dict(),
"admin": admin.dict(), "admin": admin.dict(),
"funding": funding, "funding": funding,
"settings": g().admin_conf.dict(), "settings": g().admin_conf.dict(),
"balance": balance "balance": balance,
} },
) )

View File

@ -15,16 +15,18 @@ from .crud import get_admin, update_admin, update_funding, update_wallet_balance
@admin_ext.get("/api/v1/admin/{wallet_id}/{topup_amount}", status_code=HTTPStatus.OK) @admin_ext.get("/api/v1/admin/{wallet_id}/{topup_amount}", status_code=HTTPStatus.OK)
async def api_update_balance(wallet_id, topup_amount: int, g: WalletTypeInfo = Depends(require_admin_key)): async def api_update_balance(
wallet_id, topup_amount: int, g: WalletTypeInfo = Depends(require_admin_key)
):
try: try:
wallet = await get_wallet(wallet_id) wallet = await get_wallet(wallet_id)
except: except:
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.FORBIDDEN, detail="Not allowed: not an admin" status_code=HTTPStatus.FORBIDDEN, detail="Not allowed: not an admin"
) )
await update_wallet_balance(wallet_id=wallet_id, amount=int(topup_amount)) await update_wallet_balance(wallet_id=wallet_id, amount=int(topup_amount))
return {"status": "Success"} return {"status": "Success"}
@ -32,39 +34,40 @@ async def api_update_balance(wallet_id, topup_amount: int, g: WalletTypeInfo = D
async def api_update_admin( async def api_update_admin(
request: Request, request: Request,
data: UpdateAdminSettings = Body(...), data: UpdateAdminSettings = Body(...),
w: WalletTypeInfo = Depends(require_admin_key) w: WalletTypeInfo = Depends(require_admin_key),
): ):
admin = await get_admin() admin = await get_admin()
# print(data) # print(data)
if not admin.user == w.wallet.user: if not admin.user == w.wallet.user:
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.FORBIDDEN, detail="Not allowed: not an admin" status_code=HTTPStatus.FORBIDDEN, detail="Not allowed: not an admin"
) )
updated = await update_admin(user=w.wallet.user, **data.dict()) updated = await update_admin(user=w.wallet.user, **data.dict())
updated.admin_users = removeEmptyString(updated.admin_users.split(',')) updated.admin_users = removeEmptyString(updated.admin_users.split(","))
updated.allowed_users = removeEmptyString(updated.allowed_users.split(',')) updated.allowed_users = removeEmptyString(updated.allowed_users.split(","))
updated.admin_ext = removeEmptyString(updated.admin_ext.split(',')) updated.admin_ext = removeEmptyString(updated.admin_ext.split(","))
updated.disabled_ext = removeEmptyString(updated.disabled_ext.split(',')) updated.disabled_ext = removeEmptyString(updated.disabled_ext.split(","))
updated.theme = removeEmptyString(updated.theme.split(',')) updated.theme = removeEmptyString(updated.theme.split(","))
updated.ad_space = removeEmptyString(updated.ad_space.split(',')) updated.ad_space = removeEmptyString(updated.ad_space.split(","))
g().admin_conf = g().admin_conf.copy(update=updated.dict()) g().admin_conf = g().admin_conf.copy(update=updated.dict())
# print(g().admin_conf) # print(g().admin_conf)
return {"status": "Success"} return {"status": "Success"}
@admin_ext.post("/api/v1/admin/funding/", status_code=HTTPStatus.OK) @admin_ext.post("/api/v1/admin/funding/", status_code=HTTPStatus.OK)
async def api_update_funding( async def api_update_funding(
request: Request, request: Request,
data: Funding = Body(...), data: Funding = Body(...),
w: WalletTypeInfo = Depends(require_admin_key) w: WalletTypeInfo = Depends(require_admin_key),
): ):
admin = await get_admin() admin = await get_admin()
if not admin.user == w.wallet.user: if not admin.user == w.wallet.user:
raise HTTPException( raise HTTPException(
status_code=HTTPStatus.FORBIDDEN, detail="Not allowed: not an admin" status_code=HTTPStatus.FORBIDDEN, detail="Not allowed: not an admin"
) )
funding = await update_funding(data=data) funding = await update_funding(data=data)
return funding return funding