@@ -98,35 +98,40 @@ def allowed_sources_options_are_valid
9898
9999 private
100100
101+ # Normalize allowed_sources to use string keys (Rails may parse JSON with symbol keys)
102+ def normalized_allowed_sources
103+ @normalized_allowed_sources ||= allowed_sources . is_a? ( Hash ) ? allowed_sources . transform_keys ( &:to_s ) : allowed_sources
104+ end
105+
101106 def validate_allowed_sources_structure
102107 unless allowed_sources . is_a? ( Hash )
103108 errors . add ( :allowed_sources , 'must be an object' )
104109 return
105110 end
106111
107112 valid_keys = %w[ apps spaces orgs any ]
108- invalid_keys = allowed_sources . keys - valid_keys
113+ invalid_keys = normalized_allowed_sources . keys - valid_keys
109114 errors . add ( :allowed_sources , "contains invalid keys: #{ invalid_keys . join ( ', ' ) } " ) if invalid_keys . any?
110115
111116 # Validate types
112117 %w[ apps spaces orgs ] . each do |key |
113- next unless allowed_sources [ key ] . present?
118+ next unless normalized_allowed_sources [ key ] . present?
114119
115- unless allowed_sources [ key ] . is_a? ( Array ) && allowed_sources [ key ] . all? { |v | v . is_a? ( String ) }
120+ unless normalized_allowed_sources [ key ] . is_a? ( Array ) && normalized_allowed_sources [ key ] . all? { |v | v . is_a? ( String ) }
116121 errors . add ( :allowed_sources , "#{ key } must be an array of strings" )
117122 end
118123 end
119124
120- return unless allowed_sources [ 'any' ] . present? && ![ true , false ] . include? ( allowed_sources [ 'any' ] )
125+ return unless normalized_allowed_sources [ 'any' ] . present? && ![ true , false ] . include? ( normalized_allowed_sources [ 'any' ] )
121126
122127 errors . add ( :allowed_sources , 'any must be a boolean' )
123128 end
124129
125130 def validate_allowed_sources_any_exclusivity
126131 return unless allowed_sources . is_a? ( Hash )
127132
128- has_any = allowed_sources [ 'any' ] == true
129- has_lists = %w[ apps spaces orgs ] . any? { |key | allowed_sources [ key ] . present? && allowed_sources [ key ] . any? }
133+ has_any = normalized_allowed_sources [ 'any' ] == true
134+ has_lists = %w[ apps spaces orgs ] . any? { |key | normalized_allowed_sources [ key ] . present? && normalized_allowed_sources [ key ] . any? }
130135
131136 return unless has_any && has_lists
132137
@@ -143,7 +148,7 @@ def validate_allowed_sources_guids_exist
143148 end
144149
145150 def validate_app_guids_exist
146- app_guids = allowed_sources [ 'apps' ]
151+ app_guids = normalized_allowed_sources [ 'apps' ]
147152 return if app_guids . blank?
148153
149154 existing_guids = AppModel . where ( guid : app_guids ) . select_map ( :guid )
@@ -154,7 +159,7 @@ def validate_app_guids_exist
154159 end
155160
156161 def validate_space_guids_exist
157- space_guids = allowed_sources [ 'spaces' ]
162+ space_guids = normalized_allowed_sources [ 'spaces' ]
158163 return if space_guids . blank?
159164
160165 existing_guids = Space . where ( guid : space_guids ) . select_map ( :guid )
@@ -165,7 +170,7 @@ def validate_space_guids_exist
165170 end
166171
167172 def validate_org_guids_exist
168- org_guids = allowed_sources [ 'orgs' ]
173+ org_guids = normalized_allowed_sources [ 'orgs' ]
169174 return if org_guids . blank?
170175
171176 existing_guids = Organization . where ( guid : org_guids ) . select_map ( :guid )
0 commit comments