diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..95f960b5e3e8a958299cf714f38ce195f01fae21 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +sessionids diff --git a/README.md b/README.md index 6fcf4b600cbc7dd0113fdf52259f7ae42da65a6b..0f3fe37201fbb7f9e94e3aa8f17d071ac5ceee1c 100644 --- a/README.md +++ b/README.md @@ -2,3 +2,53 @@ webdispense =========== Web interface for Dispense + +[BOB] 20100501 +How to make the pictures work in the dispense interface: +-there are mappings from slot names to file names in the index.html, just upload a picture for it into the icons directory and add a mapping +-the pictures are 130 pixels wide, 49 high +-don't forget to make a 'dark-' version of the image for when the slot is empty - there is a black50alpha layer in the folder that you can use + +Example Crontab +--------------- + +This clears the sessions + +* * * * * cd /services/webdispense/ && /usr/bin/python /services/webdispense/purge.py + +Apache Config +------------- + +Example config + +<VirtualHost *:80> + Redirect / https://dispense.ucc.asn.au/ + ServerName dispense.ucc.asn.au + Serveralias dispense.ucc.gu.uwa.edu.au +</virtualhost> + +<VirtualHost *:443> + ServerName dispense.ucc.asn.au + ServerAlias dispense.ucc.gu.uwa.edu.au + + ServerAdmin wheel@ucc.gu.uwa.edu.au + + SSLCertificateKeyFile /etc/letsencrypt/live/wildcard.ucc/privkey.pem + SSLCertificateFile /etc/letsencrypt/live/wildcard.ucc/fullchain.pem + + Alias /favicon.ico /services/wiki/htdocs/favicon.ico + + # Rewrite urls + RewriteEngine On + + Alias / /services/webdispense/ + Alias /dispense /services/webdispense/ + + # Dispense WebUI + <Directory /services/webdispense> + #Options +ExecCGI -Indexes + Options +ExecCGI +Indexes + Order deny,allow + Allow from all + </Directory> +</VirtualHost> diff --git a/apple-touch-icon.png b/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..924cbf60e52a85e54dc41db299d5a55048e0e6b0 Binary files /dev/null and b/apple-touch-icon.png differ diff --git a/balance.py b/balance.py index 1b3f72f876b35a9bc0c498b6ab522021370f6f3a..d16176f523aae3270f00823d3a67abe1786576a9 100755 --- a/balance.py +++ b/balance.py @@ -5,35 +5,40 @@ import commands,re print "Content-type: text/json" print import cgi,cgitb -import os, Cookie +import os cgitb.enable () +import sys, syslog + +#import getpass result = {} form = cgi.FieldStorage () -cookies = Cookie.SimpleCookie(os.environ.get("HTTP_COOKIE","")) def checkdata (): - if not (cookies.has_key("username") and cookies.has_key("pin")): - result = {"result" : "Missing information!"} - return result + if not (form.has_key("username") and form.has_key("sid")): + return {"result" : "Missing information!"} expr_name = re.compile ("^\w*$") - expr_pin = re.compile ("^\d{4}$") - username = cookies["username"].value.lower () - pin = cookies["pin"].value - if (not expr_name.match (cookies["username"].value)) or (not expr_pin.match (cookies["pin"].value)): - result = {"result" : "Incorrect login!"} - return result - output = commands.getoutput ("sudo checkpin " + username + " " + pin) - if output == "False": - result = {"result" : "Authentication failed!"} - return result - if not output == "True": - result = {"result" : "PIN not set up."} - return result + username = form["username"].value.lower () + sid = form["sid"].value + if (not expr_name.match (username)): + return {"result" : "Invalid login!"} + file = open("sessionids", "r") + success = False + for line in file: + if (":" + username + ":" + sid + "\n") in line: + success = True + file.close() + if not success: + log = "Authentication failure for user " + username + " from " + cgi.escape(os.environ["REMOTE_ADDR"]) + "\n" + syslog.syslog((syslog.LOG_NOTICE | syslog.LOG_AUTH), log) + #logfile = open("auth.log", "a") + #logfile.write(log) + #logfile.close() + return {"result" : "Authentication Failed"} output = commands.getoutput ("dispense acct " + username); expr_bal = re.compile ("(?P<bal>\d*\.\d*)") balance = expr_bal.search (output).groups()[0] - + return {"result" : "success", "balance" : balance} diff --git a/cookies.py b/cookies.py deleted file mode 100755 index 7749cbc084b0fddd6977f1306deea782f43e44bf..0000000000000000000000000000000000000000 --- a/cookies.py +++ /dev/null @@ -1,12 +0,0 @@ -#!/usr/bin/env python -import cgi, os, Cookie - -print "Content-type: text/html" -print - -#cgi.print_environ_usage() -#cgi.print_environ() - -cookies = Cookie.SimpleCookie(os.environ.get("HTTP_COOKIE","")) - -print "<pre>%s %s</pre>" % (cookies['username'].value, cookies['pin'].value) diff --git a/dispense.css b/dispense.css index faa82772064b738bae3920f2ab2335543e07d12c..79504e3a96914d13c975933a339d49240591653b 100644 --- a/dispense.css +++ b/dispense.css @@ -35,9 +35,12 @@ div.button { margin-bottom:3px; border:1px solid black; padding:9px; - font-family:helvetica; + font-family:"Courier",monospace; font-weight:bold; - color:white; + font-size:10pt; + color:rgb(0,255,0); + text-align:right; + line-height:100% } div.button:hover { border:1px solid white; @@ -68,7 +71,7 @@ div.button:hover { #logout:hover { border:1px solid white; } -#username, #pin { +#username, #passwd { width:100px; height:25px; margin-bottom:10px; @@ -82,6 +85,7 @@ div.button:hover { width:130px; height:73px; padding:6px; - font-family:monospace; + font-family:"Courier",monospace; + font-size:12pt; color:rgb(0,255,0); } diff --git a/dispense.py b/dispense.py index a85e45e5fdefb74665f39025605c1be0356292fe..61cb3438db5531347c880117caf0b206bc60af78 100755 --- a/dispense.py +++ b/dispense.py @@ -5,37 +5,42 @@ import commands,re print "Content-type: text/json" print import cgi,cgitb +import os cgitb.enable () -import os, Cookie +import sys, syslog + +#import getpass result = {} form = cgi.FieldStorage () -cookies = Cookie.SimpleCookie(os.environ.get("HTTP_COOKIE","")) def checkdata (): - if not (cookies.has_key("username") and cookies.has_key("pin") and form.has_key("slot")): - result = {"result" : "Missing information!"} - return result - expr_name = re.compile ("^\w*$") - expr_pin = re.compile ("^\d{4}$") + if not (form.has_key("username") and form.has_key("sid")): + return {"result" : "Missing information!"} + expr_name = re.compile ("^\w*$") expr_slot = re.compile ("^\d$") - username = cookies["username"].value.lower () - pin = cookies["pin"].value + username = form["username"].value.lower () + sid = form["sid"].value slot = form["slot"].value - if (not expr_name.match (cookies["username"].value)) or (not expr_pin.match (cookies["pin"].value)): - result = {"result" : "Incorrect login!"} - return result - output = commands.getoutput ("sudo checkpin " + username + " " + pin) - if output == "False": - result = {"result" : "Authentication failed!"} - return result - if not output == "True": - result = {"result" : "PIN not set up."} - return result + if (not expr_name.match (username) or not expr_slot.match (slot)): + return {"result" : "Invalid login!"} + file = open("sessionids", "r") + success = False + for line in file: + if (":" + username + ":" + sid + "\n") in line: + success = True + file.close() + if not success: + log = "Authentication failure for user " + username + " from " + cgi.escape(os.environ["REMOTE_ADDR"]) + "\n" + syslog.syslog((syslog.LOG_NOTICE | syslog.LOG_AUTH), log) + #logfile = open("auth.log", "a") + #logfile.write(log) + #logfile.close() + return {"result" : "Authentication Failed"} output = commands.getoutput ("dispense -u " + username + " " + slot); - expr_disp = re.compile ("^Dispensing a.*") + expr_disp = re.compile (".*coke:.*") if expr_disp.match (output): return {"result" : "success"} - return {"result" : "Dispense failed."} + return {"result" : output} print str(checkdata ()) diff --git a/door.py b/door.py index 44b5cb2a3de537a64c2674164f5bbc90b0061e4a..72a918eecad4124472990a67b60588f4c4a26841 100755 --- a/door.py +++ b/door.py @@ -5,34 +5,40 @@ import commands,re print "Content-type: text/json" print import cgi,cgitb +import os cgitb.enable () +import sys, syslog + +#import getpass result = {} form = cgi.FieldStorage () def checkdata (): - if not (form.has_key("username") and form.has_key("pin")): - result = {"result" : "Missing information!"} - return result - expr_name = re.compile ("^\w*$") - expr_pin = re.compile ("^\d{4}$") - username = form["username"].value - pin = form["pin"].value - if (not expr_name.match (form["username"].value)) or (not expr_pin.match (form["pin"].value)): - result = {"result" : "Incorrect login!"} - return result - output = commands.getoutput ("sudo checkpin " + username + " " + pin) - if output == "False": - result = {"result" : "Authentication failed!"} - return result - if not output == "True": - result = {"result" : "PIN not set up."} - return result - output = commands.getoutput ("dispense -u " + username + " opendoor"); - expr_bal = re.compile ("(?P<bal>\d*\.\d*)") - balance = expr_bal.search (output).groups()[0] - - return {"result" : "success", "balance" : balance} + if not (form.has_key("username") and form.has_key("sid")): + return {"result" : "Missing information!"} + expr_name = re.compile ("^\w*$") + username = form["username"].value.lower () + sid = form["sid"].value + if (not expr_name.match (username)): + return {"result" : "Invalid login!"} + file = open("sessionids", "r") + success = False + for line in file: + if (":" + username + ":" + sid + "\n") in line: + success = True + file.close() + if not success: + log = "Authentication failure for user " + username + " from " + cgi.escape(os.environ["REMOTE_ADDR"]) + "\n" + syslog.syslog((syslog.LOG_NOTICE | syslog.LOG_AUTH), log) + #logfile = open("auth.log", "a") + #logfile.write(log) + #logfile.close() + return {"result" : "Authentication Failed"} + output = commands.getoutput ("dispense -u " + username + " door"); + if not "Dispense OK" in output: + return {"result" : "Door failed"} + return {"result" : "success"} diff --git a/icons/black50alpha.png b/icons/black50alpha.png new file mode 100644 index 0000000000000000000000000000000000000000..4a2676534320ec34020196f7aea80aaac004f35a Binary files /dev/null and b/icons/black50alpha.png differ diff --git a/icons/dark-default.png b/icons/dark-default.png new file mode 100644 index 0000000000000000000000000000000000000000..10c7d114c5e055453b5eb3abe23c44f83856f534 Binary files /dev/null and b/icons/dark-default.png differ diff --git a/icons/dark-default.png.white b/icons/dark-default.png.white new file mode 100644 index 0000000000000000000000000000000000000000..031eca9c77b91d71def6edb7e8a0563888a45e1b Binary files /dev/null and b/icons/dark-default.png.white differ diff --git a/icons/dark-dietcoke.png b/icons/dark-dietcoke.png new file mode 100644 index 0000000000000000000000000000000000000000..e147554d4c785d284771183069a36542edf3ed3c Binary files /dev/null and b/icons/dark-dietcoke.png differ diff --git a/icons/dark-gingerbeer.png b/icons/dark-gingerbeer.png new file mode 100644 index 0000000000000000000000000000000000000000..321ba9be10334fbad6a4306cdf5c34be83a0b2a2 Binary files /dev/null and b/icons/dark-gingerbeer.png differ diff --git a/icons/dark-greensolo.png b/icons/dark-greensolo.png new file mode 100644 index 0000000000000000000000000000000000000000..8c2801e089b06502a1c1a56613ab169a4a379724 Binary files /dev/null and b/icons/dark-greensolo.png differ diff --git a/icons/dark-lemonfoo.png b/icons/dark-lemonfoo.png new file mode 100644 index 0000000000000000000000000000000000000000..c7f72d8fc6fd55136b35c5e2718c6668aca0e563 Binary files /dev/null and b/icons/dark-lemonfoo.png differ diff --git a/icons/dark-orangefoo.png b/icons/dark-orangefoo.png new file mode 100644 index 0000000000000000000000000000000000000000..134fdc934ea8ac6b62019eb4f1ed89fecdb748f8 Binary files /dev/null and b/icons/dark-orangefoo.png differ diff --git a/icons/dark-pasito.png b/icons/dark-pasito.png new file mode 100644 index 0000000000000000000000000000000000000000..0efbeca9f99b16f8327ae8477e9e8a37ee2c1c9e Binary files /dev/null and b/icons/dark-pasito.png differ diff --git a/icons/dark-randomdrink.gif b/icons/dark-randomdrink.gif new file mode 100644 index 0000000000000000000000000000000000000000..672dec4fcf49d80d2a40002036664e511474af4f Binary files /dev/null and b/icons/dark-randomdrink.gif differ diff --git a/icons/dark-redcreamingsoda.png b/icons/dark-redcreamingsoda.png new file mode 100644 index 0000000000000000000000000000000000000000..40b862ffbef3b3c13ae969987d5f2920df55ffac Binary files /dev/null and b/icons/dark-redcreamingsoda.png differ diff --git a/icons/dark-sprite.png b/icons/dark-sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..efed205f6790036d237389ad0c25bf10b97b1b11 Binary files /dev/null and b/icons/dark-sprite.png differ diff --git a/icons/dark-vanillacoke.png b/icons/dark-vanillacoke.png new file mode 100644 index 0000000000000000000000000000000000000000..a94411da6c41267c88ca5b9ed5cb20bd79d6c813 Binary files /dev/null and b/icons/dark-vanillacoke.png differ diff --git a/icons/dark-vblack.png b/icons/dark-vblack.png new file mode 100644 index 0000000000000000000000000000000000000000..b428c2a4f0feba33cf0a82fefd8c03d034bf3a72 Binary files /dev/null and b/icons/dark-vblack.png differ diff --git a/icons/dark-vgreen.png b/icons/dark-vgreen.png new file mode 100644 index 0000000000000000000000000000000000000000..c0c0a00c2d50dca4265560c456ce418a6c9fdda3 Binary files /dev/null and b/icons/dark-vgreen.png differ diff --git a/icons/default.png b/icons/default.png new file mode 100644 index 0000000000000000000000000000000000000000..10c7d114c5e055453b5eb3abe23c44f83856f534 Binary files /dev/null and b/icons/default.png differ diff --git a/icons/default.png.white b/icons/default.png.white new file mode 100644 index 0000000000000000000000000000000000000000..031eca9c77b91d71def6edb7e8a0563888a45e1b Binary files /dev/null and b/icons/default.png.white differ diff --git a/icons/dietcoke.png b/icons/dietcoke.png new file mode 100644 index 0000000000000000000000000000000000000000..2638c6bf2599d2cdc6bf8de1f0fecb38cbb1915d Binary files /dev/null and b/icons/dietcoke.png differ diff --git a/icons/gingerbeer.png b/icons/gingerbeer.png new file mode 100644 index 0000000000000000000000000000000000000000..15c7f6ca93d13b3004016dd29e9ae7d1450f7e8d Binary files /dev/null and b/icons/gingerbeer.png differ diff --git a/icons/greensolo.png b/icons/greensolo.png new file mode 100644 index 0000000000000000000000000000000000000000..678e8a307cadf7862d86c85b7bfe498d89cfb4dd Binary files /dev/null and b/icons/greensolo.png differ diff --git a/icons/lemonfoo.png b/icons/lemonfoo.png new file mode 100644 index 0000000000000000000000000000000000000000..9a8d7e5dd116ff47493852515dc628da304c3a73 Binary files /dev/null and b/icons/lemonfoo.png differ diff --git a/icons/orangefoo.png b/icons/orangefoo.png new file mode 100644 index 0000000000000000000000000000000000000000..639ebd6923349f07ce0f1002fa8b96ced5dcbb59 Binary files /dev/null and b/icons/orangefoo.png differ diff --git a/icons/pasito.png b/icons/pasito.png new file mode 100644 index 0000000000000000000000000000000000000000..11efa5e90aa8f27989bd68990fa16a4fc4f14935 Binary files /dev/null and b/icons/pasito.png differ diff --git a/icons/randomdrink.gif b/icons/randomdrink.gif new file mode 100644 index 0000000000000000000000000000000000000000..e9837248966af4367445fd1c4efc9f48974da380 Binary files /dev/null and b/icons/randomdrink.gif differ diff --git a/icons/redcreamingsoda.png b/icons/redcreamingsoda.png new file mode 100644 index 0000000000000000000000000000000000000000..975cab49c25553f8818cf80c1d6ca4d124877f19 Binary files /dev/null and b/icons/redcreamingsoda.png differ diff --git a/icons/sprite.png b/icons/sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..4c0648b0aab8b0333732b82c9f7f5e5fe63f343c Binary files /dev/null and b/icons/sprite.png differ diff --git a/icons/vanillacoke.png b/icons/vanillacoke.png new file mode 100644 index 0000000000000000000000000000000000000000..7567b55afb3ca171ce6e6b988e0e6704e3f1d772 Binary files /dev/null and b/icons/vanillacoke.png differ diff --git a/icons/vblack.png b/icons/vblack.png new file mode 100644 index 0000000000000000000000000000000000000000..9100cf3cb9c61a1142f195ee45a9893965c03314 Binary files /dev/null and b/icons/vblack.png differ diff --git a/icons/vgreen.png b/icons/vgreen.png new file mode 100644 index 0000000000000000000000000000000000000000..01ddf0bc06232ded738f3cf04c42ff0b07025ba2 Binary files /dev/null and b/icons/vgreen.png differ diff --git a/icons/white50alpha.png b/icons/white50alpha.png new file mode 100644 index 0000000000000000000000000000000000000000..e8e6bc4e3b20bf2f6808d0b9a49625c6ae29045f Binary files /dev/null and b/icons/white50alpha.png differ diff --git a/index.html b/index.html index 9c5304e1af76040f4c884770eb5f60e1eb4209de..201bc857668f3f05d1624c64b4797ea0353f7faa 100644 --- a/index.html +++ b/index.html @@ -3,109 +3,174 @@ <head> <title>Dispense @ UCC</title> <link rel="stylesheet" type="text/css" href="dispense.css" /> +<link rel="apple-touch-icon" href="/dispense/apple-touch-icon.png" /> <meta name="viewport" content="initial-scale = 1.0, user-scalable = no, width=device-width"> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-status-bar-style" content="hidden" /> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> -drink_icons = { "Sunkist" : "sunkist.png", - "lemony fizz" : "lemonade.png", +drink_icons = { "coke" : "coke.png", + "fanta" : "fanta.png", + "diet coke" : "dietcoke.png", + "diet_coke" : "dietcoke.png", + "green solo" : "greensolo.png", + "green_solo" : "greensolo.png", + "ginger beer" : "gingerbeer.png", + "ginger_beer" : "gingerbeer.png", "han solo" : "solo.png", + "kolebeer" : "kolebeer.png", + "lemonade" : "lemonade.png", + "lemon foo" : "lemonfoo.png", + "lemon_foo" : "lemonfoo.png", + "lemon lime solo" : "greensolo.png", "lemony aide" : "lemonade.png", - "coke" : "coke.png", + "lemony fizz" : "lemonade.png", + "lift" : "lemonfoo.png", + "mountain dew" : "mountaindew.png", + "mountain_dew" : "mountaindew.png", + "null coke" : "cokezero.png", + "null_coke" : "cokezero.png", + "orange foo" : "orangefoo.png", + "orange_foo" : "orangefoo.png", + "pasito" : "pasito.png", + "pepsi" : "pepsi.png", "pepsi max" : "pepsimax.png", - "null coke" : "cokezero.png" + "red creaming sod" : "redcreamingsoda.png", + "red creaming soda" : "redcreamingsoda.png", + "red_creaming_sod" : "redcreamingsoda.png", + "random" : "randomdrink.gif", + "random 200ml" : "randomdrink.gif", + "solo" : "solo.png", + "sprite" : "sprite.png", + "sunkist" : "sunkist.png", + "Sunkist" : "sunkist.png", + "vanilla coke" : "vanillacoke.png", + "vanilla_coke" : "vanillacoke.png", + "v black" : "vblack.png", + "v green" : "vgreen.png" }; + function dispense (slot) { - $("#slot" + slot).css ("background", "no-repeat url('loading.gif') center center"); - $.getJSON ("dispense.py?slot=" + slot, {}, function (data) { - result = data["result"]; + function DispenseResult (data) { + var result = data["result"]; if (result != "success") { alert ("Error: " + result); } else { alert ("Dispense successful!"); } updateStatus (); - }); + } + $("#slot" + slot).css ("background", "no-repeat url('loading.gif') center center"); + $.post ("dispense.py", { "username" : escape (username) , "sid" : escape (sid) , "slot" : slot }, DispenseResult, 'json'); } -// Loads machine status, then displays it. -function updateStatus () { - $.getJSON ("query.py", {}, function (data) { - $.getJSON ("balance.py", {}, function (baldata) { - result = baldata["result"]; +function opendoor() { + function DoorResult (data) { + var result = data["result"]; if (result != "success") { alert ("Error: " + result); - $('#login').css ("background", "no-repeat url('login.png')"); - return; + } else { + alert ("Door open!"); } - window.balance = baldata["balance"]; - showScreen ("main_menu"); - $("#lcdusername").text (window.username); - $("#lcdbalance").text (window.balance); - for (i=0;i<=6;i++) { - drink = data["slot" + i][0]; - available = ""; - if (!data["slot" + i][2]) available = "dark-"; - if (drink in drink_icons) icon = available + drink_icons[drink]; - else icon = available + "default.png"; - $("#slot" + i).html (data["slot" + i][1] + "c"); - $("#slot" + i).css ("background", "no-repeat url('icons/" + icon + "') center center"); + updateStatus (); + } + $.post ("door.py", { "username" : escape (username) , "sid" : escape (sid) }, DoorResult, 'json'); +} + +// Loads machine status, then displays it. +function updateStatus () { + function GotDrinks (data) { + function GotBalance (baldata) { + var result = baldata["result"]; + if (result != "success") { + alert ("Error: " + result); + $('#login').css ("background", "no-repeat url('login.png')"); + logout(); + return; + } + window.balance = baldata["balance"]; + showScreen ("main_menu"); + $("#lcdusername").text (window.username); + $("#lcdbalance").text (window.balance); + for (i=0;i<=6;i++) { + var drink = data["slot" + i][0].toLowerCase(); + var available = ""; + if (drink in drink_icons) { + var strSize = (drink.indexOf("200ml") == -1)?"":"200mL " + if (data["slot" + i][2] == "true") { + $("#slot" + i).html ("<FONT style=\"BACKGROUND-COLOR: rgba(0, 0, 0, 0.5)\">" + strSize + data["slot" + i][1] + "c </FONT>"); + } else { + available = "dark-"; + $("#slot" + i).html ("<FONT style=\"BACKGROUND-COLOR: rgba(0, 0, 0, 0.5)\">SLD " + strSize + data["slot" + i][1] + "c </FONT>"); + } + icon = available + drink_icons[drink]; + } else { + if (data["slot" + i][2] == "true") { + $("#slot" + i).html (drink + ": " + data["slot" + i][1] + "c"); + } else { + $("#slot" + i).html ("SLD " + drink + ": " + data["slot" + i][1] + "c"); + } + icon = "default.png"; + } + //$("#slot" + i).html (data["slot" + i][1] + "c"); + $("#slot" + i).css ("background", "no-repeat url('icons/" + icon + "') center center"); + } + $('#login').css ("background", "no-repeat url('login.png')"); } - $('#login').css ("background", "no-repeat url('login.png')"); - }); - }); + $.post ("balance.py", { "username" : escape (username) , "sid" : escape (sid) }, GotBalance, 'json'); + } + $.getJSON ("query.py", {}, GotDrinks); } function load () { - window.username = getCookie ("username"); - window.pin = getCookie ("pin"); - $('#username').val (window.username); - $('#pin').val (window.pin); + $('#username').val (""); + $('#passwd').val (""); window.current_screen = "login_screen"; - if (window.username != "" && window.pin != ""){ - $('#login').css ("background", "no-repeat url('loading.gif') center center"); - updateStatus (); - } } + function login () { $('#login').css ("background", "no-repeat url('loading.gif') center center"); window.username = $("#username").val (); - window.pin = $("#pin").val (); - document.cookie = "username=" + escape (username) + ";"; - document.cookie = "pin=" + escape (pin) + ";"; - updateStatus (); + function LoginResult (data) { + if (data["result"] != "success") { + alert ("Login Error: " + data["result"]); + } else { + window.sid = data["sid"]; + updateStatus (); + } + } + $.post ("login.py", { "username" : escape (username) , "passwd" : $('#passwd').val () }, LoginResult, 'json'); + $('#passwd').val (""); + $('#login').css ("background", "no-repeat url('login.png')"); } + function logout () { - document.cookie = "username="; - document.cookie = "pin="; + function LogoutResult (data) { + if (data["result"] != "success") { + alert ("Error: " + data["result"]); + } + } + $.post ("logout.py", { "username" : escape (username) , "sid" : escape (sid) }, LogoutResult, 'json'); + window.sid = ""; + $('#username').val (window.username); + $('#passwd').val (""); showScreen ("login_screen"); } + function showScreen (name) { $("#" + window.current_screen).css ("display","none"); $("#" + name).css ("display", "block"); window.current_screen = name; } -function getCookie(c_name) { - if (document.cookie.length>0) { - c_start=document.cookie.indexOf(c_name + "="); - if (c_start!=-1) { - c_start=c_start + c_name.length+1; - c_end=document.cookie.indexOf(";",c_start); - if (c_end==-1) c_end=document.cookie.length; - return unescape(document.cookie.substring(c_start,c_end)); - } - } - return ""; -} + </script> </head> <body onload="load();"> <div class="screen" id="login_screen"> UCC Account Name:<br /> -<input type="text" id="username" /><br /> -Dispense PIN:<br /> -<input type="password" id="pin" /> +<input type="text" name="username" id="username" onkeypress="{if (event.keyCode==13)login()}"/><br /> +Password:<br /> +<input type="password" name="passwd" id="passwd" onkeypress="{if (event.keyCode==13)login()}"/> <div id="login" onclick="login();"></div> </div> <div class="screen" id="main_menu"> @@ -122,3 +187,4 @@ Dispense PIN:<br /> </div> </body> </html> + diff --git a/login.py b/login.py new file mode 100755 index 0000000000000000000000000000000000000000..830f41d4ec37f4d337b53e647374e8850fed933b --- /dev/null +++ b/login.py @@ -0,0 +1,54 @@ +#!/usr/bin/python + +import commands,re + +print "Content-type: text/json" +print +import cgi,cgitb +cgitb.enable () +import os +import ldap +import string, random +import sys, time, syslog + +#import getpass + +result = {} +form = cgi.FieldStorage () + +def sid_generator(size=64, chars=string.ascii_uppercase + string.ascii_lowercase + string.digits): + return ''.join(random.choice(chars) for c in range(size)) + +def checkdata (): + expr_name = re.compile ("^\w*$") + username = form["username"].value.lower() + if (not expr_name.match (username)): + return {"result" : "Invalid login!"} + passwd = form["passwd"].value + #dn = "uid=%s,ou=People,dc=ucc,dc=gu,dc=uwa,dc=edu,dc=au" % username + dn = "cn=%s,cn=Users,dc=ad,dc=ucc,dc=gu,dc=uwa,dc=edu,dc=au" % username + try: + ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT,ldap.OPT_X_TLS_NEVER) + l = ldap.initialize("ldaps://ad.ucc.gu.uwa.edu.au") + l.simple_bind_s(dn, passwd) + except: + log = "Authentication failure for user " + username + " from " + cgi.escape(os.environ["REMOTE_ADDR"]) + "\n" + syslog.syslog((syslog.LOG_NOTICE | syslog.LOG_AUTH), log) + #logfile = open("auth.log", "a") + #logfile.write(log) + #logfile.close() + return {"result" : "Authentication Failed"} + file = open("sessionids", "r") + output = [] + for line in file: + if not (":" + username + ":") in line: + output.append(line) + file.close() + sid = sid_generator() + output.append(str(int(time.time())) + ":" + username + ":" + sid + "\n") + file = open("sessionids", "w") + file.writelines(output) + file.close() + return {"result" : "success", "sid" : str(sid)} + +print str(checkdata ()) diff --git a/logout.py b/logout.py new file mode 100755 index 0000000000000000000000000000000000000000..62c1da1b288912c7a8ee68fad3e8ede406f4c393 --- /dev/null +++ b/logout.py @@ -0,0 +1,47 @@ +#!/usr/bin/python + +import commands,re + +print "Content-type: text/json" +print +import cgi,cgitb +cgitb.enable () +import os +import ldap +import sys + +#import getpass + +result = {} +form = cgi.FieldStorage () + +def checkdata (): + if not (form.has_key("username") and form.has_key("sid")): + return {"result" : "Missing information!"} + expr_name = re.compile ("^\w*$") + username = form["username"].value.lower () + sid = form["sid"].value + if (not expr_name.match (username)): + return {"result" : "Invalid login!"} + file = open("sessionids", "r") + output = [] + success = False + for line in file: + if (":" + username + ":" + sid + "\n") in line: + success = True + else: + output.append(line) + file.close() + if not success: + log = "Authentication failure for user " + username + " from " + cgi.escape(os.environ["REMOTE_ADDR"]) + "\n" + syslog.syslog((syslog.LOG_NOTICE | syslog.LOG_AUTH), log) + #logfile = open("auth.log", "a") + #logfile.write(log) + #logfile.close() + return {"result" : "Authentication Failed"} + file = open("sessionids", "w") + file.writelines(output) + file.close() + return {"result" : "success"} + +print str(checkdata ()) diff --git a/purge.py b/purge.py new file mode 100755 index 0000000000000000000000000000000000000000..d1e13010260f16334bc187a805377e09b534fe37 --- /dev/null +++ b/purge.py @@ -0,0 +1,15 @@ +#!/usr/bin/python + +import sys, time + +ts = int(time.time()) - 1200 +file = open("sessionids", "r") +output = [] +for line in file: + fields = line.split(':') + if int(fields[0]) > ts: + output.append(line) +file.close() +file = open("sessionids", "w") +file.writelines(output) +file.close() diff --git a/query.py b/query.py index f8ddb3a40cc1817502623ad916dcae1d1bdc3915..305515db1e867f562dc0ea4e63d4d44dbcd0a259 100755 --- a/query.py +++ b/query.py @@ -1,6 +1,5 @@ #!/usr/bin/python -import re -import urllib +import commands,re import cgi, cgitb cgitb.enable () @@ -8,16 +7,16 @@ cgitb.enable () print "Content-type: text/json" print -site = urllib.urlopen("http://ucc.asn.au/cgi-bin/dispense?html.menu") -lines = site.readlines ()[15:22] +output = commands.getoutput("dispense finger") +lines = output.split("\n")[2:9] - -expr = re.compile ("<STRONG>(?P<price>\d*)c</STRONG>\s*(<A[^>]*>|)(?P<name>[^<]*)(</A\>|)[^>]*>(?P<available>[^<]*)") +expr = re.compile("^(\d) - (\w+) +(\d+) (.*)") drinks = {} for i, line in enumerate (lines): +# print line r = expr.search (line).groups () available = "true" - if r[4] == "empty": available = "false" - drinks["slot" + str(i)] = [r[2].rstrip(), r[0], available] + if r[1] != "Avail": available = "false" + drinks["slot" + str(i)] = [r[3].rstrip(), r[2], available] print str (drinks)