Commit 848ce12d authored by rexxnor's avatar rexxnor

Securepasswords

parent a0f695a9
---
- name: Install PrepaidMate system as daemon and run it
hosts: prepaidmate
become: True
become: true
tasks:
- name: Install required packages
apt:
name: [apache2, libapache2-mod-wsgi-py3, python3-venv, git, virtualenv]
state: present
update_cache: yes
update_cache: true
- name: Clone repository
git:
repo: https://git.chaostreffbern.ch/rexxnor/prepaid-mate-website
dest: /var/www/html/ppm/
version: securepasswords
force: yes
- name: Install Virtualenv and requirements.txt
pip:
requirements: /var/www/html/ppm/requirements.txt
virtualenv: /var/www/prepaidmatevenv/
virtualenv_python: python3
ignore_errors: yes
ignore_errors: true
- name: Adding prepaidmate config for apache
template:
src: templates/prepaidmate.conf.j2
......@@ -43,7 +45,7 @@
dest: /var/www/html/
owner: www-data
group: www-data
recurse: yes
recurse: true
- name: Creating the apache run directory if it does not exist
file:
dest: /var/run/apache2/
......@@ -75,9 +77,9 @@
dest: /var/www/html/
owner: www-data
group: www-data
recurse: yes
recurse: true
- name: Reloading apache and enabling it
systemd:
name: apache2
state: reloaded
enabled: yes
enabled: true
......@@ -13,21 +13,20 @@ class CardAdmin(admin.ModelAdmin):
"""
Customize the Card Listing in Admin interface
"""
readonly_fields = ('owner_id',)
fields = ('owner_id', 'current_balance', 'pin_hash', 'holder_nickname')
list_display = ('owner_id', 'current_balance', 'pin_hash', 'holder_nickname')
fields = ('username', 'current_balance', 'holder_nickname')
list_display = ('username', 'current_balance', 'holder_nickname')
class TransactionAdmin(admin.ModelAdmin):
"""
Customize the Transaction Listing in Admin interface
"""
list_display = ('owner_id', 'amount', 'date_time')
list_display = ('username', 'amount', 'date_time')
class ChargeAdmin(admin.ModelAdmin):
"""
Customize the Charge Listing in Admin interface
"""
list_display = ('owner_id', 'amount', 'date_time')
list_display = ('username', 'amount', 'date_time')
class ReportAdmin(admin.ModelAdmin):
"""
......
# Generated by Django 2.1.3 on 2019-02-04 16:13
from django.conf import settings
from django.apps import apps
import django.contrib.auth.models
from django.db import migrations, models
import django.db.models.deletion
from django.contrib.auth.models import User
# Dirty global list
usertuples = []
def add_users(apps, schema_editor):
for card in apps.get_model('prepaid', model_name='Card').objects.all():
user = User.objects.create_user(username=card.owner_id, password=card.pin_hash)
user.save()
usertuples.append((user.username, card.owner_id))
def fix_references(apps, schema_editor):
for username, owner_id in usertuples:
user = apps.get_model('auth', model_name='user').objects.filter(username=username)[0]
userid = user.id
card = apps.get_model('prepaid', model_name='Card').objects.filter(id=owner_id)[0]
card.user_ptr_id = userid
card.save()
class Migration(migrations.Migration):
dependencies = [
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
('prepaid', '0005_auto_20181121_1818'),
]
operations = [
migrations.AlterModelOptions(
name='card',
options={'verbose_name': 'user', 'verbose_name_plural': 'users'},
),
migrations.AlterModelManagers(
name='card',
managers=[
('objects', django.contrib.auth.models.UserManager()),
],
),
migrations.RenameField(
model_name='charge',
old_name='owner_id',
new_name='username',
),
migrations.RenameField(
model_name='transaction',
old_name='owner_id',
new_name='username',
),
migrations.RunPython(add_users),
migrations.RemoveField(
model_name='card',
name='owner_id',
),
migrations.RemoveField(
model_name='card',
name='pin_hash',
),
migrations.AddField(
model_name='card',
name='user_ptr',
field=models.ForeignKey(auto_created=True, default=0, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=False, serialize=False, to=settings.AUTH_USER_MODEL),
preserve_default=False,
),
#migrations.RunSQL(
# sql='UPDATE prepaid_card SET user_ptr_id = (SELECT username FROM auth_user WHERE is_staff = 0)',
#),
migrations.RunPython(fix_references),
#migrations.AlterField(
# model_name='card',
# name='user_ptr',
# field=models.OneToOneField(auto_created=True, default=0, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL),
# preserve_default=False,
#),
]
# Generated by Django 2.1.5 on 2019-02-04 18:03
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('prepaid', '0006_auto_20190204_1613'),
]
operations = [
migrations.AlterField(
model_name='charge',
name='username',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL),
),
migrations.AlterField(
model_name='transaction',
name='username',
field=models.ForeignKey(null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL),
),
]
# Generated by Django 2.1.5 on 2019-02-05 13:58
from django.conf import settings
from django.db import migrations, models
import django.db.models.deletion
class Migration(migrations.Migration):
dependencies = [
('prepaid', '0007_auto_20190204_1803'),
]
operations = [
migrations.AlterField(
model_name='card',
name='user_ptr',
field=models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to=settings.AUTH_USER_MODEL),
),
]
......@@ -3,18 +3,16 @@ Models for Prepaidmate
"""
from django.db import models
from django.contrib.auth.models import User
from djmoney.models.fields import MoneyField
from django.conf import settings
# Create your models here.
class Card(models.Model):
class Card(User):
"""
Class for card Model
"""
owner_id = models.AutoField(primary_key=True)
current_balance = MoneyField(max_digits=10, decimal_places=2, default_currency='CHF')
pin_hash = models.CharField(max_length=64,
default=
'03ac674216f3e15c761ee1a5e255f067953623c8b388b4459e13f978d7c846f4')
holder_nickname = models.CharField(max_length=50)
def getbalance(self):
......@@ -38,7 +36,7 @@ class Transaction(models.Model):
"""
Class for transaction Model
"""
owner_id = models.ForeignKey(Card,
username = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.SET_NULL,
null=True)
amount = MoneyField(max_digits=10, decimal_places=2, default_currency='CHF')
......@@ -52,7 +50,7 @@ class Charge(models.Model):
"""
Class for transaction Model
"""
owner_id = models.ForeignKey(Card,
username = models.ForeignKey(settings.AUTH_USER_MODEL,
on_delete=models.SET_NULL,
null=True)
amount = MoneyField(max_digits=10, decimal_places=2, default_currency='CHF')
......
function hashpin(pin){
function hashid_password(id_password){
var sha256 = new jsSHA('SHA-256', 'TEXT');
sha256.update(pin);
sha256.update(id_password);
return sha256.getHash("HEX");
}
function hash(){
var pinfield = document.getElementById('pin');
var hashedpin = hashpin(pinfield.value);
pinfield.value = hashedpin;
return hashedpin;
var id_passwordfield = document.getElementById('id_password');
var hashedid_password = hashid_password(id_passwordfield.value);
id_passwordfield.value = hashedid_password;
return hashedid_password;
}
function presubmit() {
var search = search2json();
var form = document.getElementById('form');
var ownerid = document.getElementById('ownerid').value;
var pin = document.getElementById('pin');
var id_username = document.getElementById('id_username').value;
var id_password = document.getElementById('id_password');
if (document.getElementById('total')) {
var total = document.getElementById('total');
total.value = Number(search.total)
}
if (pin.value == "") {
field='pin';
pin.focus();
if (id_password.value == "") {
field='id_password';
id_password.focus();
return false;
}
if (pin.value.length == 64) {
if (id_password.value.length == 64) {
return true;
}
var myhash = hash(pin);
pin.value = String(myhash);
var myhash = hash(id_password);
id_password.value = String(myhash);
return true;
}
......@@ -59,7 +59,7 @@ if ( document.getElementById("buydrink") ) {
// hide modal on cancel
modalcancel.onclick = function() {
modal.style.display = "none";
pin.value = "";
id_password.value = "";
}
// submit form if ok is clicked
......
document.getElementById("charge").addEventListener('click', function () {
if ( typeof(total) !== "undefined" ) {
fillvalues();
var formatter = new Intl.NumberFormat('de-CH', {
style: 'currency',
currency: 'CHF'
......
......@@ -14,13 +14,6 @@ for (var i = 0; i < numpad.length; i++) {
});
}
function fillvalues() {
var ownerid = document.getElementById('ownerid')
ownerid.value = search.ownerid
var pin = document.getElementById('pin')
pin.value = search.pin
}
document.getElementById("numpadc").addEventListener('click', function () {
total.value = null;
});
......
var ownerid = document.getElementById('ownerid');
var pin = document.getElementById('pin');
var id_username = document.getElementById('id_username');
var id_password = document.getElementById('id_password');
numpad = document.getElementsByClassName("numpad")
field = 'ownerid';
field = 'id_username';
for (var i = 0; i < numpad.length; i++) {
numpad[i].addEventListener('click', function() {
if ( field == 'ownerid' ){
ownerid.value += String(this.innerHTML)
} else if ( field == 'pin' ){
pin.value += String(this.innerHTML)
if ( field == 'id_username' ){
id_username.value += String(this.innerHTML)
} else if ( field == 'id_password' ){
id_password.value += String(this.innerHTML)
}
});
}
document.getElementById("numpadc").addEventListener('click', function () {
if ( field == 'ownerid' ){
ownerid.value = ''
} else if ( field == 'pin' ){
pin.value = ''
if ( field == 'id_username' ){
id_username.value = ''
} else if ( field == 'id_password' ){
id_password.value = ''
}
});
......@@ -25,13 +25,13 @@ document.getElementById("add").addEventListener('click', function () {
function check(){
if(total.value.length == 0) {
console.log(total.value);
console.log(temptotal.value);
total.value = Number(temptotal.value);
total.value = roundup(total.value, 1);
temptotal.value = null;
} else {
total.value = Number(temptotal.value) + Number(total.value);
total.value = roundup(total.value, 1);
temptotal.value = null;
}
}
......@@ -40,3 +40,40 @@ function roundup(v, n) {
return Math.ceil(v * Math.pow(10, n)) / Math.pow(10, n);
}
document.getElementById("buy").addEventListener('click', function () {
check();
var formatter = new Intl.NumberFormat('de-CH', {
style: 'currency',
currency: 'CHF'
});
// get modal and buttons
var modal = document.getElementById('confirm-delete');
var modalcancel = document.getElementById('modalcancel');
var modalok = document.getElementById('modalok');
var price = document.getElementById('price');
// fill modal values
price.innerHTML = formatter.format(total.value);
// display modal
modal.style.display = "block";
// hide modal on cancel
modalcancel.onclick = function() {
modal.style.display = "none";
pin.value = "";
}
// submit form if ok is clicked
document.getElementById('modalok').addEventListener('click', function(){
document.getElementById('cart').submit();
});
// When the user clicks anywhere outside of the modal, close it
window.onclick = function(event) {
if (event.target == modal) {
modal.style.display = "none";
}
}
});
......@@ -10,23 +10,15 @@
<link rel="stylesheet" href="../static/css/bootstrap.css " >
<script charset="utf-8" src="../static/js/search2json.js"></script>
</head>
<body onLoad="window.setTimeout(function() {location.href='../';}, 10000)">
<body onLoad="window.setTimeout(function() {location.href='../logout/';}, 10000)">
<div class="container">
<br />
<h1>Balance</h1>
<div class="row">
<div class="col-md-12">
<button id="balance" class="btn-success btn-numpad btn-xl btn-block" onclick="window.location = '../'">Your remaining balance is: <b>{{ balance }}</b></button>
<button id="balance" class="btn-success btn-numpad btn-xl btn-block" onclick="window.location = '../logout/'">Your remaining balance is: <b>{{ balance }}</b></button>
<br />
<form action="../charge/" method="get" id="form">
<input type="hidden" class="numpad userid form-control" name="ownerid" id="ownerid" value="{{ ownerid }}"/>
<input type="hidden" class="numpad userid form-control" name="pin" id="pin" value="{{ pin }}"/>
<button type="submit" id="charge" class="btn-info btn-numpad btn-xl btn-block">Charge your Balance?</button>
</form>
<br />
<button class="btn-info btn-numpad btn-xl btn-block" onclick="window.location='../priceentry/'">Donate</button>
<br />
<a class="btn btn-warning btn-block btn-numpad" href="../" role="button">Back to Home</a>
<a class="btn btn-warning btn-block btn-numpad" href="../logout/" role="button">Back to Home</a>
</div>
</div>
</div>
......
......@@ -14,7 +14,7 @@
<script charset="utf-8" src="../static/js/search2json.js" defer></script>
<script charset="utf-8" src="../static/js/buydrink.js" defer></script>
</head>
<body onLoad="window.setTimeout(function() {location.href='../';}, 60000)">
<body onLoad="window.setTimeout(function() {location.href='../logout';}, 60000)">
<div class="container" id="main">
<div class="alert alert-danger" id="alert" hidden="">
<strong>Transaction Failed!</strong> Please try again.
......
......@@ -13,7 +13,7 @@
<script charset="utf-8" src="../static/js/charge.js" defer></script>
<script charset="utf-8" src="../static/js/moneypad.js" defer></script>
</head>
<body onLoad="window.setTimeout(function() {location.href='../';}, 60000)">
<body onLoad="window.setTimeout(function() {location.href='../logout';}, 30000)">
<div class="container">
<div class="row">
<div class="container col-md-8">
......@@ -24,12 +24,11 @@
</div>
<div class="row">
<div class="container col-md-12">
<form action="../chargecard/" method="post" id="form">{% csrf_token %}
<form action="../chargecard/" method="post" id="form">
{% csrf_token %}
<div class="input-group">
<span class="input-group-addon">CHF</span>
{{ form.total }}
<input type="hidden" name="owner_id" id="ownerid" value="" />
<input type="hidden" name="pin" id="pin" value="" />
</div>
</form>
</div>
......@@ -59,7 +58,7 @@
</div>
<div class="row">
<div class="container col-md-6">
<a class="btn btn-danger btn-block btn-numpad" href="../" role="button">Cancel</a>
<a class="btn btn-danger btn-block btn-numpad" href="../logout" role="button">Cancel</a>
</div>
<div class="container col-md-6">
<button class="btn btn-success btn-block btn-numpad" id="charge" type="button" value="Submit">Submit</button>
......
......@@ -13,12 +13,13 @@
<script charset="utf-8" src="../static/js/search2json.js" defer></script>
<script charset="utf-8" src="../static/js/buydrink.js" defer></script>
</head>
<body onLoad="window.setTimeout(function() {location.href='../';}, 60000)">
<body onLoad="window.setTimeout(function() {location.href='../logout';}, 60000)">
<div class="container" id="main">
<div class="alert alert-danger" id="alert" hidden="">
<strong>Transaction Failed!</strong> Please try again.
</div>
<form action="../checkbalance/" method="post" id="form">{% csrf_token %}
<form action="../checkbalance/" method="post" id="form">
{% csrf_token %}
<div class="row">
<div class="container col-md-offset-4 col-md-8">
<h4>Please enter your User ID.</h4>
......@@ -75,7 +76,7 @@
</div>
<div class="row">
<div class="container col-md-6">
<a class="btn btn-danger btn-block btn-numpad" href="../" role="button">Cancel</a>
<a class="btn btn-danger btn-block btn-numpad" href="../logout" role="button">Cancel</a>
</div>
<div class="container col-md-6">
<button class="btn btn-success btn-block btn-numpad" id="buydrink" type="button" value="Submit">Submit</button>
......
......@@ -21,11 +21,14 @@
<h1>Welcome to the Prepaidmate System!</h1>
<p>Please select your desired action</p>
<div class="row">
<div class="container col-md-6">
<div class="container col-md-4">
<a class="btn btn-primary btn-xl btn-block" href="priceentry/" role="button">Buy Something</a>
</div>
<div class="container col-md-6">
<a class="btn btn-primary btn-xl btn-block" href="checkbal/" role="button">Check Card Balance</a>
<div class="container col-md-4">
<a class="btn btn-primary btn-xl btn-block" href="login/?next=../checkbalance/" role="button">Check Balance</a>
</div>
<div class="container col-md-4">
<a class="btn btn-primary btn-xl btn-block" href="login/?next=../charge/" role="button">Charge Balance</a>
</div>
</div>
</div>
......
<!doctype html>
<html lang="en">
<head>
<title>Login</title>
<!-- Required meta tags -->
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="../static/css/bootstrap.css " >
<script charset="utf-8" src="../static/js/numpad.js" defer></script>
<script charset="utf-8" src="../static/js/sha256.js" defer></script>
<script charset="utf-8" src="../static/js/search2json.js" defer></script>
<script charset="utf-8" src="../static/js/buydrink.js" defer></script>
</head>
<body onLoad="window.setTimeout(function() {location.href='../logout';}, 60000)">
<div class="container" id="main">
<div class="alert alert-danger" id="alert" hidden="">
<strong>Transaction Failed!</strong> Please try again.
</div>
<form method="post" id="form">
{% csrf_token %}
<div class="row">
<div class="container col-md-offset-4 col-md-8">
<h4>Please enter your User ID.</h4>
<input autofocus="" type="text" class="numpad userid form-control" name="username" id="id_username" value="" onfocus="field='username';" />
</div>
</div>
<div class="row">
<div class="container col-md-offset-4 col-md-8">
<h4>Please enter your pin.</h4>
<input type="password" class="numpad userid form-control" required name="password" id="id_password" value="" onfocus="field='id_password';"/>
</div>
</div>
</form>
<div class="row">
<div class="container col-md-4">
<button type="button" class="numpad btn btn-numpad btn-primary btn-block">1</button>
</div>
<div class="container col-md-4">
<button type="button" class="numpad btn btn-numpad btn-primary btn-block">2</button>
</div>
<div class="container col-md-4">
<button type="button" class="numpad btn btn-numpad btn-primary btn-block">3</button>
</div>
</div>
<div class="row">
<div class="container col-md-4">
<button type="button" class="numpad btn btn-numpad btn-primary btn-block">4</button>
</div>
<div class="container col-md-4">
<button type="button" class="numpad btn btn-numpad btn-primary btn-block">5</button>
</div>
<div class="container col-md-4">
<button type="button" class="numpad btn btn-numpad btn-primary btn-block">6</button>
</div>
</div>
<div class="row">
<div class="container col-md-4">
<button type="button" class="numpad btn btn-numpad btn-primary btn-block">7</button>
</div>
<div class="container col-md-4">
<button type="button" class="numpad btn btn-numpad btn-primary btn-block">8</button>
</div>
<div class="container col-md-4">
<button type="button" class="numpad btn btn-numpad btn-primary btn-block">9</button>
</div>
</div>
<div class="row">
<div class="container col-md-8">
<button type="button" class="numpad btn btn-numpad btn-primary btn-block">0</button>
</div>
<div class="container col-md-4">
<button type="button" id="numpadc" class="btn btn-numpad btn-warning btn-block">C</button>
</div>
</div>
<div class="row">
<div class="container col-md-6">
<a class="btn btn-danger btn-block btn-numpad" href="../logout" role="button">Cancel</a>
</div>
<div class="container col-md-6">
<button class="btn btn-success btn-block btn-numpad" id="buydrink" type="button" value="Submit">Submit</button>
</div>
</div>
</div>
</body>
</html>
......@@ -9,7 +9,7 @@
</head>
<body>
<header>
<h1>Monatsabrechnung Prepaidmate</h1>
<h1>Abrechnung Prepaidmate</h1>
<address contenteditable id="address1">
<p>Arbeitsgruppe Kiosk & Getränke</p>
<p>c/o Chaostreffbern</p>
......
......@@ -8,9 +8,10 @@
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="../static/css/bootstrap.css">
<link rel="stylesheet" href="../static/css/modalstyle.css" >
<script charset="utf-8" src="../static/js/priceentry.js" defer></script>
</head>
<body onLoad="window.setTimeout(function() {location.href='../';}, 60000)">
<body onLoad="window.setTimeout(function() {location.href='../logout';}, 60000)">
<div class="container">
<div class="row">
<div class="container col-md-8">
......@@ -22,7 +23,8 @@
</div>
<div class="row">
<div class="container col-md-12">
<form action="../buydrin/" method="get"