From d6e5bde11d06c846035d1670b4800cf574d2420d Mon Sep 17 00:00:00 2001 From: Jogi Hofmüller Date: Mon, 1 Aug 2011 17:16:59 +0000 Subject: - finished registration procedure - user can sign up now - registration needs confirmation (email sent) - registration can also be canceled git-svn-id: https://svn.spreadspace.org/mur.sat@88 7de4ea59-55d0-425e-a1af-a3118ea81d4c --- tools/mmd/MmdCommands.py | 54 ++++++++++++++++++++++++++++++++++++------------ tools/mmd/MmdDb.py | 27 +++++++++++++++++++----- tools/mmd/MmdSession.py | 17 ++++++++++----- tools/mmd/MmdUser.py | 40 ++++++++++++++++++++++++++++++++--- tools/mmd/MmdWidgets.py | 54 ++++++++++++++++++++++++++++++++++++++++++------ tools/mmd/mmd.css | 12 +++++++++++ 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 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 = '''

Thank you for registering!

- 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 = ''' +

Completing registration!

+
+ By clicking confirm 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 cancel the registration or simply do nothing since a registration code is only valid vor 24 hrs. +
+
+ Greetings from the MURSAT1 Team! +
+ '''.format (code) + + return html + +def confirmRegistrationWidget (user): + html = ''' +

Dear {0} {1}!

+
+ Thank you for participating in this project by registerting here! We are looking forward to receiving your reports from MURSAT1. +
+
+ 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: http://hofos.at/mmd/?cmd=login. +
+ '''.format (user.firstname, user.lastname) + + return html + +def cancelRegistrationWidget (): + html = ''' +

We are sorry!

+
+ Your registration has been canceled and all the data has been deleted from our records. +
+
+ Regards from the MURSAT1 team +
''' 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 = '''logout''' + else: + inout = '''login''' html = ''' - + mur.sat logo MURSAT1 Mission Dashboard
- Hello {0} with session id '{1}'! Local time is {2} + Hello {0} with session id '{1}'! Local time is {2}. {3}
- '''.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):
Latitude: {1}

Submit a report
-
Login to your personal account
View Log of reports

Checkout the project page!
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' -- cgit v1.2.3