forked from Dniel97/artemis
add ability to add users, cards, arcades and cabs on the webui
This commit is contained in:
parent
de2e2349e6
commit
87c7c91e3a
@ -94,7 +94,7 @@ class ArcadeData(BaseData):
|
|||||||
return None
|
return None
|
||||||
return result.fetchone()
|
return result.fetchone()
|
||||||
|
|
||||||
async def put_machine(
|
async def create_machine(
|
||||||
self,
|
self,
|
||||||
arcade_id: int,
|
arcade_id: int,
|
||||||
serial: str = "",
|
serial: str = "",
|
||||||
@ -102,12 +102,12 @@ class ArcadeData(BaseData):
|
|||||||
game: str = None,
|
game: str = None,
|
||||||
is_cab: bool = False,
|
is_cab: bool = False,
|
||||||
) -> Optional[int]:
|
) -> Optional[int]:
|
||||||
if arcade_id:
|
if not arcade_id:
|
||||||
self.logger.error(f"{__name__ }: Need arcade id!")
|
self.logger.error(f"{__name__ }: Need arcade id!")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
sql = machine.insert().values(
|
sql = machine.insert().values(
|
||||||
arcade=arcade_id, keychip=serial, board=board, game=game, is_cab=is_cab
|
arcade=arcade_id, serial=serial, board=board, game=game, is_cab=is_cab
|
||||||
)
|
)
|
||||||
|
|
||||||
result = await self.execute(sql)
|
result = await self.execute(sql)
|
||||||
@ -148,15 +148,15 @@ class ArcadeData(BaseData):
|
|||||||
return None
|
return None
|
||||||
return result.fetchall()
|
return result.fetchall()
|
||||||
|
|
||||||
async def put_arcade(
|
async def create_arcade(
|
||||||
self,
|
self,
|
||||||
name: str,
|
name: str = None,
|
||||||
nickname: str = None,
|
nickname: str = None,
|
||||||
country: str = "JPN",
|
country: str = "JPN",
|
||||||
country_id: int = 1,
|
country_id: int = 1,
|
||||||
state: str = "",
|
state: str = "",
|
||||||
city: str = "",
|
city: str = "",
|
||||||
regional_id: int = 1,
|
region_id: int = 1,
|
||||||
) -> Optional[int]:
|
) -> Optional[int]:
|
||||||
if nickname is None:
|
if nickname is None:
|
||||||
nickname = name
|
nickname = name
|
||||||
@ -168,7 +168,7 @@ class ArcadeData(BaseData):
|
|||||||
country_id=country_id,
|
country_id=country_id,
|
||||||
state=state,
|
state=state,
|
||||||
city=city,
|
city=city,
|
||||||
regional_id=regional_id,
|
region_id=region_id,
|
||||||
)
|
)
|
||||||
|
|
||||||
result = await self.execute(sql)
|
result = await self.execute(sql)
|
||||||
@ -206,8 +206,8 @@ class ArcadeData(BaseData):
|
|||||||
return None
|
return None
|
||||||
return result.lastrowid
|
return result.lastrowid
|
||||||
|
|
||||||
async def format_serial(
|
def format_serial( # TODO: Actual serial stuff
|
||||||
self, platform_code: str, platform_rev: int, serial_num: int, append: int = 4152
|
self, platform_code: str, platform_rev: int, serial_num: int, append: int = 8888
|
||||||
) -> str:
|
) -> str:
|
||||||
return f"{platform_code}{platform_rev:02d}A{serial_num:04d}{append:04d}" # 0x41 = A, 0x52 = R
|
return f"{platform_code}{platform_rev:02d}A{serial_num:04d}{append:04d}" # 0x41 = A, 0x52 = R
|
||||||
|
|
||||||
|
120
core/frontend.py
120
core/frontend.py
@ -10,6 +10,9 @@ import bcrypt
|
|||||||
import re
|
import re
|
||||||
import jwt
|
import jwt
|
||||||
import yaml
|
import yaml
|
||||||
|
import secrets
|
||||||
|
import string
|
||||||
|
import random
|
||||||
from base64 import b64decode
|
from base64 import b64decode
|
||||||
from enum import Enum
|
from enum import Enum
|
||||||
from datetime import datetime, timezone
|
from datetime import datetime, timezone
|
||||||
@ -131,6 +134,10 @@ class FrontendServlet():
|
|||||||
Route("/", self.system.render_GET, methods=['GET']),
|
Route("/", self.system.render_GET, methods=['GET']),
|
||||||
Route("/lookup.user", self.system.lookup_user, methods=['GET']),
|
Route("/lookup.user", self.system.lookup_user, methods=['GET']),
|
||||||
Route("/lookup.shop", self.system.lookup_shop, methods=['GET']),
|
Route("/lookup.shop", self.system.lookup_shop, methods=['GET']),
|
||||||
|
Route("/add.user", self.system.add_user, methods=['POST']),
|
||||||
|
Route("/add.card", self.system.add_card, methods=['POST']),
|
||||||
|
Route("/add.shop", self.system.add_shop, methods=['POST']),
|
||||||
|
Route("/add.cab", self.system.add_cab, methods=['POST']),
|
||||||
]),
|
]),
|
||||||
Mount("/shop", routes=[
|
Mount("/shop", routes=[
|
||||||
Route("/", self.arcade.render_GET, methods=['GET']),
|
Route("/", self.arcade.render_GET, methods=['GET']),
|
||||||
@ -551,10 +558,16 @@ class FE_System(FE_Base):
|
|||||||
if not usr_sesh or not self.test_perm_minimum(usr_sesh.permissions, PermissionOffset.USERMOD):
|
if not usr_sesh or not self.test_perm_minimum(usr_sesh.permissions, PermissionOffset.USERMOD):
|
||||||
return RedirectResponse("/gate/", 303)
|
return RedirectResponse("/gate/", 303)
|
||||||
|
|
||||||
|
if request.query_params.get("e", None):
|
||||||
|
err = int(request.query_params.get("e"))
|
||||||
|
else:
|
||||||
|
err = 0
|
||||||
|
|
||||||
return Response(template.render(
|
return Response(template.render(
|
||||||
title=f"{self.core_config.server.name} | System",
|
title=f"{self.core_config.server.name} | System",
|
||||||
sesh=vars(usr_sesh),
|
sesh=vars(usr_sesh),
|
||||||
usrlist=[],
|
usrlist=[],
|
||||||
|
error = err
|
||||||
), media_type="text/html; charset=utf-8")
|
), media_type="text/html; charset=utf-8")
|
||||||
|
|
||||||
async def lookup_user(self, request: Request):
|
async def lookup_user(self, request: Request):
|
||||||
@ -661,6 +674,113 @@ class FE_System(FE_Base):
|
|||||||
shoplist=shoplist,
|
shoplist=shoplist,
|
||||||
), media_type="text/html; charset=utf-8")
|
), media_type="text/html; charset=utf-8")
|
||||||
|
|
||||||
|
async def add_user(self, request: Request):
|
||||||
|
template = self.environment.get_template("core/templates/sys/index.jinja")
|
||||||
|
|
||||||
|
usr_sesh = self.validate_session(request)
|
||||||
|
if not usr_sesh or not self.test_perm(usr_sesh.permissions, PermissionOffset.ACMOD):
|
||||||
|
return RedirectResponse("/gate/", 303)
|
||||||
|
|
||||||
|
frm = await request.form()
|
||||||
|
username = frm.get("userName", None)
|
||||||
|
email = frm.get("userEmail", None)
|
||||||
|
perm = frm.get("usrPerm", "1")
|
||||||
|
passwd = "".join(
|
||||||
|
secrets.choice(string.ascii_letters + string.digits) for i in range(20)
|
||||||
|
)
|
||||||
|
hash = bcrypt.hashpw(passwd.encode(), bcrypt.gensalt())
|
||||||
|
|
||||||
|
if not email:
|
||||||
|
return RedirectResponse("/sys/?e=4", 303)
|
||||||
|
|
||||||
|
uid = await self.data.user.create_user(username=username if username else None, email=email, password=hash.decode(), permission=int(perm))
|
||||||
|
return Response(template.render(
|
||||||
|
title=f"{self.core_config.server.name} | System",
|
||||||
|
sesh=vars(usr_sesh),
|
||||||
|
usradd={"id": uid, "username": username, "password": passwd},
|
||||||
|
), media_type="text/html; charset=utf-8")
|
||||||
|
|
||||||
|
async def add_card(self, request: Request):
|
||||||
|
template = self.environment.get_template("core/templates/sys/index.jinja")
|
||||||
|
|
||||||
|
usr_sesh = self.validate_session(request)
|
||||||
|
if not usr_sesh or not self.test_perm(usr_sesh.permissions, PermissionOffset.ACMOD):
|
||||||
|
return RedirectResponse("/gate/", 303)
|
||||||
|
|
||||||
|
frm = await request.form()
|
||||||
|
userid = frm.get("cardUsr", None)
|
||||||
|
access_code = frm.get("cardAc", None)
|
||||||
|
idm = frm.get("cardIdm", None)
|
||||||
|
|
||||||
|
if userid is None or access_code is None or not userid.isdigit() or not len(access_code) == 20 or not access_code.isdigit:
|
||||||
|
return RedirectResponse("/sys/?e=4", 303)
|
||||||
|
|
||||||
|
cardid = await self.data.card.create_card(int(userid), access_code)
|
||||||
|
if not cardid:
|
||||||
|
return RedirectResponse("/sys/?e=99", 303)
|
||||||
|
|
||||||
|
if idm is not None:
|
||||||
|
# TODO: save IDM
|
||||||
|
pass
|
||||||
|
|
||||||
|
return Response(template.render(
|
||||||
|
title=f"{self.core_config.server.name} | System",
|
||||||
|
sesh=vars(usr_sesh),
|
||||||
|
cardadd={"id": cardid, "user": userid, "access_code": access_code},
|
||||||
|
), media_type="text/html; charset=utf-8")
|
||||||
|
|
||||||
|
async def add_shop(self, request: Request):
|
||||||
|
template = self.environment.get_template("core/templates/sys/index.jinja")
|
||||||
|
|
||||||
|
usr_sesh = self.validate_session(request)
|
||||||
|
if not usr_sesh or not self.test_perm(usr_sesh.permissions, PermissionOffset.ACMOD):
|
||||||
|
return RedirectResponse("/gate/", 303)
|
||||||
|
|
||||||
|
frm = await request.form()
|
||||||
|
name = frm.get("shopName", None)
|
||||||
|
country = frm.get("shopCountry", "JPN")
|
||||||
|
ip = frm.get("shopIp", None)
|
||||||
|
|
||||||
|
acid = await self.data.arcade.create_arcade(name if name else None, name if name else None, country)
|
||||||
|
if not acid:
|
||||||
|
return RedirectResponse("/sys/?e=99", 303)
|
||||||
|
|
||||||
|
if ip:
|
||||||
|
# TODO: set IP
|
||||||
|
pass
|
||||||
|
|
||||||
|
return Response(template.render(
|
||||||
|
title=f"{self.core_config.server.name} | System",
|
||||||
|
sesh=vars(usr_sesh),
|
||||||
|
shopadd={"id": acid},
|
||||||
|
), media_type="text/html; charset=utf-8")
|
||||||
|
|
||||||
|
async def add_cab(self, request: Request):
|
||||||
|
template = self.environment.get_template("core/templates/sys/index.jinja")
|
||||||
|
|
||||||
|
usr_sesh = self.validate_session(request)
|
||||||
|
if not usr_sesh or not self.test_perm(usr_sesh.permissions, PermissionOffset.ACMOD):
|
||||||
|
return RedirectResponse("/gate/", 303)
|
||||||
|
|
||||||
|
frm = await request.form()
|
||||||
|
shopid = frm.get("cabShop", None)
|
||||||
|
serial = frm.get("cabSerial", None)
|
||||||
|
game_code = frm.get("cabGame", None)
|
||||||
|
|
||||||
|
if not shopid or not shopid.isdigit():
|
||||||
|
return RedirectResponse("/sys/?e=4", 303)
|
||||||
|
|
||||||
|
if not serial:
|
||||||
|
serial = self.data.arcade.format_serial("A69E", 1, random.randint(1, 9999))
|
||||||
|
|
||||||
|
cab_id = await self.data.arcade.create_machine(int(shopid), serial, None, game_code if game_code else None)
|
||||||
|
|
||||||
|
return Response(template.render(
|
||||||
|
title=f"{self.core_config.server.name} | System",
|
||||||
|
sesh=vars(usr_sesh),
|
||||||
|
cabadd={"id": cab_id, "serial": serial},
|
||||||
|
), media_type="text/html; charset=utf-8")
|
||||||
|
|
||||||
class FE_Arcade(FE_Base):
|
class FE_Arcade(FE_Base):
|
||||||
async def render_GET(self, request: Request):
|
async def render_GET(self, request: Request):
|
||||||
template = self.environment.get_template("core/templates/arcade/index.jinja")
|
template = self.environment.get_template("core/templates/arcade/index.jinja")
|
||||||
|
@ -10,7 +10,7 @@ Cab added successfully
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
<ul style="font-size: 20px;">
|
<ul style="font-size: 20px;">
|
||||||
{% for c in arcade.cabs %}
|
{% for c in arcade.cabs %}
|
||||||
<li><a href="/cab/{{ c.id }}">{{ c.serial }} ({{ c.game }})</a> <button class="btn btn-secondary" onclick="prep_edit_form()">Edit</button> <button class="btn-danger btn">Delete</button></li>
|
<li><a href="/cab/{{ c.id }}">{{ c.serial }}</a> ({{ c.game if c.game else "Any" }}) <button class="btn btn-secondary" onclick="prep_edit_form()">Edit</button> <button class="btn-danger btn">Delete</button></li>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</ul>
|
</ul>
|
||||||
{% else %}
|
{% else %}
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
{% if error is defined %}
|
{% if error is defined %}
|
||||||
{% include "core/templates/widgets/err_banner.jinja" %}
|
{% include "core/templates/widgets/err_banner.jinja" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
<h2>Search</h2>
|
||||||
<div class="row" id="rowForm">
|
<div class="row" id="rowForm">
|
||||||
{% if "{:08b}".format(sesh.permissions)[6] == "1" %}
|
{% if "{:08b}".format(sesh.permissions)[6] == "1" %}
|
||||||
<div class="col-sm-6" style="max-width: 25%;">
|
<div class="col-sm-6" style="max-width: 25%;">
|
||||||
@ -21,7 +22,12 @@
|
|||||||
OR
|
OR
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="usrEmail">Email address</label>
|
<label for="usrEmail">Email address</label>
|
||||||
<input type="email" class="form-control" id="usrEmail" name="usrEmail" aria-describedby="emailHelp">
|
<input type="email" class="form-control" id="usrEmail" name="usrEmail">
|
||||||
|
</div>
|
||||||
|
OR
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="usrAc">Access Code</label>
|
||||||
|
<input type="text" class="form-control" id="usrAc" name="usrAc" maxlength="20" placeholder="00000000000000000000">
|
||||||
</div>
|
</div>
|
||||||
<br />
|
<br />
|
||||||
<button type="submit" class="btn btn-primary">Search</button>
|
<button type="submit" class="btn btn-primary">Search</button>
|
||||||
@ -63,7 +69,121 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
<h2>Add</h2>
|
||||||
<div class="row" id="rowAdd">
|
<div class="row" id="rowAdd">
|
||||||
|
{% if "{:08b}".format(sesh.permissions)[6] == "1" %}
|
||||||
|
<div class="col-sm-6" style="max-width: 25%;">
|
||||||
|
<form id="usrAdd" name="usrAdd" action="/sys/add.user" class="form-inline" method="POST">
|
||||||
|
<h3>Add User</h3>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="usrName">Username</label>
|
||||||
|
<input type="text" class="form-control" id="usrName" name="usrName">
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="usrEmail">Email address</label>
|
||||||
|
<input type="email" class="form-control" id="usrEmail" name="usrEmail" required>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="usrPerm">Permission Level</label>
|
||||||
|
<input type="number" class="form-control" id="usrPerm" name="usrPerm" value="1">
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<button type="submit" class="btn btn-primary">Add</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6" style="max-width: 25%;">
|
||||||
|
<form id="cardAdd" name="cardAdd" action="/sys/add.card" class="form-inline" method="POST">
|
||||||
|
<h3>Add Card</h3>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="cardUsr">User ID</label>
|
||||||
|
<input type="number" class="form-control" id="cardUsr" name="cardUsr" required>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="cardAc">Access Code</label>
|
||||||
|
<input type="text" class="form-control" id="cardAc" name="cardAc" maxlength="20" placeholder="00000000000000000000" required>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="cardIdm">IDm/Chip ID</label>
|
||||||
|
<input type="text" class="form-control" id="cardIdm" name="cardIdm" disabled>
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<button type="submit" class="btn btn-primary">Add</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% if "{:08b}".format(sesh.permissions)[5] == "1" %}
|
||||||
|
<div class="col-sm-6" style="max-width: 25%;">
|
||||||
|
<form id="shopAdd" name="shopAdd" action="/sys/add.shop" class="form-inline" method="POST">
|
||||||
|
<h3>Add Shop</h3>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="shopName">Name</label>
|
||||||
|
<input type="text" class="form-control" id="shopName" name="shopName">
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="shopCountry">Country Code</label>
|
||||||
|
<input type="text" class="form-control" id="shopCountry" name="shopCountry" maxlength="3" placeholder="JPN">
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="shopIp">VPN IP</label>
|
||||||
|
<input type="text" class="form-control" id="shopIp" name="shopIp">
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<button type="submit" class="btn btn-primary">Add</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6" style="max-width: 25%;">
|
||||||
|
<form id="cabAdd" name="cabAdd" action="/sys/add.cab" class="form-inline" method="POST">
|
||||||
|
<h3>Add Machine</h3>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="cabShop">Shop ID</label>
|
||||||
|
<input type="number" class="form-control" id="cabShop" name="cabShop" required>
|
||||||
|
</div>
|
||||||
|
<br>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="cabSerial">Serial</label>
|
||||||
|
<input type="text" class="form-control" id="cabSerial" name="cabSerial">
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="cabGame">Game Code</label>
|
||||||
|
<input type="text" class="form-control" id="cabGame" name="cabGame" maxlength="4" placeholder="SXXX">
|
||||||
|
</div>
|
||||||
|
<br />
|
||||||
|
<button type="submit" class="btn btn-primary">Add</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div class="row" id="rowAddResult" style="margin: 10px;">
|
||||||
|
{% if "{:08b}".format(sesh.permissions)[6] == "1" %}
|
||||||
|
<div id="userAddResult" class="col-sm-6" style="max-width: 25%;">
|
||||||
|
{% if usradd is defined %}
|
||||||
|
<pre>Added user {{ usradd.username if usradd.username is not none else "with no name"}} with id {{usradd.id}} and password {{ usradd.password }}</pre>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div id="cardAddResult" class="col-sm-6" style="max-width: 25%;">
|
||||||
|
{% if cardadd is defined %}
|
||||||
|
<pre>Added {{ cardadd.access_code }} with id {{cardadd.id}} to user {{ cardadd.user }}</pre>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
{% if "{:08b}".format(sesh.permissions)[5] == "1" %}
|
||||||
|
<div id="shopAddResult" class="col-sm-6" style="max-width: 25%;">
|
||||||
|
{% if shopadd is defined %}
|
||||||
|
<pre>Added Shop {{ shopadd.id }}</pre></a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
<div id="cabAddResult" class="col-sm-6" style="max-width: 25%;">
|
||||||
|
{% if cabadd is defined %}
|
||||||
|
<pre>Added Machine {{ cabadd.id }} with serial {{ cabadd.serial }}</pre></a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
Loading…
Reference in New Issue
Block a user