Add admin panel to delete URLs from the browser. Add copyright notice.

This commit is contained in:
Kevin Alberts 2019-06-30 15:57:11 +02:00
parent 332d82e97a
commit 8288b3624e
Signed by: Kurocon
GPG key ID: BCD496FEBA0C6BC1
11 changed files with 445 additions and 75 deletions

View file

@ -1,9 +1,10 @@
# Copyright (c) 2019 Steven Spangler <132@ikl.sh>
# Copyright (c) 2019 Steven Spangler <132@ikl.sh>, Kevin Alberts <kevin@kevinalberts.nl>
# This file is part of liteshort by 132ikl
# This software is license under the MIT license. It should be included in your copy of this software.
# A copy of the MIT license can be obtained at https://mit-license.org/
from flask import Flask, current_app, flash, g, jsonify, make_response, redirect, render_template, request, send_from_directory, url_for
from flask import Flask, current_app, flash, g, jsonify, make_response, redirect, render_template, request, \
send_from_directory, url_for, session
import bcrypt
import os
import random
@ -22,13 +23,14 @@ def load_config():
req_options = {'admin_username': 'admin', 'database_name': "urls", 'random_length': 4,
'allowed_chars': 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
'random_gen_timeout': 5, 'site_name': 'liteshort', 'site_domain': None, 'show_github_link': True,
'secret_key': None, 'disable_api': False, 'subdomain': '', 'latest': 'l'
'secret_key': None, 'disable_api': False, 'subdomain': '', 'latest': 'l', 'admin_links_per_page': 20
}
config_types = {'admin_username': str, 'database_name': str, 'random_length': int,
'allowed_chars': str, 'random_gen_timeout': int, 'site_name': str,
'site_domain': (str, type(None)), 'show_github_link': bool, 'secret_key': str,
'disable_api': bool, 'subdomain': (str, type(None)), 'latest': (str, type(None))
'disable_api': bool, 'subdomain': (str, type(None)), 'latest': (str, type(None)),
'admin_links_per_page': int
}
for option in req_options.keys():
@ -128,6 +130,26 @@ def list_shortlinks():
return result
def list_shortlinks_page(page, limit=50):
assert page >= 1
assert type(page) == int
assert type(limit) == int
start_index = (page - 1) * limit
result = query_db('SELECT * FROM urls ORDER BY short LIMIT ? OFFSET ?', (limit, start_index), False, None)
result = nested_list_to_dict(result)
return result
def get_num_pages(limit=50):
assert type(limit) == int
result = query_db('SELECT COUNT(*) FROM urls', (), False, None)
items = result[0][0]
page_count = result[0][0] // limit
if page_count * limit < items:
page_count += 1
return page_count, items
def nested_list_to_dict(l):
d = {}
for nl in l:
@ -300,5 +322,58 @@ def main_post():
return response(request, None, 'Long URL required')
@app.route('/login', methods=['POST'])
def login():
if 'admin_hashed_password' not in app.config or app.config['admin_hashed_password'] is None:
raise AssertionError("Login is disabled.")
if authenticate(request.form['username'], request.form['password']):
session['logged_in'] = True
else:
flash('Wrong password!', 'error')
return make_response(redirect(url_for('admin')))
@app.route('/logout')
def logout():
if 'logged_in' in session and session['logged_in']:
session['logged_in'] = False
return make_response(redirect(url_for('admin')))
@app.route('/delete/<short>')
def delete(short):
if 'logged_in' in session and session['logged_in']:
success = delete_url(short)
if success:
flash("Link '/{}' deleted.".format(short), "success")
else:
flash("Failed to delete URL.".format(short), "error")
page = request.args.get('page', '1')
return make_response(redirect(url_for('admin')+"?page="+page))
else:
return make_response(redirect(url_for('admin')))
@app.route('/admin')
def admin():
if 'logged_in' in session and session['logged_in']:
page_count, num_items = get_num_pages(app.config['admin_links_per_page'])
page = request.args.get('page', '1')
try:
page = int(page)
if page > page_count:
return make_response(redirect(url_for('admin')+"?page="+str(page_count)))
if page < 1:
return make_response(redirect(url_for('admin')+"?page=1"))
except ValueError:
page = 1
urls = list_shortlinks_page(page, app.config['admin_links_per_page'])
return render_template('admin.html', urls=urls, page=page, page_count=page_count, num_items=num_items)
else:
return render_template('login.html')
if __name__ == '__main__':
app.run()