This commit is contained in:
Joseph Schorr 2013-09-27 19:24:30 -04:00
commit 038e9afc97
7 changed files with 68 additions and 4 deletions

View file

@ -3,6 +3,8 @@ import logging
import dateutil.parser
from database import *
from util.validation import (validate_email, validate_username,
validate_password)
logger = logging.getLogger(__name__)
@ -14,8 +16,20 @@ class DataModelException(Exception):
def create_user(username, password, email):
pw_hash = bcrypt.hashpw(password, bcrypt.gensalt())
new_user = User.create(username=username, password_hash=pw_hash,
email=email)
if not validate_email(email):
raise DataModelException('Invalid email address: %s' % email)
if not validate_username(username):
raise DataModelException('Invalid username: %s' % username)
if not validate_password(password):
raise DataModelException('Invalid password, password must be at least ' +
'8 characters and contain no whitespace.')
try:
new_user = User.create(username=username, password_hash=pw_hash,
email=email)
except Exception as ex:
raise DataModelException(ex.message)
return new_user

View file

@ -7,6 +7,7 @@ from functools import wraps
from data import model
from app import app
from util.names import parse_repository_name
from util.gravatar import compute_hash
from auth.permissions import (ReadRepositoryPermission,
ModifyRepositoryPermission,
AdministerRepositoryPermission)
@ -15,6 +16,11 @@ from auth.permissions import (ReadRepositoryPermission,
logger = logging.getLogger(__name__)
@app.errorhandler(model.DataModelException)
def handle_dme(ex):
return make_response(ex.message, 400)
@app.route('/api/')
def welcome():
return make_response('welcome', 200)
@ -29,6 +35,7 @@ def get_logged_in_user():
'anonymous': False,
'username': user.username,
'email': user.email,
'gravatar': compute_hash(user.email),
})

View file

@ -221,6 +221,17 @@ p.editable:hover i {
margin: 10px;
}
.navbar-nav > li > .user-dropdown {
padding-top: 9px;
padding-bottom: 9px;
}
.user-dropdown > img {
padding-right: 6px;
}
/* Overrides for typeahead to work with bootstrap 3. */
.twitter-typeahead .tt-query,
.twitter-typeahead .tt-hint {
@ -279,4 +290,4 @@ p.editable:hover i {
font-size: 14px;
line-height: 1.428571429;
border: 1px solid transparent;
}
}

View file

@ -57,7 +57,13 @@
</form>
<li class="dropdown" ng-switch-when="false">
<a href="javascript:void(0)" class="dropdown-toggle" data-toggle="dropdown">{{ user.username }} <b class="caret"></b></a>
<!--<button type="button" class="btn btn-default navbar-btn">Sign in</button>-->
<a href="javascript:void(0)" class="dropdown-toggle user-dropdown" data-toggle="dropdown">
<img src="http://www.gravatar.com/avatar/{{ user.gravatar }}?s=32&d=identicon" />
{{ user.username }}
<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li><a href="/signout">Sign out</a></li>
</ul>

BIN
test.db

Binary file not shown.

5
util/gravatar.py Normal file
View file

@ -0,0 +1,5 @@
import hashlib
def compute_hash(email_address):
return hashlib.md5(email_address.strip().lower()).hexdigest()

21
util/validation.py Normal file
View file

@ -0,0 +1,21 @@
import re
import urllib
def validate_email(email_address):
if re.match(r'[^@]+@[^@]+\.[^@]+', email_address):
return True
return False
def validate_username(username):
# Minimum length of 2, maximum length of 255, no url unsafe characters
return (urllib.quote(username, safe='') == username and
len(username) > 1 and
len(username) < 256)
def validate_password(password):
# No whitespace and minimum length of 8
if re.search(r'\s', password):
return False
return len(password) > 7