Created
June 30, 2014 09:29
-
-
Save kenchangh/e3ee1008eface35c46c0 to your computer and use it in GitHub Desktop.
Validation methods in Google App Engine
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
########## | |
import re | |
import hmac | |
import random | |
from hashlib import sha256 | |
from base_handler import BaseHandler | |
from google.appengine.ext import db | |
from google.appengine.api import memcache | |
########## | |
""" | |
validate module for validating usernames, passwords and emails for Sign Up feature. | |
""" | |
def valid_user(user): | |
USER_RE = re.compile("^[a-zA-Z0-9_-]{3,20}$") | |
if len(user)>=6: | |
return USER_RE.match(user) | |
def valid_pw(pw): | |
PW_RE = re.compile("^.{3,20}$") | |
if len(pw)>=6: | |
return PW_RE.match(pw) | |
def valid_email(email): | |
EMAIL_RE = re.compile("^[\S]+@[\S]+\.[\S]+$") | |
if len(email)>=6: | |
return EMAIL_RE.match(email) | |
def make_salt(): | |
""" | |
Generates 16-character salt for encrypting passwords. | |
Encryption done with SHA256 via HMAC. | |
""" | |
ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" | |
chars = [] | |
for i in range(16): | |
chars.append(random.choice(ALPHABET)) | |
return ''.join(chars) | |
def make_cookie(uid, pw): | |
cookie = uid + '|' + pw | |
return cookie | |
class SafeLogin(BaseHandler): | |
def valid_login(self): | |
""" | |
Cookies are in a string separated by a pipe | |
>>> cookie = make_cookie('maverick', 'hashed_pw_here') | |
>>> cookie | |
'maverick|hashed_pw_here' | |
>>> valid_cookie(cookie) | |
True | |
Checks the browser's cookie and extract password. | |
Matches with memcache-stored (sometimes, but RARELY DB-stored) password. | |
Checks with DB if memcache dies down | |
Returns a Boolean value of user's login cookie | |
""" | |
cookie = self.request.cookies.get('login') | |
# Checks if cookie is present | |
if cookie: | |
cookie = cookie.split('|') | |
# Checks if cookie contains pipe | |
if len(cookie) == 2: | |
username = cookie[0] | |
cookie_pw = cookie[1] | |
# This value in cache should be set on login | |
# Gets this value each page refresh | |
db_pw = memcache.get('login_' + username) | |
if db_pw is not None: | |
if cookie_pw == db_pw: | |
return True | |
else: | |
# THIS IS RARE | |
# It means that the cache died down and DB query needs to be done | |
# Queries and set memcache | |
sql = "SELECT * FROM User WHERE username = '{0}'".format( | |
username) | |
query = db.GqlQuery(sql).get() | |
if cookie_pw == query.pw: | |
memcache.set('login_' + username, query.pw) | |
return True | |
else: | |
return False | |
else: | |
return False | |
else: | |
return False | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment