3
2
forked from Dniel97/artemis

add ability to add users, cards, arcades and cabs on the webui

This commit is contained in:
Hay1tsme 2024-03-23 20:01:32 -04:00
parent de2e2349e6
commit 87c7c91e3a
4 changed files with 252 additions and 12 deletions

View File

@ -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

View File

@ -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")

View File

@ -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>&nbsp;<button class="btn btn-secondary" onclick="prep_edit_form()">Edit</button>&nbsp;<button class="btn-danger btn">Delete</button></li> <li><a href="/cab/{{ c.id }}">{{ c.serial }}</a> ({{ c.game if c.game else "Any" }})&nbsp;<button class="btn btn-secondary" onclick="prep_edit_form()">Edit</button>&nbsp;<button class="btn-danger btn">Delete</button></li>
{% endfor %} {% endfor %}
</ul> </ul>
{% else %} {% else %}

View File

@ -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 %}