summaryrefslogtreecommitdiff
path: root/users/test/integration/api
diff options
context:
space:
mode:
authorjessib <jessib@riseup.net>2014-02-10 10:27:52 -0800
committerjessib <jessib@riseup.net>2014-02-10 10:27:52 -0800
commitb6ef51277b4e6d65cfda15f0124ae4f222f7f241 (patch)
treeda7eb2d3a3a648be0be519aae23f997f248ba320 /users/test/integration/api
parentbcdde2f6bfb4ed3a1535bd2e50ab47529a9141e2 (diff)
parentb4719619aabbe9ebf74563b62e1eb8e4fb248c21 (diff)
Merge pull request #138 from azul/feature/token-only-api-auth
Feature/token only api auth
Diffstat (limited to 'users/test/integration/api')
-rw-r--r--users/test/integration/api/account_flow_test.rb136
-rw-r--r--users/test/integration/api/login_test.rb46
-rw-r--r--users/test/integration/api/pgp_key_test.rb35
-rw-r--r--users/test/integration/api/rack_test.rb9
-rw-r--r--users/test/integration/api/signup_test.rb20
-rw-r--r--users/test/integration/api/srp_test.rb104
-rw-r--r--users/test/integration/api/update_account_test.rb51
7 files changed, 250 insertions, 151 deletions
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 edd0859..0000000
--- a/users/test/integration/api/account_flow_test.rb
+++ /dev/null
@@ -1,136 +0,0 @@
-require 'test_helper'
-require_relative 'rack_test'
-
-class AccountFlowTest < RackTest
-
- 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)
- 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
- server_auth = @srp.authenticate(self)
- 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)
- 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)
- 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
- @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)
- assert last_response.successful?
- assert_nil server_auth["errors"]
- assert server_auth["M2"]
- end
-
- test "prevent changing login without changing password_verifier" do
- server_auth = @srp.authenticate(self)
- 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
- 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]
- 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..92d153f 100644
--- a/users/test/integration/api/login_test.rb
+++ b/users/test/integration/api/login_test.rb
@@ -1,16 +1,50 @@
require 'test_helper'
-require_relative 'rack_test'
+require_relative 'srp_test'
-class AccountFlowTest < 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_equal ["M2", "id", "token"], server_auth.keys
+ 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
+
+ test "logout requires token" do
+ authenticate
+ logout(nil, {})
+ assert_equal 422, last_response.status
+ end
end
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/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
new file mode 100644
index 0000000..946450e
--- /dev/null
+++ b/users/test/integration/api/srp_test.rb
@@ -0,0 +1,104 @@
+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_params(login: login, password: password)
+ @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_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(params=nil, headers=nil)
+ delete "http://api.lvh.me:3000/1/logout.json",
+ params || {format: :json},
+ headers || auth_headers
+ 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 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),
+ :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/integration/api/update_account_test.rb b/users/test/integration/api/update_account_test.rb
new file mode 100644
index 0000000..63429e7
--- /dev/null
+++ b/users/test/integration/api/update_account_test.rb
@@ -0,0 +1,51 @@
+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 "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."
+ 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