require "test_helper" module PrxAuth::Rails::Ext class ControllerTest < ActionController::TestCase setup do @controller = ApplicationController.new @jwt_session_key = ApplicationController::PRX_JWT_SESSION_KEY @user_info_key = ApplicationController::PRX_USER_INFO_SESSION_KEY @account_mapping_key = ApplicationController::PRX_ACCOUNT_MAPPING_SESSION_KEY @stub_claims = {"iat" => Time.now.to_i, "exp" => Time.now.to_i + 3600} end # stub auth and init controller+session by getting a page def with_stubbed_auth(jwt) session[@jwt_session_key] = "some-jwt" @controller.stub(:prx_auth_needs_refresh?, false) do get :index assert_equal response.code, "200" yield end end test "redirects unless you are authenticated" do get :index assert_equal response.code, "302" assert response.headers["Location"].ends_with?("/sessions/new") end test "uses a valid session token" do session[@jwt_session_key] = "some-jwt" JSON::JWT.stub(:decode, @stub_claims) do get :index assert_equal response.code, "200" assert response.body.include?("the controller index!") assert @controller.current_user.is_a?(PrxAuth::Rails::Token) end end test "redirects if your token is nearing expiration" do session[@jwt_session_key] = "some-jwt" @stub_claims["exp"] = Time.now.to_i + 10 JSON::JWT.stub(:decode, @stub_claims) do get :index assert_equal response.code, "302" assert response.headers["Location"].ends_with?("/sessions/new") end end test "does not redirect if your token has expired on a non-GET request" do session[@jwt_session_key] = "some-jwt" @stub_claims["exp"] = Time.now.to_i + 10 JSON::JWT.stub(:decode, @stub_claims) do put :index assert_equal response.code, "200" assert response.body.include?("the controller index!") end end test "fetches current user info" do with_stubbed_auth("some-jwt") do body = { "name" => "Some Username", "apps" => {"publish.prx.test" => "https://publish.prx.test"}, "other" => "stuff" } id_host = PrxAuth::Rails.configuration.id_host stub_request(:get, "https://#{id_host}/userinfo?scope=apps%20email%20profile") .with(headers: {"Authorization" => "Bearer some-jwt"}) .to_return(status: 200, body: JSON.generate(body)) assert session[@user_info_key].nil? assert_equal @controller.current_user_info, body.slice("name", "apps") refute session[@user_info_key].nil? assert_equal @controller.current_user_name, "Some Username" assert_equal @controller.current_user_apps, {"PRX Publish" => "https://publish.prx.test"} end end test "has user name fallbacks" do with_stubbed_auth("some-jwt") do session[@user_info_key] = {"name" => "one", "preferred_username" => "two", "email" => "three"} assert_equal @controller.current_user_name, "one" session[@user_info_key] = {"preferred_username" => "two", "email" => "three"} assert_equal @controller.current_user_name, "two" session[@user_info_key] = {"email" => "three"} assert_equal @controller.current_user_name, "three" end end test "filters apps displayed in production" do with_stubbed_auth("some-jwt") do Rails.env.stub(:production?, true) do session[@user_info_key] = { "apps" => { "localhost stuff" => "http://localhost:4000/path1", "publish.prx.test" => "https://publish.prx.test/path2", "metrics.prx.tech" => "https://metrics.prx.tech/path3", "augury.prx.org" => "https://augury.prx.org/path4" } } assert_equal @controller.current_user_apps, { "PRX Metrics" => "https://metrics.prx.tech/path3", "PRX Augury" => "https://augury.prx.org/path4" } end end end test "fetches accounts" do with_stubbed_auth("some-jwt") do one = {"id" => 1, "type" => "IndividualAccount", "name" => "One"} three = {"id" => 3, "type" => "GroupAccount", "name" => "Three"} body = {"_embedded" => {"prx:items" => [one, three]}} min_one = one.slice("name", "type") min_three = three.slice("name", "type") id_host = PrxAuth::Rails.configuration.id_host stub_request(:get, "https://#{id_host}/api/v1/accounts?account_ids=1,2,3") .to_return(status: 200, body: JSON.generate(body)) assert_nil session[@account_mapping_key] assert_equal @controller.accounts_for([1, 2, 3]), [min_one, nil, min_three] refute_nil session[@account_mapping_key] assert_equal @controller.account_for(1), min_one assert_equal @controller.account_for(3), min_three assert_equal @controller.account_name_for(1), "One" assert_equal @controller.account_name_for(3), "Three" end end test "handles unknown account ids" do with_stubbed_auth("some-jwt") do id_host = PrxAuth::Rails.configuration.id_host stub_request(:get, "https://#{id_host}/api/v1/accounts?account_ids=2") .to_return(status: 200, body: JSON.generate({"_embedded" => {"prx:items" => []}})) .times(3) assert_equal @controller.accounts_for([2]), [nil] assert_nil @controller.account_for(2) assert_nil @controller.account_name_for(2) end end test "only fetches only missing accounts" do with_stubbed_auth("some-jwt") do one = {"name" => "One"} two = {"id" => 2, "type" => "StationAccount", "name" => "Two"} three = {"name" => "Three"} session[@account_mapping_key] = {1 => one, 3 => three} body = {"_embedded" => {"prx:items" => [two]}} min_one = one.slice("name", "type") min_two = two.slice("name", "type") min_three = three.slice("name", "type") id_host = PrxAuth::Rails.configuration.id_host stub_request(:get, "https://#{id_host}/api/v1/accounts?account_ids=2") .to_return(status: 200, body: JSON.generate(body)) assert_equal @controller.accounts_for([1, 2, 3]), [min_one, min_two, min_three] assert_equal @controller.account_for(2), min_two assert_equal @controller.account_name_for(2), "Two" end end end end