From 19f81ff5e75bdc771cdd6aa7b3d97b74691b9027 Mon Sep 17 00:00:00 2001 From: Chris Preisinger Date: Wed, 21 Aug 2024 13:58:22 -0400 Subject: [PATCH 01/11] 56 WIP shared session storage configuration --- app/controllers/application_controller.rb | 11 +++++++++-- config/initializers/session_store.rb | 10 ++++++++++ 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 config/initializers/session_store.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index b895df11..ab7553c9 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -22,20 +22,27 @@ def sign_in(login_userinfo) @current_user = user renew_session session[:userinfo] = login_userinfo + session[:user_token] = user.token + session[:user_id] = user.id end def sign_out @current_user = nil session.delete(:userinfo) session.delete(:session_timeout_at) + session.delete(:user_token) + session.delete(:user_id) end def renew_session - session[:session_timeout_at] = Time.current + ENV.fetch("SESSION_TIMEOUT_IN_MINUTES", 15).to_i.minutes + session[:session_timeout_at] = (Time.current + ENV.fetch("SESSION_TIMEOUT_IN_MINUTES", 15).to_i.minutes).to_i end def check_session_expiration - if session[:session_timeout_at].present? && session[:session_timeout_at] < Time.current + puts("SESSION") + puts(session.to_h) + if session[:session_timeout_at].present? && session[:session_timeout_at] < Time.current.to_i + puts("Signing out") sign_out redirect_to dashboard_path, alert: I18n.t("session_expired_alert") else diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb new file mode 100644 index 00000000..afa5d5a9 --- /dev/null +++ b/config/initializers/session_store.rb @@ -0,0 +1,10 @@ +# config/initializer/session_store.rb +# Use cookie session storage in JSON format. Here, we scope the cookie to the root domain. +# Rails.application.config.session_store :cookie_store, key: '_rails_app_session', domain: ".#{ENV['DOMAIN']}" +Rails.application.config.session_store :cookie_store, key: '_rails_app_session', domain: "localhost" +Rails.application.config.action_dispatch.cookies_serializer = :json +# These salts are optional, but it doesn't hurt to explicitly configure them the same between the two apps. +# Rails.application.config.action_dispatch.encrypted_cookie_salt = ENV['SESSION_ENCRYPTED_COOKIE_SALT'] +# Rails.application.config.action_dispatch.encrypted_signed_cookie_salt = ENV['SESSION_ENCRYPTED_SIGNED_COOKIE_SALT']" +Rails.application.config.action_dispatch.encrypted_cookie_salt = "+S7HWPoL" +Rails.application.config.action_dispatch.encrypted_signed_cookie_salt = "encryption salt" \ No newline at end of file From 5897b886a6240c7e2617659d1f4528e2a633489d Mon Sep 17 00:00:00 2001 From: Chris Preisinger Date: Thu, 29 Aug 2024 20:44:04 -0400 Subject: [PATCH 02/11] Revert "56 WIP shared session storage configuration" This reverts commit 19f81ff5e75bdc771cdd6aa7b3d97b74691b9027. --- app/controllers/application_controller.rb | 11 ++--------- config/initializers/session_store.rb | 10 ---------- 2 files changed, 2 insertions(+), 19 deletions(-) delete mode 100644 config/initializers/session_store.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index ab7553c9..b895df11 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -22,27 +22,20 @@ def sign_in(login_userinfo) @current_user = user renew_session session[:userinfo] = login_userinfo - session[:user_token] = user.token - session[:user_id] = user.id end def sign_out @current_user = nil session.delete(:userinfo) session.delete(:session_timeout_at) - session.delete(:user_token) - session.delete(:user_id) end def renew_session - session[:session_timeout_at] = (Time.current + ENV.fetch("SESSION_TIMEOUT_IN_MINUTES", 15).to_i.minutes).to_i + session[:session_timeout_at] = Time.current + ENV.fetch("SESSION_TIMEOUT_IN_MINUTES", 15).to_i.minutes end def check_session_expiration - puts("SESSION") - puts(session.to_h) - if session[:session_timeout_at].present? && session[:session_timeout_at] < Time.current.to_i - puts("Signing out") + if session[:session_timeout_at].present? && session[:session_timeout_at] < Time.current sign_out redirect_to dashboard_path, alert: I18n.t("session_expired_alert") else diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb deleted file mode 100644 index afa5d5a9..00000000 --- a/config/initializers/session_store.rb +++ /dev/null @@ -1,10 +0,0 @@ -# config/initializer/session_store.rb -# Use cookie session storage in JSON format. Here, we scope the cookie to the root domain. -# Rails.application.config.session_store :cookie_store, key: '_rails_app_session', domain: ".#{ENV['DOMAIN']}" -Rails.application.config.session_store :cookie_store, key: '_rails_app_session', domain: "localhost" -Rails.application.config.action_dispatch.cookies_serializer = :json -# These salts are optional, but it doesn't hurt to explicitly configure them the same between the two apps. -# Rails.application.config.action_dispatch.encrypted_cookie_salt = ENV['SESSION_ENCRYPTED_COOKIE_SALT'] -# Rails.application.config.action_dispatch.encrypted_signed_cookie_salt = ENV['SESSION_ENCRYPTED_SIGNED_COOKIE_SALT']" -Rails.application.config.action_dispatch.encrypted_cookie_salt = "+S7HWPoL" -Rails.application.config.action_dispatch.encrypted_signed_cookie_salt = "encryption salt" \ No newline at end of file From 2fb142cd0624adfe8907f5d03a45bd71fa287139 Mon Sep 17 00:00:00 2001 From: Chris Preisinger Date: Mon, 9 Sep 2024 09:00:22 -0400 Subject: [PATCH 03/11] 56 Shared session API with phoenix app --- .envrc | 4 ++ app/controllers/application_controller.rb | 48 +++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/.envrc b/.envrc index 4fbb075a..1ecfb9d7 100644 --- a/.envrc +++ b/.envrc @@ -5,5 +5,9 @@ use nix mkdir -p .nix-bundler export BUNDLE_PATH=./.nix-bundler +export LOGIN_SECRET="f4d3c40a00a8e6ed72fae5204d9ddacd40f087865d40803a6fcfb935591a271838533f06081067dac24c0085c74123e7e1c8b3e0ab562c6645b17eb769854d0d" +export JWT_SECRET="fc28c5738ca45162f61126e770a8fbdbd938d0fedcfe8fbb9f851b855b0264866364a9130e96aca8b1977e9f58edf064f1aa435ceccf415ff22fd3c24adba320" +export PHOENIX_URI="http://localhost:4000" + # Login Env Vars source .env_login diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 88d1fe77..aad495da 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -19,6 +19,9 @@ def logged_in? def sign_in(login_userinfo) user = User.user_from_userinfo(login_userinfo) + user_jwt = generate_user_jwt(user) + send_user_jwt_to_phoenix(user_jwt) + @current_user = user renew_session session[:userinfo] = login_userinfo @@ -50,4 +53,49 @@ def redirect_if_logged_in(path = "/dashboard") redirect_to path, notice: I18n.t("already_logged_in_notice") end + + def generate_user_jwt(user) + payload = { + email: user.email, + sub: user.token, + exp: 24.hours.from_now.to_i + } + + JWT.encode(payload, ENV.fetch('JWT_SECRET', nil), 'HS256') + end + + def send_user_jwt_to_phoenix(jwt) + uri = URI("#{ENV.fetch('PHOENIX_URI', nil)}/api/external_login") + + req = Net::HTTP::Post.new(uri) + req['Login-Secret'] = ENV.fetch('LOGIN_SECRET', nil) + req['User-JWT'] = jwt + + res = Net::HTTP.start(uri.hostname, uri.port) do |http| + http.request(req) + end + + phoenix_cookie = extract_phoenix_cookie_from_response(res) + phoenix_session_cookie(phoenix_cookie) + + res.code == '200' + end + + def extract_phoenix_cookie_from_response(res) + cookie_header = res['Set-Cookie'] + cookie_value = cookie_header.split(';').first.split('=').last + + # TODO: Should this have an expires? + { value: cookie_value } + end + + def phoenix_session_cookie(phoenix_cookie) + cookies[:_challenge_gov_key] = { + value: phoenix_cookie[:value], + expires: phoenix_cookie[:expires], + secure: true, + httponly: true, + same_site: :lax + } + end end From 686a726e9e631710333aaa4aaed0d81a49d48a24 Mon Sep 17 00:00:00 2001 From: Chris Preisinger Date: Wed, 11 Sep 2024 17:21:00 -0400 Subject: [PATCH 04/11] 56 Update spec helper with shared session --- .env_login | 6 +++++- .envrc | 4 ---- app/controllers/application_controller.rb | 10 ++++++---- config/application.rb | 6 ++++++ spec/requests/sessions_request_spec.rb | 6 ++++++ spec/spec_helper.rb | 2 ++ 6 files changed, 25 insertions(+), 9 deletions(-) diff --git a/.env_login b/.env_login index de4aac84..e2b5cdc8 100644 --- a/.env_login +++ b/.env_login @@ -1,4 +1,8 @@ # local dev env vars for login.gov export LOGIN_CLIENT_ID=urn:gov:gsa:openidconnect.profiles:sp:sso:gsa:challenge_gov_portal_eval_dev export LOGIN_REDIRECT_EVAL_URL=http://localhost:3000/auth/result -export LOGOUT_REDIRECT_EVAL_URL=http://localhost:3000/ \ No newline at end of file +export LOGOUT_REDIRECT_EVAL_URL=http://localhost:3000/ + +export PHOENIX_URI="http://localhost:4000" +export LOGIN_SECRET="f4d3c40a00a8e6ed72fae5204d9ddacd40f087865d40803a6fcfb935591a271838533f06081067dac24c0085c74123e7e1c8b3e0ab562c6645b17eb769854d0d" +export JWT_SECRET="fc28c5738ca45162f61126e770a8fbdbd938d0fedcfe8fbb9f851b855b0264866364a9130e96aca8b1977e9f58edf064f1aa435ceccf415ff22fd3c24adba320" \ No newline at end of file diff --git a/.envrc b/.envrc index 1ecfb9d7..4fbb075a 100644 --- a/.envrc +++ b/.envrc @@ -5,9 +5,5 @@ use nix mkdir -p .nix-bundler export BUNDLE_PATH=./.nix-bundler -export LOGIN_SECRET="f4d3c40a00a8e6ed72fae5204d9ddacd40f087865d40803a6fcfb935591a271838533f06081067dac24c0085c74123e7e1c8b3e0ab562c6645b17eb769854d0d" -export JWT_SECRET="fc28c5738ca45162f61126e770a8fbdbd938d0fedcfe8fbb9f851b855b0264866364a9130e96aca8b1977e9f58edf064f1aa435ceccf415ff22fd3c24adba320" -export PHOENIX_URI="http://localhost:4000" - # Login Env Vars source .env_login diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index aad495da..eeedc442 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -61,14 +61,14 @@ def generate_user_jwt(user) exp: 24.hours.from_now.to_i } - JWT.encode(payload, ENV.fetch('JWT_SECRET', nil), 'HS256') + JWT.encode(payload, config.phoenix_interop.jwt_secret, 'HS256') end - def send_user_jwt_to_phoenix(jwt) - uri = URI("#{ENV.fetch('PHOENIX_URI', nil)}/api/external_login") + def send_user_jwt_to_phoenix(jwt) + uri = URI("#{config.phoenix_interop.phoenix_uri}/api/external_login") req = Net::HTTP::Post.new(uri) - req['Login-Secret'] = ENV.fetch('LOGIN_SECRET', nil) + req['Login-Secret'] = config.phoenix_interop.login_secret req['User-JWT'] = jwt res = Net::HTTP.start(uri.hostname, uri.port) do |http| @@ -79,6 +79,8 @@ def send_user_jwt_to_phoenix(jwt) phoenix_session_cookie(phoenix_cookie) res.code == '200' + rescue StandardError => e + Rails.logger.error(e) end def extract_phoenix_cookie_from_response(res) diff --git a/config/application.rb b/config/application.rb index 0cc67c9a..52573923 100644 --- a/config/application.rb +++ b/config/application.rb @@ -41,6 +41,12 @@ class Application < Rails::Application private_key_path: ENV.fetch("LOGIN_PRIVATE_KEY_PATH", "config/private.pem"), } + config.phx_interop = { + phx_uri: ENV.fetch("PHOENIX_URI", nil), + login_secret: ENV.fetch("LOGIN_SECRET", "login_secret_123"), + jwt_secret: ENV.fetch("JWT_SECRET", "jwt_secret_123") + } + config.assets.initialize_on_precompile = false end end diff --git a/spec/requests/sessions_request_spec.rb b/spec/requests/sessions_request_spec.rb index 073d53e7..fcbb6508 100644 --- a/spec/requests/sessions_request_spec.rb +++ b/spec/requests/sessions_request_spec.rb @@ -36,6 +36,9 @@ allow(login_gov).to receive(:exchange_token_from_auth_result).with(code).and_return( [{ email: "test@example.com", sub: "sub" }] ) + + expect_any_instance_of(SessionsController).to receive(:send_user_jwt_to_phoenix).with(instance_of(String)).and_return(true) + get "/auth/result", params: { code: } expect(response).to have_http_status(:redirect) expect(response).to redirect_to("/dashboard") @@ -55,6 +58,9 @@ allow(login_gov).to receive(:exchange_token_from_auth_result).with(code).and_return( [{ email:, sub: token }] ) + + expect_any_instance_of(SessionsController).to receive(:send_user_jwt_to_phoenix).with(instance_of(String)).and_return(true) + get "/auth/result", params: { code: } expect(session[:userinfo]).not_to be_nil diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index b0c677be..9377daca 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -26,6 +26,8 @@ def create_and_log_in_user [{ email: user.email, sub: user.token }] ) + expect_any_instance_of(SessionsController).to receive(:send_user_jwt_to_phoenix).with(instance_of(String)).and_return(true) + get "/auth/result", params: { code: } user end From 3bfd4af4780e4210d253db1d6f1d265a0b097f0e Mon Sep 17 00:00:00 2001 From: Chris Preisinger Date: Fri, 13 Sep 2024 10:58:20 -0400 Subject: [PATCH 05/11] 56 Test and rubocop fixes --- app/controllers/application_controller.rb | 36 ++++++++++++++--------- spec/requests/sessions_request_spec.rb | 8 +++-- spec/spec_helper.rb | 6 +++- 3 files changed, 33 insertions(+), 17 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index eeedc442..6082aa71 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -29,8 +29,11 @@ def sign_in(login_userinfo) def sign_out @current_user = nil + session.delete(:userinfo) session.delete(:session_timeout_at) + + delete_phoenix_session_cookie end def renew_session @@ -61,20 +64,11 @@ def generate_user_jwt(user) exp: 24.hours.from_now.to_i } - JWT.encode(payload, config.phoenix_interop.jwt_secret, 'HS256') + JWT.encode(payload, Rails.configuration.phx_interop[:jwt_secret], 'HS256') end - def send_user_jwt_to_phoenix(jwt) - uri = URI("#{config.phoenix_interop.phoenix_uri}/api/external_login") - - req = Net::HTTP::Post.new(uri) - req['Login-Secret'] = config.phoenix_interop.login_secret - req['User-JWT'] = jwt - - res = Net::HTTP.start(uri.hostname, uri.port) do |http| - http.request(req) - end - + def send_user_jwt_to_phoenix(jwt) + res = phoenix_external_login_request(jwt) phoenix_cookie = extract_phoenix_cookie_from_response(res) phoenix_session_cookie(phoenix_cookie) @@ -83,21 +77,35 @@ def send_user_jwt_to_phoenix(jwt) Rails.logger.error(e) end + def phoenix_external_login_request(jwt) + uri = URI("#{config.phoenix_interop[:phoenix_uri]}/api/external_login") + + req = Net::HTTP::Post.new(uri) + req['Login-Secret'] = config.phoenix_interop[:login_secret] + req['User-JWT'] = jwt + + Net::HTTP.start(uri.hostname, uri.port) do |http| + http.request(req) + end + end + def extract_phoenix_cookie_from_response(res) cookie_header = res['Set-Cookie'] cookie_value = cookie_header.split(';').first.split('=').last - # TODO: Should this have an expires? { value: cookie_value } end def phoenix_session_cookie(phoenix_cookie) cookies[:_challenge_gov_key] = { value: phoenix_cookie[:value], - expires: phoenix_cookie[:expires], secure: true, httponly: true, same_site: :lax } end + + def delete_phoenix_session_cookie + cookies.delete(:_challenge_gov_key) + end end diff --git a/spec/requests/sessions_request_spec.rb b/spec/requests/sessions_request_spec.rb index fcbb6508..0a0dab31 100644 --- a/spec/requests/sessions_request_spec.rb +++ b/spec/requests/sessions_request_spec.rb @@ -37,7 +37,9 @@ [{ email: "test@example.com", sub: "sub" }] ) - expect_any_instance_of(SessionsController).to receive(:send_user_jwt_to_phoenix).with(instance_of(String)).and_return(true) + # rubocop:disable Layout/LineLength, RSpec/AnyInstance + allow_any_instance_of(SessionsController).to receive(:send_user_jwt_to_phoenix).with(instance_of(String)).and_return(true) + # rubocop:enable Layout/LineLength, RSpec/AnyInstance get "/auth/result", params: { code: } expect(response).to have_http_status(:redirect) @@ -59,7 +61,9 @@ [{ email:, sub: token }] ) - expect_any_instance_of(SessionsController).to receive(:send_user_jwt_to_phoenix).with(instance_of(String)).and_return(true) + # rubocop:disable Layout/LineLength, RSpec/AnyInstance + allow_any_instance_of(SessionsController).to receive(:send_user_jwt_to_phoenix).with(instance_of(String)).and_return(true) + # rubocop:enable Layout/LineLength, RSpec/AnyInstance get "/auth/result", params: { code: } diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 9377daca..b76d6eeb 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -17,6 +17,7 @@ config.shared_context_metadata_behavior = :apply_to_host_groups end +# rubocop:disable Metrics/AbcSize def create_and_log_in_user user = create_user code = "ABC123" @@ -26,11 +27,14 @@ def create_and_log_in_user [{ email: user.email, sub: user.token }] ) - expect_any_instance_of(SessionsController).to receive(:send_user_jwt_to_phoenix).with(instance_of(String)).and_return(true) + # rubocop:disable Layout/LineLength, RSpec/AnyInstance + allow_any_instance_of(SessionsController).to receive(:send_user_jwt_to_phoenix).with(instance_of(String)).and_return(true) + # rubocop:enable Layout/LineLength, RSpec/AnyInstance get "/auth/result", params: { code: } user end +# rubocop:enable Metrics/AbcSize def create_user email = "testsolver@example.gov" From 272ccf6288b4d75a13c0cfd6c28eba0e05dfea3e Mon Sep 17 00:00:00 2001 From: Chris Preisinger Date: Fri, 13 Sep 2024 12:18:41 -0400 Subject: [PATCH 06/11] 56 Skip some hard to test functions in simplecov --- .simplecov | 2 ++ app/controllers/application_controller.rb | 2 ++ 2 files changed, 4 insertions(+) diff --git a/.simplecov b/.simplecov index 2f52443f..90a22a90 100644 --- a/.simplecov +++ b/.simplecov @@ -29,5 +29,7 @@ SimpleCov.start 'rails' do add_filter '/app/mailers/application_mailer.rb' add_filter '/app/models/application_record.rb' + add_filter '/app/controllers/sandbox_controller.rb' + merge_timeout 1800 end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 6082aa71..a4425e40 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -67,6 +67,7 @@ def generate_user_jwt(user) JWT.encode(payload, Rails.configuration.phx_interop[:jwt_secret], 'HS256') end + # :nocov: def send_user_jwt_to_phoenix(jwt) res = phoenix_external_login_request(jwt) phoenix_cookie = extract_phoenix_cookie_from_response(res) @@ -104,6 +105,7 @@ def phoenix_session_cookie(phoenix_cookie) same_site: :lax } end + # :nocov: def delete_phoenix_session_cookie cookies.delete(:_challenge_gov_key) From 5fd750f8913e6622aa22121d2db294fda7509ac4 Mon Sep 17 00:00:00 2001 From: Chris Preisinger Date: Fri, 13 Sep 2024 16:49:36 -0400 Subject: [PATCH 07/11] 56 Possible fix for logout bug --- app/controllers/application_controller.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index a4425e40..a2778a1b 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -3,7 +3,7 @@ class ApplicationController < ActionController::Base helper_method :current_user, :logged_in? - before_action :check_session_expiration + before_action :check_session_expiration, except: [:sign_out] def current_user return unless session[:userinfo] @@ -78,17 +78,20 @@ def send_user_jwt_to_phoenix(jwt) Rails.logger.error(e) end + # rubocop:disable Metrics/AbcSize def phoenix_external_login_request(jwt) - uri = URI("#{config.phoenix_interop[:phoenix_uri]}/api/external_login") + uri = URI("#{Rails.configuration.phx_interop[:phx_uri]}/api/external_login") req = Net::HTTP::Post.new(uri) - req['Login-Secret'] = config.phoenix_interop[:login_secret] + req['Login-Secret'] = Rails.configuration.phx_interop[:login_secret] req['User-JWT'] = jwt + req['Remote-IP'] = request.remote_ip Net::HTTP.start(uri.hostname, uri.port) do |http| http.request(req) end end + # rubocop:enable Metrics/AbcSize def extract_phoenix_cookie_from_response(res) cookie_header = res['Set-Cookie'] From 28da7207d86027dc9d36bf81d69d01ff1d6204ef Mon Sep 17 00:00:00 2001 From: Stephen Chudleigh Date: Mon, 16 Sep 2024 16:58:09 -0700 Subject: [PATCH 08/11] add dynamic links to phx app --- app/helpers/dashboard_helper.rb | 40 +++++++++++++++++++++++------ app/views/layouts/_utility_menu.erb | 2 +- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/app/helpers/dashboard_helper.rb b/app/helpers/dashboard_helper.rb index e054fb09..60f8fc5a 100644 --- a/app/helpers/dashboard_helper.rb +++ b/app/helpers/dashboard_helper.rb @@ -4,23 +4,47 @@ module DashboardHelper def dashboard_cards_by_role { challenge_manager: [ - { image_path: 'emoji_events', href: 'http://localhost:4000/', alt: 'challenges', title: 'Challenges', + { image_path: 'emoji_events', + href: Rails.configuration.phx_interop[:phx_uri], + alt: 'challenges', + title: 'Challenges', subtitle: 'Create and manage challenges.' }, - { image_path: 'people', href: 'manage_submissions', alt: 'submissions', title: 'Submissions', + { image_path: 'people', + href: 'manage_submissions', + alt: 'submissions', + title: 'Submissions', subtitle: 'Manage submissions, evaluations, and evaluators.' }, - { image_path: 'content_copy', href: 'evaluation_forms', alt: 'evaluation forms', title: 'Evaluation Forms', + { image_path: 'content_copy', + href: 'evaluation_forms', + alt: 'evaluation forms', + title: 'Evaluation Forms', subtitle: 'Create and manage evaluation forms.' }, - { image_path: 'map', href: 'user_guide', alt: 'resources', title: 'Resources', + { image_path: 'map', + href: 'user_guide', + alt: 'resources', + title: 'Resources', subtitle: 'Learn how to make the most of the platform.' }, - { image_path: 'support_agent', href: 'federal-agency-faqs', alt: 'help', title: 'Help', + { image_path: 'support_agent', + href: 'federal-agency-faqs', + alt: 'help', + title: 'Help', subtitle: 'Get support on the Challenge.Gov platform.' } ], evaluator: [ - { image_path: 'content_copy', href: 'manage_submissions', alt: 'submissions', title: 'Submissions', + { image_path: 'content_copy', + href: 'manage_submissions', + alt: 'submissions', + title: 'Submissions', subtitle: 'Evaluate my assigned submissions.' }, - { image_path: 'map', href: 'user_guide', alt: 'user guides', title: 'Resources', + { image_path: 'map', + href: 'user_guide', + alt: 'user guides', + title: 'Resources', subtitle: 'Learn how to make the most of the platform.' }, - { image_path: 'support_agent', href: 'federal-agency-faqs', alt: 'help', title: 'Help', + { image_path: 'support_agent', + href: 'federal-agency-faqs', + alt: 'help', + title: 'Help', subtitle: 'Get support on the Challenge.Gov platform.' } ], solver: [] diff --git a/app/views/layouts/_utility_menu.erb b/app/views/layouts/_utility_menu.erb index 1c132557..90afa460 100644 --- a/app/views/layouts/_utility_menu.erb +++ b/app/views/layouts/_utility_menu.erb @@ -2,7 +2,7 @@
<%= utility_menu_link('grid_view', 'dashboard', 'dashboard', 'Dashboard') %> <% if current_user.role == "challenge_manager" %> - <%= utility_menu_link('emoji_events', 'http://localhost:4000/', 'challenges', 'Challenges') %> + <%= utility_menu_link('emoji_events', Rails.configuration.phx_interop[:phx_uri], 'challenges', 'Challenges') %> <%= utility_menu_link('content_copy', 'evaluation_forms', 'Evaluation Forms', 'Evaluations') %> <%= utility_menu_link('folder_open', 'manage_submissions', 'Manage Submissions', 'Submissions') %> <% end %> From 55acd12333e85287e3ced75456252348ac1cd5b6 Mon Sep 17 00:00:00 2001 From: Stephen Chudleigh Date: Mon, 16 Sep 2024 17:01:17 -0700 Subject: [PATCH 09/11] linter fixes --- app/helpers/dashboard_helper.rb | 56 ++++++++++----------------------- spec/spec_helper.rb | 2 ++ 2 files changed, 18 insertions(+), 40 deletions(-) diff --git a/app/helpers/dashboard_helper.rb b/app/helpers/dashboard_helper.rb index 60f8fc5a..5e0d8fb8 100644 --- a/app/helpers/dashboard_helper.rb +++ b/app/helpers/dashboard_helper.rb @@ -4,48 +4,24 @@ module DashboardHelper def dashboard_cards_by_role { challenge_manager: [ - { image_path: 'emoji_events', - href: Rails.configuration.phx_interop[:phx_uri], - alt: 'challenges', - title: 'Challenges', - subtitle: 'Create and manage challenges.' }, - { image_path: 'people', - href: 'manage_submissions', - alt: 'submissions', - title: 'Submissions', - subtitle: 'Manage submissions, evaluations, and evaluators.' }, - { image_path: 'content_copy', - href: 'evaluation_forms', - alt: 'evaluation forms', - title: 'Evaluation Forms', - subtitle: 'Create and manage evaluation forms.' }, - { image_path: 'map', - href: 'user_guide', - alt: 'resources', - title: 'Resources', - subtitle: 'Learn how to make the most of the platform.' }, - { image_path: 'support_agent', - href: 'federal-agency-faqs', - alt: 'help', - title: 'Help', - subtitle: 'Get support on the Challenge.Gov platform.' } + { image_path: 'emoji_events', href: Rails.configuration.phx_interop[:phx_uri], + alt: 'challenges', title: 'Challenges', subtitle: 'Create and manage challenges.' }, + { image_path: 'people', href: 'manage_submissions', + alt: 'submissions', title: 'Submissions', subtitle: 'Manage submissions, evaluations, and evaluators.' }, + { image_path: 'content_copy', href: 'evaluation_forms', + alt: 'evaluation forms', title: 'Evaluation Forms', subtitle: 'Create and manage evaluation forms.' }, + { image_path: 'map', href: 'user_guide', + alt: 'resources', title: 'Resources', subtitle: 'Learn how to make the most of the platform.' }, + { image_path: 'support_agent', href: 'federal-agency-faqs', + alt: 'help', title: 'Help', subtitle: 'Get support on the Challenge.Gov platform.' } ], evaluator: [ - { image_path: 'content_copy', - href: 'manage_submissions', - alt: 'submissions', - title: 'Submissions', - subtitle: 'Evaluate my assigned submissions.' }, - { image_path: 'map', - href: 'user_guide', - alt: 'user guides', - title: 'Resources', - subtitle: 'Learn how to make the most of the platform.' }, - { image_path: 'support_agent', - href: 'federal-agency-faqs', - alt: 'help', - title: 'Help', - subtitle: 'Get support on the Challenge.Gov platform.' } + { image_path: 'content_copy', href: 'manage_submissions', + alt: 'submissions', title: 'Submissions', subtitle: 'Evaluate my assigned submissions.' }, + { image_path: 'map', href: 'user_guide', + alt: 'user guides', title: 'Resources', subtitle: 'Learn how to make the most of the platform.' }, + { image_path: 'support_agent', href: 'federal-agency-faqs', + alt: 'help', title: 'Help', subtitle: 'Get support on the Challenge.Gov platform.' } ], solver: [] } diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ffe6aeb2..aa5f0e94 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -17,6 +17,7 @@ config.shared_context_metadata_behavior = :apply_to_host_groups end +# rubocop:disable Metrics/AbcSize def create_and_log_in_user(user_attrs = {}) user = create_user(user_attrs) code = "ABC123" @@ -33,6 +34,7 @@ def create_and_log_in_user(user_attrs = {}) get "/auth/result", params: { code: } user end +# rubocop:enable Metrics/AbcSize def create_user(user_attrs = {}) email = "testsolver@example.gov" From 0aea97866df0bf2447eded87b5f1c1d6df94fc7c Mon Sep 17 00:00:00 2001 From: Stephen Chudleigh Date: Tue, 17 Sep 2024 10:32:51 -0700 Subject: [PATCH 10/11] linter code format --- spec/requests/sessions_request_spec.rb | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/spec/requests/sessions_request_spec.rb b/spec/requests/sessions_request_spec.rb index 0a0dab31..e2219ea7 100644 --- a/spec/requests/sessions_request_spec.rb +++ b/spec/requests/sessions_request_spec.rb @@ -37,9 +37,11 @@ [{ email: "test@example.com", sub: "sub" }] ) - # rubocop:disable Layout/LineLength, RSpec/AnyInstance - allow_any_instance_of(SessionsController).to receive(:send_user_jwt_to_phoenix).with(instance_of(String)).and_return(true) - # rubocop:enable Layout/LineLength, RSpec/AnyInstance + # rubocop:disable RSpec/AnyInstance + allow_any_instance_of(SessionsController).to( + receive(:send_user_jwt_to_phoenix).with(instance_of(String)).and_return(true) + ) + # rubocop:enable RSpec/AnyInstance get "/auth/result", params: { code: } expect(response).to have_http_status(:redirect) @@ -61,9 +63,11 @@ [{ email:, sub: token }] ) - # rubocop:disable Layout/LineLength, RSpec/AnyInstance - allow_any_instance_of(SessionsController).to receive(:send_user_jwt_to_phoenix).with(instance_of(String)).and_return(true) - # rubocop:enable Layout/LineLength, RSpec/AnyInstance + # rubocop:disable RSpec/AnyInstance + allow_any_instance_of(SessionsController).to( + receive(:send_user_jwt_to_phoenix).with(instance_of(String)).and_return(true) + ) + # rubocop:enable RSpec/AnyInstance get "/auth/result", params: { code: } From 3c990e00ba8766035ecb1083180978064d9e8a97 Mon Sep 17 00:00:00 2001 From: Stephen Chudleigh Date: Tue, 17 Sep 2024 10:45:17 -0700 Subject: [PATCH 11/11] refactor mock_login_gov --- spec/requests/sessions_request_spec.rb | 27 ++++---------------------- spec/spec_helper.rb | 24 ++++++++++++----------- 2 files changed, 17 insertions(+), 34 deletions(-) diff --git a/spec/requests/sessions_request_spec.rb b/spec/requests/sessions_request_spec.rb index e2219ea7..acfef510 100644 --- a/spec/requests/sessions_request_spec.rb +++ b/spec/requests/sessions_request_spec.rb @@ -30,18 +30,9 @@ end it "get /auth/result successful" do + user = User.new(email: "test@example.com", token: SecureRandom.uuid) code = "ABC123" - login_gov = instance_double(LoginGov) - allow(LoginGov).to receive(:new).and_return(login_gov) - allow(login_gov).to receive(:exchange_token_from_auth_result).with(code).and_return( - [{ email: "test@example.com", sub: "sub" }] - ) - - # rubocop:disable RSpec/AnyInstance - allow_any_instance_of(SessionsController).to( - receive(:send_user_jwt_to_phoenix).with(instance_of(String)).and_return(true) - ) - # rubocop:enable RSpec/AnyInstance + mock_login_gov(user, code) get "/auth/result", params: { code: } expect(response).to have_http_status(:redirect) @@ -54,20 +45,10 @@ email = "test@example.gov" token = SecureRandom.uuid - User.create!({ email:, token: }) + user = User.create!({ email:, token: }) code = "ABC123" - login_gov = instance_double(LoginGov) - allow(LoginGov).to receive(:new).and_return(login_gov) - allow(login_gov).to receive(:exchange_token_from_auth_result).with(code).and_return( - [{ email:, sub: token }] - ) - - # rubocop:disable RSpec/AnyInstance - allow_any_instance_of(SessionsController).to( - receive(:send_user_jwt_to_phoenix).with(instance_of(String)).and_return(true) - ) - # rubocop:enable RSpec/AnyInstance + mock_login_gov(user, code) get "/auth/result", params: { code: } diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index aa5f0e94..ee468378 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -17,24 +17,14 @@ config.shared_context_metadata_behavior = :apply_to_host_groups end -# rubocop:disable Metrics/AbcSize def create_and_log_in_user(user_attrs = {}) user = create_user(user_attrs) code = "ABC123" - login_gov = instance_double(LoginGov) - allow(LoginGov).to receive(:new).and_return(login_gov) - allow(login_gov).to receive(:exchange_token_from_auth_result).with(code).and_return( - [{ email: user.email, sub: user.token }] - ) - - # rubocop:disable Layout/LineLength, RSpec/AnyInstance - allow_any_instance_of(SessionsController).to receive(:send_user_jwt_to_phoenix).with(instance_of(String)).and_return(true) - # rubocop:enable Layout/LineLength, RSpec/AnyInstance + mock_login_gov(user, code) get "/auth/result", params: { code: } user end -# rubocop:enable Metrics/AbcSize def create_user(user_attrs = {}) email = "testsolver@example.gov" @@ -42,3 +32,15 @@ def create_user(user_attrs = {}) user_attrs = { email:, token: }.merge(user_attrs) User.create!(user_attrs) end + +def mock_login_gov(user, code = "ABC123") # rubocop:disable Metrics/AbcSize + login_gov = instance_double(LoginGov) + allow(LoginGov).to receive(:new).and_return(login_gov) + allow(login_gov).to receive(:exchange_token_from_auth_result).with(code).and_return( + [{ email: user.email, sub: user.token }] + ) + + allow_any_instance_of(SessionsController).to( # rubocop:disable RSpec/AnyInstance + receive(:send_user_jwt_to_phoenix).with(instance_of(String)).and_return(true) + ) +end