diff options
-rw-r--r-- | tools/mmd/MmdCommands.py | 54 | ||||
-rw-r--r-- | tools/mmd/MmdDb.py | 27 | ||||
-rw-r--r-- | tools/mmd/MmdSession.py | 17 | ||||
-rw-r--r-- | tools/mmd/MmdUser.py | 40 | ||||
-rw-r--r-- | tools/mmd/MmdWidgets.py | 54 | ||||
-rw-r--r-- | tools/mmd/mmd.css | 12 | ||||
-rw-r--r-- | tools/mmd/mmd.wsgi | 6 |
7 files changed, 178 insertions, 32 deletions
diff --git a/tools/mmd/MmdCommands.py b/tools/mmd/MmdCommands.py index 0ac98da..d33190b 100644 --- a/tools/mmd/MmdCommands.py +++ b/tools/mmd/MmdCommands.py @@ -10,7 +10,7 @@ def loginForm (session): """ display the login form """ - return indexWidget (dataWidget (), loginFormWidget (), statusWidget (session.session_id, session.email)) + return indexWidget (dataWidget (), loginFormWidget (), statusWidget (session)) def login (session): """ @@ -19,13 +19,13 @@ def login (session): email = escape (session.qs.get ('email', [''])[0]) # check for account # verify password - return indexWidget (dataWidget (), loginWidget (email), statusWidget (session.session_id, email)) + return indexWidget (dataWidget (), loginWidget (email), statusWidget (session)) def registerForm (session): """ display the register form """ - return indexWidget (dataWidget (), registerFormWidget (), statusWidget (session.session_id, session.email)) + return indexWidget (dataWidget (), registerFormWidget (), statusWidget (session)) def register (session): """ @@ -42,10 +42,10 @@ def register (session): if password != confirm: error_message = {'error': 'Password', 'description': 'Passwords do not match.'} - return indexWidget (dataWidget (), errorWidget (error_message), statusWidget (session.session_id, session.email)) + return indexWidget (dataWidget (), errorWidget (error_message), statusWidget (session)) user = User () - confreg = user.create (session.session_id, firstname, lastname, email, callsign, longitude, latitude, password) + code = user.create (session.session_id, firstname, lastname, email, callsign, longitude, latitude, password) user.email = email message = '''From: noreply <noreply@mur.at> To: {0} @@ -58,41 +58,69 @@ Someone (probably you) has registered at the MURSAT1 Mission Dashbaord using the link below: - http://hofos.at/mmd/mmd?cmd=confirmRegistration&code={1} + http://hofos.at/mmd/?cmd=completeRegistration&code={1} Regards, MURSAT1 team -'''.format (user.email, confreg) +'''.format (user.email, code) if not user.sendEmail (message): error_message = {'error': 'Email', 'description': 'Email could not be sent.'} - return indexWidget (dataWidget (), errorWidget (error_message), statusWidget (session.session_id, session.email)) + return indexWidget (dataWidget (), errorWidget (error_message), statusWidget (session)) - return indexWidget (dataWidget (), registerWidget (), statusWidget (session.session_id, session.email)) + return indexWidget (dataWidget (), registerWidget (), statusWidget (session)) + +def completeRegistration (session): + user = User () + code = session.getQsCode () + if not user.findPending (code): + error_message = {'error': 'Registration', 'description': 'Registration Failed.'} + return indexWidget (dataWidget (), errorWidget (error_message), statusWidget (session)) + return indexWidget (dataWidget (), completeRegistrationWidget (code), statusWidget (session)) + +# TODO finish theses methods +def confirmRegistration (session): + user = User () + code = session.getQsCode () + if not user.findPending (code): + error_message = {'error': 'Registration', 'description': 'Registration Failed.'} + return indexWidget (dataWidget (), errorWidget (error_message), statusWidget (session)) + user.confirm (code) + session.authenticate (user) + return indexWidget (dataWidget (), confirmRegistrationWidget (user), statusWidget (session)) + +def cancelRegistration (session): + user = User () + code = session.getQsCode () + if not user.findPending (code): + error_message = {'error': 'Registration', 'description': 'Canceling failed.'} + return indexWidget (dataWidget (), errorWidget (error_message), statusWidget (session)) + user.cancel (code) + return indexWidget (dataWidget (), cancelRegistrationWidget (), statusWidget (session)) def submitForm (session): """ display the form for data submission """ - return indexWidget (dataWidget (), submitFormWidget (), statusWidget (session.session_id, session.email)) + return indexWidget (dataWidget (), submitFormWidget (), statusWidget (session)) def submit (session): """ evaluate data from submitForm """ - return indexWidget (dataWidget (), submitWidget (), statusWidget (session.session_id, session.email)) + return indexWidget (dataWidget (), submitWidget (), statusWidget (session)) def viewlog (session): """ show latest log entries/submissions """ - return indexWidget (dataWidget (), logWidget (), statusWidget (session.session_id, session.email)) + return indexWidget (dataWidget (), logWidget (), statusWidget (session)) def index (session): """ display the index page """ - return indexWidget (dataWidget (), osmWidget (), statusWidget (session.session_id, session.email)) + return indexWidget (dataWidget (), osmWidget (), statusWidget (session)) def mmdtest (env, cookie): body = '' diff --git a/tools/mmd/MmdDb.py b/tools/mmd/MmdDb.py index 1065bb6..cba395d 100644 --- a/tools/mmd/MmdDb.py +++ b/tools/mmd/MmdDb.py @@ -10,6 +10,7 @@ class Db: def __init__ (self): self.conn = sqlite3.connect ('/usr/local/mmd/db/mmd.db') self.conn.text_factory = str + self.conn.row_factory = sqlite3.Row self.cursor = self.conn.cursor () def sessionFind (self, session_id): @@ -44,9 +45,17 @@ class Db: # # user related methods # - def userCreate (self, user_id, firstname, lastname, email, callsign, password, confreg): - self.cursor.execute ('INSERT INTO user (id, firstname, lastname, email, callsign, password, confreg) VALUES (?,?,?,?,?,?,?)', - (user_id, firstname, lastname, email, callsign, password, confreg)) + def userCreate (self, user_id, firstname, lastname, email, callsign, password, code, regtimeout): + self.cursor.execute ('INSERT INTO user (id, firstname, lastname, email, callsign, password, code, regtimeout) VALUES (?,?,?,?,?,?,?,?)', + (user_id, firstname, lastname, email, callsign, password, code, regtimeout)) + self.conn.commit () + + def userConfirm (self, code): + self.cursor.execute ('UPDATE user SET status="valid" WHERE code=?', (code, )) + self.conn.commit () + + def userCancel (self, code): + self.cursor.execute ('DELETE FROM user WHERE code=?', (code, )) self.conn.commit () def userDelete (self, user_id): @@ -57,6 +66,14 @@ class Db: self.cursor.execute ('SELECT * FROM user WHERE id=?', (user_id,)) return self.cursor.fetchone () + def userFindEmail (self, email): + self.cursor.execute ('SELECT * FROM user WHERE email=?', (email,)) + return self.cursor.fetchone () + + def userFindPending (self, code): + self.cursor.execute ('SELECT * FROM user WHERE code=? and status="pending"', (code,)) + return self.cursor.fetchone () + def close (self): self.cursor.close () self.conn.close () @@ -66,11 +83,11 @@ if __name__ == "__main__": print db.sessionFind ('1234567890') db.sessionInit ('1234567890', 'jogi@mur.at', '1') data = db.sessionFind ('1234567890') - print data[0], data[1] + print data['id'], data['email'] db.sessionDelete ('1234567890') print db.sessionFind ('1234567890') print db.userFindId ('1') - db.userCreate ('1', 'Jogi', 'Hofmüller', 'jogi@mur.at', '', '', '') + db.userCreate ('1', 'Jogi', 'Hofmüller', 'jogi@mur.at', '', '', '', '') print db.userFindId ('1') db.userDelete ('1') diff --git a/tools/mmd/MmdSession.py b/tools/mmd/MmdSession.py index ff92684..2dda34e 100644 --- a/tools/mmd/MmdSession.py +++ b/tools/mmd/MmdSession.py @@ -16,12 +16,12 @@ class Session: self.status = 'anon' self.headers = [] self.db = Db () - data = self.db.sessionFind (session_id) - if not data: + s = self.db.sessionFind (session_id) + if not s: self.db.sessionInit (self.session_id, self.email, int (time.strftime ('%s')) + timeout) else: - self.email = data[1] - self.status = data[2] + self.email = s['email'] + self.status = s['status'] def addHeader (self, header): self.headers.append (header) @@ -37,11 +37,15 @@ class Session: self.status = status self.db.sessionSetStatus (self.session_id, self.status) + def authenticate (self, user): + self.setEmail (user.email) + self.setStatus ('auth') + def valid (self): data = self.db.sessionFind (self.session_id) if not data: return False - if data[3] < int (time.strftime ('%s')): + if data['expires'] < int (time.strftime ('%s')): return False return True @@ -76,6 +80,9 @@ class Session: def getQsConfirm (self): return self.getField ('confirm') + def getQsCode (self): + return self.getField ('code') + def getField (self, field): try: return escape (self.qs.get (field)[0]) diff --git a/tools/mmd/MmdUser.py b/tools/mmd/MmdUser.py index 1521fae..c7d0ee0 100644 --- a/tools/mmd/MmdUser.py +++ b/tools/mmd/MmdUser.py @@ -3,6 +3,7 @@ User class for MURSAT1 Mission Dashboard """ import hashlib import smtplib +import time from cgi import parse_qs, escape from MmdDb import Db @@ -13,9 +14,42 @@ class User: def create (self, user_id, firstname, lastname, email, callsign, longitude, latitude, password): password_hash = hashlib.sha1 (password).hexdigest () - confreg = hashlib.sha1 ('{0}{1}{2}{3}'.format (user_id, firstname, lastname, email)).hexdigest () - self.db.userCreate (user_id, firstname, lastname, email, callsign, password_hash, confreg) - return confreg + code = hashlib.sha1 ('{0}{1}{2}{3}'.format (user_id, firstname, lastname, email)).hexdigest () + regtimeout = int (time.strftime ('%s')) + (3600 * 24) + self.db.userCreate (user_id, firstname, lastname, email, callsign, password_hash, code, regtimeout) + return code + + def findPending (self, code): + u = self.db.userFindPending (code) + if not u: + return False + if int (u['regtimeout']) < int (time.strftime ('%s')): + return False + return True + + def confirm (self, code): + u = self.db.userFindPending (code) + if not u: + return False + if int (u['regtimeout']) < int (time.strftime ('%s')): + return False + self.db.userConfirm (code) + self.email = u['email'] + self.firstname = u['firstname'] + self.lastname = u['lastname'] + return True + + def load (self, email): + u = self.db.userFindEmail (email) + if not u: + return False + self.email = email + self.firstname = u['firstname'] + self.lastname = u['lastname'] + # include loading of location data here + + def cancel (self, code): + self.db.userCancel (code) def sendEmail (self, message): server = smtplib.SMTP ('localhost') diff --git a/tools/mmd/MmdWidgets.py b/tools/mmd/MmdWidgets.py index 252b6f8..1c83ac5 100644 --- a/tools/mmd/MmdWidgets.py +++ b/tools/mmd/MmdWidgets.py @@ -54,7 +54,46 @@ def registerFormWidget (): def registerWidget (): html = ''' <h3>Thank you for registering!</h3> - You will receive an email conataining a link to confirm your registration. Please use this link within 24 hours to complete registration. + You will receive an email containing a link to confirm your registration. Please use this link within 24 hours to complete registration. + ''' + + return html + +def completeRegistrationWidget (code): + html = ''' + <h3>Completing registration!</h3> + <div> + By clicking <a href="?cmd=confirmRegistration&code={0}">confirm</a> you confirm you registration to the MURSAT1 Mission Dashboard. If you received an email that brought you here but never registered, you might want to <a href="?cmd=cancelRegistration&code={0}">cancel</a> the registration or simply do nothing since a registration code is only valid vor 24 hrs. + </div> + <div> + Greetings from the MURSAT1 Team! + </div> + '''.format (code) + + return html + +def confirmRegistrationWidget (user): + html = ''' + <h3>Dear {0} {1}!</h3> + <div> + Thank you for participating in this project by registerting here! We are looking forward to receiving your reports from MURSAT1. + </div> + <div> + Sessions here stay valid for 24 hours after your last click. If your session expires, just use your email and password to logon again using this link: <a href="http://hofos.at/mmd/?cmd=login">http://hofos.at/mmd/?cmd=login</a>. + </div> + '''.format (user.firstname, user.lastname) + + return html + +def cancelRegistrationWidget (): + html = ''' + <h3>We are sorry!</h3> + <div> + Your registration has been canceled and all the data has been deleted from our records. + </div> + <div> + Regards from the MURSAT1 team + </div> ''' return html @@ -114,16 +153,20 @@ def osmWidget (longitude = 15.4426, latitude = 47.06576): return html -def statusWidget (ip, email): +def statusWidget (session): + if session.status == 'auth': + inout = '''<span id="logout"><a href="?cmd=logout">logout</a></span>''' + else: + inout = '''<span id="login"><a href="?cmd=loginForm">login</a></span>''' html = ''' - <a href=""> + <a href="/mmd/"> <img src="http://sat.mur.at/pics/sat-logo-notext.png" alt="mur.sat logo" /> </a> MURSAT1 Mission Dashboard <div id="info"> - Hello {0} with session id '{1}'! Local time is {2} + Hello {0} with session id '{1}'! Local time is {2}. {3} </div> - '''.format (email, ip, time.strftime ('%c')) + '''.format (session.email, session.session_id, time.strftime ('%c'), inout) return html @@ -165,7 +208,6 @@ def dataWidget (longitude = 15.44226, latitude = 47.06576): <div>Latitude: {1}</div> <hr /> <div><a href="?cmd=submitForm">Submit</a> a report</div> - <div><a href="?cmd=loginForm">Login</a> to your personal account</div> <div>View <a href="?cmd=viewlog">Log</a> of reports</div> <hr /> <div>Checkout the <a href="http://sat.mur.at/">project page</a>!</div> diff --git a/tools/mmd/mmd.css b/tools/mmd/mmd.css index e2847ba..8a58ec3 100644 --- a/tools/mmd/mmd.css +++ b/tools/mmd/mmd.css @@ -4,6 +4,18 @@ html, body background-color: #003366; } +#login a +{ + color: green; + margin-left: 32px; +} + +#logout a +{ + color: red; + margin-left: 32px; +} + #status img { border: 0; diff --git a/tools/mmd/mmd.wsgi b/tools/mmd/mmd.wsgi index 4c0d3ee..4227f7c 100644 --- a/tools/mmd/mmd.wsgi +++ b/tools/mmd/mmd.wsgi @@ -62,6 +62,12 @@ def application (environ, response): body = submit (session) elif cmd == 'viewlog': body = viewlog (session) + elif cmd == 'confirmRegistration': + body = confirmRegistration (session) + elif cmd == 'completeRegistration': + body = completeRegistration (session) + elif cmd == 'cancelRegistration': + body = cancelRegistration (session) elif cmd == 'mmdtest': body = mmdtest (environ, cookie) content_type = 'text/plain' |