Skip to content

Commit

Permalink
This PR replaces fixes the way SP request UUID generation is handled.
Browse files Browse the repository at this point in the history
- Replace the mutable RubySaml::Utils::UUID_PREFIX constant with `Settings.sp_uuid_prefix`
- Make Authnrequest, etc. `uuid` attribute to be immutable.
- Initialize Authnrequest, etc. `uuid` attribute when `create` is called, based on `Settings.sp_uuid_prefix`, not when instantiating the Ruby object.
  • Loading branch information
johnnyshields committed Jan 11, 2025
1 parent 6f73a4f commit 10bdc2b
Show file tree
Hide file tree
Showing 6 changed files with 26 additions and 45 deletions.
16 changes: 3 additions & 13 deletions lib/ruby_saml/authrequest.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,16 @@ module RubySaml
class Authrequest < SamlMessage

# AuthNRequest ID
attr_accessor :uuid

# Initializes the AuthNRequest. An Authrequest Object that is an extension of the SamlMessage class.
# Asigns an ID, a random uuid.
#
def initialize
@uuid = RubySaml::Utils.uuid
super()
end

def request_id
@uuid
end
attr_reader :uuid
alias_method :request_id, :uuid

# Creates the AuthNRequest string.
# @param settings [RubySaml::Settings|nil] Toolkit settings
# @param params [Hash] Some extra parameters to be added in the GET for example the RelayState
# @return [String] AuthNRequest string that includes the SAMLRequest
#
def create(settings, params = {})
@uuid = RubySaml::Utils.generate_uuid(settings.sp_uuid_prefix)
params = create_params(settings, params)
params_prefix = /\?/.match?(settings.idp_sso_service_url) ? '&' : '?'
saml_request = CGI.escape(params.delete("SAMLRequest"))
Expand Down
16 changes: 3 additions & 13 deletions lib/ruby_saml/logoutrequest.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,16 @@ module RubySaml
class Logoutrequest < SamlMessage

# Logout Request ID
attr_accessor :uuid

# Initializes the Logout Request. A Logoutrequest Object that is an extension of the SamlMessage class.
# Asigns an ID, a random uuid.
#
def initialize
@uuid = RubySaml::Utils.uuid
super()
end

def request_id
@uuid
end
attr_reader :uuid
alias_method :request_id, :uuid

# Creates the Logout Request string.
# @param settings [RubySaml::Settings|nil] Toolkit settings
# @param params [Hash] Some extra parameters to be added in the GET for example the RelayState
# @return [String] Logout Request string that includes the SAMLRequest
#
def create(settings, params={})
@uuid = RubySaml::Utils.generate_uuid(settings.sp_uuid_prefix)
params = create_params(settings, params)
params_prefix = /\?/.match?(settings.idp_slo_service_url) ? '&' : '?'
saml_request = CGI.escape(params.delete("SAMLRequest"))
Expand Down
1 change: 1 addition & 0 deletions lib/ruby_saml/settings.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ def initialize(overrides = {}, keep_security_attributes = false)
attr_reader :assertion_consumer_service_binding
attr_accessor :single_logout_service_url
attr_reader :single_logout_service_binding
attr_accessor :sp_uuid_prefix
attr_accessor :sp_name_qualifier
attr_accessor :name_identifier_format
attr_accessor :name_identifier_value
Expand Down
16 changes: 3 additions & 13 deletions lib/ruby_saml/slo_logoutresponse.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,8 @@ module RubySaml
class SloLogoutresponse < SamlMessage

# Logout Response ID
attr_accessor :uuid

# Initializes the Logout Response. A SloLogoutresponse Object that is an extension of the SamlMessage class.
# Asigns an ID, a random uuid.
#
def initialize
@uuid = RubySaml::Utils.uuid
super()
end

def response_id
@uuid
end
attr_reader :uuid
alias_method :request_id, :uuid

# Creates the Logout Response string.
# @param settings [RubySaml::Settings|nil] Toolkit settings
Expand All @@ -37,6 +26,7 @@ def response_id
# @return [String] Logout Request string that includes the SAMLRequest
#
def create(settings, request_id = nil, logout_message = nil, params = {}, logout_status_code = nil)
@uuid = RubySaml::Utils.generate_uuid(settings.sp_uuid_prefix)
params = create_params(settings, request_id, logout_message, params, logout_status_code)
params_prefix = /\?/.match?(settings.idp_slo_service_url) ? '&' : '?'
url = settings.idp_slo_response_service_url || settings.idp_slo_service_url
Expand Down
20 changes: 15 additions & 5 deletions lib/ruby_saml/utils.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ module Utils
(\d+)W # 8: Weeks
)
$/x
UUID_PREFIX = +'_'
UUID_DEFAULT_PREFIX = '_'

# @deprecated Use UUID_DEFAULT_PREFIX instead.
UUID_PREFIX = UUID_DEFAULT_PREFIX.dup

# Checks if the x509 cert provided is expired.
#
Expand Down Expand Up @@ -380,13 +383,20 @@ def retrieve_plaintext(cipher_text, symmetric_key, algorithm)
end
end

def set_prefix(value)
UUID_PREFIX.replace value
def set_prefix(_value)
raise NoMethodError.new('RubySaml::Util.set_prefix has been removed. Please use RubySaml::Settings#uuid_prefix instead.')
end

def uuid
"#{UUID_PREFIX}#{SecureRandom.uuid}"
# Generates a UUID with a prefix.
#
# @param prefix [String|false|nil] An explicit prefix override.
# Using nil will use the default prefix, and false will use no prefix.
# @return [String] The generated UUID.
def generate_uuid(prefix = nil)
prefix = prefix.is_a?(FalseClass) ? nil : prefix || UUID_DEFAULT_PREFIX
"#{prefix}#{SecureRandom.uuid}"
end
alias_method :uuid, :generate_uuid

# Given two strings, attempt to match them as URIs using Rails' parse method. If they can be parsed,
# then the fully-qualified domain name and the host should performa a case-insensitive match, per the
Expand Down
2 changes: 1 addition & 1 deletion test/test_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,7 @@ def ruby_saml_key_text
# logoutresponse fixtures
#
def random_id
"_#{RubySaml::Utils.uuid}"
"_#{RubySaml::Utils.generate_uuid}"
end

#
Expand Down

0 comments on commit 10bdc2b

Please sign in to comment.