summaryrefslogtreecommitdiff
path: root/users
diff options
context:
space:
mode:
authorjessib <jessib@riseup.net>2013-04-08 11:04:01 -0700
committerjessib <jessib@riseup.net>2013-04-08 11:04:01 -0700
commit176845b45f6982b0bf26aa69e7432562eed97c69 (patch)
tree1dd74d5afcdb8cfb96588937eda612b37449923c /users
parent602229c463c58be9ffb909570155d14d59f6b4d5 (diff)
parent654ab25fa4659119d5ddaa9ae116fce69a386ab1 (diff)
Merge pull request #41 from azul/feature/allow-getting-salt
Allow getting salt and proper error messages for invalid login attempts
Diffstat (limited to 'users')
-rw-r--r--users/app/controllers/controller_extension/authentication.rb16
-rw-r--r--users/app/controllers/v1/sessions_controller.rb7
-rw-r--r--users/app/models/user.rb3
-rw-r--r--users/config/locales/en.yml1
-rw-r--r--users/test/functional/sessions_controller_test.rb11
-rw-r--r--users/test/functional/v1/sessions_controller_test.rb27
-rw-r--r--users/test/integration/api/account_flow_test.rb23
-rw-r--r--users/test/integration/api/login_test.rb16
-rw-r--r--users/test/integration/api/rack_test.rb12
9 files changed, 79 insertions, 37 deletions
diff --git a/users/app/controllers/controller_extension/authentication.rb b/users/app/controllers/controller_extension/authentication.rb
index f2184d9..f0a6564 100644
--- a/users/app/controllers/controller_extension/authentication.rb
+++ b/users/app/controllers/controller_extension/authentication.rb
@@ -8,13 +8,27 @@ module ControllerExtension::Authentication
end
def authentication_errors
- return unless errors = warden.winning_strategy.try(:message)
+ return unless attempted_login?
+ errors = get_warden_errors
errors.inject({}) do |translated,err|
translated[err.first] = I18n.t(err.last)
translated
end
end
+ def get_warden_errors
+ if strategy = warden.winning_strategy
+ strategy.message
+ else
+ { login: :all_strategies_failed }
+ end
+ end
+
+ def attempted_login?
+ request.env['warden.options'] &&
+ request.env['warden.options'][:attempted_path]
+ end
+
def logged_in?
!!current_user
end
diff --git a/users/app/controllers/v1/sessions_controller.rb b/users/app/controllers/v1/sessions_controller.rb
index 0551ca9..9365d76 100644
--- a/users/app/controllers/v1/sessions_controller.rb
+++ b/users/app/controllers/v1/sessions_controller.rb
@@ -13,7 +13,12 @@ module V1
def create
logout if logged_in?
- authenticate!
+ if params['A']
+ authenticate!
+ else
+ @user = User.find_by_login(params['login'])
+ render :json => {salt: @user.salt}
+ end
end
def update
diff --git a/users/app/models/user.rb b/users/app/models/user.rb
index c9b367f..62c5054 100644
--- a/users/app/models/user.rb
+++ b/users/app/models/user.rb
@@ -47,7 +47,8 @@ class User < CouchRest::Model::Base
timestamps!
design do
- load_views(Rails.root.join('users', 'app', 'designs', 'user'))
+ own_path = Pathname.new(File.dirname(__FILE__))
+ load_views(own_path.join('..', 'designs', 'user'))
view :by_login
view :by_created_at
end
diff --git a/users/config/locales/en.yml b/users/config/locales/en.yml
index 9e7d4b2..2077858 100644
--- a/users/config/locales/en.yml
+++ b/users/config/locales/en.yml
@@ -6,6 +6,7 @@ en:
login: "Login"
login_message: "Please login with your account."
invalid_user_pass: "Not a valid username/password combination"
+ all_strategies_failed: "Could not understand your login attempt. Please first send your login and a SRP ephemeral value A and then send the client_auth in the same session (using cookies)."
update_login_and_password: "Update Login and Password"
cancel_account: "Cancel your account"
remove_account: "Remove Account"
diff --git a/users/test/functional/sessions_controller_test.rb b/users/test/functional/sessions_controller_test.rb
index f99c0d7..b22c3a3 100644
--- a/users/test/functional/sessions_controller_test.rb
+++ b/users/test/functional/sessions_controller_test.rb
@@ -11,7 +11,6 @@ class SessionsControllerTest < ActionController::TestCase
end
test "should get login screen" do
- request.env['warden'].expects(:winning_strategy)
get :new
assert_response :success
assert_equal "text/html", response.content_type
@@ -19,13 +18,13 @@ class SessionsControllerTest < ActionController::TestCase
end
test "renders json" do
- request.env['warden'].expects(:winning_strategy)
get :new, :format => :json
assert_response :success
assert_json_error nil
end
test "renders warden errors" do
+ request.env['warden.options'] = {attempted_path: '/1/sessions/asdf.json'}
strategy = stub :message => {:field => :translate_me}
request.env['warden'].stubs(:winning_strategy).returns(strategy)
I18n.expects(:t).with(:translate_me).at_least_once.returns("translation stub")
@@ -34,6 +33,14 @@ class SessionsControllerTest < ActionController::TestCase
assert_json_error :field => "translation stub"
end
+ test "renders failed attempt message" do
+ request.env['warden.options'] = {attempted_path: '/1/sessions/asdf.json'}
+ request.env['warden'].stubs(:winning_strategy).returns(nil)
+ get :new, :format => :json
+ assert_response 422
+ assert_json_error :login => I18n.t(:all_strategies_failed)
+ end
+
# Warden takes care of parsing the params and
# rendering the response. So not much to test here.
test "should perform handshake" do
diff --git a/users/test/functional/v1/sessions_controller_test.rb b/users/test/functional/v1/sessions_controller_test.rb
index be085ce..1226c9d 100644
--- a/users/test/functional/v1/sessions_controller_test.rb
+++ b/users/test/functional/v1/sessions_controller_test.rb
@@ -7,26 +7,10 @@ class V1::SessionsControllerTest < ActionController::TestCase
setup do
@request.env['HTTP_HOST'] = 'api.lvh.me'
- @user = stub :login => "me", :id => 123
+ @user = stub_record :user
@client_hex = 'a123'
end
- test "renders json" do
- request.env['warden'].expects(:winning_strategy)
- get :new, :format => :json
- assert_response :success
- assert_json_error nil
- end
-
- test "renders warden errors" do
- strategy = stub :message => {:field => :translate_me}
- request.env['warden'].stubs(:winning_strategy).returns(strategy)
- I18n.expects(:t).with(:translate_me).at_least_once.returns("translation stub")
- get :new, :format => :json
- assert_response 422
- assert_json_error :field => "translation stub"
- end
-
# Warden takes care of parsing the params and
# rendering the response. So not much to test here.
test "should perform handshake" do
@@ -36,6 +20,15 @@ class V1::SessionsControllerTest < ActionController::TestCase
post :create, :login => @user.login, 'A' => @client_hex
end
+ test "should send salt" do
+ User.expects(:find_by_login).with(@user.login).returns(@user)
+
+ post :create, :login => @user.login
+
+ assert_equal @user, assigns(:user)
+ assert_json_response salt: @user.salt
+ end
+
test "should authorize" do
request.env['warden'].expects(:authenticate!)
@controller.expects(:current_user).returns(@user)
diff --git a/users/test/integration/api/account_flow_test.rb b/users/test/integration/api/account_flow_test.rb
index e618541..1698105 100644
--- a/users/test/integration/api/account_flow_test.rb
+++ b/users/test/integration/api/account_flow_test.rb
@@ -1,18 +1,9 @@
require 'test_helper'
+require_relative 'rack_test'
-CONFIG_RU = (Rails.root + 'config.ru').to_s
-OUTER_APP = Rack::Builder.parse_file(CONFIG_RU).first
+class AccountFlowTest < RackTest
-class AccountFlowTest < ActiveSupport::TestCase
- include Rack::Test::Methods
- include Warden::Test::Helpers
- include LeapWebCore::AssertResponses
-
- def app
- OUTER_APP
- end
-
- def setup
+ setup do
@login = "integration_test_user"
User.find_by_login(@login).tap{|u| u.destroy if u}
@password = "srp, verify me!"
@@ -26,7 +17,7 @@ class AccountFlowTest < ActiveSupport::TestCase
@user = User.find_by_login(@login)
end
- def teardown
+ teardown do
@user.destroy if @user
Warden.test_reset!
end
@@ -75,7 +66,8 @@ class AccountFlowTest < ActiveSupport::TestCase
test "signup and wrong password login attempt" do
srp = SRP::Client.new @login, :password => "wrong password"
server_auth = srp.authenticate(self)
- assert_json_error({:login => "Not a valid username/password combination", :password => "Not a valid username/password combination"})
+ assert_json_error login: "Not a valid username/password combination",
+ password: "Not a valid username/password combination"
assert !last_response.successful?
assert_nil server_auth["M2"]
end
@@ -86,7 +78,8 @@ class AccountFlowTest < ActiveSupport::TestCase
assert_raises RECORD_NOT_FOUND do
server_auth = srp.authenticate(self)
end
- assert_json_error({:login => "Not a valid username/password combination", :password => "Not a valid username/password combination"})
+ assert_json_error login: "Not a valid username/password combination",
+ password: "Not a valid username/password combination"
assert !last_response.successful?
assert_nil server_auth
end
diff --git a/users/test/integration/api/login_test.rb b/users/test/integration/api/login_test.rb
new file mode 100644
index 0000000..fb761e5
--- /dev/null
+++ b/users/test/integration/api/login_test.rb
@@ -0,0 +1,16 @@
+require 'test_helper'
+require_relative 'rack_test'
+
+class AccountFlowTest < RackTest
+
+ setup do
+ @login = "integration_test_user"
+ end
+
+ test "require json requests" do
+ put "http://api.lvh.me:3000/1/sessions/" + @login,
+ :client_auth => "This is not a valid login anyway"
+ assert_json_error login: I18n.t(:all_strategies_failed)
+ end
+
+end
diff --git a/users/test/integration/api/rack_test.rb b/users/test/integration/api/rack_test.rb
new file mode 100644
index 0000000..da960f2
--- /dev/null
+++ b/users/test/integration/api/rack_test.rb
@@ -0,0 +1,12 @@
+CONFIG_RU = (Rails.root + 'config.ru').to_s
+OUTER_APP = Rack::Builder.parse_file(CONFIG_RU).first
+
+class RackTest < ActiveSupport::TestCase
+ include Rack::Test::Methods
+ include Warden::Test::Helpers
+ include LeapWebCore::AssertResponses
+
+ def app
+ OUTER_APP
+ end
+end