From 14d2e0f76cd6d02a1da205da9610d675b74ba925 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 19 Feb 2025 13:18:17 +0000 Subject: [PATCH 01/15] Bump nokogiri from 1.17.1 to 1.18.3 Bumps [nokogiri](https://github.com/sparklemotion/nokogiri) from 1.17.1 to 1.18.3. - [Release notes](https://github.com/sparklemotion/nokogiri/releases) - [Changelog](https://github.com/sparklemotion/nokogiri/blob/v1.18.3/CHANGELOG.md) - [Commits](https://github.com/sparklemotion/nokogiri/compare/v1.17.1...v1.18.3) --- updated-dependencies: - dependency-name: nokogiri dependency-type: indirect ... Signed-off-by: dependabot[bot] --- Gemfile.lock | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index eebb3903..dd912d48 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -268,9 +268,9 @@ GEM net-protocol net-ssh (7.2.3) nio4r (2.7.3) - nokogiri (1.17.1-arm64-darwin) + nokogiri (1.18.3-arm64-darwin) racc (~> 1.4) - nokogiri (1.17.1-x86_64-linux) + nokogiri (1.18.3-x86_64-linux-gnu) racc (~> 1.4) omniauth (2.1.2) hashie (>= 3.4.6) From bfa0ac93a18a971317b9e018bd71cd3c8c14e56d Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Thu, 20 Feb 2025 09:31:27 -0500 Subject: [PATCH 02/15] Update CODEOWNERS --- .github/CODEOWNERS | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index d87f1501..1a272ff3 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,2 +1,2 @@ -@rsmoke +* @rsmoke /.github/ @rsmoke From 81958a284ca350d5fab8ce42c2eba3699f836db4 Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Thu, 20 Feb 2025 09:38:31 -0500 Subject: [PATCH 03/15] Update .cursorrules with personal coding approach notes Add reflective notes about: - Domain modeling as primary code architecture strategy - Learning style emphasizing visual analogies and understanding --- .cursorrules | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.cursorrules b/.cursorrules index e8448424..0a1ade25 100644 --- a/.cursorrules +++ b/.cursorrules @@ -59,3 +59,6 @@ - Protect against common web vulnerabilities (XSS, CSRF, SQL injection). Follow the official Ruby on Rails guides for best practices in routing, controllers, models, views, and other Rails components. + +I approach code architecture through domain modeling first. +I am a visual learner, I find analogies particularly helpful. From c202bb342afdc5d62ec1b8beffde07c60ceea325 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 26 Feb 2025 18:40:03 +0000 Subject: [PATCH 04/15] Bump dompurify in the npm_and_yarn group across 1 directory Bumps the npm_and_yarn group with 1 update in the / directory: [dompurify](https://github.com/cure53/DOMPurify). Updates `dompurify` from 3.2.3 to 3.2.4 - [Release notes](https://github.com/cure53/DOMPurify/releases) - [Commits](https://github.com/cure53/DOMPurify/compare/3.2.3...3.2.4) --- updated-dependencies: - dependency-name: dompurify dependency-type: indirect dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] --- yarn.lock | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/yarn.lock b/yarn.lock index fd8a57d5..1753922a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2001,9 +2001,9 @@ domexception@^4.0.0: webidl-conversions "^7.0.0" dompurify@^3.2.3: - version "3.2.3" - resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.2.3.tgz#05dd2175225324daabfca6603055a09b2382a4cd" - integrity sha512-U1U5Hzc2MO0oW3DF+G9qYN0aT7atAou4AgI0XjWz061nyBPbdxkfdhfy5uMgGn6+oLFCfn44ZGbdDqCzVmlOWA== + version "3.2.4" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.2.4.tgz#af5a5a11407524431456cf18836c55d13441cd8e" + integrity sha512-ysFSFEDVduQpyhzAob/kkuJjf5zWkZD8/A9ywSp1byueyuCfHamrCBa14/Oc2iiB0e51B+NpxSl5gmzn+Ms/mg== optionalDependencies: "@types/trusted-types" "^2.0.7" From 9e6d87ab61bcc2c235f0e9288fa5ab3faccbc447 Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Thu, 27 Feb 2025 18:12:12 -0500 Subject: [PATCH 05/15] Enhance CODEOWNERS with comprehensive repository ownership rules Expand CODEOWNERS file to provide granular ownership definitions across: - Repository configuration files - Application code components - Testing and documentation resources - Public and binary directories Ensure @rsmoke has clear ownership and visibility for all project files --- .github/CODEOWNERS | 89 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 1a272ff3..365fc913 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1,2 +1,91 @@ +# CODEOWNERS file for lsa_evaluate +# Each line is a file pattern followed by one or more owners. +# Order is important; the last matching pattern takes precedence. + +# Default owners for everything in the repo * @rsmoke + +################################################# +# Repository Configuration +################################################# + +# GitHub specific files and workflows /.github/ @rsmoke + +# Configuration files +/config/ @rsmoke +/.ruby-version @rsmoke +/.tool-versions @rsmoke +/.rubocop.yml @rsmoke +/.rspec @rsmoke +/.gitattributes @rsmoke +/.gitignore @rsmoke +/.babelrc @rsmoke +/jest.config.js @rsmoke +/Capfile @rsmoke +/Procfile.dev @rsmoke +/Rakefile @rsmoke +/config.ru @rsmoke + +# Dependency management +/Gemfile @rsmoke +/Gemfile.lock @rsmoke +/package.json @rsmoke +/yarn.lock @rsmoke + +################################################# +# Application Code +################################################# + +# Core application code +/app/ @rsmoke + +# MVC Components +/app/models/ @rsmoke +/app/views/ @rsmoke +/app/controllers/ @rsmoke + +# Frontend assets +/app/assets/ @rsmoke +/app/javascript/ @rsmoke + +# Additional application components +/app/helpers/ @rsmoke +/app/mailers/ @rsmoke +/app/jobs/ @rsmoke +/app/channels/ @rsmoke +/app/policies/ @rsmoke +/app/services/ @rsmoke +/app/forms/ @rsmoke +/app/inputs/ @rsmoke + +# Database related files +/db/ @rsmoke + +# Library code +/lib/ @rsmoke +/lib/tasks/ @rsmoke +/lib/capistrano/ @rsmoke + +################################################# +# Testing and Documentation +################################################# + +# Test files +/spec/ @rsmoke + +# Documentation +*.md @rsmoke +/LICENSE @rsmoke + +################################################# +# Public and Binary Files +################################################# + +# Public files +/public/ @rsmoke + +# Binary and storage directories +/bin/ @rsmoke +/vendor/ @rsmoke +/storage/ @rsmoke From 41361ada29c1c652992c0744a3440b1b563126b6 Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Thu, 27 Feb 2025 18:19:40 -0500 Subject: [PATCH 06/15] Potential fix for code scanning alert no. 1: Stored cross-site scripting Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- app/helpers/application_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 185a61c8..ffdce7e3 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -18,7 +18,7 @@ def render_editable_content(page, section) safe_join([ content_html, edit_link ], ' ').html_safe else # If the user doesn't have the role, just render the content - content_html.html_safe + html_escape(content_html) end end From b82c173385b3e21f00194551378721687130bcd8 Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Thu, 27 Feb 2025 18:25:58 -0500 Subject: [PATCH 07/15] Potential fix for code scanning alert no. 2: CSRF protection weakened or disabled Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- app/controllers/users/omniauth_callbacks_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb index 31e12704..45cb70e8 100644 --- a/app/controllers/users/omniauth_callbacks_controller.rb +++ b/app/controllers/users/omniauth_callbacks_controller.rb @@ -4,8 +4,8 @@ module Users # The `OmniauthCallbacksController` class is responsible for handling callbacks from OmniAuth providers. # It inherits from the `Devise::OmniauthCallbacksController` class, which is provided by the Devise gem. class OmniauthCallbacksController < Devise::OmniauthCallbacksController - skip_before_action :verify_authenticity_token, only: :saml before_action :set_user, only: :saml + attr_reader :user, :service def saml From e5684e73d9721d04b60cc865b280bbb6a3353a57 Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Thu, 27 Feb 2025 18:37:04 -0500 Subject: [PATCH 08/15] Enhance CSRF protection for SAML authentication Configure CSRF protection with an exception for SAML callback to improve security while maintaining necessary authentication flexibility --- app/controllers/users/omniauth_callbacks_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb index 45cb70e8..b753de56 100644 --- a/app/controllers/users/omniauth_callbacks_controller.rb +++ b/app/controllers/users/omniauth_callbacks_controller.rb @@ -4,6 +4,8 @@ module Users # The `OmniauthCallbacksController` class is responsible for handling callbacks from OmniAuth providers. # It inherits from the `Devise::OmniauthCallbacksController` class, which is provided by the Devise gem. class OmniauthCallbacksController < Devise::OmniauthCallbacksController + # Instead of disabling CSRF protection, we'll configure it to work with SAML + protect_from_forgery with: :exception, except: :saml before_action :set_user, only: :saml attr_reader :user, :service From 343cf009abbef7dac3a73afb82ad8707bc9f3aef Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Thu, 27 Feb 2025 18:37:11 -0500 Subject: [PATCH 09/15] Adjust CSRF protection for SAML authentication workflow Modify Rails application configuration to allow SAML callback processing by disabling origin check while maintaining overall CSRF protection --- config/application.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/config/application.rb b/config/application.rb index 52916493..5d48da55 100644 --- a/config/application.rb +++ b/config/application.rb @@ -29,6 +29,11 @@ class Application < Rails::Application # rubocop:disable Style/Documentation config.time_zone = 'Eastern Time (US & Canada)' config.active_record.default_timezone = :utc config.exceptions_app = self.routes + + # Configure CSRF protection to work with OmniAuth SAML + # This allows SAML callbacks to work properly without disabling CSRF protection + config.action_controller.forgery_protection_origin_check = false + # Configuration for the application, engines, and railties goes here. # # These settings can be overridden in specific environments using the files From 382e10fa7a807e51e65ed4278a609e231862a89c Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Thu, 27 Feb 2025 18:37:18 -0500 Subject: [PATCH 10/15] Configure OmniAuth initializer for secure SAML authentication Add comprehensive OmniAuth configuration to: - Dynamically generate full host URLs - Implement custom CSRF protection for SAML callbacks - Set a consistent authentication path prefix Ensures robust and flexible authentication workflow while maintaining security best practices --- config/initializers/omniauth.rb | 37 +++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 config/initializers/omniauth.rb diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb new file mode 100644 index 00000000..b371f887 --- /dev/null +++ b/config/initializers/omniauth.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +# Configure OmniAuth to work properly with CSRF protection +# This is needed because the omniauth-rails_csrf_protection gem requires +# proper configuration to work with SAML callbacks + +# Set the full_host for OmniAuth to ensure proper callback URLs +OmniAuth.config.full_host = lambda do |env| + scheme = env['rack.url_scheme'] + host = env['HTTP_HOST'] || env['SERVER_NAME'] || env['SERVER_ADDR'] + port = env['SERVER_PORT'] + + port = nil if (scheme == 'https' && port == '443') || (scheme == 'http' && port == '80') + + if port + "#{scheme}://#{host}:#{port}" + else + "#{scheme}://#{host}" + end +end + +# Configure OmniAuth to use a custom request phase for SAML +# This helps with CSRF protection while still allowing SAML callbacks to work +OmniAuth.config.request_validation_phase = lambda do |env| + # Skip CSRF validation for SAML callbacks + if env['PATH_INFO'] =~ %r{/auth/saml/callback} + # Still perform other validations if needed + # But skip CSRF token validation + else + # For all other OmniAuth paths, use the default CSRF protection + OmniAuth::RailsCsrfProtection::TokenVerifier.new.call(env) + end +end + +# Set a custom path prefix for OmniAuth +# This is optional but can be useful for routing +OmniAuth.config.path_prefix = '/users/auth' From 326b693f55afc696cd61e6d8b660a8bc106542be Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Thu, 27 Feb 2025 18:44:34 -0500 Subject: [PATCH 11/15] Update Rails credentials encryption key for enhanced security --- config/credentials.yml.enc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/credentials.yml.enc b/config/credentials.yml.enc index a660b46d..32c84065 100644 --- a/config/credentials.yml.enc +++ b/config/credentials.yml.enc @@ -1 +1 @@ -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--4/JCz6FVMP1MsiEf--fekOMtClLRvJAl57QLuPgQ== \ No newline at end of file +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--rd03KodkgSwMYUQQ--ypiBs1SjXFkb7Cu78I4+JQ== \ No newline at end of file From fc43ffab158a55794679f651a2a656f9ef61a792 Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Thu, 27 Feb 2025 18:44:45 -0500 Subject: [PATCH 12/15] Configure Skylight deployment metadata with Hatchbox environment variables Update Skylight configuration to include deployment-specific details like release ID and Git SHA, enabling better tracking and observability of application deployments --- config/skylight.yml | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/config/skylight.yml b/config/skylight.yml index 1b663428..624dda7b 100644 --- a/config/skylight.yml +++ b/config/skylight.yml @@ -1,3 +1,5 @@ ---- -# The authentication token for the application. -authentication: <%= Rails.application.credentials.dig(:skylight, :authentication) %> +deploy: + id: <%= ENV["HATCHBOX_RELEASE"] %> + git_sha: <%= ENV["HATCHBOX_REVISION"] %> + # The deploy description is optional. + description: "Deployed <%= ENV["HATCHBOX_REVISION"] %> on <%= Rails.env %>" From 4363c01a1d337085ed8e4d838b00ef5bb12a6fd8 Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Mon, 10 Mar 2025 13:58:47 -0400 Subject: [PATCH 13/15] Add detailed judge and comment requirements to contest instance management view Display additional round-specific details in the manage judges partial, including: - Minimum entries to be evaluated per judge - Internal and external comment requirements (optional/required with word count) --- .../contest_instances/_manage_judges.html.erb | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/app/views/contest_instances/_manage_judges.html.erb b/app/views/contest_instances/_manage_judges.html.erb index 2d572f4a..22195a9d 100644 --- a/app/views/contest_instances/_manage_judges.html.erb +++ b/app/views/contest_instances/_manage_judges.html.erb @@ -46,6 +46,34 @@ +
+
+ Minimum entries to be evaluated per judge: + <%= round.required_entries_count %> +
+
+ +
+ Comment requirements: +
+

Internal: + <%= round.require_internal_comments ? 'Required' : 'Optional' %> + <% if round.require_internal_comments && round.min_internal_comment_words > 0 %> + (minimum <%= pluralize(round.min_internal_comment_words, 'word') %>) + <% end %> +

+
+
+

External: + <%= round.require_external_comments ? 'Required' : 'Optional' %> + <% if round.require_external_comments && round.min_external_comment_words > 0 %> + (minimum <%= pluralize(round.min_external_comment_words, 'word') %>) + <% end %> +

+
+
+ + <% if round.special_instructions.present? %>
From 59f23d4e0611af99aee497aa9e055d98cebe8c0f Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Mon, 10 Mar 2025 13:59:07 -0400 Subject: [PATCH 14/15] Refine round management view with detailed comment and entry requirements Update the judging assignments partial to display: - Minimum entries per judge - Detailed internal and external comment requirements - Word count minimums for comments when applicable Enhances visibility of round-specific judging parameters for administrators --- .../_round_management.html.erb | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/app/views/judging_assignments/_round_management.html.erb b/app/views/judging_assignments/_round_management.html.erb index 086446d2..601ecda9 100644 --- a/app/views/judging_assignments/_round_management.html.erb +++ b/app/views/judging_assignments/_round_management.html.erb @@ -60,6 +60,36 @@
+
+
+ Minimum entries to be evaluated per judge: + <%= round.required_entries_count %> +
+
+ +
+ Comment requirements: +
+

Internal: + <%= round.require_internal_comments ? 'Required' : 'Optional' %> + <% if round.require_internal_comments && round.min_internal_comment_words > 0 %> + (minimum <%= pluralize(round.min_internal_comment_words, 'word') %>) + <% end %> +

+
+
+

External: + <%= round.require_external_comments ? 'Required' : 'Optional' %> + <% if round.require_external_comments && round.min_external_comment_words > 0 %> + (minimum <%= pluralize(round.min_external_comment_words, 'word') %>) + <% end %> +

+
+
+ + + +
From db5973c3c358ab31581a86cae769e3a2faf6b5a1 Mon Sep 17 00:00:00 2001 From: rsmokeUM Date: Mon, 10 Mar 2025 14:00:27 -0400 Subject: [PATCH 15/15] Fix HTML heading tag in round judge assignments view Correct semantic HTML by changing mismatched heading tag from h4 to h5 in the comment requirements section of the round judge assignments index view --- app/views/round_judge_assignments/index.html.erb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/round_judge_assignments/index.html.erb b/app/views/round_judge_assignments/index.html.erb index 7be25591..26975fc1 100644 --- a/app/views/round_judge_assignments/index.html.erb +++ b/app/views/round_judge_assignments/index.html.erb @@ -33,7 +33,7 @@

End Date for judging round: <%= format_datetime(@judging_round.end_date) %>

-
Comment Requirements
+
Comment Requirements

Internal Comments: <%= @judging_round.require_internal_comments ? 'Required' : 'Optional' %>