-
Notifications
You must be signed in to change notification settings - Fork 73
THREESCALE-15550: Upgrade uri gem #4356
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
09fa2ae
361e3b9
46b5aff
47252e4
4cb28f4
8641c06
4d98455
9f32039
b216d16
5b5bc85
794a67c
493a7cf
3dd8111
4b7f655
6400cf4
99b10e6
e47b127
f720960
2ed9e4c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -24,9 +24,9 @@ def show | |
| protected | ||
|
|
||
| def referrer_url | ||
| url = params[:referrer] | ||
| url = params.permit(:referrer)[:referrer] | ||
| if url | ||
| URI.decode(url) | ||
| CGI.unescapeURIComponent(url) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The referrer URL is generated by our app and passed through the OAuth redirect flow. Malformed percent encoding would only occur if the user tampered with their own callback URL, which isn't a scenario we need to guard against
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Minor:
jlledom marked this conversation as resolved.
|
||
| else | ||
| new_admin_service_path | ||
| end | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| # The uri gem's RFC3986_PARSER does not provide composable string-pattern | ||
| # constants (.pattern only exists on RFC2396_PARSER). | ||
| # These RFC2396 patterns are used intentionally to preserve compatibility. | ||
| module UriPatterns | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| UNRESERVED = URI::RFC2396_REGEXP::PATTERN::UNRESERVED | ||
| ESCAPED = URI::RFC2396_REGEXP::PATTERN::ESCAPED | ||
| RESERVED = URI::RFC2396_REGEXP::PATTERN::RESERVED | ||
|
|
||
| HOSTNAME = URI::RFC2396_PARSER.pattern[:HOSTNAME] | ||
| ABS_PATH = URI::RFC2396_PARSER.pattern[:ABS_PATH] | ||
| QUERY = URI::RFC2396_PARSER.pattern[:QUERY] | ||
|
|
||
| # URL scanner for free-form text (e.g. message bodies). | ||
| HYPERLINK_SCANNER = %r{https?://(?:[^\s()\[\]>]|\([^\s()]*\)|\[[^\s\[\]]*\])+} | ||
| end | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -31,8 +31,9 @@ class AuthenticationProvider < ApplicationRecord | |
|
|
||
| validates :client_id, :client_secret, presence: true, if: :oauth_config_required? | ||
|
|
||
| with_options format: { with: URI::DEFAULT_PARSER.make_regexp(%w[http https]), allow_blank: true, message: :invalid_url } do |ops| | ||
| ops.validates :site | ||
| with_options uri: { path: true, query: true, fragment: true }, allow_blank: true do |ops| | ||
| # Skip uri: for whitespace URLs — each subclass whitespace validator handles these | ||
| ops.validates :site, unless: -> { site.to_s.match?(/\s/) } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The UX improvement is nice (one error instead of two for whitespace URLs). Was stripping whitespace with
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The UX improvement is nice (one error instead of two for whitespace URLs). Was stripping whitespace with
jlledom marked this conversation as resolved.
|
||
| ops.validates :token_url | ||
| ops.validates :authorize_url | ||
| ops.validates :user_info_url | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,5 @@ | ||
| class AuthenticationProvider::Custom < AuthenticationProvider | ||
| self.authorization_scope = :iam_tools | ||
|
|
||
| validates :site, format: { without: /\s/, message: :contains_whitespace } | ||
| end |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -29,12 +29,11 @@ class Proxy < ApplicationRecord # rubocop:disable Metrics/ClassLength | |
|
|
||
| validates :error_status_no_match, :error_status_auth_missing, :error_status_auth_failed, :error_status_limits_exceeded, presence: true | ||
|
|
||
| uri_pattern = URI::DEFAULT_PARSER.pattern | ||
| OPTIONAL_QUERY_FORMAT = "(?:\\?(#{UriPatterns::QUERY}))?" | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| URI_PATH_PART = Regexp.new('\A' + UriPatterns::ABS_PATH + OPTIONAL_QUERY_FORMAT + '\z') | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| HOST = Regexp.new('\A' + UriPatterns::HOSTNAME + '(:\d+)?' + '\z') | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| URI_OR_LOCALHOST = /\A(https?:\/\/([a-zA-Z0-9._:\/?-])+|.*localhost.*)\Z/ | ||
| OPTIONAL_QUERY_FORMAT = "(?:\\?(#{uri_pattern.fetch(:QUERY)}))?" | ||
| URI_PATH_PART = Regexp.new('\A' + uri_pattern.fetch(:ABS_PATH) + OPTIONAL_QUERY_FORMAT + '\z') | ||
| HOST = Regexp.new('\A' + uri_pattern.fetch(:HOSTNAME) + '(:\d+)?' + '\z') | ||
|
|
||
| OAUTH_PARAMS = /(\?|&)(scope=|state=|tok=)/ | ||
|
|
||
|
|
@@ -675,7 +674,7 @@ def call(attribute) | |
|
|
||
| begin | ||
| uri = URI.parse(attribute_value) | ||
| value = URI::Generic.new(uri.scheme, uri.userinfo, uri.host, uri.port, uri.registry, uri.path, uri.opaque, uri.query, uri.fragment).to_s | ||
| value = URI::Generic.new(uri.scheme, uri.userinfo, uri.host, uri.port, nil, uri.path, uri.opaque, uri.query, uri.fragment).to_s | ||
|
qltysh[bot] marked this conversation as resolved.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Found 8 issues: |
||
| @model[attribute] = value unless @model[attribute] == value | ||
| rescue URI::InvalidURIError | ||
| @model.errors.add(attribute, 'Invalid domain') | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -780,6 +780,10 @@ en: | |
| success: Referrer filter has been deleted | ||
|
|
||
| service_discovery: | ||
| auth: | ||
| show: | ||
| success: Service discovery authentication was successful | ||
| error: Service discovery authentication failed | ||
| services: | ||
| create: | ||
| error: Cannot create product | ||
|
|
@@ -1898,6 +1902,7 @@ en: | |
|
|
||
| errors: | ||
| messages: | ||
| invalid_url: "Invalid URL format" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now that all validators use
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed in 794a67c
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now that all validators use |
||
| host_label_too_long: is too long for one or more labels of the host (maximum is %{count} characters) | ||
| duplicated_user_provider_side: "Duplicate user registration. Delete one of the duplicates in order to continue." | ||
| duplicated_user_buyer_side: "For activating your account please contact support." | ||
|
|
@@ -2027,17 +2032,17 @@ en: | |
| base: | ||
| cannot_be_destroyed_with_products: cannot be deleted because it is used by at least one Product | ||
| private_endpoint: | ||
| invalid: "the accepted format is 'scheme://address(:port)(/path)'. Accepted schemes are http, https, ws and wss" | ||
| invalid_url: "the accepted format is 'scheme://address(:port)(/path)'. Accepted schemes are http, https, ws and wss" | ||
| proxy: | ||
| attributes: | ||
| api_backend: | ||
| invalid: "the accepted format is 'scheme://address(:port)(/path)'. Accepted schemes are http, https, ws and wss" | ||
| invalid_url: "the accepted format is 'scheme://address(:port)(/path)'. Accepted schemes are http, https, ws and wss" | ||
| api_test_path: | ||
| invalid: "only URI characters allowed" | ||
| endpoint: | ||
| invalid: "the accepted format is 'protocol://address(:port)'" | ||
| invalid_url: "the accepted format is 'protocol://address(:port)'" | ||
| sandbox_endpoint: | ||
| invalid: "the accepted format is 'protocol://address(:port)'" | ||
| invalid_url: "the accepted format is 'protocol://address(:port)'" | ||
| oauth_login_url: | ||
| invalid: "invalid auth login url. (hint: make sure it uses https scheme)" | ||
| proxy_config: | ||
|
|
@@ -2105,7 +2110,7 @@ en: | |
| web_hook: | ||
| attributes: | ||
| url: | ||
| invalid: Must be a valid URL such as http://example.com | ||
| invalid_url: Must be a valid URL such as http://example.com | ||
|
|
||
| cms/partial: | ||
| attributes: | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| # frozen_string_literal: true | ||
|
|
||
| require 'test_helper' | ||
|
|
||
| class Provider::Admin::ServiceDiscovery::AuthControllerTest < ActionDispatch::IntegrationTest | ||
| setup do | ||
| @provider = FactoryBot.create(:provider_account) | ||
| @callback_url = "/p/admin/auth/#{ServiceDiscovery::AuthenticationProviderSupport::SERVICE_DISCOVERY_SYSTEM_NAME}/callback" | ||
|
|
||
| ThreeScale.config.service_discovery.stubs(enabled: true, authentication_method: 'oauth') | ||
| Rails.application.reload_routes! | ||
|
|
||
| login_provider @provider | ||
| host! @provider.external_admin_domain | ||
| end | ||
|
|
||
| test 'callback decodes referrer url' do | ||
| user_data = ThreeScale::OAuth2::UserData.new(username: 'discovery_user') | ||
| ServiceDiscovery::OAuthConfiguration.instance.stubs( | ||
| token_endpoint: 'https://oauth.example.com/token', | ||
| authorization_endpoint: 'https://oauth.example.com/authorize', | ||
| userinfo_endpoint: 'https://oauth.example.com/userinfo' | ||
| ) | ||
| ThreeScale::OAuth2::ServiceDiscoveryClient.any_instance.stubs(:authenticate!).returns(user_data) | ||
| ThreeScale::OAuth2::ServiceDiscoveryClient.any_instance.stubs(:access_token).returns(stub(token: 'tok', expires_at: 1.hour.from_now.to_i)) | ||
|
|
||
| get @callback_url, params: { referrer: '/p/admin/dashboard%3Ffoo%3Dbar' } | ||
| assert_redirected_to '/p/admin/dashboard?foo=bar' | ||
|
|
||
| get @callback_url, params: { referrer: '/p/admin/search?q=hello+world' } | ||
| assert_redirected_to '/p/admin/search?q=hello+world' | ||
|
|
||
| get @callback_url, params: { referrer: '/p/admin/hello+world' } | ||
| assert_redirected_to '/p/admin/hello+world' | ||
| end | ||
| end |
Uh oh!
There was an error while loading. Please reload this page.