Skip to content

Commit

Permalink
Merge branch 'feature/nima_fixes' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
localprojects committed Jun 19, 2013
2 parents d88fb23 + 0d04d96 commit ab75739
Show file tree
Hide file tree
Showing 8 changed files with 109 additions and 71 deletions.
63 changes: 59 additions & 4 deletions auth/__init__.py
Expand Up @@ -93,6 +93,7 @@ def __init__(self, id, username, email, password, active=True, **kwargs):
self.email = email
self.password = password
self.active = active


def is_active(self):
return self.active
Expand All @@ -110,24 +111,62 @@ def __init__(self, salt=None):
def encrypt(self, password):
raise NotImplementedError("encrypt")

def matches_encryption_pattern(self, password):
"""Validate whether the pattern of the password matches the usual output of the encryptor
:param password: String of password characters
"""
# The default implementation should fail, since each encryptor is
# expected to implement its own checks
raise NotImplementedError("encryptor pattern match")

class NoOpPasswordEncryptor(PasswordEncryptor):
"""Plain text password encryptor
"""
def encrypt(self, password):
return password

def matches_encryption_pattern(self, password):
# The NoOp encryptor must assume that every pattern is valid
return True

class MD5PasswordEncryptor(PasswordEncryptor):
"""MD5 password encryptor
"""
def encrypt(self, password):
seasoned = "%s%s" % (password, self.salt)
return hashlib.md5(seasoned.encode('utf-8')).hexdigest()

def matches_encryption_pattern(self, password):
# md5.hexdigest returns string of length 32, containing only hexadecimal digits
try:
int(password, 16)
if len(password) == 32:
return True

except ValueError:
current_app.logger.debug("Password doesn't match MD5 pattern")

return False


class SHA1PasswordEncryptor(PasswordEncryptor):
def encrypt(self, password):
seasoned = "%s%s" % (password, self.salt)
return hashlib.sha1(seasoned.encode('utf-8')).hexdigest()

def matches_encryption_pattern(self, password):
# md5.hexdigest returns string of length 40, containing only hexadecimal digits
try:
int(password, 16)
if len(password) == 40:
return True

except ValueError:
current_app.logger.debug("Password doesn't match SHA1 pattern")

return False

class SHA256PasswordEncryptor(PasswordEncryptor):
def encrypt(self, password):
seasoned = "%s%s" % (password, self.salt)
Expand Down Expand Up @@ -218,8 +257,17 @@ def do_authenticate(self, username, password):
self.auth_error('Unexpected authentication error: %s' % e)

# compare passwords
encrypted_pw = current_app.password_encryptor.encrypt(password)
if user.password == encrypted_pw:
encrypted_password = current_app.password_encryptor.encrypt(password)
if user.password == encrypted_password:
return user
elif user.password == password:
# Convert plain-text to encrypted password
current_app.logger.debug("Found plain-text password. Encrypting with %s" %
current_app.config.get('AUTH').get('password_encryptor'))
user.password = encrypted_password
user.save()

#current_app.logger.debug("SHA'ed pass: " + user.password)
return user
# bad match
raise BadCredentialsException("Password does not match")
Expand Down Expand Up @@ -310,7 +358,14 @@ def init_app(self, app):
@login_manager.user_loader
def load_user(id):
try:
return user_service.get_user_with_id(id)
user = user_service.get_user_with_id(id)
# check if the password matches encryptor pattern
if not current_app.password_encryptor.matches_encryption_pattern(user.password):
encrypted_password = current_app.password_encryptor.encrypt(user.password)
user.password = encrypted_password
user.save()

return user
except Exception, e:
current_app.logger.error('Error getting user: %s' % e)
return None
Expand All @@ -328,7 +383,7 @@ def authenticate():

try:
user = auth_provider.authenticate(request.form)

if login_user(user):
redirect_url = get_post_login_redirect()
if not is_ajax():
Expand Down
2 changes: 1 addition & 1 deletion cdw/services.py
Expand Up @@ -48,7 +48,7 @@ def with_id(self, id):

raise EntityNotFoundException(self.clazz.__name__, {"id":id})

def with_fields(self, **fields):
def with_fields(self, **fields):
return self.clazz.objects(**fields)

def with_fields_recent_first(self, **fields):
Expand Down
Binary file modified cdw/static/images/facebook_signin_btn.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
87 changes: 28 additions & 59 deletions cdw/static/js/app/common.js
Expand Up @@ -2,58 +2,6 @@
Copyright (c) 2011 Local Projects. All rights reserved.
License: Affero GNU GPL v3, see LEGAL/LICENSE for more details.
--------------------------------------------------------------------*/
/*
window.WhatIsThisView = Backbone.View.extend({
//el: $('div.whatisthis'),
tagName: 'div',
className: 'whatisthis',
template: _.template($('#what-is-this-template').html()),
events: {
'click li a': 'onNavClick',
'click a.close-btn': 'onEnterClick',
'click a.enter-btn': 'onEnterClick'
},
initialize: function(data) {
this.homePage = data.homePage || false;
},
render: function() {
$(this.el).html(this.template());
this.$('div.contents div').hide();
this.$('div.contents div.screen-1').show();
this.currentScreen = "screen-1";
this.$('a.' + this.currentScreen).css('opacity', 0.7);
return this;
},
onEnterClick: function(e) {
e.preventDefault();
if(this.homePage) {
this.remove();
} else {
window.opener.location = "/";
window.close();
}
},
onNavClick: function(e) {
e.preventDefault();
this.showScreen($(e.currentTarget).attr('class'));
},
showScreen: function(selector) {
//console.log('show screen: ' + selector);
this.$('div.contents div.' + this.currentScreen).hide();
this.$('a.' + this.currentScreen).css('opacity', 1);
this.currentScreen = selector;
this.$('div.contents div.' + this.currentScreen).show();
this.$('a.' + this.currentScreen).css('opacity', 0.7);
}
});
*/

/**
* PopupHolderView
Expand All @@ -64,7 +12,6 @@ window.PopupHolderView = Backbone.View.extend({
initialize : function() {
this.$inner = this.$('div.popup-inner');
this.$mask = this.$('div.popup-mask');
// alert("common window.PopupHolderView init");
},

/**
Expand Down Expand Up @@ -117,7 +64,7 @@ window.LoginPopupView = Backbone.View.extend({
},

initialize : function() {
this.isSignin = true;
this.isSignin = false;
},

render : function() {
Expand All @@ -143,10 +90,10 @@ window.LoginPopupView = Backbone.View.extend({
/**
* Set the values for the form.
*/
setValues : function(signIn, label, action, addClass, removeClass, fieldName) {
setValues : function(signIn, label, action, addClass, removeClass, fieldName, selector) {

this.isSignin = signIn;
this.$('form').attr('action', action).addClass(addClass).removeClass(removeClass);
this.$('form').filter(selector).attr('action', action).addClass(addClass).removeClass(removeClass);
this.$('p.username input').attr('name', fieldName);
this.$('#login_or_signup_form button').text(label);
},
Expand All @@ -155,14 +102,14 @@ window.LoginPopupView = Backbone.View.extend({
* Makes the form a register form
*/
setRegister : function(label) {
this.setValues(false, label || 'Register', '/register/email', 'register-form', 'signin-form', 'email');
this.setValues(false, label || 'Register', '/register/email', 'register-form', 'signin-form', 'email', '#login_or_signup_form');
},

/**
* Makes the form a login form
*/
setSignin : function(label) {
this.setValues(true, label || 'Register/Sign In', '/auth', 'signin-form', 'register-form', 'username');
this.setValues(true, label || 'Register/Sign In', '/auth', 'signin-form', 'register-form', 'username', '#login_or_signup_form');
},

/**
Expand Down Expand Up @@ -207,7 +154,29 @@ window.LoginPopupView = Backbone.View.extend({
if (data.length == 1) {
this.setSignin('Sign In');
} else {
this.setRegister('Register');
$.ajax({
url : '/api/users/search',
type : 'POST',
data : {
'username' : this.$('p.username input').val()
},

complete : $.proxy(function() {
this.toggle();
}, this),

error : $.proxy(function() {
this.setSignin();
}, this),

success : $.proxy(function(data) {
if (data.length == 1) {
this.setSignin('Sign In');
} else {
this.setRegister('Register');
}
}, this)
});
}
}, this)
});
Expand Down
9 changes: 6 additions & 3 deletions cdw/static/js/views/home/main.js
Expand Up @@ -107,10 +107,12 @@ define(['jquery', 'underscore', 'backbone', 'config', 'sdate', 'cdw',
if ($.mobile.activePage.attr('id') != 'home') {
return;
}

//alert($(document).height() + ", " + $(window).height() + ", " + $(document).scrollTop());
var d = $(document).height() - $(window).height() - $(document).scrollTop();
if (d < scrollDist) {
//alert("before call more: " + homeView.currentpage + ", " + d + ", " + scrollDist);
if (d < scrollDist && $(document).scrollTop()) {
homeView.getMore();
//alert("after call more");
}
});

Expand Down Expand Up @@ -231,7 +233,8 @@ define(['jquery', 'underscore', 'backbone', 'config', 'sdate', 'cdw',

////load response

homeView.models.debates.url = apiHost + "api/questions/" + currentdata.id + "/posts?skip=" + (homeView.currentpage * homeView.perPage) + "&limit=" + homeView.perPage;
//homeView.models.debates.url = apiHost + "api/questions/" + currentdata.id + "/posts?skip=" + (homeView.currentpage * homeView.perPage) + "&limit=" + homeView.perPage;
homeView.models.debates.url = apiHost + "api/questions/" + currentdata.id + "/posts?skip=0&limit=" + homeView.perPage;
homeView.models.debates.fetch({
dataType : "jsonp",
success : function(model, debatesdata) {
Expand Down
2 changes: 1 addition & 1 deletion cdw/templates/index_m.html
Expand Up @@ -521,7 +521,7 @@ <h1>Login</h1>
<div class="intro">
<div class="sm5">Please LOG IN or SIGN UP using Facebook or your debate wall account.
<div class="divider sm5"></div>
<a href="#" class="facebook_auth"><img src="/static/css/images/facebook-button.png" border="0" /></a>
<a href="#" class="facebook_auth"><img src="/static/images/facebook_signin_btn.png" border="0" /></a>
</div>
<div class="divider sm5"></div>
</div>
Expand Down
6 changes: 3 additions & 3 deletions cdw/templates/layouts/public.html
Expand Up @@ -44,11 +44,11 @@
<form action="{{ url_for('social.login', provider_id='facebook') }}" id='facebook_login_form' method="POST">
<input type="image" name="login_facebook" src="/static/images/facebook_signin_btn.png"/>
</form>
<form action="/signin" method="POST" class="login-form" id="login_or_signup_form">
<p>Or with your email ...</p>
<form action="/register/email" method="POST" class="login-form" id="login_or_signup_form">
<p>Or with your username/email</p>
<div class="error-msg"></div>
<input type="hidden" name="modal" value="true"/>
<p class="cozy username"><input name="username" type="text" class="text username defaulttext" title="EMAIL ADDRESS"/></p>
<p class="cozy username"><input name="username" type="text" class="text username defaulttext" title="EMAIL/USERNAME"/></p>
<p class="cozy password"><input name="password" type="password" class="text password defaulttext" title="PASSWORD"/></p>
<p class="submit"><button type="submit">Register/Sign In</button></p>
</form>
Expand Down
11 changes: 11 additions & 0 deletions cdw/views.py
Expand Up @@ -667,6 +667,17 @@ def fb_login():

# Set user as logged-in, but check if profile is complete
user = cdw.users.with_id(fbuser.get('user_id'))
# check if the password is plain or SHA
#try:
# int(user.password, 16)
# current_app.logger.debug("Password is SHA1 encrypted")
#except ValueError:
# current_app.logger.debug("Password is plain, encrypting...")
# encrypted_password = current_app.password_encryptor.encrypt(user.password)
# from pdb import set_trace; set_trace()
# user.password = encrypted_password
# user.save()

if user:
login_user(user)
# Take the user back to where they came from (from the front-end cookie)
Expand Down

0 comments on commit ab75739

Please sign in to comment.