From 3f9dc65636afb57fed441978dca4bf7d3209bd2d Mon Sep 17 00:00:00 2001 From: Azul Date: Fri, 7 Feb 2014 14:38:56 +0100 Subject: rename authorize to require_login authorize_admin -> require_admin also add require_token which will ensure token has been used for auth. --- users/test/functional/application_controller_test.rb | 12 ++++++------ users/test/functional/v1/sessions_controller_test.rb | 2 +- users/test/unit/unauthenticated_user_test.rb | 7 +++++++ users/test/unit/unauthorized_user_test.rb | 7 ------- 4 files changed, 14 insertions(+), 14 deletions(-) create mode 100644 users/test/unit/unauthenticated_user_test.rb delete mode 100644 users/test/unit/unauthorized_user_test.rb (limited to 'users/test') diff --git a/users/test/functional/application_controller_test.rb b/users/test/functional/application_controller_test.rb index 94b77bd..c4c922b 100644 --- a/users/test/functional/application_controller_test.rb +++ b/users/test/functional/application_controller_test.rb @@ -7,21 +7,21 @@ class ApplicationControllerTest < ActionController::TestCase @controller.response = @response end - def test_authorize_redirect - @controller.send(:authorize) + def test_require_login_redirect + @controller.send(:require_login) assert_access_denied(true, false) end - def test_authorized + def test_require_login login - @controller.send(:authorize) + @controller.send(:require_login) assert_access_denied(false) end - def test_authorize_admin + def test_require_admin login @current_user.expects(:is_admin?).returns(false) - @controller.send(:authorize_admin) + @controller.send(:require_admin) assert_access_denied end diff --git a/users/test/functional/v1/sessions_controller_test.rb b/users/test/functional/v1/sessions_controller_test.rb index 4200e8f..df0d681 100644 --- a/users/test/functional/v1/sessions_controller_test.rb +++ b/users/test/functional/v1/sessions_controller_test.rb @@ -36,7 +36,7 @@ class V1::SessionsControllerTest < ActionController::TestCase post :create, :login => @user.login, 'A' => @client_hex end - test "should authorize" do + test "should authenticate" do request.env['warden'].expects(:authenticate!) @controller.stubs(:current_user).returns(@user) handshake = stub(:to_hash => {h: "ash"}) diff --git a/users/test/unit/unauthenticated_user_test.rb b/users/test/unit/unauthenticated_user_test.rb new file mode 100644 index 0000000..e5fafb8 --- /dev/null +++ b/users/test/unit/unauthenticated_user_test.rb @@ -0,0 +1,7 @@ +require 'test_helper' + +class UnauthenticatedUserTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/users/test/unit/unauthorized_user_test.rb b/users/test/unit/unauthorized_user_test.rb deleted file mode 100644 index 5b96ae1..0000000 --- a/users/test/unit/unauthorized_user_test.rb +++ /dev/null @@ -1,7 +0,0 @@ -require 'test_helper' - -class UnauthorizedUserTest < ActiveSupport::TestCase - # test "the truth" do - # assert true - # end -end -- cgit v1.2.3 From 67f17e65b9e9e8ad2991b9c4002dba5203baa77f Mon Sep 17 00:00:00 2001 From: Azul Date: Sat, 8 Feb 2014 11:13:10 +0100 Subject: refactor tests to ease the testing of token only auth --- users/test/integration/api/account_flow_test.rb | 114 +++++------------------- users/test/integration/api/login_test.rb | 3 +- users/test/integration/api/pgp_key_test.rb | 35 ++++++++ users/test/integration/api/rack_test.rb | 9 -- users/test/integration/api/srp_test.rb | 83 +++++++++++++++++ users/test/support/integration_test_helper.rb | 12 --- 6 files changed, 141 insertions(+), 115 deletions(-) create mode 100644 users/test/integration/api/pgp_key_test.rb delete mode 100644 users/test/integration/api/rack_test.rb create mode 100644 users/test/integration/api/srp_test.rb delete mode 100644 users/test/support/integration_test_helper.rb (limited to 'users/test') diff --git a/users/test/integration/api/account_flow_test.rb b/users/test/integration/api/account_flow_test.rb index edd0859..b56d07b 100644 --- a/users/test/integration/api/account_flow_test.rb +++ b/users/test/integration/api/account_flow_test.rb @@ -1,50 +1,10 @@ require 'test_helper' -require_relative 'rack_test' +require_relative 'srp_test' -class AccountFlowTest < RackTest +class AccountFlowTest < SrpTest setup do - @login = "integration_test_user" - Identity.find_by_address(@login + '@' + APP_CONFIG[:domain]).tap{|i| i.destroy if i} - User.find_by_login(@login).tap{|u| u.destroy if u} - @password = "srp, verify me!" - @srp = SRP::Client.new @login, :password => @password - @user_params = { - :login => @login, - :password_verifier => @srp.verifier.to_s(16), - :password_salt => @srp.salt.to_s(16) - } - post 'http://api.lvh.me:3000/1/users.json', :user => @user_params - @user = User.find_by_login(@login) - end - - teardown do - if @user.reload - @user.identity.destroy - @user.destroy - end - Warden.test_reset! - end - - # this test wraps the api and implements the interface the ruby-srp client. - def handshake(login, aa) - post "http://api.lvh.me:3000/1/sessions.json", - :login => login, - 'A' => aa, - :format => :json - response = JSON.parse(last_response.body) - if response['errors'] - raise RECORD_NOT_FOUND.new(response['errors']) - else - return response['B'] - end - end - - def validate(m) - put "http://api.lvh.me:3000/1/sessions/" + @login + '.json', - :client_auth => m, - :format => :json - return JSON.parse(last_response.body) + register_user end test "signup response" do @@ -53,25 +13,22 @@ class AccountFlowTest < RackTest end test "signup and login with srp via api" do - server_auth = @srp.authenticate(self) + authenticate assert last_response.successful? assert_nil server_auth["errors"] assert server_auth["M2"] end test "signup and wrong password login attempt" do - srp = SRP::Client.new @login, :password => "wrong password" - server_auth = srp.authenticate(self) + authenticate password: "wrong password" assert_json_error "base" => "Not a valid username/password combination" assert !last_response.successful? assert_nil server_auth["M2"] end test "signup and wrong username login attempt" do - srp = SRP::Client.new "wrong_login", :password => @password - server_auth = nil assert_raises RECORD_NOT_FOUND do - server_auth = srp.authenticate(self) + authenticate login: "wrong login" end assert_json_error "base" => "Not a valid username/password combination" assert !last_response.successful? @@ -79,58 +36,31 @@ class AccountFlowTest < RackTest end test "update password via api" do - @srp.authenticate(self) - @password = "No! Verify me instead." - @srp = SRP::Client.new @login, :password => @password - @user_params = { - # :login => @login, - :password_verifier => @srp.verifier.to_s(16), - :password_salt => @srp.salt.to_s(16) - } - put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', - :user => @user_params, - :format => :json - server_auth = @srp.authenticate(self) + authenticate + update_user password: "No! Verify me instead." + authenticate assert last_response.successful? assert_nil server_auth["errors"] assert server_auth["M2"] end + test "change login with password_verifier" do + authenticate + new_login = 'zaph' + cleanup_user new_login + update_user login: new_login, password: @password + assert last_response.successful? + assert_equal new_login, @user.reload.login + end + test "prevent changing login without changing password_verifier" do - server_auth = @srp.authenticate(self) + authenticate original_login = @user.login new_login = 'zaph' - User.find_by_login(new_login).try(:destroy) - Identity.by_address.key(new_login + '@' + APP_CONFIG[:domain]).each do |identity| - identity.destroy - end - put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', :user => {:login => new_login}, :format => :json + cleanup_user new_login + update_user login: new_login assert last_response.successful? # does not change login if no password_verifier is present - assert_equal original_login, @user.login - end - - test "upload pgp key" do - server_auth = @srp.authenticate(self) - key = FactoryGirl.build :pgp_key - put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', :user => {:public_key => key}, :format => :json - assert_equal key, Identity.for(@user).keys[:pgp] + assert_equal original_login, @user.reload.login end - - # eventually probably want to remove most of this into a non-integration - # functional test - test "prevent uploading invalid key" do - server_auth = @srp.authenticate(self) - put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', :user => {:public_key => :blah}, :format => :json - assert_nil Identity.for(@user).keys[:pgp] - end - - test "prevent emptying public key" do - server_auth = @srp.authenticate(self) - key = FactoryGirl.build :pgp_key - put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', :user => {:public_key => key}, :format => :json - put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', :user => {:public_key => ""}, :format => :json - assert_equal key, Identity.for(@user).keys[:pgp] - end - end diff --git a/users/test/integration/api/login_test.rb b/users/test/integration/api/login_test.rb index fb761e5..a760d38 100644 --- a/users/test/integration/api/login_test.rb +++ b/users/test/integration/api/login_test.rb @@ -1,7 +1,6 @@ require 'test_helper' -require_relative 'rack_test' -class AccountFlowTest < RackTest +class LoginTest < RackTest setup do @login = "integration_test_user" diff --git a/users/test/integration/api/pgp_key_test.rb b/users/test/integration/api/pgp_key_test.rb new file mode 100644 index 0000000..4c7fb4c --- /dev/null +++ b/users/test/integration/api/pgp_key_test.rb @@ -0,0 +1,35 @@ +require 'test_helper' +require_relative 'srp_test' + +class PgpKeyTest < SrpTest + + setup do + # todo: prepare user and login without doing the srp dance + register_user + authenticate + end + + test "upload pgp key" do + update_user public_key: key + assert_equal key, Identity.for(@user).keys[:pgp] + end + + # eventually probably want to remove most of this into a non-integration + # functional test + test "prevent uploading invalid key" do + update_user public_key: "invalid key" + assert_nil Identity.for(@user).keys[:pgp] + end + + test "prevent emptying public key" do + update_user public_key: key + update_user public_key: "" + assert_equal key, Identity.for(@user).keys[:pgp] + end + + protected + + def key + @key ||= FactoryGirl.build :pgp_key + end +end diff --git a/users/test/integration/api/rack_test.rb b/users/test/integration/api/rack_test.rb deleted file mode 100644 index 9a69f52..0000000 --- a/users/test/integration/api/rack_test.rb +++ /dev/null @@ -1,9 +0,0 @@ -class RackTest < ActiveSupport::TestCase - include Rack::Test::Methods - include Warden::Test::Helpers - include LeapWebCore::AssertResponses - - def app - OUTER_APP - end -end diff --git a/users/test/integration/api/srp_test.rb b/users/test/integration/api/srp_test.rb new file mode 100644 index 0000000..b291269 --- /dev/null +++ b/users/test/integration/api/srp_test.rb @@ -0,0 +1,83 @@ +class SrpTest < RackTest + + teardown do + if @user + cleanup_user + end + Warden.test_reset! + end + + # this test wraps the api and implements the interface the ruby-srp client. + def handshake(login, aa) + post "http://api.lvh.me:3000/1/sessions.json", + :login => login, + 'A' => aa, + :format => :json + response = JSON.parse(last_response.body) + if response['errors'] + raise RECORD_NOT_FOUND.new(response['errors']) + else + return response['B'] + end + end + + def validate(m) + put "http://api.lvh.me:3000/1/sessions/" + @login + '.json', + :client_auth => m, + :format => :json + return JSON.parse(last_response.body) + end + + protected + + attr_reader :server_auth + + def register_user(login = "integration_test_user", password = 'srp, verify me!') + cleanup_user(login) + post 'http://api.lvh.me:3000/1/users.json', + user: user_params(login: login, password: password), + format: :json + @user = User.find_by_login(login) + @login = login + @password = password + end + + def update_user(params) + put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', + :user => user_params(params), + :format => :json + end + + def authenticate(params = nil) + @server_auth = srp(params).authenticate(self) + end + + def cleanup_user(login = nil) + login ||= @user.login + Identity.by_address.key(login + '@' + APP_CONFIG[:domain]).each do |identity| + identity.destroy + end + if user = User.find_by_login(login) + user.destroy + end + end + + def user_params(params) + # if there is no srp magic needed just return the params + return params unless params.keys.include?(:password) + params.reverse_merge! login: @login, salt: @salt + @srp = SRP::Client.new params[:login], password: params.delete(:password) + @salt = srp.salt.to_s(16) + params.merge :password_verifier => srp.verifier.to_s(16), + :password_salt => @salt + end + + def srp(params = nil) + if params.nil? + @srp + else + params.reverse_merge! password: @password + SRP::Client.new(params.delete(:login) || @login, params) + end + end +end diff --git a/users/test/support/integration_test_helper.rb b/users/test/support/integration_test_helper.rb deleted file mode 100644 index 51e47c6..0000000 --- a/users/test/support/integration_test_helper.rb +++ /dev/null @@ -1,12 +0,0 @@ -module IntegrationTestHelper - def submit_signup(username = nil, password = nil) - username ||= "test_#{SecureRandom.urlsafe_base64}".downcase - password ||= SecureRandom.base64 - visit '/users/new' - fill_in 'Username', with: username - fill_in 'Password', with: password - fill_in 'Password confirmation', with: password - click_on 'Sign Up' - return username, password - end -end -- cgit v1.2.3 From 758b9a3c30a73fd985943fb7a887f0373be3a833 Mon Sep 17 00:00:00 2001 From: Azul Date: Sat, 8 Feb 2014 12:29:08 +0100 Subject: split up and expand account integration test --- users/test/integration/api/account_flow_test.rb | 66 ----------------------- users/test/integration/api/login_test.rb | 38 +++++++++++-- users/test/integration/api/signup_test.rb | 20 +++++++ users/test/integration/api/srp_test.rb | 5 ++ users/test/integration/api/update_account_test.rb | 44 +++++++++++++++ 5 files changed, 102 insertions(+), 71 deletions(-) delete mode 100644 users/test/integration/api/account_flow_test.rb create mode 100644 users/test/integration/api/signup_test.rb create mode 100644 users/test/integration/api/update_account_test.rb (limited to 'users/test') diff --git a/users/test/integration/api/account_flow_test.rb b/users/test/integration/api/account_flow_test.rb deleted file mode 100644 index b56d07b..0000000 --- a/users/test/integration/api/account_flow_test.rb +++ /dev/null @@ -1,66 +0,0 @@ -require 'test_helper' -require_relative 'srp_test' - -class AccountFlowTest < SrpTest - - setup do - register_user - end - - test "signup response" do - assert_json_response :login => @login, :ok => true - assert last_response.successful? - end - - test "signup and login with srp via api" do - authenticate - assert last_response.successful? - assert_nil server_auth["errors"] - assert server_auth["M2"] - end - - test "signup and wrong password login attempt" do - authenticate password: "wrong password" - assert_json_error "base" => "Not a valid username/password combination" - assert !last_response.successful? - assert_nil server_auth["M2"] - end - - test "signup and wrong username login attempt" do - assert_raises RECORD_NOT_FOUND do - authenticate login: "wrong login" - end - assert_json_error "base" => "Not a valid username/password combination" - assert !last_response.successful? - assert_nil server_auth - end - - test "update password via api" do - authenticate - update_user password: "No! Verify me instead." - authenticate - assert last_response.successful? - assert_nil server_auth["errors"] - assert server_auth["M2"] - end - - test "change login with password_verifier" do - authenticate - new_login = 'zaph' - cleanup_user new_login - update_user login: new_login, password: @password - assert last_response.successful? - assert_equal new_login, @user.reload.login - end - - test "prevent changing login without changing password_verifier" do - authenticate - original_login = @user.login - new_login = 'zaph' - cleanup_user new_login - update_user login: new_login - assert last_response.successful? - # does not change login if no password_verifier is present - assert_equal original_login, @user.reload.login - end -end diff --git a/users/test/integration/api/login_test.rb b/users/test/integration/api/login_test.rb index a760d38..82219d0 100644 --- a/users/test/integration/api/login_test.rb +++ b/users/test/integration/api/login_test.rb @@ -1,15 +1,43 @@ require 'test_helper' +require_relative 'srp_test' -class LoginTest < RackTest +class LoginTest < SrpTest setup do - @login = "integration_test_user" + register_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" + test "requires handshake before validation" do + validate("bla") assert_json_error login: I18n.t(:all_strategies_failed) end + test "login with srp" do + authenticate + assert last_response.successful? + assert_nil server_auth["errors"] + assert server_auth["M2"] + end + + test "wrong password login attempt" do + authenticate password: "wrong password" + assert_json_error "base" => "Not a valid username/password combination" + assert !last_response.successful? + assert_nil server_auth["M2"] + end + + test "wrong username login attempt" do + assert_raises RECORD_NOT_FOUND do + authenticate login: "wrong login" + end + assert_json_error "base" => "Not a valid username/password combination" + assert !last_response.successful? + assert_nil server_auth + end + + test "logout" do + authenticate + logout + assert_equal 204, last_response.status + end end diff --git a/users/test/integration/api/signup_test.rb b/users/test/integration/api/signup_test.rb new file mode 100644 index 0000000..236c547 --- /dev/null +++ b/users/test/integration/api/signup_test.rb @@ -0,0 +1,20 @@ +require 'test_helper' +require_relative 'srp_test' + +class SignupTest < SrpTest + + setup do + register_user + end + + test "signup response" do + assert_json_response :login => @login, :ok => true + assert last_response.successful? + end + + test "signup creates user" do + assert @user + assert_equal @login, @user.login + end +end + diff --git a/users/test/integration/api/srp_test.rb b/users/test/integration/api/srp_test.rb index b291269..bb24f5f 100644 --- a/users/test/integration/api/srp_test.rb +++ b/users/test/integration/api/srp_test.rb @@ -52,6 +52,11 @@ class SrpTest < RackTest @server_auth = srp(params).authenticate(self) end + def logout + delete "http://api.lvh.me:3000/1/logout.json", + format: :json + end + def cleanup_user(login = nil) login ||= @user.login Identity.by_address.key(login + '@' + APP_CONFIG[:domain]).each do |identity| diff --git a/users/test/integration/api/update_account_test.rb b/users/test/integration/api/update_account_test.rb new file mode 100644 index 0000000..16c2357 --- /dev/null +++ b/users/test/integration/api/update_account_test.rb @@ -0,0 +1,44 @@ +require 'test_helper' +require_relative 'srp_test' + +class UpdateAccountTest < SrpTest + + setup do + register_user + end + + test "require authentication" do + update_user password: "No! Verify me instead." + assert_access_denied + end + + test "update password via api" do + authenticate + update_user password: "No! Verify me instead." + authenticate + assert last_response.successful? + assert_nil server_auth["errors"] + assert server_auth["M2"] + end + + test "change login with password_verifier" do + authenticate + new_login = 'zaph' + cleanup_user new_login + update_user login: new_login, password: @password + authenticate + assert last_response.successful? + assert_equal new_login, @user.reload.login + end + + test "prevent changing login without changing password_verifier" do + authenticate + original_login = @user.login + new_login = 'zaph' + cleanup_user new_login + update_user login: new_login + assert last_response.successful? + # does not change login if no password_verifier is present + assert_equal original_login, @user.reload.login + end +end -- cgit v1.2.3 From cbd757cf151cd61bfdd5637d09f43e4831fec3bb Mon Sep 17 00:00:00 2001 From: Azul Date: Sat, 8 Feb 2014 16:15:46 +0100 Subject: require token when updating user via API --- users/test/integration/api/login_test.rb | 1 + users/test/integration/api/srp_test.rb | 29 +++++++++++++++++------ users/test/integration/api/update_account_test.rb | 7 ++++++ 3 files changed, 30 insertions(+), 7 deletions(-) (limited to 'users/test') diff --git a/users/test/integration/api/login_test.rb b/users/test/integration/api/login_test.rb index 82219d0..d56dfd1 100644 --- a/users/test/integration/api/login_test.rb +++ b/users/test/integration/api/login_test.rb @@ -14,6 +14,7 @@ class LoginTest < SrpTest test "login with srp" do authenticate + assert_equal ["M2", "id", "token"], server_auth.keys assert last_response.successful? assert_nil server_auth["errors"] assert server_auth["M2"] diff --git a/users/test/integration/api/srp_test.rb b/users/test/integration/api/srp_test.rb index bb24f5f..fcda187 100644 --- a/users/test/integration/api/srp_test.rb +++ b/users/test/integration/api/srp_test.rb @@ -35,8 +35,7 @@ class SrpTest < RackTest def register_user(login = "integration_test_user", password = 'srp, verify me!') cleanup_user(login) post 'http://api.lvh.me:3000/1/users.json', - user: user_params(login: login, password: password), - format: :json + user_params(login: login, password: password) @user = User.find_by_login(login) @login = login @password = password @@ -44,14 +43,25 @@ class SrpTest < RackTest def update_user(params) put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', - :user => user_params(params), - :format => :json + user_params(params), + auth_headers end def authenticate(params = nil) @server_auth = srp(params).authenticate(self) end + def auth_headers + return {} if @server_auth.nil? + { + "HTTP_AUTHORIZATION" => encoded_token + } + end + + def encoded_token + ActionController::HttpAuthentication::Token.encode_credentials(server_auth["token"]) + end + def logout delete "http://api.lvh.me:3000/1/logout.json", format: :json @@ -68,12 +78,17 @@ class SrpTest < RackTest end def user_params(params) - # if there is no srp magic needed just return the params - return params unless params.keys.include?(:password) + if params.keys.include?(:password) + srp_process_password(params) + end + return { user: params, format: :json } + end + + def srp_process_password(params) params.reverse_merge! login: @login, salt: @salt @srp = SRP::Client.new params[:login], password: params.delete(:password) @salt = srp.salt.to_s(16) - params.merge :password_verifier => srp.verifier.to_s(16), + params.merge! :password_verifier => srp.verifier.to_s(16), :password_salt => @salt end diff --git a/users/test/integration/api/update_account_test.rb b/users/test/integration/api/update_account_test.rb index 16c2357..63429e7 100644 --- a/users/test/integration/api/update_account_test.rb +++ b/users/test/integration/api/update_account_test.rb @@ -12,6 +12,13 @@ class UpdateAccountTest < SrpTest assert_access_denied end + test "require token" do + authenticate + put "http://api.lvh.me:3000/1/users/" + @user.id + '.json', + user_params(password: "No! Verify me instead.") + assert_access_denied + end + test "update password via api" do authenticate update_user password: "No! Verify me instead." -- cgit v1.2.3 From c8fcd0d26c3ad5c1c3cfbaf6b57239f907925ed6 Mon Sep 17 00:00:00 2001 From: Azul Date: Sat, 8 Feb 2014 16:20:37 +0100 Subject: require token when logging out via API --- users/test/integration/api/login_test.rb | 6 ++++++ users/test/integration/api/srp_test.rb | 5 +++-- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'users/test') diff --git a/users/test/integration/api/login_test.rb b/users/test/integration/api/login_test.rb index d56dfd1..92d153f 100644 --- a/users/test/integration/api/login_test.rb +++ b/users/test/integration/api/login_test.rb @@ -41,4 +41,10 @@ class LoginTest < SrpTest logout assert_equal 204, last_response.status end + + test "logout requires token" do + authenticate + logout(nil, {}) + assert_equal 422, last_response.status + end end diff --git a/users/test/integration/api/srp_test.rb b/users/test/integration/api/srp_test.rb index fcda187..946450e 100644 --- a/users/test/integration/api/srp_test.rb +++ b/users/test/integration/api/srp_test.rb @@ -62,9 +62,10 @@ class SrpTest < RackTest ActionController::HttpAuthentication::Token.encode_credentials(server_auth["token"]) end - def logout + def logout(params=nil, headers=nil) delete "http://api.lvh.me:3000/1/logout.json", - format: :json + params || {format: :json}, + headers || auth_headers end def cleanup_user(login = nil) -- cgit v1.2.3