Skip to content

Commit

Permalink
bcrypt and log_token added
Browse files Browse the repository at this point in the history
  • Loading branch information
Aleksandar Rodić committed Aug 30, 2012
1 parent d58a436 commit 15f46c8
Show file tree
Hide file tree
Showing 13 changed files with 84 additions and 33 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
*.pyc
8 changes: 4 additions & 4 deletions controllers/BaseHandler.py
@@ -1,7 +1,3 @@
import webapp2
import jinja2
import os

# Basic webapp2 handler with some useful methods
#
# render(template_name, template_vals={})
Expand All @@ -22,6 +18,10 @@
# get_params([param1, param2...]) - return [value1, value2...]
# get_params_dict([param1, param2...]) - return {param1:value1, param2:value2}

import webapp2
import jinja2
import os


head, tail = os.path.split(os.path.dirname(__file__))
template_dir = os.path.join(head, "templates")
Expand Down
33 changes: 29 additions & 4 deletions controllers/authentication.py
Expand Up @@ -2,19 +2,44 @@
#
# @Authentication.do decorator check
# if user is allowed to see a page
#
#
# valid_login(username, password)
# valid_log_token(username, log_token)
# create_and_save_log_token(user)


from models.User import User
from externals.bcrypt import bcrypt as bc

class Authentication(object):

@staticmethod
def do(fn):
def wrapper(self, *args):
username = self.request.cookies.get("username")
password = self.request.cookies.get("password")
if User.exist(username, password):
username = self.request.cookies.get("username")
log_token = self.request.cookies.get("log_token")

if Authentication.valid_log_token(username, log_token):
return fn(self, *args)
else:
self.redirect("/forbidden")
return wrapper
return wrapper

@staticmethod
def valid_login(username, password):
user = User.get_user(username)
if user and bc.hashpw(password, user.password) == user.password:
return Authentication.create_and_save_log_token(user)

@staticmethod
def valid_log_token(username, log_token):
user = User.get_user(username)
return user and bc.hashpw(log_token, user.log_token) == user.log_token

@staticmethod
def create_and_save_log_token(user):
log_token = bc.gensalt()
user.log_token = bc.hashpw(log_token, bc.gensalt())
user.put()
return log_token
10 changes: 6 additions & 4 deletions controllers/login.py
@@ -1,15 +1,17 @@
from BaseHandler import *
from models.User import User
from authentication import Authentication as aut
from externals.bcrypt import bcrypt as bc

class LoginPage(BaseHandler):
def get(self):
self.render("login.html")

def post(self):
params = self.get_params(["username", "password"])
if User.exist(*params):
username, password = params
self.set_cookies({"username":username, "password":password})
log_token = aut.valid_login(*params)
if log_token:
username, _ = params
self.set_cookies({"username":username, "log_token":log_token})
self.redirect("/")
else:
self.redirect("/login")
2 changes: 1 addition & 1 deletion controllers/logout.py
Expand Up @@ -2,5 +2,5 @@

class LogoutPage(BaseHandler):
def get(self):
self.set_cookies({"username":"", "password":""})
self.set_cookies({"username":"", "log_token":""})
self.redirect("/")
9 changes: 9 additions & 0 deletions controllers/messages.py
@@ -0,0 +1,9 @@
from BaseHandler import *
from controllers.authentication import Authentication


class MessagePage(BaseHandler):

@Authentication.do
def get(self):
self.response.out.write("Hello World")
5 changes: 4 additions & 1 deletion controllers/signup.py
@@ -1,4 +1,6 @@
from BaseHandler import *
from models.User import User
from authentication import Authentication as aut

class SignUpPage(BaseHandler):

Expand All @@ -10,7 +12,8 @@ def post(self):
user = User.save(*params)

if user:
self.set_cookies({'username':user.username, 'password':user.password})
log_token = aut.create_and_save_log_token(user)
self.set_cookies({'username':user.username, 'log_token':log_token})
self.redirect("/")
else:
self.redirect("/signup")
Empty file added externals/__init__.py
Empty file.
1 change: 1 addition & 0 deletions externals/bcrypt
Submodule bcrypt added at 8fc098
4 changes: 3 additions & 1 deletion main.py
Expand Up @@ -4,12 +4,14 @@
from controllers.login import LoginPage
from controllers.logout import LogoutPage
from controllers.forbidden import Forbidden
from controllers.messages import MessagePage

app = webapp2.WSGIApplication([
('/', HomePage),
('/signup', SignUpPage),
('/login', LoginPage),
('/logout', LogoutPage),
('/forbidden', Forbidden)
('/forbidden', Forbidden),
('/messages.*', MessagePage)
], debug=True)

42 changes: 25 additions & 17 deletions models/User.py
@@ -1,5 +1,3 @@
from google.appengine.ext import db

# Simple user model that we can use
# in further development of pm part
#
Expand All @@ -17,25 +15,38 @@
# SAVE
#
# save() - save and return user if valid() else False
#
#
# LOG TOKEN
#
# bcrypt.gensalt() is used for creating tokens
# tokens in database are hashed with bcrypt
# new token is generated with every new login


from google.appengine.ext import db
from externals.bcrypt import bcrypt as bc

class User(db.Model):
username = db.StringProperty(required=True)
password = db.StringProperty(required=True)
salt = db.StringProperty()
email = db.StringProperty(required=True)
username = db.StringProperty(required=True)
password = db.StringProperty(required=True)
email = db.StringProperty(required=True)
log_token = db.StringProperty(required=False)

@staticmethod
def get_user(username):
# shortcut for other classes that import User
return User.gql("WHERE username=:1", username).get()

@staticmethod
def valid_password(password):
n = len(password)
return n > 7 and n < 21
return len(password) < 40

@staticmethod
def valid_username(username):
n = len(username)
users = User.gql("WHERE username=:1", username).get()
return users == None and n > 4 and n < 21
users = User.get_user(username)
return not users and n > 4 and n < 21

@staticmethod
def valid_email(email):
Expand All @@ -52,12 +63,9 @@ def valid(username, email, password):
@staticmethod
def save(username, email, password):
if User.valid(username, email, password):
user = User(username=username, password=password, email=email)
password = bc.hashpw(password, bc.gensalt())
# call to create and save log token is in signup controller
user = User(username = username, password = password, email = email)
user.put()
return user
return False

@staticmethod
def exist(username, password):
user = User.gql("WHERE username=:1", username).get()
return user and user.password == password
return False
1 change: 1 addition & 0 deletions templates/base.html
Expand Up @@ -8,6 +8,7 @@
<a href="/login">Login</a>
<a href="/signup">Sign up</a>
<a href="/logout">Logout</a>
<a href="/messages">Messages</a>
</div>
<div id="content">
{% block content %}
Expand Down
1 change: 0 additions & 1 deletion templates/forbidden_resource.html
Expand Up @@ -2,5 +2,4 @@
{% block content %}
<h1>You are not authorized to see this page</h1>
<p>Go to <a href="/login">Login</a> or <a href="/signup">Sign up</a></p>
<a href="/">Home page</a>
{% endblock %}

0 comments on commit 15f46c8

Please sign in to comment.