diff --git a/db/sqlite.py b/db/sqlite.py
index 3ba8d41..cc44416 100644
--- a/db/sqlite.py
+++ b/db/sqlite.py
@@ -340,5 +340,52 @@ class DB:
# User already exists, probably
return False
+ def get_users(self):
+ return self._db().execute('''
+ select user_id, name, join_time, role, banned_until
+ from users
+ ''',
+ )
+
+ def set_forum_name(self, forum_id, name):
+ return self.change_one('''
+ update forums
+ set name = ?
+ where forum_id = ?
+ ''',
+ (name, forum_id)
+ )
+
+ def set_forum_description(self, forum_id, description):
+ return self.change_one('''
+ update forums
+ set description = ?
+ where forum_id = ?
+ ''',
+ (description, forum_id)
+ )
+
+ def add_forum(self, name, description):
+ db = self._db()
+ db.execute('''
+ insert into forums(name, description)
+ values (?, ?)
+ ''',
+ (name, description)
+ )
+ db.commit()
+
+ def change_one(self, query, values):
+ db = self._db()
+ c = db.cursor()
+ c.execute(query, values)
+ if c.rowcount > 0:
+ db.commit()
+ return True
+ return False
+
+ def query(self, q):
+ return self._db().execute(q)
+
def _db(self):
return sqlite3.connect(self.conn)
diff --git a/main.py b/main.py
index e477f9d..55d7a22 100644
--- a/main.py
+++ b/main.py
@@ -308,6 +308,67 @@ def register():
answer = answer,
)
+@app.route('/admin/')
+def admin():
+ user = get_user()
+ if user is None:
+ return redirect(url_for('login'))
+ if not user.is_admin():
+ return '
Forbidden ', 403
+
+ return render_template(
+ 'admin/index.html',
+ title = 'Admin panel',
+ forums = db.get_forums(),
+ users = db.get_users(),
+ )
+
+@app.route('/admin/query/', methods = ['GET', 'POST'])
+def admin_query():
+ user = get_user()
+ if user is None:
+ return redirect(url_for('login'))
+ if not user.is_admin():
+ return 'Forbidden ', 403
+
+ try:
+ rows = db.query(request.form['q']) if request.method == 'POST' else []
+ except Exception as e:
+ flash(e, 'error')
+ rows = []
+ return render_template(
+ 'admin/query.html',
+ title = 'Query',
+ rows = rows,
+ )
+
+@app.route('/admin/forum//edit//', methods = ['POST'])
+def admin_edit_forum(forum_id, what):
+ try:
+ if what == 'description':
+ res = db.set_forum_description(forum_id, request.form['description'].replace('\r', ''))
+ elif what == 'name':
+ res = db.set_forum_name(forum_id, request.form['name'])
+ else:
+ flash(f'Unknown property "{what}"', 'error')
+ res = None
+ if res is True:
+ flash(f'Updated {what}', 'success')
+ elif res is False:
+ flash(f'Failed to update {what}', 'error')
+ except Exception as e:
+ flash(e, 'error')
+ return redirect(url_for('admin'))
+
+@app.route('/admin/forum/new/', methods = ['POST'])
+def admin_new_forum():
+ try:
+ db.add_forum(request.form['name'], request.form['description'].replace('\r', ''))
+ flash('Added forum', 'success')
+ except Exception as e:
+ flash(str(e), 'error')
+ return redirect(url_for('admin'))
+
class Comment:
def __init__(self, id, author_id, author, text, create_time, modify_time, parent_id):
@@ -407,6 +468,9 @@ def utility_processor():
# This shouldn't be reachable, but it's still better to return something
return "incredibly long ago"
+ def format_time(t):
+ return datetime.utcfromtimestamp(t / 10 ** 9)
+
def minimd(text):
# Replace angle brackets to prevent XSS
# Also replace ampersands to prevent surprises.
@@ -420,6 +484,7 @@ def utility_processor():
return {
'format_since': format_since,
+ 'format_time': format_time,
'minimd': minimd,
}
diff --git a/schema.txt b/schema.txt
index 596bfca..af2fee7 100644
--- a/schema.txt
+++ b/schema.txt
@@ -5,7 +5,8 @@ create table users (
email varchar(254),
about text not null default '',
join_time integer not null,
- role integer not null default 0
+ role integer not null default 0,
+ banned_until integer
);
create table threads (
@@ -34,10 +35,9 @@ create table comments (
);
create table forums (
- forum_id integer unique not null primary key autoincrement,
+ forum_id integer unique not null primary key autoincrement,
name varchar(64) not null,
- description text,
- allowed_roles_mask integer not null
+ description text not null default ''
);
-- Both of these speed up searches significantly if there are many threads or comments.
diff --git a/templates/admin/base.html b/templates/admin/base.html
new file mode 100644
index 0000000..a864555
--- /dev/null
+++ b/templates/admin/base.html
@@ -0,0 +1,45 @@
+{# Don't use the default theme to emphasize this page is special -#}
+
+
+{{ title }}
+
+
+
+
+
+{{ title }}
+
+Admin panel
+Home page
+
+{%- for category, msg in get_flashed_messages(True) -%}
+{{ msg }}
+{%- endfor %}
+{%- block content %}{% endblock -%}
+
diff --git a/templates/admin/index.html b/templates/admin/index.html
new file mode 100644
index 0000000..d6a3765
--- /dev/null
+++ b/templates/admin/index.html
@@ -0,0 +1,101 @@
+{% extends 'admin/base.html' -%}
+{% block content -%}
+Query
+⚠ Only use queries if you know what you're doing ⚠
+
+Configuration
+
+Forums
+
+
+ID
+Name
+Description
+Actions
+
+{% for id, name, description, _, _, _ in forums %}
+
+{{ id }}
+
+
+
+
+
+Remove
+
+{% endfor %}
+
+Add forum
+
+
+
+
+Users
+
+{%- endblock %}
diff --git a/templates/admin/query.html b/templates/admin/query.html
new file mode 100644
index 0000000..8c89a92
--- /dev/null
+++ b/templates/admin/query.html
@@ -0,0 +1,17 @@
+{% extends 'admin/base.html' -%}
+{% block content -%}
+
+
+
+
+
+{%- for r in rows -%}
+
+{%- for c in r -%}
+{{ c }}
+{%- endfor -%}
+
+{%- endfor -%}
+
+{%- endblock -%}
+
diff --git a/templates/base.html b/templates/base.html
index 662d81d..4c165a3 100644
--- a/templates/base.html
+++ b/templates/base.html
@@ -12,6 +12,10 @@
{% if user is not none %}
{{ user.name }}
|
+ {% if user.is_admin() %}
+ Admin panel
+ |
+ {% endif %}
Logout
{% else %}
Register
diff --git a/templates/index.html b/templates/index.html
index 6725f52..32ac9be 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -10,7 +10,7 @@
{{ name }}
- {{ description }}
+ {{ minimd(description) | safe }}
{% if t_id %}
@@ -21,6 +21,6 @@
No threads
{% endif %}
- {% endfor %}
+ {%- endfor -%}
{% endblock %}
diff --git a/test/init_db.txt b/test/init_db.txt
index b77856d..94ad0c0 100644
--- a/test/init_db.txt
+++ b/test/init_db.txt
@@ -12,15 +12,16 @@ insert into users (name, password, email, join_time) values (
"bar@foo.baz",
0
);
-insert into users (name, password, join_time) values (
+insert into users (name, password, join_time, role) values (
"bazzers",
-- e
"$argon2id$v=19$m=65536,t=3,p=4$9v5fS2ktxTinNEbIGUOoFQ$LMdEuAuuTCJ7utOE88+nXn7o6R/DEKY8ZA6wV+YkVGQ",
- 0
+ 0,
+ 2
);
-insert into forums (name, description, allowed_roles_mask)
- values ("Earth", "The totality of all space and time; all that is, has been, and will be.", 1);
+insert into forums (name, description)
+ values ("Earth", "The totality of all space and time; all that is, has been, and will be.");
insert into threads (author_id, forum_id, create_time, modify_time, update_time, title, text)
values (1, 1, 0, 0, 0, "Hello, world!",