Browse Source

Basic web ui auth (password)

ideas
sirgje 2 years ago
parent
commit
42bafe9f9a
No known key found for this signature in database GPG Key ID: 9F326B1EC4A97073
  1. 24
      cogs/web/templates/base.html
  2. 96
      cogs/web/templates/index.html
  3. 12
      cogs/web/templates/login.html
  4. 33
      cogs/webserver.py
  5. 4
      config.py.example
  6. 3
      requirements.txt

24
cogs/web/templates/base.html

@ -0,0 +1,24 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Rooster Web UI</title>
<link rel="stylesheet" href="/assets/style.css">
</head>
<body>
<div class="d-flex flex-column flex-md-row align-items-center p-3 px-md-4 mb-3 bg-white border-bottom shadow-sm">
<h5 class="my-0 mr-md-auto font-weight-normal">Rooster Web UI</h5>
<nav class="my-2 my-md-0 mr-md-3">
{% if current_user.is_authenticated %}
<a class="p-2 text-dark" href="/logout">Logout</a>
{% endif %}
</nav>
</div>
<div class="container">
{% block content %}{% endblock %}
</div>
</body>
</html>

96
cogs/web/templates/index.html

@ -1,58 +1,44 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Rooster Web UI</title>
<link rel="stylesheet" href="/assets/style.css">
</head>
<body>
{% extends "base.html" %}
<div class="d-flex flex-column flex-md-row align-items-center p-3 px-md-4 mb-3 bg-white border-bottom shadow-sm">
<h5 class="my-0 mr-md-auto font-weight-normal">Rooster Web UI</h5>
</div>
{% block content %}
<p>Rooster is currently in <span class="badge">{{ guilds|length }}</span> guilds and is serving
<span class="badge">{{ users|length }}</span> users.</p>
<div class="container">
<p>Rooster is currently in <span class="badge">{{ guilds|length }}</span> guilds and is serving
<span class="badge">{{ users|length }}</span> users.</p>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th scope="col">Id</th>
<th scope="col">Name</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user.id }}</td>
<td>{{ user.name }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th scope="col">Id</th>
<th scope="col">Name</th>
</tr>
</thead>
<tbody>
{% for user in users %}
<tr>
<td>{{ user.id }}</td>
<td>{{ user.name }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th scope="col">Id</th>
<th scope="col">Name</th>
<th scope="col">Members</th>
<th scope="col">Channels</th>
</tr>
</thead>
<tbody>
{% for guild in guilds %}
<tr>
<td>{{ guild.id }}</td>
<td>{{ guild.name }}</td>
<td>{{ guild.members|length }}</td>
<td>{{ guild.channels|length }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</body>
</html>
<table class="table table-bordered table-striped">
<thead>
<tr>
<th scope="col">Id</th>
<th scope="col">Name</th>
<th scope="col">Members</th>
<th scope="col">Channels</th>
</tr>
</thead>
<tbody>
{% for guild in guilds %}
<tr>
<td>{{ guild.id }}</td>
<td>{{ guild.name }}</td>
<td>{{ guild.members|length }}</td>
<td>{{ guild.channels|length }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

12
cogs/web/templates/login.html

@ -0,0 +1,12 @@
{% extends "base.html" %}
{% block content %}
<p>You need to login to access this page.</p>
<form class="form" action="{{ url_for('login') }}" method="post">
<div class="form-group">
<label for="access_key">Access key</label>
<input type="password" class="form-control" id="access_key" name="access_key" required>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
{% endblock %}

33
cogs/webserver.py

@ -1,10 +1,14 @@
import logging
import config
from discord.ext import commands, tasks
from quart import Quart, render_template
from quart import Quart, render_template, ResponseReturnValue, redirect, url_for, request
from quart.exceptions import Unauthorized
from quart_auth import AuthManager, AuthUser, login_required, login_user, logout_user
log = logging.getLogger(__name__)
app = Quart(__name__, static_url_path='/assets/', static_folder='web/assets', template_folder='web/templates')
app.secret_key = config.web_secret_key
AuthManager(app)
class Webserver(commands.Cog):
@ -13,18 +17,41 @@ class Webserver(commands.Cog):
self.web_server.start()
@app.route('/')
async def welcome():
@login_required
async def index():
return await render_template('index.html', guilds=self.bot.guilds, users=self.bot.users)
@app.route('/send-message/<channel_id>')
@login_required
async def test_message(channel_id):
channel = self.bot.get_channel(int(channel_id))
await channel.send('web ui test')
return 'Done!'
@app.errorhandler(Unauthorized)
async def redirect_to_login(*_: Exception) -> ResponseReturnValue:
return redirect(url_for("login"))
@app.route("/login", methods=['GET', 'POST'])
async def login():
if request.method == 'POST':
access_key = (await request.form)["access_key"]
if access_key == config.web_access_key:
login_user(AuthUser(access_key))
return redirect(url_for('index'))
else:
return redirect(url_for('login'))
else:
return await render_template('login.html')
@app.route("/logout")
async def logout():
logout_user()
return redirect(url_for('index'))
@tasks.loop()
async def web_server(self):
await app.run_task(host=config.web_host, port=config.web_port)
await app.run_task(host=config.web_host, port=config.web_port, use_reloader=False)
@web_server.before_loop
async def web_server_before_loop(self):

4
config.py.example

@ -13,4 +13,6 @@ redis_host = 'localhost'
redis_port = 6379
web_host = 'localhost'
web_port = 5000
web_port = 5000
web_secret_key = 'replaceme'
web_access_key = 'replaceme'

3
requirements.txt

@ -18,4 +18,5 @@ sqlalchemy
pyyaml
pint
websockets
quart
quart
quart-auth
Loading…
Cancel
Save