parent
ac16c46e01
commit
09a2c47edc
@ -1,27 +1,27 @@ |
||||
from datetime import datetime,timedelta |
||||
from uuid import uuid1 |
||||
import secrets |
||||
|
||||
class Nounce(object): |
||||
def __init__(self): |
||||
self.id = uuid1() |
||||
self.expiration = datetime.now()+timedelta(seconds=60) |
||||
self.token = secrets.token_urlsafe() |
||||
|
||||
def expired(self): |
||||
return datetime.now() > self.expiration |
||||
|
||||
def bump(self): |
||||
self.expiration = datetime.now()+timedelta(seconds=60) |
||||
|
||||
class AuthSession(object): |
||||
def __init__(self, username): |
||||
self.id = uuid1() |
||||
self.expiration = datetime.now()+timedelta(minutes=30) |
||||
self.username = username |
||||
|
||||
def expired(self): |
||||
return datetime.now() > self.expiration |
||||
|
||||
def bumpExpiration(self): |
||||
from datetime import datetime,timedelta |
||||
from uuid import uuid1 |
||||
import secrets |
||||
|
||||
class Nounce(object): |
||||
def __init__(self): |
||||
self.id = uuid1() |
||||
self.expiration = datetime.now()+timedelta(seconds=60) |
||||
self.token = secrets.token_urlsafe() |
||||
|
||||
def expired(self): |
||||
return datetime.now() > self.expiration |
||||
|
||||
def bump(self): |
||||
self.expiration = datetime.now()+timedelta(seconds=60) |
||||
|
||||
class AuthSession(object): |
||||
def __init__(self, username): |
||||
self.id = uuid1() |
||||
self.expiration = datetime.now()+timedelta(minutes=30) |
||||
self.username = username |
||||
|
||||
def expired(self): |
||||
return datetime.now() > self.expiration |
||||
|
||||
def bumpExpiration(self): |
||||
self.expiration = datetime.now()+timedelta(minutes=30) |
||||
@ -1,19 +1,19 @@ |
||||
#!/usr/bin/env python3 |
||||
from flask import * |
||||
import secrets |
||||
import nonce |
||||
import os.path |
||||
|
||||
app = Flask(__name__) |
||||
app.secret_key = secrets.token_urlsafe() |
||||
app.register_blueprint(nonce.app) |
||||
|
||||
ROUTES = {'routes': ['/', '/nonce'] } |
||||
@app.route('/') |
||||
def home(): |
||||
return jsonify(ROUTES) |
||||
|
||||
nonce.loadUsers( os.path.join('data','userlist.json') ) |
||||
if __name__ == '__main__': |
||||
app.run( host='0.0.0.0', port=7070) |
||||
|
||||
#!/usr/bin/env python3 |
||||
from flask import * |
||||
import secrets |
||||
import nonce |
||||
import os.path |
||||
|
||||
app = Flask(__name__) |
||||
app.secret_key = secrets.token_urlsafe() |
||||
app.register_blueprint(nonce.app) |
||||
|
||||
ROUTES = {'routes': ['/', '/nonce'] } |
||||
@app.route('/') |
||||
def home(): |
||||
return jsonify(ROUTES) |
||||
|
||||
nonce.loadUsers( os.path.join('data','userlist.json') ) |
||||
if __name__ == '__main__': |
||||
app.run( host='0.0.0.0', port=7070) |
||||
|
||||
|
||||
@ -1,179 +1,179 @@ |
||||
<!doctype html> |
||||
<html> |
||||
<head> |
||||
<script |
||||
src="https://code.jquery.com/jquery-3.4.1.min.js" |
||||
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" |
||||
crossorigin="anonymous"></script> |
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsSHA/2.3.1/sha256.js" |
||||
integrity="sha384-rxrcz1OyCVG21aEKlNBwgap2/r4pSV/RrN6eEMQhLriiTZnnzhCFZr+ZKGPJNSJX" |
||||
crossorigin="anonymous"></script> |
||||
|
||||
<script> |
||||
|
||||
function generateCnonce() { |
||||
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
||||
var text = ""; |
||||
for(var i = 0; i < 43; i++) { |
||||
text += possible.charAt(Math.floor(Math.random() * possible.length)); |
||||
} |
||||
return text; |
||||
} |
||||
|
||||
function submit() { |
||||
var user = $("#user").val(); |
||||
var pwd = $("#pwd").val(); |
||||
jQuery.get( 'nonce', {}, function(data){ |
||||
var nonce = data.token; |
||||
var cnonce = generateCnonce(); |
||||
|
||||
var sha256 = new jsSHA('SHA-256', 'TEXT'); //B64 |
||||
sha256.update(pwd); |
||||
var pwdHashed_sha256 = sha256.getHash('HEX') |
||||
|
||||
sha256 = new jsSHA('SHA-256', 'TEXT'); |
||||
sha256.update( pwdHashed_sha256+cnonce+nonce ); |
||||
const pwdhash= sha256.getHash('HEX') |
||||
const payload = { |
||||
user: user, |
||||
cnonce: cnonce, |
||||
pwdhash: pwdhash |
||||
} |
||||
jQuery.post('login', payload, |
||||
function(data){ |
||||
location.href = '/'; |
||||
} |
||||
).fail(function() { |
||||
var el = $('.error_msg'); |
||||
el.css('animation-name',''); |
||||
void el[0].offsetWidth; //trigger reflow |
||||
el.css('animation-name','fade'); |
||||
}); |
||||
} ); |
||||
} |
||||
|
||||
$( document ).ready(function() { |
||||
$("body").keypress( function(e) { |
||||
if(e.key=='Enter') { |
||||
submit(); |
||||
} |
||||
}); |
||||
$("#login").click( submit ); |
||||
}); |
||||
</script> |
||||
<style> |
||||
input { |
||||
border: 1px solid lightgray; |
||||
border-radius: 5px; |
||||
padding: 5px 5px 5px 5px; |
||||
/*width: 150px;*/ |
||||
width:100%; |
||||
display: block; |
||||
margin: 1px auto 3px auto; |
||||
box-sizing: border-box; |
||||
} |
||||
|
||||
button { |
||||
border: none; |
||||
border-radius: 5px; |
||||
padding: 5px 5px 5px 5px; |
||||
/*width: 150px;*/ |
||||
width:100%; |
||||
display: block; |
||||
margin: 1px auto 3px auto; |
||||
box-shadow: 0px 1px 3px 0px rgba(0,0,0,0.75); |
||||
cursor: pointer; |
||||
} |
||||
|
||||
button:hover { |
||||
background-color: lightgray; |
||||
} |
||||
|
||||
button:active { |
||||
transform: translateY(1px); |
||||
box-shadow: 0px 1px 2px 0px rgba(0,0,0,0.75); |
||||
} |
||||
|
||||
button:focus { |
||||
outline: 0; |
||||
} |
||||
|
||||
.error_msg { |
||||
border: none; |
||||
border-radius: 5px; |
||||
display: block; |
||||
background-color: #CC3333; |
||||
color: white; |
||||
animation-duration: 2.5s; |
||||
opacity: 0; |
||||
padding: 5px; |
||||
width:100%; |
||||
box-sizing: border-box; |
||||
font: 400 13.3333px Arial; |
||||
font-weight: 600; |
||||
text-align: center; |
||||
margin: 1px auto 3px auto; |
||||
} |
||||
|
||||
@keyframes fade { |
||||
0% {opacity: 1;} |
||||
25% {opacity: 1;} |
||||
100% {opacity: 0;} |
||||
} |
||||
|
||||
.centered { |
||||
width: 180px; |
||||
margin: 0; |
||||
position: absolute; |
||||
top: 50%; |
||||
left: 50%; |
||||
transform: translate(-50%, -50%); |
||||
} |
||||
|
||||
body { |
||||
background: |
||||
linear-gradient(27deg, |
||||
#151515 5px, |
||||
transparent 5px |
||||
) 0 5px, |
||||
linear-gradient(207deg, |
||||
#151515 5px, |
||||
transparent 5px |
||||
) 10px 0px, |
||||
linear-gradient(27deg, |
||||
#222 5px, |
||||
transparent 5px |
||||
) 0px 10px, |
||||
linear-gradient(207deg, |
||||
#222 5px, |
||||
transparent 5px |
||||
) 10px 5px, |
||||
linear-gradient(90deg, |
||||
#1b1b1b 10px, |
||||
transparent 10px |
||||
), |
||||
linear-gradient( |
||||
#1d1d1d 25%, |
||||
#1a1a1a 25%, |
||||
#1a1a1a 50%, |
||||
transparent 50%, |
||||
transparent 75%, |
||||
#242424 75%, |
||||
#242424 |
||||
); |
||||
background-color: #131313; |
||||
background-size: 20px 20px; |
||||
background-clip: content-box; |
||||
} |
||||
|
||||
</style> |
||||
</head> |
||||
<body> |
||||
<div class="centered"> |
||||
<input id="user" type="text" /> |
||||
<input id="pwd" type="password" /> |
||||
<button id="login">Login</button> |
||||
<div class="error_msg">Login failed!</div> |
||||
</div> |
||||
</body> |
||||
<!doctype html> |
||||
<html> |
||||
<head> |
||||
<script |
||||
src="https://code.jquery.com/jquery-3.4.1.min.js" |
||||
integrity="sha256-CSXorXvZcTkaix6Yvo6HppcZGetbYMGWSFlBw8HfCJo=" |
||||
crossorigin="anonymous"></script> |
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/jsSHA/2.3.1/sha256.js" |
||||
integrity="sha384-rxrcz1OyCVG21aEKlNBwgap2/r4pSV/RrN6eEMQhLriiTZnnzhCFZr+ZKGPJNSJX" |
||||
crossorigin="anonymous"></script> |
||||
|
||||
<script> |
||||
|
||||
function generateCnonce() { |
||||
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
||||
var text = ""; |
||||
for(var i = 0; i < 43; i++) { |
||||
text += possible.charAt(Math.floor(Math.random() * possible.length)); |
||||
} |
||||
return text; |
||||
} |
||||
|
||||
function submit() { |
||||
var user = $("#user").val(); |
||||
var pwd = $("#pwd").val(); |
||||
jQuery.get( 'nonce', {}, function(data){ |
||||
var nonce = data.token; |
||||
var cnonce = generateCnonce(); |
||||
|
||||
var sha256 = new jsSHA('SHA-256', 'TEXT'); //B64 |
||||
sha256.update(pwd); |
||||
var pwdHashed_sha256 = sha256.getHash('HEX') |
||||
|
||||
sha256 = new jsSHA('SHA-256', 'TEXT'); |
||||
sha256.update( pwdHashed_sha256+cnonce+nonce ); |
||||
const pwdhash= sha256.getHash('HEX') |
||||
const payload = { |
||||
user: user, |
||||
cnonce: cnonce, |
||||
pwdhash: pwdhash |
||||
} |
||||
jQuery.post('login', payload, |
||||
function(data){ |
||||
location.href = '/'; |
||||
} |
||||
).fail(function() { |
||||
var el = $('.error_msg'); |
||||
el.css('animation-name',''); |
||||
void el[0].offsetWidth; //trigger reflow |
||||
el.css('animation-name','fade'); |
||||
}); |
||||
} ); |
||||
} |
||||
|
||||
$( document ).ready(function() { |
||||
$("body").keypress( function(e) { |
||||
if(e.key=='Enter') { |
||||
submit(); |
||||
} |
||||
}); |
||||
$("#login").click( submit ); |
||||
}); |
||||
</script> |
||||
<style> |
||||
input { |
||||
border: 1px solid lightgray; |
||||
border-radius: 5px; |
||||
padding: 5px 5px 5px 5px; |
||||
/*width: 150px;*/ |
||||
width:100%; |
||||
display: block; |
||||
margin: 1px auto 3px auto; |
||||
box-sizing: border-box; |
||||
} |
||||
|
||||
button { |
||||
border: none; |
||||
border-radius: 5px; |
||||
padding: 5px 5px 5px 5px; |
||||
/*width: 150px;*/ |
||||
width:100%; |
||||
display: block; |
||||
margin: 1px auto 3px auto; |
||||
box-shadow: 0px 1px 3px 0px rgba(0,0,0,0.75); |
||||
cursor: pointer; |
||||
} |
||||
|
||||
button:hover { |
||||
background-color: lightgray; |
||||
} |
||||
|
||||
button:active { |
||||
transform: translateY(1px); |
||||
box-shadow: 0px 1px 2px 0px rgba(0,0,0,0.75); |
||||
} |
||||
|
||||
button:focus { |
||||
outline: 0; |
||||
} |
||||
|
||||
.error_msg { |
||||
border: none; |
||||
border-radius: 5px; |
||||
display: block; |
||||
background-color: #CC3333; |
||||
color: white; |
||||
animation-duration: 2.5s; |
||||
opacity: 0; |
||||
padding: 5px; |
||||
width:100%; |
||||
box-sizing: border-box; |
||||
font: 400 13.3333px Arial; |
||||
font-weight: 600; |
||||
text-align: center; |
||||
margin: 1px auto 3px auto; |
||||
} |
||||
|
||||
@keyframes fade { |
||||
0% {opacity: 1;} |
||||
25% {opacity: 1;} |
||||
100% {opacity: 0;} |
||||
} |
||||
|
||||
.centered { |
||||
width: 180px; |
||||
margin: 0; |
||||
position: absolute; |
||||
top: 50%; |
||||
left: 50%; |
||||
transform: translate(-50%, -50%); |
||||
} |
||||
|
||||
body { |
||||
background: |
||||
linear-gradient(27deg, |
||||
#151515 5px, |
||||
transparent 5px |
||||
) 0 5px, |
||||
linear-gradient(207deg, |
||||
#151515 5px, |
||||
transparent 5px |
||||
) 10px 0px, |
||||
linear-gradient(27deg, |
||||
#222 5px, |
||||
transparent 5px |
||||
) 0px 10px, |
||||
linear-gradient(207deg, |
||||
#222 5px, |
||||
transparent 5px |
||||
) 10px 5px, |
||||
linear-gradient(90deg, |
||||
#1b1b1b 10px, |
||||
transparent 10px |
||||
), |
||||
linear-gradient( |
||||
#1d1d1d 25%, |
||||
#1a1a1a 25%, |
||||
#1a1a1a 50%, |
||||
transparent 50%, |
||||
transparent 75%, |
||||
#242424 75%, |
||||
#242424 |
||||
); |
||||
background-color: #131313; |
||||
background-size: 20px 20px; |
||||
background-clip: content-box; |
||||
} |
||||
|
||||
</style> |
||||
</head> |
||||
<body> |
||||
<div class="centered"> |
||||
<input id="user" type="text" /> |
||||
<input id="pwd" type="password" /> |
||||
<button id="login">Login</button> |
||||
<div class="error_msg">Login failed!</div> |
||||
</div> |
||||
</body> |
||||
</html> |
||||
Loading…
Reference in new issue