This commit is contained in:
benarc
2022-02-07 20:43:47 +00:00
parent a7c65d5d60
commit 4b11342f0c
4 changed files with 41 additions and 11 deletions

View File

@ -13,7 +13,7 @@ from starlette.requests import Request
from lnbits.core.crud import get_user, get_wallet_for_key from lnbits.core.crud import get_user, get_wallet_for_key
from lnbits.core.models import User, Wallet from lnbits.core.models import User, Wallet
from lnbits.requestvars import g from lnbits.requestvars import g
from lnbits.settings import LNBITS_ALLOWED_USERS, LNBITS_ADMIN_USERS from lnbits.settings import LNBITS_ALLOWED_USERS, LNBITS_ADMIN_USERS, LNBITS_ADMIN_EXTENSIONS
class KeyChecker(SecurityBase): class KeyChecker(SecurityBase):
@ -122,6 +122,7 @@ async def get_key_type(
# 0: admin # 0: admin
# 1: invoice # 1: invoice
# 2: invalid # 2: invalid
pathname = r['path'].split('/')[1]
if not api_key_header and not api_key_query: if not api_key_header and not api_key_query:
raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST) raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST)
@ -131,7 +132,10 @@ async def get_key_type(
try: try:
checker = WalletAdminKeyChecker(api_key=token) checker = WalletAdminKeyChecker(api_key=token)
await checker.__call__(r) await checker.__call__(r)
return WalletTypeInfo(0, checker.wallet) wallet = WalletTypeInfo(0, checker.wallet)
if (LNBITS_ADMIN_USERS and wallet.wallet.user not in LNBITS_ADMIN_USERS) and (LNBITS_ADMIN_EXTENSIONS and pathname in LNBITS_ADMIN_EXTENSIONS):
raise HTTPException(status_code=HTTPStatus.UNAUTHORIZED, detail="User not authorized.")
return wallet
except HTTPException as e: except HTTPException as e:
if e.status_code == HTTPStatus.BAD_REQUEST: if e.status_code == HTTPStatus.BAD_REQUEST:
raise raise
@ -143,7 +147,10 @@ async def get_key_type(
try: try:
checker = WalletInvoiceKeyChecker(api_key=token) checker = WalletInvoiceKeyChecker(api_key=token)
await checker.__call__(r) await checker.__call__(r)
return WalletTypeInfo(1, checker.wallet) wallet = WalletTypeInfo(0, checker.wallet)
if (LNBITS_ADMIN_USERS and wallet.wallet.user not in LNBITS_ADMIN_USERS) and (LNBITS_ADMIN_EXTENSIONS and pathname in LNBITS_ADMIN_EXTENSIONS):
raise HTTPException(status_code=HTTPStatus.UNAUTHORIZED, detail="User not authorized.")
return wallet
except HTTPException as e: except HTTPException as e:
if e.status_code == HTTPStatus.BAD_REQUEST: if e.status_code == HTTPStatus.BAD_REQUEST:
raise raise

View File

@ -15,6 +15,7 @@ import lnbits.settings as settings
class Extension(NamedTuple): class Extension(NamedTuple):
code: str code: str
is_valid: bool is_valid: bool
is_admin_only: bool
name: Optional[str] = None name: Optional[str] = None
short_description: Optional[str] = None short_description: Optional[str] = None
icon: Optional[str] = None icon: Optional[str] = None
@ -25,6 +26,7 @@ class Extension(NamedTuple):
class ExtensionManager: class ExtensionManager:
def __init__(self): def __init__(self):
self._disabled: List[str] = settings.LNBITS_DISABLED_EXTENSIONS self._disabled: List[str] = settings.LNBITS_DISABLED_EXTENSIONS
self._admin_only: List[str] = [x.strip(' ') for x in settings.LNBITS_ADMIN_EXTENSIONS]
self._extension_folders: List[str] = [ self._extension_folders: List[str] = [
x[1] for x in os.walk(os.path.join(settings.LNBITS_PATH, "extensions")) x[1] for x in os.walk(os.path.join(settings.LNBITS_PATH, "extensions"))
][0] ][0]
@ -47,6 +49,7 @@ class ExtensionManager:
) as json_file: ) as json_file:
config = json.load(json_file) config = json.load(json_file)
is_valid = True is_valid = True
is_admin_only = True if extension in self._admin_only else False
except Exception: except Exception:
config = {} config = {}
is_valid = False is_valid = False
@ -55,6 +58,7 @@ class ExtensionManager:
Extension( Extension(
extension, extension,
is_valid, is_valid,
is_admin_only,
config.get("name"), config.get("name"),
config.get("short_description"), config.get("short_description"),
config.get("icon"), config.get("icon"),

View File

@ -29,6 +29,7 @@ LNBITS_ALLOWED_USERS: List[str] = env.list(
"LNBITS_ALLOWED_USERS", default=[], subcast=str "LNBITS_ALLOWED_USERS", default=[], subcast=str
) )
LNBITS_ADMIN_USERS: List[str] = env.list("LNBITS_ADMIN_USERS", default=[], subcast=str) LNBITS_ADMIN_USERS: List[str] = env.list("LNBITS_ADMIN_USERS", default=[], subcast=str)
LNBITS_ADMIN_EXTENSIONS: List[str] = env.list("LNBITS_ADMIN_EXTENSIONS", default=[], subcast=str)
LNBITS_DISABLED_EXTENSIONS: List[str] = env.list( LNBITS_DISABLED_EXTENSIONS: List[str] = env.list(
"LNBITS_DISABLED_EXTENSIONS", default=[], subcast=str "LNBITS_DISABLED_EXTENSIONS", default=[], subcast=str
) )

View File

@ -111,7 +111,7 @@ window.LNbits = {
'/wallet?' + (userId ? 'usr=' + userId + '&' : '') + 'nme=' + walletName '/wallet?' + (userId ? 'usr=' + userId + '&' : '') + 'nme=' + walletName
}, },
updateWallet: function (walletName, userId, walletId) { updateWallet: function (walletName, userId, walletId) {
window.location.href = `/wallet?usr=${userId}&wal=${walletId}&nme=${walletName}` window.location.href = `/wallet?usr=${userId}&wal=${walletId}&nme=${walletName}`
}, },
deleteWallet: function (walletId, userId) { deleteWallet: function (walletId, userId) {
window.location.href = '/deletewallet?usr=' + userId + '&wal=' + walletId window.location.href = '/deletewallet?usr=' + userId + '&wal=' + walletId
@ -123,6 +123,7 @@ window.LNbits = {
[ [
'code', 'code',
'isValid', 'isValid',
'isAdminOnly',
'name', 'name',
'shortDescription', 'shortDescription',
'icon', 'icon',
@ -135,7 +136,12 @@ window.LNbits = {
return obj return obj
}, },
user: function (data) { user: function (data) {
var obj = {id: data.id, email: data.email, extensions: data.extensions, wallets: data.wallets} var obj = {
id: data.id,
email: data.email,
extensions: data.extensions,
wallets: data.wallets
}
var mapWallet = this.wallet var mapWallet = this.wallet
obj.wallets = obj.wallets obj.wallets = obj.wallets
.map(function (obj) { .map(function (obj) {
@ -153,16 +159,23 @@ window.LNbits = {
return obj return obj
}, },
wallet: function (data) { wallet: function (data) {
newWallet = {id: data.id, name: data.name, adminkey: data.adminkey, inkey: data.inkey} newWallet = {
id: data.id,
name: data.name,
adminkey: data.adminkey,
inkey: data.inkey
}
newWallet.msat = data.balance_msat newWallet.msat = data.balance_msat
newWallet.sat = Math.round(data.balance_msat / 1000) newWallet.sat = Math.round(data.balance_msat / 1000)
newWallet.fsat = new Intl.NumberFormat(window.LOCALE).format(newWallet.sat) newWallet.fsat = new Intl.NumberFormat(window.LOCALE).format(
newWallet.sat
)
newWallet.url = ['/wallet?usr=', data.user, '&wal=', data.id].join('') newWallet.url = ['/wallet?usr=', data.user, '&wal=', data.id].join('')
return newWallet return newWallet
}, },
payment: function (data) { payment: function (data) {
obj = { obj = {
checking_id:data.id, checking_id: data.id,
pending: data.pending, pending: data.pending,
amount: data.amount, amount: data.amount,
fee: data.fee, fee: data.fee,
@ -174,7 +187,7 @@ window.LNbits = {
extra: data.extra, extra: data.extra,
wallet_id: data.wallet_id, wallet_id: data.wallet_id,
webhook: data.webhook, webhook: data.webhook,
webhook_status: data.webhook_status, webhook_status: data.webhook_status
} }
obj.date = Quasar.utils.date.formatDate( obj.date = Quasar.utils.date.formatDate(
@ -225,7 +238,8 @@ window.LNbits = {
Quasar.plugins.Notify.create({ Quasar.plugins.Notify.create({
timeout: 5000, timeout: 5000,
type: types[error.response.status] || 'warning', type: types[error.response.status] || 'warning',
message: error.response.data.message || error.response.data.detail || null, message:
error.response.data.message || error.response.data.detail || null,
caption: caption:
[error.response.status, ' ', error.response.statusText] [error.response.status, ' ', error.response.statusText]
.join('') .join('')
@ -368,6 +382,10 @@ window.windowMixin = {
.filter(function (obj) { .filter(function (obj) {
return !obj.hidden return !obj.hidden
}) })
.filter(function (obj) {
if (window.user.admin) return obj
return !obj.isAdminOnly
})
.map(function (obj) { .map(function (obj) {
if (user) { if (user) {
obj.isEnabled = user.extensions.indexOf(obj.code) !== -1 obj.isEnabled = user.extensions.indexOf(obj.code) !== -1