Skip to content
Snippets Groups Projects
Commit 19993f0a authored by Marco De Donno's avatar Marco De Donno
Browse files

Basic authentification system

parent dce59320
No related branches found
No related tags found
No related merge requests found
......@@ -15,3 +15,7 @@ redis_url = os.environ.get( "REDIS_URL", "redis://127.0.0.1:6379/0" )
SESSION_REDIS = redis.from_url( redis_url )
session_timeout = int( os.environ.get( "SESSION_TIMEOUT", 15 * 60 ) )
dburl = os.environ.get( "DB_URL", "pgsql://localhost/icnml" )
db = Database( dburl )
......@@ -2,7 +2,47 @@
# -*- coding: UTF-8 -*-
import random
import re
import string
import psycopg2
def random_data( N ):
return ''.join( random.choice( string.ascii_uppercase + string.digits ) for _ in range( N ) )
def urlsplit( url ):
data = re.match( '((?P<protocol>[^:]+)://)((?P<user>[^:]+)?(:(?P<password>[^@]+))?)?@(?P<host>[^:/]+)(:(?P<port>\d+))?(/(?P<database>[^&]+))?', url )
return dict( [ ( key, data.group( key ) ) for key in [ 'user', 'password', 'host', 'port', 'database' ] ] )
class Database( object ):
def __init__( self, url, docommit = True ):
self.conn = psycopg2.connect( **urlsplit( url ) )
self.docommit = docommit
def cursor( self ):
return self.conn.cursor()
def commit( self ):
if self.docommit:
self.conn.commit()
def close( self ):
self.conn.close()
def query( self, sql, *args, **kwargs ):
c = self.conn.cursor()
c.execute( sql, *args, **kwargs )
return c
def query_fetchone( self, sql ):
return self.query( sql ).fetchone()
def query_fetchall( self, sql ):
return self.query( sql ).fetchall()
def __enter__( self ):
return self
def __exit__( self, exc_type, exc_val, exc_tb ):
self.commit()
self.close()
......@@ -2,17 +2,20 @@
# -*- coding: UTF-8 -*-
from datetime import timedelta
from hashlib import sha512
from uuid import uuid4
import os
from flask import Flask
from flask import render_template, send_from_directory
from flask import request
from flask import session
from flask import url_for
from flask_compress import Compress
from flask_session import Session
from werkzeug import redirect
from functions import random_data
import config
################################################################################
......@@ -55,17 +58,32 @@ def logout():
@app.route( baseurl + '/login' )
def login():
session.clear()
session[ 'challenge' ] = random_data( 20 )
return render_template(
"login.html",
baseurl = baseurl,
challenge = session[ 'challenge' ],
js = config.cdnjs,
css = config.cdncss
)
@app.route( baseurl + '/do_login', methods = [ 'POST' ] )
def do_login():
session[ 'session_id' ] = str( uuid4() )
return redirect( url_for( 'home' ) )
q = config.db.query( 'SELECT username, password FROM users WHERE username = %s', ( request.form.get( "username" ), ) )
_, password = q.fetchone()
algo, db_hash = password.split( "$" )
db_challenge_hash = sha512( session[ 'challenge' ] + ":" + db_hash ).hexdigest()
if db_challenge_hash == request.form.get( "password" ):
session[ 'logged' ] = True
session[ 'session_id' ] = str( uuid4() )
return redirect( url_for( 'home' ) )
else:
session.clear()
return redirect( url_for( 'home' ) )
################################################################################
# Home page
......
flask
flask_compress
\ No newline at end of file
flask_compress
psycopg2-binary
\ No newline at end of file
......@@ -12,6 +12,17 @@
<script type="text/javascript">
baseurl = "{{ baseurl }}";
challenge = "{{ challenge }}";
login_action = function()
{
var username = $( '#username' ).val();
var password = $( '#password' ).val();
var passval = sha512( challenge + ':' + sha512( username + ':' + password ) );
$( '#password' ).val( passval );
};
</script>
</head>
<body>
......@@ -20,22 +31,25 @@
<h4 style="margin-top: 0px">International Close Non-Matches Library</h4>
<div class="ui-widget-header ui-corner-top icnml_login_top">Please enter your login information</div>
<form action="{{ url_for( 'do_login' ) }}" method="post">
<form action="{{ url_for( 'do_login' ) }}" method="post" onsubmit="login_action();" id="login_form">
<div class="ui-widget-content ui-corner-bottom icnml_login_form">
<div class="icnml_login_field">
<div style="text-align: right;">
<label for="username">Username</label>
</div>
<div>
<input id="username" type="text" style="width: 100%">
<input id="username" name="username" type="text" style="width: 100%">
</div>
<div style="text-align: right;">
<label for="password">Password</label>
</div>
<div>
<input id="password" type="password" style="width: 100%">
<input id="password" name="password" type="password" style="width: 100%">
</div>
</div>
<div>
<input id="challenge" name="challenge" type="hidden" value="{{ challenge }}">
</div>
<div class="icnml_login_button">
<input class="ui-button ui-widget ui-state-default ui-corner-all" type="submit" value="Login">
</div>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment