1 Commits

Author SHA1 Message Date
Dan Milne
65c19fa732 Upgrade to Ruby 4.0.1, bump version to 0.9.0
Some checks failed
CI / scan_ruby (push) Has been cancelled
CI / scan_js (push) Has been cancelled
CI / scan_container (push) Has been cancelled
CI / lint (push) Has been cancelled
CI / test (push) Has been cancelled
CI / system-test (push) Has been cancelled
Replace CGI.parse (removed in Ruby 4.0) with Rack::Utils.parse_query
in application controller, sessions controller, and OIDC tests.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-05 21:52:11 +11:00
8 changed files with 36 additions and 17 deletions

View File

@@ -1 +1 @@
3.4.8 4.0.1

View File

@@ -8,7 +8,7 @@
# For a containerized dev environment, see Dev Containers: https://guides.rubyonrails.org/getting_started_with_devcontainer.html # For a containerized dev environment, see Dev Containers: https://guides.rubyonrails.org/getting_started_with_devcontainer.html
# Make sure RUBY_VERSION matches the Ruby version in .ruby-version # Make sure RUBY_VERSION matches the Ruby version in .ruby-version
ARG RUBY_VERSION=3.4.8 ARG RUBY_VERSION=4.0.1
FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base
LABEL org.opencontainers.image.source=https://github.com/dkam/clinch LABEL org.opencontainers.image.source=https://github.com/dkam/clinch

View File

@@ -446,6 +446,7 @@ PLATFORMS
arm-linux-gnu arm-linux-gnu
arm-linux-musl arm-linux-musl
arm64-darwin-24 arm64-darwin-24
arm64-darwin-25
x86_64-linux x86_64-linux
x86_64-linux-gnu x86_64-linux-gnu
x86_64-linux-musl x86_64-linux-musl

View File

@@ -28,12 +28,10 @@ class ApplicationController < ActionController::Base
uri = URI.parse(url) uri = URI.parse(url)
return url unless uri.query return url unless uri.query
# Parse query string into hash params = Rack::Utils.parse_query(uri.query)
params = CGI.parse(uri.query)
params.delete(param_name) params.delete(param_name)
# Rebuild query string (empty string if no params left) uri.query = params.any? ? Rack::Utils.build_query(params) : nil
uri.query = params.any? ? URI.encode_www_form(params) : nil
uri.to_s uri.to_s
rescue URI::InvalidURIError rescue URI::InvalidURIError
url url

View File

@@ -20,8 +20,8 @@ class SessionsController < ApplicationController
begin begin
uri = URI.parse(session[:return_to_after_authenticating]) uri = URI.parse(session[:return_to_after_authenticating])
if uri.query.present? if uri.query.present?
query_params = CGI.parse(uri.query) query_params = Rack::Utils.parse_query(uri.query)
@login_hint = query_params["login_hint"]&.first @login_hint = query_params["login_hint"]
end end
rescue URI::InvalidURIError rescue URI::InvalidURIError
# Ignore parsing errors # Ignore parsing errors

View File

@@ -1,5 +1,5 @@
# frozen_string_literal: true # frozen_string_literal: true
module Clinch module Clinch
VERSION = "0.8.8" VERSION = "0.9.0"
end end

22
db/schema.rb generated
View File

@@ -10,7 +10,7 @@
# #
# It's strongly recommended that you check this file into your version control system. # It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[8.1].define(version: 2026_01_05_000809) do ActiveRecord::Schema[8.1].define(version: 2026_03_05_000001) do
create_table "active_storage_attachments", force: :cascade do |t| create_table "active_storage_attachments", force: :cascade do |t|
t.bigint "blob_id", null: false t.bigint "blob_id", null: false
t.datetime "created_at", null: false t.datetime "created_at", null: false
@@ -39,6 +39,24 @@ ActiveRecord::Schema[8.1].define(version: 2026_01_05_000809) do
t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true
end end
create_table "api_keys", force: :cascade do |t|
t.integer "application_id", null: false
t.datetime "created_at", null: false
t.datetime "expires_at"
t.datetime "last_used_at"
t.string "name", null: false
t.datetime "revoked_at"
t.string "token_hmac", null: false
t.datetime "updated_at", null: false
t.integer "user_id", null: false
t.index ["application_id"], name: "index_api_keys_on_application_id"
t.index ["expires_at"], name: "index_api_keys_on_expires_at"
t.index ["revoked_at"], name: "index_api_keys_on_revoked_at"
t.index ["token_hmac"], name: "index_api_keys_on_token_hmac", unique: true
t.index ["user_id", "application_id"], name: "index_api_keys_on_user_id_and_application_id"
t.index ["user_id"], name: "index_api_keys_on_user_id"
end
create_table "application_groups", force: :cascade do |t| create_table "application_groups", force: :cascade do |t|
t.integer "application_id", null: false t.integer "application_id", null: false
t.datetime "created_at", null: false t.datetime "created_at", null: false
@@ -249,6 +267,8 @@ ActiveRecord::Schema[8.1].define(version: 2026_01_05_000809) do
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
add_foreign_key "api_keys", "applications"
add_foreign_key "api_keys", "users"
add_foreign_key "application_groups", "applications" add_foreign_key "application_groups", "applications"
add_foreign_key "application_groups", "groups" add_foreign_key "application_groups", "groups"
add_foreign_key "application_user_claims", "applications", on_delete: :cascade add_foreign_key "application_user_claims", "applications", on_delete: :cascade

View File

@@ -46,7 +46,7 @@ class OidcPromptLoginTest < ActionDispatch::IntegrationTest
assert_response :redirect assert_response :redirect
first_redirect_url = response.location first_redirect_url = response.location
first_code = CGI.parse(URI(first_redirect_url).query)["code"].first first_code = Rack::Utils.parse_query(URI(first_redirect_url).query)["code"]
# Exchange for tokens and extract auth_time # Exchange for tokens and extract auth_time
post "/oauth/token", params: { post "/oauth/token", params: {
@@ -90,7 +90,7 @@ class OidcPromptLoginTest < ActionDispatch::IntegrationTest
# Should receive authorization code # Should receive authorization code
assert_response :redirect assert_response :redirect
second_redirect_url = response.location second_redirect_url = response.location
second_code = CGI.parse(URI(second_redirect_url).query)["code"].first second_code = Rack::Utils.parse_query(URI(second_redirect_url).query)["code"]
assert second_code.present?, "Should receive authorization code after re-authentication" assert second_code.present?, "Should receive authorization code after re-authentication"
@@ -134,11 +134,11 @@ class OidcPromptLoginTest < ActionDispatch::IntegrationTest
# Parse the redirect URL # Parse the redirect URL
uri = URI.parse(redirect_url) uri = URI.parse(redirect_url)
query_params = uri.query ? CGI.parse(uri.query) : {} query_params = uri.query ? Rack::Utils.parse_query(uri.query) : {}
assert_equal "login_required", query_params["error"]&.first, assert_equal "login_required", query_params["error"],
"Should return login_required error for prompt=none when not authenticated" "Should return login_required error for prompt=none when not authenticated"
assert_equal "test-state", query_params["state"]&.first, assert_equal "test-state", query_params["state"],
"Should return state parameter" "Should return state parameter"
end end
@@ -165,7 +165,7 @@ class OidcPromptLoginTest < ActionDispatch::IntegrationTest
assert_response :redirect assert_response :redirect
first_redirect_url = response.location first_redirect_url = response.location
first_code = CGI.parse(URI(first_redirect_url).query)["code"].first first_code = Rack::Utils.parse_query(URI(first_redirect_url).query)["code"]
# Exchange for tokens and extract auth_time from ID token # Exchange for tokens and extract auth_time from ID token
post "/oauth/token", params: { post "/oauth/token", params: {
@@ -209,7 +209,7 @@ class OidcPromptLoginTest < ActionDispatch::IntegrationTest
# Should receive authorization code redirect # Should receive authorization code redirect
assert_response :redirect assert_response :redirect
second_redirect_url = response.location second_redirect_url = response.location
second_code = CGI.parse(URI(second_redirect_url).query)["code"].first second_code = Rack::Utils.parse_query(URI(second_redirect_url).query)["code"]
assert second_code.present?, "Should receive authorization code after re-authentication" assert second_code.present?, "Should receive authorization code after re-authentication"