Permalink
Browse files

Bug 10: Added a login (mostly code copied from pencilbox). If you're …

…logged in when creating a level then the level will be owned by you; you can only edit levels you own.
  • Loading branch information...
1 parent e6be4ad commit 05cd93cafdaf9b49f77750139d6ce23dbe540f5f @jonoxia committed Oct 25, 2011
Showing with 143 additions and 17 deletions.
  1. +14 −0 index.html
  2. +18 −7 listlevels.py
  3. +31 −0 login.js
  4. +65 −0 login.py
  5. +4 −5 newlevel.py
  6. +3 −1 platformer_config.py.template
  7. BIN sign_in_green.png
  8. +4 −1 templates/list-level-row.html
  9. +2 −1 templates/list-levels.html
  10. +2 −2 webserver_utils.py
View
@@ -0,0 +1,14 @@
+<html>
+<head>
+<title>Webrunner</title>
+<script src="https://browserid.org/include.js" type="text/javascript"></script>
+<script src="jquery.js" type="text/javascript"></script>
+<script src="login.js" type="text/javascript"></script>
+</head>
+<body>
+<h1>Webrunner</h1>
+<p><img src="sign_in_green.png" onclick="doBrowserIdLogin();"/></p>
+<p id="debug"></p>
+<img src="running_human_frames.png"/>
+</body>
+</html>
View
@@ -6,32 +6,43 @@
import cgitb
from database_tables import Level, LevelObject
-from webserver_utils import render_template_file
+from webserver_utils import render_template_file, verify_id
-def printList():
+def printList(player):
print "Content-type: text/html"
print
matches = Level.select(orderBy = "-modified")
work_list = ""
for match in matches:
title = match.name
- url = "webrunner.html?level=%s" % title
date = match.modified
+ edit_link = ""
+ if match.creator != None:
+ if match.creator == player:
+ creator = "You"
+ edit_link = "<a href=\"designer.html?level=%s\">Edit</a>" % title
+ else:
+ creator = match.creator.name
+ else:
+ creator = "Nobody"
work_list += render_template_file( "list-level-row.html",
{"moddate": date,
- "title": title} )
+ "title": title,
+ "creator": creator,
+ "editlink": edit_link} )
- print render_template_file( "list-levels.html", {"work_list": work_list})
+ print render_template_file( "list-levels.html", {"work_list": work_list,
+ "player": player.name})
if __name__ == "__main__":
cgitb.enable()
q = cgi.FieldStorage()
- # artist = verify_id()
+ player = verify_id()
# action = q.getfirst("action", "")
# title = q.getfirst("title", "")
- printList()
+ printList(player)
View
@@ -0,0 +1,31 @@
+
+function doBrowserIdLogin() {
+ navigator.id.getVerifiedEmail(function(assertion) {
+ if (assertion) {
+ // This code will be invoked once the user has successfully
+ // selected an email address they control to sign in with.
+ $.ajax({url: "login.py",
+ data: {"assertion": assertion},
+ type: "POST",
+ success: function(data, textStatus) {
+ var json = JSON.parse(data);
+ if (json["logged_in"] == "true") {
+ // Set cookie with email and sessionID and redirect
+ // to listlevels.py.
+ document.cookie = "email=" + json["email"];
+ document.cookie = "session=" + json["session"];
+ document.location = "listlevels.py";
+ } else {
+ $("#debug").html("Login rejected.");
+ }
+ },
+ error: function(req, textStatus, error) {
+ $("#debug").html("Error");
+ },
+ dataType: "html"});
+ } else {
+ $("#debug").html("BrowserID login failed.");
+ // something went wrong! the user isn't logged in.
+ }
+ });
+}
View
@@ -0,0 +1,65 @@
+#!/usr/bin/python
+
+# The JS from the sign in button needs to XHR the assertion to this code here
+# login.py will then verify it against the browserID server
+# see https://browserid.org/developers
+# if that works then we generate a session id
+# store session id in a row in the users table along with username and email address
+# redirect to listworks.py (or back to index.html if login fails)
+
+import cgi
+import cgitb
+import uuid
+import Cookie
+import subprocess
+import simplejson
+from database_tables import Player
+from platformer_config import DOMAIN, DEFAULT_AVATAR_URL
+
+def verifyBrowserId(assertion):
+ postargs = "assertion=%s&audience=%s" % (assertion, DOMAIN)
+ url = "https://browserid.org/verify"
+ # TODO verify SSL?
+ process = subprocess.Popen(["curl", "-d", postargs, url],
+ stdout = subprocess.PIPE )
+ data = simplejson.loads(process.communicate()[0])
+ # expect browserid.org/verify to return fields like this:{
+ # "status": "okay",
+ # "email": "lloyd@mozilla.com",
+ # "audience": "mysite.com",
+ # "valid-until": 1308859352261,
+ # "issuer": "browserid.org:443"
+ if data["status"] == "okay":
+ return data["email"]
+ else:
+ return False
+
+if __name__ == "__main__":
+ cgitb.enable()
+ q = cgi.FieldStorage()
+ print "Content-type: text/html"
+ print
+
+ assertion = q.getfirst("assertion", "")
+
+ email = verifyBrowserId(assertion)
+ if (email == False):
+ print simplejson.dumps({"logged_in": "false"})
+ else:
+ session = str(uuid.uuid1())
+
+ matches = Player.selectBy( email = email )
+ if (matches.count() == 0):
+ # user has not logged in before: create account
+ kwargs = {"email": email,
+ "name": email.split("@")[0], # use first part of email address as username
+ "session": session,
+ "avatarURL": DEFAULT_AVATAR_URL}
+ newUser = Player(**kwargs)
+ else:
+ oldUser = matches[0]
+ oldUser.session = session
+
+ # Return JSON to the client's XHR containing email and session uuid
+ print simplejson.dumps({"logged_in": "true", "email": email, "session": session})
+
View
@@ -1,13 +1,11 @@
#!/usr/bin/python
-# This script takes a username and spits out a list of links to all
-# works drawn by that user.
import cgi
import cgitb
import datetime
from database_tables import Level
-from webserver_utils import render_template_file, print_redirect
+from webserver_utils import *
def level_exists(name):
@@ -31,8 +29,9 @@ def make_new_title(base_title):
title = q.getfirst("title", "")
if title == "":
title = "Untitled"
- title = title.replace(" ", "_") # workaround for bug 9
+ title = title.replace(" ", "_") # terrible workaround for bug 9
title = make_new_title(title)
- newLevel = Level(name=title, creator = None, modified=datetime.datetime.now(), startX = 0, startY = 0)
+ player = verify_id()
+ newLevel = Level(name=title, creator = player, modified=datetime.datetime.now(), startX = 0, startY = 0)
print_redirect("listlevels.py")
@@ -1,3 +1,5 @@
DB_URL = "your database connection url here"
DOMAIN = "your domain here"
-BASE_DIR = "your absolute path here"
+TEMPLATE_DIR = "your absolute path here"
+DEFAULT_AVATAR_URL = "url to image here"
+DEBUG = False # set to true to show debug output
View
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -6,9 +6,12 @@
<a href="webrunner.html?level=${title}">Play</a>
</td>
<td>
- <a href="designer.html?level=${title}">Edit</a>
+ ${editlink}
</td>
<td>
${moddate}
</td>
+ <td>
+ ${creator}
+ </td>
</tr>
@@ -6,8 +6,9 @@
</head>
<body>
<h1>Platformer - All Levels</h1>
+ <h2>Welcome, ${player}</h2>
<table>
- <tr><th>Title</th><th></th><th></th><th>Last Modified</th></tr>
+ <tr><th>Title</th><th></th><th></th><th>Last Modified</th><th>Creator</th></tr>
${work_list}
</table>
<hr/>
View
@@ -5,7 +5,7 @@
import sys
import string
from platformer_config import TEMPLATE_DIR
-# from database_tables import Artist
+from database_tables import Player
def render_template_file( filename, substitutionDict ):
file = open( os.path.join( TEMPLATE_DIR, filename ), "r")
@@ -34,7 +34,7 @@ def verify_id():
if os.environ.has_key('HTTP_COOKIE'):
cookie = Cookie.SimpleCookie(os.environ['HTTP_COOKIE'])
if cookie.has_key("email") and cookie.has_key("session"):
- matches = Artist.selectBy(email = cookie["email"].value,
+ matches = Player.selectBy(email = cookie["email"].value,
session = cookie["session"].value)
if matches.count() > 0:
if matches[0].session != "":

0 comments on commit 05cd93c

Please sign in to comment.