Commit 40fcfd55 authored by Jacotsu's avatar Jacotsu
Browse files

Added login logging

Added referers tracking
Fixed uus_mng inconsistent database user key creation
parent 805d4729
......@@ -3,7 +3,8 @@ This is a url shortener written in python with flask
## Management CLI
A simple CLI is provided to add, modify and delete admin users. `REDIS_URL` must be provided unless it is the default. Also, `FLASK_APP=uus` must be set when not running in Docker (the Dockerfile already sets this).
A simple CLI is provided to add, modify and delete admin users. `REDIS_URL` must be provided unless it is the default.
Also, `FLASK_APP=uus` must be set when not running in Docker (the Dockerfile already sets this).
Run `flask` to get the list of commands.
......@@ -19,10 +19,11 @@ pure_string = re.compile(r'^\w+$')
def redis_key_for_user(user: str) -> str:
return "user.{}".format(user)
def redis_key_for_url(url: str) -> str:
return "url.{}".format(url)
def redis_key_for_referrer_count(url: str, referrer: str) -> str:
return "url.{}.referrers.{}.count".format(url, referrer)
def redis_key_for_count(url: str) -> str:
return "count.{}".format(url)
......@@ -33,6 +34,17 @@ def handle_redirect(path):
final_url = redis_store.get('url.' + path)
if final_url:
redis_store.incr('count.' + path)
referrer = flask.request.headers.get('referer')
if referrer:
if not redis_store.exists(redis_key_for_referrer_count(path,
app.logger.debug('Adding {} as referer for {}'.format(
referrer, path))
referrer), 0)
app.logger.debug('Increased counter for {}'.format(referrer))
return flask.redirect(final_url)
return flask.abort(404)
......@@ -47,6 +59,7 @@ def handle_login(username, password):
crypt_pw = crypt_pw.decode()
return crypt_pw == crypt.crypt(password, crypt_pw)
else:'{} failed login'.format(username))
return False
......@@ -84,6 +97,9 @@ def del_url():
for key in redis_store.scan_iter('url.{}.*'
return ''
except KeyError:
return flask.abort(400)
......@@ -94,15 +110,42 @@ def del_url():
def list_urls():
keys = map(lambda x: x.decode(), redis_store.keys('url.*'))
keys = filter(lambda z: not'\\.referrers*', z),
map(lambda x: x.decode(), redis_store.keys('url.*')))
return_dict = {}
for key in keys:
real_key = key.replace('url.', '', 1)
return_dict[real_key] = {'url': redis_store.get(key).decode(),
'count': int(redis_store.get(redis_key_for_count(real_key)).decode())}
return flask.jsonify(return_dict)
def list_referrers(shortedurl=None):
if shortedurl:
# According to this
# string injection shouldn't be possible
keys = map(lambda x: x.decode(),
return_list = []
for key in keys:
referrer_url = re.sub('url\\.{}\\.referrers\\.|\\.count$'
'', key)
referrer_url_count = int(redis_store.get(
return_list.append({'url': referrer_url,
'count': referrer_url_count})
return flask.jsonify(return_list)
return flask.jsonify([])
@app.route('/<path:path>', strict_slashes=False)
def redirect(path):
if pure_string.match(path):
......@@ -110,7 +153,7 @@ def redirect(path):
return flask.abort(404)
from .management_cli import *
#from .management_cli import *
if __name__ == "__main__":
var edit_field = '<input type="button" class="edit_btn" value="Edit"></input><input type="button" class="del_btn" value="Delete"></input>';
function list_to_sorted_table(list) {
var tmpString = '';
list.sort(function(a, b) {b.count - a.count});
for (var referrer in list) {
tmpString += '<tr><td>' + list[referrer].count + '</td><td>' + list[referrer].url + '</td></tr>';
return tmpString;
function refresh_list(){
type: "GET",
url: "/api/v1/listurls",
dataType: "json",
success: function(response){
$.each(response, function(index, value){
$("#link_table").append('<tr id="'+ index +'"><td>'+ index +
"</td><td>"+ value['url'] +
"</td><td>"+ value['count'] +
"</td><td>"+ edit_field +"</td>")
type: "GET",
url: "/api/v1/listurls",
dataType: "json",
success: function(response){
var referrers = null;
$.each(response, function(index, value){
type: "GET",
url: "/api/v1/listreferrers/" + index,
dataType: "json",
success: function(response){
$("#link_table").append('<tr id="'+ index +'"><td>'+ index +
"</td><td>"+ value['url'] +
"</td><td>"+ value['count'] +
"</td><td><table><th>Count</th><th>Url</th>"+ list_to_sorted_table(response) +
"</table></td><td>"+ edit_field +"</td>")
......@@ -20,6 +20,7 @@
<th>Short Link Name</th>
<th>Redirect Url</th>
<th>View Count</th>
......@@ -21,7 +21,7 @@ def cli(redisurl):
def adduser(username, passwd):
"""Add UUS admin user"""
cryptpwd = crypt.crypt(passwd)
redis_store.set('usr.' + username, cryptpwd)
redis_store.set('user.' + username, cryptpwd)
......@@ -36,7 +36,7 @@ def passwd(username, passwd):
def deluser(username):
"""Delete UUS admin user"""
redis_store.delete('usr.' + username)
redis_store.delete('user.' + username)
if __name__ == '__main__':
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment