def post(self): (user_data, is_password_reset) = self.resolve_user_info() if not user_data: self.response.write("Oops. Something went wrong. Please try again.") return if not is_password_reset: existing = self.request_string("existing") if not user_data.validate_password(existing): # TODO(benkomalo): throttle incorrect password attempts self.render_form(message="Incorrect password", user_data=user_data) return password1 = self.request_string("password1") password2 = self.request_string("password2") if (not password1 or not password2 or password1 != password2): self.render_form(message="Passwords don't match", user_data=user_data) elif not auth.passwords.is_sufficient_password(password1, user_data.nickname, user_data.username): self.render_form(message="Password too weak", user_data=user_data) else: # We're good! user_data.set_password(password1) if is_password_reset: # Password resets are done when the user is not even logged in, # so redirect the host page to the login page (done via # client side JS) self.render_form(message="Password reset. Redirecting...", success=True, user_data=user_data) else: # Need to create a new auth token as the existing cookie will # expire. Use /postlogin to set the cookie. This requires # some redirects (/postlogin on http, then back to this # pwchange form in https). auth_token = AuthToken.for_user(user_data) self.redirect("%s?%s" % ( util.insecure_url("/postlogin"), util.build_params({ 'auth': auth_token.value, 'continue': self.secure_url_with_token( "/pwchange?success=1", user_data), })))
def post(self): (user_data, is_password_reset) = self.resolve_user_info() if not user_data: self.response.write( "Oops. Something went wrong. Please try again.") return if not is_password_reset: existing = self.request_string("existing") if not user_data.validate_password(existing): # TODO(benkomalo): throttle incorrect password attempts self.render_form(message="Incorrect password", user_data=user_data) return password1 = self.request_string("password1") password2 = self.request_string("password2") if (not password1 or not password2 or password1 != password2): self.render_form(message="Passwords don't match", user_data=user_data) elif not auth.passwords.is_sufficient_password( password1, user_data.nickname, user_data.username): self.render_form(message="Password too weak", user_data=user_data) else: # We're good! user_data.set_password(password1) if is_password_reset: # Password resets are done when the user is not even logged in, # so redirect the host page to the login page (done via # client side JS) self.render_form(message="Password reset. Redirecting...", success=True, user_data=user_data) else: # Need to create a new auth token as the existing cookie will # expire. Use /postlogin to set the cookie. This requires # some redirects (/postlogin on http, then back to this # pwchange form in https). auth_token = AuthToken.for_user(user_data) self.redirect("%s?%s" % (util.insecure_url("/postlogin"), util.build_params({ 'auth': auth_token.value, 'continue': self.secure_url_with_token( "/pwchange?success=1", user_data), })))
def return_login_json(handler, user_data, cont="/"): """Handle a successful login for a user by redirecting them to the PostLogin URL with the auth token, which will ultimately set the auth cookie for them. This level of indirection is needed since the Login/Register handlers must accept requests with password strings over https, but the rest of the site is not (yet) using https, and therefore must use a non-https cookie. """ auth_token = AuthToken.for_user(user_data) handler.response.write(jsonify.jsonify({ 'auth': auth_token.value, 'continue': cont }, camel_cased=True))
def return_login_json(handler, user_data, cont="/"): """Handle a successful login for a user by redirecting them to the PostLogin URL with the auth token, which will ultimately set the auth cookie for them. This level of indirection is needed since the Login/Register handlers must accept requests with password strings over https, but the rest of the site is not (yet) using https, and therefore must use a non-https cookie. """ auth_token = AuthToken.for_user(user_data) handler.response.write( jsonify.jsonify({ 'auth': auth_token.value, 'continue': cont }, camel_cased=True))
def post(self): """POST submissions are for username/password based logins to acquire an OAuth access token. """ identifier = self.request_string('identifier') password = self.request_string('password') if not identifier or not password: self.render_login_page("Please enter your username and password.") return user_data = UserData.get_from_username_or_email(identifier.strip()) if not user_data or not user_data.validate_password(password): # TODO(benkomalo): IP-based throttling of failed logins? self.render_login_page("Your login or password is incorrect.") return # Successful login - convert to an OAuth access_token oauth_map_id = self.request_string("oauth_map_id", default="") oauth_map = OAuthMap.get_by_id_safe(oauth_map_id) if not oauth_map: self.render_login_page("Unable to find OAuthMap by id.") return # Mint the token and persist to the oauth_map oauth_map.khan_auth_token = AuthToken.for_user(user_data).value oauth_map.put() # Flush the "apply phase" of the above put() to ensure that subsequent # retrievals of this OAuthmap returns fresh data. GAE's HRD can # otherwise take a second or two to propagate the data, and the # following authorize endpoint redirect below could happen quicker # than that in some cases. oauth_map = OAuthMap.get(oauth_map.key()) # Need to redirect back to the http authorize endpoint return auth_util.authorize_token_redirect(oauth_map, force_http=True)