forked from Dniel97/artemis
Compare commits
1 Commits
idac
...
frontend_u
Author | SHA1 | Date | |
---|---|---|---|
c51103aaf5 |
155
core/frontend.py
155
core/frontend.py
@ -18,22 +18,26 @@ from core.data import Data
|
|||||||
|
|
||||||
|
|
||||||
class IUserSession(Interface):
|
class IUserSession(Interface):
|
||||||
userId = Attribute("User's ID")
|
user_id = Attribute("User's ID")
|
||||||
|
username = Attribute("User's username")
|
||||||
current_ip = Attribute("User's current ip address")
|
current_ip = Attribute("User's current ip address")
|
||||||
permissions = Attribute("User's permission level")
|
permissions = Attribute("User's permission level")
|
||||||
|
|
||||||
|
|
||||||
class PermissionOffset(Enum):
|
class PermissionOffset(Enum):
|
||||||
USER = 0 # Regular user
|
USER = 0 # Regular user
|
||||||
USERMOD = 1 # Can moderate other users
|
USERMOD = 1 # Can moderate other users
|
||||||
ACMOD = 2 # Can add arcades and cabs
|
ACMOD = 2 # Can add arcades and cabs
|
||||||
SYSADMIN = 3 # Can change settings
|
SYSADMIN = 3 # Can change settings
|
||||||
# 4 - 6 reserved for future use
|
# 4 - 6 reserved for future use
|
||||||
OWNER = 7 # Can do anything
|
OWNER = 7 # Can do anything
|
||||||
|
|
||||||
|
|
||||||
@implementer(IUserSession)
|
@implementer(IUserSession)
|
||||||
class UserSession(object):
|
class UserSession(object):
|
||||||
def __init__(self, session):
|
def __init__(self, session):
|
||||||
self.userId = 0
|
self.user_id = 0
|
||||||
|
self.username = None
|
||||||
self.current_ip = "0.0.0.0"
|
self.current_ip = "0.0.0.0"
|
||||||
self.permissions = 0
|
self.permissions = 0
|
||||||
|
|
||||||
@ -106,6 +110,7 @@ class FrontendServlet(resource.Resource):
|
|||||||
server_name=self.config.server.name,
|
server_name=self.config.server.name,
|
||||||
title=self.config.server.name,
|
title=self.config.server.name,
|
||||||
game_list=self.game_list,
|
game_list=self.game_list,
|
||||||
|
active_page="/",
|
||||||
sesh=vars(IUserSession(request.getSession())),
|
sesh=vars(IUserSession(request.getSession())),
|
||||||
).encode("utf-16")
|
).encode("utf-16")
|
||||||
|
|
||||||
@ -134,7 +139,7 @@ class FE_Gate(FE_Base):
|
|||||||
|
|
||||||
sesh = request.getSession()
|
sesh = request.getSession()
|
||||||
usr_sesh = IUserSession(sesh)
|
usr_sesh = IUserSession(sesh)
|
||||||
if usr_sesh.userId > 0:
|
if usr_sesh.user_id > 0:
|
||||||
return redirectTo(b"/user", request)
|
return redirectTo(b"/user", request)
|
||||||
|
|
||||||
if uri.startswith("/gate/create"):
|
if uri.startswith("/gate/create"):
|
||||||
@ -153,6 +158,7 @@ class FE_Gate(FE_Base):
|
|||||||
return template.render(
|
return template.render(
|
||||||
title=f"{self.core_config.server.name} | Login Gate",
|
title=f"{self.core_config.server.name} | Login Gate",
|
||||||
error=err,
|
error=err,
|
||||||
|
active_page="gate",
|
||||||
sesh=vars(usr_sesh),
|
sesh=vars(usr_sesh),
|
||||||
).encode("utf-16")
|
).encode("utf-16")
|
||||||
|
|
||||||
@ -161,7 +167,7 @@ class FE_Gate(FE_Base):
|
|||||||
ip = Utils.get_ip_addr(request)
|
ip = Utils.get_ip_addr(request)
|
||||||
|
|
||||||
if uri == "/gate/gate.login":
|
if uri == "/gate/gate.login":
|
||||||
access_code: str = request.args[b"access_code"][0].decode()
|
access_code: str = request.args[b"access-code"][0].decode()
|
||||||
passwd: bytes = request.args[b"passwd"][0]
|
passwd: bytes = request.args[b"passwd"][0]
|
||||||
if passwd == b"":
|
if passwd == b"":
|
||||||
passwd = None
|
passwd = None
|
||||||
@ -187,9 +193,10 @@ class FE_Gate(FE_Base):
|
|||||||
|
|
||||||
sesh = request.getSession()
|
sesh = request.getSession()
|
||||||
usr_sesh = IUserSession(sesh)
|
usr_sesh = IUserSession(sesh)
|
||||||
usr_sesh.userId = uid
|
usr_sesh.user_id = uid
|
||||||
|
usr_sesh.username = user["username"]
|
||||||
usr_sesh.current_ip = ip
|
usr_sesh.current_ip = ip
|
||||||
usr_sesh.permissions = user['permissions']
|
usr_sesh.permissions = user["permissions"]
|
||||||
|
|
||||||
return redirectTo(b"/user", request)
|
return redirectTo(b"/user", request)
|
||||||
|
|
||||||
@ -228,20 +235,23 @@ class FE_Gate(FE_Base):
|
|||||||
card = self.data.card.get_card_by_access_code(ac)
|
card = self.data.card.get_card_by_access_code(ac)
|
||||||
if card is None:
|
if card is None:
|
||||||
return redirectTo(b"/gate?e=1", request)
|
return redirectTo(b"/gate?e=1", request)
|
||||||
|
|
||||||
user = self.data.user.get_user(card['user'])
|
user = self.data.user.get_user(card["user"])
|
||||||
if user is None:
|
if user is None:
|
||||||
self.logger.warning(f"Card {ac} exists with no/invalid associated user ID {card['user']}")
|
self.logger.warning(
|
||||||
|
f"Card {ac} exists with no/invalid associated user ID {card['user']}"
|
||||||
|
)
|
||||||
return redirectTo(b"/gate?e=0", request)
|
return redirectTo(b"/gate?e=0", request)
|
||||||
|
|
||||||
if user['password'] is not None:
|
if user["password"] is not None:
|
||||||
return redirectTo(b"/gate?e=1", request)
|
return redirectTo(b"/gate?e=1", request)
|
||||||
|
|
||||||
template = self.environment.get_template("core/frontend/gate/create.jinja")
|
template = self.environment.get_template("core/frontend/gate/create.jinja")
|
||||||
return template.render(
|
return template.render(
|
||||||
title=f"{self.core_config.server.name} | Create User",
|
title=f"{self.core_config.server.name} | Create User",
|
||||||
code=ac,
|
code=ac,
|
||||||
sesh={"userId": 0, "permissions": 0},
|
active_page="gate",
|
||||||
|
sesh={"user_id": 0, "permissions": 0},
|
||||||
).encode("utf-16")
|
).encode("utf-16")
|
||||||
|
|
||||||
|
|
||||||
@ -252,48 +262,51 @@ class FE_User(FE_Base):
|
|||||||
|
|
||||||
sesh: Session = request.getSession()
|
sesh: Session = request.getSession()
|
||||||
usr_sesh = IUserSession(sesh)
|
usr_sesh = IUserSession(sesh)
|
||||||
if usr_sesh.userId == 0:
|
if usr_sesh.user_id == 0:
|
||||||
return redirectTo(b"/gate", request)
|
return redirectTo(b"/gate", request)
|
||||||
|
|
||||||
m = re.match("\/user\/(\d*)", uri)
|
m = re.match("\/user\/(\d*)", uri)
|
||||||
|
|
||||||
if m is not None:
|
if m is not None:
|
||||||
usrid = m.group(1)
|
usrid = m.group(1)
|
||||||
if usr_sesh.permissions < 1 << PermissionOffset.USERMOD.value or not usrid == usr_sesh.userId:
|
if (
|
||||||
|
usr_sesh.permissions < 1 << PermissionOffset.USERMOD.value
|
||||||
|
or not usrid == usr_sesh.user_id
|
||||||
|
):
|
||||||
return redirectTo(b"/user", request)
|
return redirectTo(b"/user", request)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
usrid = usr_sesh.userId
|
usrid = usr_sesh.user_id
|
||||||
|
|
||||||
user = self.data.user.get_user(usrid)
|
user = self.data.user.get_user(usrid)
|
||||||
if user is None:
|
if user is None:
|
||||||
return redirectTo(b"/user", request)
|
return redirectTo(b"/user", request)
|
||||||
|
|
||||||
cards = self.data.card.get_user_cards(usrid)
|
cards = self.data.card.get_user_cards(usrid)
|
||||||
arcades = self.data.arcade.get_arcades_managed_by_user(usrid)
|
arcades = self.data.arcade.get_arcades_managed_by_user(usrid)
|
||||||
|
|
||||||
card_data = []
|
card_data = []
|
||||||
arcade_data = []
|
arcade_data = []
|
||||||
|
|
||||||
for c in cards:
|
for i, c in enumerate(cards):
|
||||||
if c['is_locked']:
|
if c["is_locked"]:
|
||||||
status = 'Locked'
|
status = "Locked"
|
||||||
elif c['is_banned']:
|
elif c["is_banned"]:
|
||||||
status = 'Banned'
|
status = "Banned"
|
||||||
else:
|
else:
|
||||||
status = 'Active'
|
status = "Active"
|
||||||
|
|
||||||
card_data.append({'access_code': c['access_code'], 'status': status})
|
card_data.append({"index": i+1, "access_code": c["access_code"], "status": status})
|
||||||
|
|
||||||
for a in arcades:
|
for i, a in enumerate(arcades):
|
||||||
arcade_data.append({'id': a['id'], 'name': a['name']})
|
arcade_data.append({"index": i+1, "id": a["id"], "name": a["name"]})
|
||||||
|
|
||||||
return template.render(
|
return template.render(
|
||||||
title=f"{self.core_config.server.name} | Account",
|
title=f"{self.core_config.server.name} | Account",
|
||||||
sesh=vars(usr_sesh),
|
sesh=vars(usr_sesh),
|
||||||
cards=card_data,
|
cards=card_data,
|
||||||
username=user['username'],
|
arcades=arcade_data,
|
||||||
arcades=arcade_data
|
active_page="user",
|
||||||
).encode("utf-16")
|
).encode("utf-16")
|
||||||
|
|
||||||
def render_POST(self, request: Request):
|
def render_POST(self, request: Request):
|
||||||
@ -310,11 +323,16 @@ class FE_System(FE_Base):
|
|||||||
|
|
||||||
sesh: Session = request.getSession()
|
sesh: Session = request.getSession()
|
||||||
usr_sesh = IUserSession(sesh)
|
usr_sesh = IUserSession(sesh)
|
||||||
if usr_sesh.userId == 0 or usr_sesh.permissions < 1 << PermissionOffset.USERMOD.value:
|
if (
|
||||||
|
usr_sesh.user_id == 0
|
||||||
|
or usr_sesh.permissions < 1 << PermissionOffset.USERMOD.value
|
||||||
|
):
|
||||||
return redirectTo(b"/gate", request)
|
return redirectTo(b"/gate", request)
|
||||||
|
|
||||||
if uri.startswith("/sys/lookup.user?"):
|
if uri.startswith("/sys/lookup.user?"):
|
||||||
uri_parse = parse.parse_qs(uri.replace("/sys/lookup.user?", "")) # lop off the first bit
|
uri_parse = parse.parse_qs(
|
||||||
|
uri.replace("/sys/lookup.user?", "")
|
||||||
|
) # lop off the first bit
|
||||||
uid_search = uri_parse.get("usrId")
|
uid_search = uri_parse.get("usrId")
|
||||||
email_search = uri_parse.get("usrEmail")
|
email_search = uri_parse.get("usrEmail")
|
||||||
uname_search = uri_parse.get("usrName")
|
uname_search = uri_parse.get("usrName")
|
||||||
@ -335,7 +353,9 @@ class FE_System(FE_Base):
|
|||||||
usrlist.append(u._asdict())
|
usrlist.append(u._asdict())
|
||||||
|
|
||||||
elif uri.startswith("/sys/lookup.arcade?"):
|
elif uri.startswith("/sys/lookup.arcade?"):
|
||||||
uri_parse = parse.parse_qs(uri.replace("/sys/lookup.arcade?", "")) # lop off the first bit
|
uri_parse = parse.parse_qs(
|
||||||
|
uri.replace("/sys/lookup.arcade?", "")
|
||||||
|
) # lop off the first bit
|
||||||
ac_id_search = uri_parse.get("arcadeId")
|
ac_id_search = uri_parse.get("arcadeId")
|
||||||
ac_name_search = uri_parse.get("arcadeName")
|
ac_name_search = uri_parse.get("arcadeName")
|
||||||
ac_user_search = uri_parse.get("arcadeUser")
|
ac_user_search = uri_parse.get("arcadeUser")
|
||||||
@ -354,9 +374,11 @@ class FE_System(FE_Base):
|
|||||||
ul = self.data.arcade.get_arcades_managed_by_user(ac_user_search[0])
|
ul = self.data.arcade.get_arcades_managed_by_user(ac_user_search[0])
|
||||||
for u in ul:
|
for u in ul:
|
||||||
aclist.append(u._asdict())
|
aclist.append(u._asdict())
|
||||||
|
|
||||||
elif uri.startswith("/sys/lookup.cab?"):
|
elif uri.startswith("/sys/lookup.cab?"):
|
||||||
uri_parse = parse.parse_qs(uri.replace("/sys/lookup.cab?", "")) # lop off the first bit
|
uri_parse = parse.parse_qs(
|
||||||
|
uri.replace("/sys/lookup.cab?", "")
|
||||||
|
) # lop off the first bit
|
||||||
cab_id_search = uri_parse.get("cabId")
|
cab_id_search = uri_parse.get("cabId")
|
||||||
cab_serial_search = uri_parse.get("cabSerial")
|
cab_serial_search = uri_parse.get("cabSerial")
|
||||||
cab_acid_search = uri_parse.get("cabAcId")
|
cab_acid_search = uri_parse.get("cabAcId")
|
||||||
@ -377,11 +399,12 @@ class FE_System(FE_Base):
|
|||||||
cablist.append(u._asdict())
|
cablist.append(u._asdict())
|
||||||
|
|
||||||
return template.render(
|
return 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,
|
usrlist=usrlist,
|
||||||
aclist=aclist,
|
aclist=aclist,
|
||||||
cablist=cablist,
|
cablist=cablist,
|
||||||
|
active_page="sys",
|
||||||
).encode("utf-16")
|
).encode("utf-16")
|
||||||
|
|
||||||
|
|
||||||
@ -403,31 +426,32 @@ class FE_Arcade(FE_Base):
|
|||||||
uri = request.uri.decode()
|
uri = request.uri.decode()
|
||||||
template = self.environment.get_template("core/frontend/arcade/index.jinja")
|
template = self.environment.get_template("core/frontend/arcade/index.jinja")
|
||||||
managed = []
|
managed = []
|
||||||
|
|
||||||
sesh: Session = request.getSession()
|
sesh: Session = request.getSession()
|
||||||
usr_sesh = IUserSession(sesh)
|
usr_sesh = IUserSession(sesh)
|
||||||
if usr_sesh.userId == 0:
|
if usr_sesh.user_id == 0:
|
||||||
return redirectTo(b"/gate", request)
|
return redirectTo(b"/gate", request)
|
||||||
|
|
||||||
m = re.match("\/arcade\/(\d*)", uri)
|
m = re.match("\/arcade\/(\d*)", uri)
|
||||||
|
|
||||||
if m is not None:
|
if m is not None:
|
||||||
arcadeid = m.group(1)
|
arcadeid = m.group(1)
|
||||||
perms = self.data.arcade.get_manager_permissions(usr_sesh.userId, arcadeid)
|
perms = self.data.arcade.get_manager_permissions(usr_sesh.user_id, arcadeid)
|
||||||
arcade = self.data.arcade.get_arcade(arcadeid)
|
arcade = self.data.arcade.get_arcade(arcadeid)
|
||||||
|
|
||||||
if perms is None:
|
if perms is None:
|
||||||
perms = 0
|
perms = 0
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return redirectTo(b"/user", request)
|
return redirectTo(b"/user", request)
|
||||||
|
|
||||||
return template.render(
|
return template.render(
|
||||||
title=f"{self.core_config.server.name} | Arcade",
|
title=f"{self.core_config.server.name} | Arcade",
|
||||||
sesh=vars(usr_sesh),
|
sesh=vars(usr_sesh),
|
||||||
error=0,
|
error=0,
|
||||||
perms=perms,
|
perms=perms,
|
||||||
arcade=arcade._asdict()
|
arcade=arcade._asdict(),
|
||||||
|
active_page="arcade",
|
||||||
).encode("utf-16")
|
).encode("utf-16")
|
||||||
|
|
||||||
|
|
||||||
@ -435,15 +459,16 @@ class FE_Machine(FE_Base):
|
|||||||
def render_GET(self, request: Request):
|
def render_GET(self, request: Request):
|
||||||
uri = request.uri.decode()
|
uri = request.uri.decode()
|
||||||
template = self.environment.get_template("core/frontend/machine/index.jinja")
|
template = self.environment.get_template("core/frontend/machine/index.jinja")
|
||||||
|
|
||||||
sesh: Session = request.getSession()
|
sesh: Session = request.getSession()
|
||||||
usr_sesh = IUserSession(sesh)
|
usr_sesh = IUserSession(sesh)
|
||||||
if usr_sesh.userId == 0:
|
if usr_sesh.user_id == 0:
|
||||||
return redirectTo(b"/gate", request)
|
return redirectTo(b"/gate", request)
|
||||||
|
|
||||||
return template.render(
|
return template.render(
|
||||||
title=f"{self.core_config.server.name} | Machine",
|
title=f"{self.core_config.server.name} | Machine",
|
||||||
sesh=vars(usr_sesh),
|
sesh=vars(usr_sesh),
|
||||||
arcade={},
|
arcade={},
|
||||||
error=0,
|
error=0,
|
||||||
).encode("utf-16")
|
active_page="machine",
|
||||||
|
).encode("utf-16")
|
||||||
|
@ -1,24 +1,44 @@
|
|||||||
{% extends "core/frontend/index.jinja" %}
|
{% extends "core/frontend/index.jinja" %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Create User</h1>
|
<div class="row justify-content-md-center form-signin">
|
||||||
<form id="create" style="max-width: 240px; min-width: 10%;" action="/gate/gate.create" method="post">
|
<div class="col col-lg-4">
|
||||||
<div class="form-group row">
|
<form id="create" action="/gate/gate.create" method="post">
|
||||||
<label for="access_code">Card Access Code</label><br>
|
<h1 class="h3 mb-3 fw-normal">Sign-up</h1>
|
||||||
<input class="form-control" name="access_code" id="access_code" type="text" placeholder="00000000000000000000" value={{ code }} maxlength="20" readonly>
|
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input class="form-control" name="access-code" id="access-code" type="text"
|
||||||
|
placeholder="00000000000000000000" value={{ code }} maxlength="20" required>
|
||||||
|
<label for="access-code">Access Code*</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input type="text" class="form-control" name="username" id="username" placeholder="username">
|
||||||
|
<label for="username">Username*</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input type="email" class="form-control" name="email" id="email" placeholder="example@example.com">
|
||||||
|
<label for="email">E-Mail*</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-floating mb-3">
|
||||||
|
<input type="password" class="form-control" name="passwd" id="passwd" placeholder="Password">
|
||||||
|
<label for="passwd">Password*</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<div class="form-check text-start my-3">
|
||||||
|
<input class="form-check-input" type="checkbox" value="remember-me" id="remember-me">
|
||||||
|
<label class="form-check-label" for="remember-me">
|
||||||
|
Remember me
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<div class="alert alert-warning" role="alert">
|
||||||
|
If you have not registered a card with this server, you cannot create a WebUI account!
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="btn btn-primary w-100 py-2" type="submit">Sign-up</button>
|
||||||
|
<!-- <p class="mt-5 mb-3 text-body-secondary">© 2023 ARTEMiS</p>-->
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row">
|
</div>
|
||||||
<label for="username">Username</label><br>
|
|
||||||
<input id="username" class="form-control" name="username" type="text" placeholder="username">
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<label for="email">Email</label><br>
|
|
||||||
<input id="email" class="form-control" name="email" type="email" placeholder="example@example.com">
|
|
||||||
</div>
|
|
||||||
<div class="form-group row">
|
|
||||||
<label for="passwd">Password</label><br>
|
|
||||||
<input id="passwd" class="form-control" name="passwd" type="password" placeholder="password">
|
|
||||||
</div>
|
|
||||||
<p></p>
|
|
||||||
<input id="submit" class="btn btn-primary" style="display: block; margin: 0 auto;" type="submit" value="Create">
|
|
||||||
</form>
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
@ -1,32 +1,52 @@
|
|||||||
{% extends "core/frontend/index.jinja" %}
|
{% extends "core/frontend/index.jinja" %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Gate</h1>
|
|
||||||
{% include "core/frontend/widgets/err_banner.jinja" %}
|
|
||||||
<style>
|
<style>
|
||||||
/* Chrome, Safari, Edge, Opera */
|
.form-signin input[type="text"] {
|
||||||
input::-webkit-outer-spin-button,
|
margin-bottom: -1px;
|
||||||
input::-webkit-inner-spin-button {
|
border-bottom-right-radius: 0;
|
||||||
-webkit-appearance: none;
|
border-bottom-left-radius: 0;
|
||||||
margin: 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Firefox */
|
.form-signin input[type="password"] {
|
||||||
input[type=number] {
|
margin-bottom: 10px;
|
||||||
-moz-appearance: textfield;
|
border-top-left-radius: 0;
|
||||||
|
border-top-right-radius: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<form id="login" style="max-width: 240px; min-width: 10%;" action="/gate/gate.login" method="post">
|
<div class="row justify-content-md-center form-signin">
|
||||||
<div class="form-group row">
|
<div class="col col-lg-4">
|
||||||
<label for="access_code">Card Access Code</label><br>
|
<form id="login" action="/gate/gate.login" method="post">
|
||||||
<input form="login" class="form-control" name="access_code" id="access_code" type="number" placeholder="00000000000000000000" maxlength="20" required>
|
<h1 class="h3 mb-3 fw-normal">Login</h1>
|
||||||
|
|
||||||
|
{% include "core/frontend/widgets/err_banner.jinja" %}
|
||||||
|
|
||||||
|
<div class="form-floating">
|
||||||
|
<input form="login" class="form-control" name="access-code" id="access-code" type="text"
|
||||||
|
placeholder="00000000000000000000" maxlength="20" required>
|
||||||
|
<label for="access-code">Access Code</label>
|
||||||
|
</div>
|
||||||
|
<div class="form-floating">
|
||||||
|
<input form="login" type="password" class="form-control" name="passwd" id="passwd" placeholder="Password">
|
||||||
|
<label for="passwd">Password</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<div class="form-check text-start my-3">
|
||||||
|
<input class="form-check-input" type="checkbox" value="remember-me" id="remember-me">
|
||||||
|
<label class="form-check-label" for="remember-me">
|
||||||
|
Remember me
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<div class="alert alert-info" role="alert">
|
||||||
|
To register for the WebUI, type in the <strong>access code</strong> of your card, as shown in a game, and leave the
|
||||||
|
password field blank.
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button class="btn btn-primary w-100 py-2" type="submit">Sign in</button>
|
||||||
|
<!-- <p class="mt-5 mb-3 text-body-secondary">© 2023 ARTEMiS</p>-->
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group row">
|
</div>
|
||||||
<label for="passwd">Password</label><br>
|
|
||||||
<input id="passwd" class="form-control" name="passwd" type="password" placeholder="password">
|
|
||||||
</div>
|
|
||||||
<p></p>
|
|
||||||
<input id="submit" class="btn btn-primary" style="display: block; margin: 0 auto;" form="login" type="submit" value="Login">
|
|
||||||
</form>
|
|
||||||
<h6>*To register for the webui, type in the access code of your card, as shown in a game, and leave the password field blank.</h6>
|
|
||||||
<h6>*If you have not registered a card with this server, you cannot create a webui account.</h6>
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
@ -1,88 +1,25 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html lang="en" data-bs-theme="dark">
|
||||||
<head>
|
|
||||||
<title>{{ title }}</title>
|
<head>
|
||||||
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
|
<meta charset="utf-8">
|
||||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
<style>
|
<title>{{ title }}</title>
|
||||||
html {
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/css/bootstrap.min.css" rel="stylesheet"
|
||||||
background-color: #181a1b !important;
|
integrity="sha384-4bw+/aepP/YC94hEpVNVgiZdgIC5+VKNBQNGCHeKRQN+PtmoHDEXuppvnDJzQIu9" crossorigin="anonymous">
|
||||||
margin: 10px;
|
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.10.5/font/bootstrap-icons.css">
|
||||||
}
|
</head>
|
||||||
html {
|
|
||||||
color-scheme: dark !important;
|
<body>
|
||||||
}
|
|
||||||
html, body, input, textarea, select, button, dialog {
|
|
||||||
background-color: #181a1b;
|
|
||||||
}
|
|
||||||
html, body, input, textarea, select, button {
|
|
||||||
border-color: #736b5e;
|
|
||||||
color: #e8e6e3;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: #3391ff;
|
|
||||||
}
|
|
||||||
table {
|
|
||||||
border-color: #545b5e;
|
|
||||||
}
|
|
||||||
::placeholder {
|
|
||||||
color: #b2aba1;
|
|
||||||
}
|
|
||||||
input:-webkit-autofill,
|
|
||||||
textarea:-webkit-autofill,
|
|
||||||
select:-webkit-autofill {
|
|
||||||
background-color: #404400 !important;
|
|
||||||
color: #e8e6e3 !important;
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar {
|
|
||||||
background-color: #202324;
|
|
||||||
color: #aba499;
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar-thumb {
|
|
||||||
background-color: #454a4d;
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar-thumb:hover {
|
|
||||||
background-color: #575e62;
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar-thumb:active {
|
|
||||||
background-color: #484e51;
|
|
||||||
}
|
|
||||||
::-webkit-scrollbar-corner {
|
|
||||||
background-color: #181a1b;
|
|
||||||
}
|
|
||||||
* {
|
|
||||||
scrollbar-color: #454a4d #202324;
|
|
||||||
}
|
|
||||||
::selection {
|
|
||||||
background-color: #004daa !important;
|
|
||||||
color: #e8e6e3 !important;
|
|
||||||
}
|
|
||||||
::-moz-selection {
|
|
||||||
background-color: #004daa !important;
|
|
||||||
color: #e8e6e3 !important;
|
|
||||||
}
|
|
||||||
input[type="text"], input[type="text"]:focus, input[type="password"], input[type="password"]:focus, input[type="email"], input[type="email"]:focus {
|
|
||||||
background-color: #202324 !important;
|
|
||||||
color: #e8e6e3;
|
|
||||||
}
|
|
||||||
form {
|
|
||||||
outline: 1px solid grey;
|
|
||||||
padding: 20px;
|
|
||||||
padding-top: 10px;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
.err-banner {
|
|
||||||
background-color: #AA0000;
|
|
||||||
padding: 20px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
width: 15%;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
{% include "core/frontend/widgets/topbar.jinja" %}
|
{% include "core/frontend/widgets/topbar.jinja" %}
|
||||||
{% block content %}
|
<div class="container">
|
||||||
<h1>{{ server_name }}</h1>
|
{% block content %}
|
||||||
{% endblock content %}
|
<h1>{{ server_name }}</h1>
|
||||||
</body>
|
{% endblock content %}
|
||||||
|
</div>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.1/dist/js/bootstrap.bundle.min.js"
|
||||||
|
integrity="sha384-HwwvtgBNo3bZJJLYd8oVXjrBZt8cqVSpeBNS5n7C8IVInixGAoxmnlMuBnhbgrkm"
|
||||||
|
crossorigin="anonymous"></script>
|
||||||
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
@ -1,41 +1,126 @@
|
|||||||
{% extends "core/frontend/index.jinja" %}
|
{% extends "core/frontend/index.jinja" %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Management for {{ username }}</h1>
|
<h1>{{ sesh["username"] }}'s Account</h1>
|
||||||
<h2>Cards <button class="btn btn-success" data-bs-toggle="modal" data-bs-target="#card_add">Add</button></h2>
|
|
||||||
<ul style="font-size: 20px;">
|
|
||||||
{% for c in cards %}
|
|
||||||
<li>{{ c.access_code }}: {{ c.status }} {% if c.status == 'Active'%}<button class="btn-warning btn">Lock</button>{% elif c.status == 'Locked' %}<button class="btn-warning btn">Unlock</button>{% endif %} <button class="btn-danger btn">Delete</button></li>
|
|
||||||
{% endfor %}
|
|
||||||
</ul>
|
|
||||||
|
|
||||||
{% if arcades is defined %}
|
<div class="card mb-3">
|
||||||
<h2>Arcades</h2>
|
<div class="card-body">
|
||||||
<ul style="font-size: 20px;">
|
<h3 class="card-title">Cards</h3>
|
||||||
{% for a in arcades %}
|
<!--<h4 class="card-subtitle mb-2 text-body-secondary">Card subtitle</h4>-->
|
||||||
<li><a href=/arcade/{{ a.id }}>{{ a.name }}</a></li>
|
<p class="card-text">All aime cards are listed here for the given user.</p>
|
||||||
{% endfor %}
|
<a href="#" data-bs-toggle="modal" data-bs-target="#card-add" class="btn btn-primary mb-3">Add Card</a>
|
||||||
</ul>
|
{% if cards is defined and cards|length > 0 %}
|
||||||
{% endif %}
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
<div class="modal fade" id="card_add" tabindex="-1" aria-labelledby="card_add_label" aria-hidden="true">
|
<div class="col-12">
|
||||||
<div class="modal-dialog">
|
<table class="table table-hover">
|
||||||
<div class="modal-content">
|
<thead>
|
||||||
<div class="modal-header">
|
<tr>
|
||||||
<h1 class="modal-title fs-5" id="card_add_label">Add Card</h1>
|
<th scope="col">#</th>
|
||||||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
<th scope="col">Access Code</th>
|
||||||
</div>
|
<th scope="col">Status</th>
|
||||||
<div class="modal-body">
|
<th scope="col">Actions</th>
|
||||||
HOW TO:<br>
|
</tr>
|
||||||
Scan your card on any networked game and press the "View Access Code" button (varies by game) and enter the 20 digit code below.<br>
|
</thead>
|
||||||
!!FOR AMUSEIC CARDS: DO NOT ENTER THE CODE SHOWN ON THE BACK OF THE CARD ITSELF OR IT WILL NOT WORK!!
|
<tbody>
|
||||||
<p /><label for="card_add_frm_access_code">Access Code: </label><input id="card_add_frm_access_code" maxlength="20" type="text" required>
|
{% for c in cards %}
|
||||||
</div>
|
<tr class="align-middle">
|
||||||
<div class="modal-footer">
|
<th scope="row">{{ c.index }}</th>
|
||||||
<button type="button" class="btn btn-primary">Add</button>
|
<td>{{ c.access_code }}</td>
|
||||||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
<td>
|
||||||
</div>
|
{% if c.status == 'Active'%}
|
||||||
|
<span class="badge rounded-pill text-bg-success">Active</span>
|
||||||
|
{% elif c.status == 'Locked' %}
|
||||||
|
<span class="badge rounded-pill text-bg-warning">Locked</span>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
{% if c.status == 'Active'%}
|
||||||
|
<button type="button" class="btn btn-warning btn-sm">Lock</i></button>
|
||||||
|
{% elif c.status == 'Locked' %}
|
||||||
|
<button type="button" class="btn btn-success btn-sm">Unlock</i></button>
|
||||||
|
{% endif %}
|
||||||
|
<button type="button" class="btn btn-danger btn-sm">Delete</i></button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="alert alert-warning" role="alert">
|
||||||
|
You have no cards registered to your account. Please add one.
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
<!--<a href="#" data-bs-toggle="modal" data-bs-target="#card-add" class="card-link">Add Card</a>-->
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card">
|
||||||
|
<div class="card-body">
|
||||||
|
<h3 class="card-title">Arcades</h3>
|
||||||
|
<!--<h4 class="card-subtitle mb-2 text-body-secondary">Card subtitle</h4>-->
|
||||||
|
<p class="card-text">All arcades connected to the given account are listed here.</p>
|
||||||
|
{% if arcades is defined and arcades|length > 0 %}
|
||||||
|
<div class="container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-12">
|
||||||
|
<table class="table table-hover">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th scope="col">#</th>
|
||||||
|
<th scope="col">Name</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for a in arcades %}
|
||||||
|
<tr class="align-middle clickable-row" data-href=/arcade/{{ a.id }}>
|
||||||
|
<th scope="row">{{ a.index }}</th>
|
||||||
|
<td>{{ a.name }}</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="alert alert-info" role="alert">
|
||||||
|
You have no arcades connected to your account.
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="card-add" tabindex="-1" aria-labelledby="card-add-label" aria-hidden="true">
|
||||||
|
<div class="modal-dialog">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<h1 class="modal-title fs-5" id="card-add-label">Add Card</h1>
|
||||||
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
<h3 class="fs-5">How to:</h3>
|
||||||
|
Scan your card on any networked game and press the "View Access Code" button (varies by game) and enter
|
||||||
|
the 20
|
||||||
|
digit code below.
|
||||||
|
<hr>
|
||||||
|
FOR AMUSE IC CARDS: DO NOT ENTER THE CODE SHOWN ON THE BACK OF THE CARD ITSELF OR IT WILL NOT WORK!
|
||||||
|
<form>
|
||||||
|
<div class="form-floating mt-3">
|
||||||
|
<label for="access-code" class="col-form-label">Access Code</label>
|
||||||
|
<input maxlength="20" type="text" required pattern="[0-9]{20}" class="form-control"
|
||||||
|
id="access-code">
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
|
||||||
|
<button type="button" class="btn btn-primary">Add</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{% endblock content %}
|
{% endblock content %}
|
@ -1,6 +1,5 @@
|
|||||||
{% if error > 0 %}
|
{% if error > 0 %}
|
||||||
<div class="err-banner">
|
<div class="alert alert-danger" role="alert">
|
||||||
<h3>Error</h3>
|
|
||||||
{% if error == 1 %}
|
{% if error == 1 %}
|
||||||
Card not registered, or wrong password
|
Card not registered, or wrong password
|
||||||
{% elif error == 2 %}
|
{% elif error == 2 %}
|
||||||
|
@ -1,21 +1,56 @@
|
|||||||
<div style="background: #333; color: #f9f9f9; width: 10%; height: 50px; line-height: 50px; text-align: center; float: left;">
|
<nav class="p-3 mb-3 navbar navbar-expand-lg bg-body-tertiary" aria-label="Thirteenth navbar example">
|
||||||
Navigation
|
<div class="container">
|
||||||
</div>
|
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarsExample11"
|
||||||
<div style="background: #333; color: #f9f9f9; width: 80%; height: 50px; line-height: 50px; padding-left: 10px; float: left;">
|
aria-controls="navbarsExample11" aria-expanded="false" aria-label="Toggle navigation">
|
||||||
<a href=/><button class="btn btn-primary">Home</button></a>
|
<span class="navbar-toggler-icon"></span>
|
||||||
{% for game in game_list %}
|
</button>
|
||||||
<a href=/game/{{ game.url }}><button class="btn btn-success">{{ game.name }}</button></a>
|
|
||||||
{% endfor %}
|
<div class="collapse navbar-collapse d-lg-flex" id="navbarsExample11">
|
||||||
</div>
|
<a class="navbar-brand col-lg-3 me-0" href= />ARTEMiS</a>
|
||||||
</div>
|
<ul class="navbar-nav col-lg-6 justify-content-lg-center nav-pills">
|
||||||
<div style="background: #333; color: #f9f9f9; width: 10%; height: 50px; line-height: 50px; text-align: center; float: left;">
|
<li class="nav-item">
|
||||||
{% if sesh is defined and sesh["permissions"] >= 2 %}
|
<a class="nav-link {% if active_page == '/' %}active{% endif %}" aria-current="page" href= />Home</a>
|
||||||
<a href="/sys"><button class="btn btn-primary">System</button></a>
|
</li>
|
||||||
{% endif %}
|
{% for game in game_list %}
|
||||||
{% if sesh is defined and sesh["userId"] > 0 %}
|
<li class="nav-item">
|
||||||
<a href="/user"><button class="btn btn-primary">Account</button></a>
|
<a class="nav-link {% if active_page == game.url %}active{% endif %}" href=/game/{{ game.url }}>{{ game.name }}</a>
|
||||||
{% else %}
|
</li>
|
||||||
<a href="/gate"><button class="btn btn-primary">Gate</button></a>
|
{% endfor %}
|
||||||
{% endif %}
|
<!--
|
||||||
|
<li class="nav-item dropdown">
|
||||||
</div>
|
<a class="nav-link dropdown-toggle" href="#" data-bs-toggle="dropdown"
|
||||||
|
aria-expanded="false">Dropdown</a>
|
||||||
|
<ul class="dropdown-menu">
|
||||||
|
<li><a class="dropdown-item" href="#">Action</a></li>
|
||||||
|
<li><a class="dropdown-item" href="#">Another action</a></li>
|
||||||
|
<li><a class="dropdown-item" href="#">Something else here</a></li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
|
-->
|
||||||
|
</ul>
|
||||||
|
<div class="d-lg-flex col-lg-3 justify-content-lg-end">
|
||||||
|
{% if sesh is defined and sesh["user_id"] > 0 %}
|
||||||
|
<div class="btn-group dropdown">
|
||||||
|
<a href="#" class="d-block link-body-emphasis text-decoration-none dropdown-toggle"
|
||||||
|
data-bs-toggle="dropdown" aria-expanded="false">
|
||||||
|
{{ sesh["username"] }}
|
||||||
|
</a>
|
||||||
|
<ul class="dropdown-menu text-small">
|
||||||
|
{% if sesh["permissions"] >= 2 %}
|
||||||
|
<li><a class="dropdown-item {% if active_page == 'sys' %}active{% endif %}" href="/sys">System</a></li>
|
||||||
|
{% endif %}
|
||||||
|
<li><a class="dropdown-item" href="#">Settings</a></li>
|
||||||
|
<li><a class="dropdown-item {% if active_page == 'user' %}active{% endif %}" href="/user">Account</a></li>
|
||||||
|
<li>
|
||||||
|
<hr class="dropdown-divider">
|
||||||
|
</li>
|
||||||
|
<li><a class="dropdown-item" href="#">Sign out</a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<a href="/gate"><button class="btn {% if active_page == 'gate' %}btn-primary{% else %}btn-outline-primary{% endif %}">Login</button></a>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</nav>
|
@ -22,7 +22,7 @@ class PokkenFrontend(FE_Base):
|
|||||||
self.game_cfg.update(
|
self.game_cfg.update(
|
||||||
yaml.safe_load(open(f"{cfg_dir}/{PokkenConstants.CONFIG_NAME}"))
|
yaml.safe_load(open(f"{cfg_dir}/{PokkenConstants.CONFIG_NAME}"))
|
||||||
)
|
)
|
||||||
self.nav_name = "Pokken"
|
self.nav_name = "Pokkén"
|
||||||
|
|
||||||
def render_GET(self, request: Request) -> bytes:
|
def render_GET(self, request: Request) -> bytes:
|
||||||
template = self.environment.get_template(
|
template = self.environment.get_template(
|
||||||
@ -35,5 +35,6 @@ class PokkenFrontend(FE_Base):
|
|||||||
return template.render(
|
return template.render(
|
||||||
title=f"{self.core_config.server.name} | {self.nav_name}",
|
title=f"{self.core_config.server.name} | {self.nav_name}",
|
||||||
game_list=self.environment.globals["game_list"],
|
game_list=self.environment.globals["game_list"],
|
||||||
sesh=vars(usr_sesh)
|
sesh=vars(usr_sesh),
|
||||||
|
active_page="pokken",
|
||||||
).encode("utf-16")
|
).encode("utf-16")
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends "core/frontend/index.jinja" %}
|
{% extends "core/frontend/index.jinja" %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Pokken</h1>
|
<h1>Pokkén</h1>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
@ -22,7 +22,7 @@ class WaccaFrontend(FE_Base):
|
|||||||
self.game_cfg.update(
|
self.game_cfg.update(
|
||||||
yaml.safe_load(open(f"{cfg_dir}/{WaccaConstants.CONFIG_NAME}"))
|
yaml.safe_load(open(f"{cfg_dir}/{WaccaConstants.CONFIG_NAME}"))
|
||||||
)
|
)
|
||||||
self.nav_name = "Wacca"
|
self.nav_name = "WACCA"
|
||||||
|
|
||||||
def render_GET(self, request: Request) -> bytes:
|
def render_GET(self, request: Request) -> bytes:
|
||||||
template = self.environment.get_template(
|
template = self.environment.get_template(
|
||||||
@ -30,9 +30,10 @@ class WaccaFrontend(FE_Base):
|
|||||||
)
|
)
|
||||||
sesh: Session = request.getSession()
|
sesh: Session = request.getSession()
|
||||||
usr_sesh = IUserSession(sesh)
|
usr_sesh = IUserSession(sesh)
|
||||||
|
|
||||||
return template.render(
|
return template.render(
|
||||||
title=f"{self.core_config.server.name} | {self.nav_name}",
|
title=f"{self.core_config.server.name} | {self.nav_name}",
|
||||||
game_list=self.environment.globals["game_list"],
|
game_list=self.environment.globals["game_list"],
|
||||||
sesh=vars(usr_sesh)
|
sesh=vars(usr_sesh),
|
||||||
|
active_page="wacca",
|
||||||
).encode("utf-16")
|
).encode("utf-16")
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{% extends "core/frontend/index.jinja" %}
|
{% extends "core/frontend/index.jinja" %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<h1>Wacca</h1>
|
<h1>WACCA</h1>
|
||||||
{% endblock content %}
|
{% endblock content %}
|
Loading…
Reference in New Issue
Block a user