Sha256: 888446981ae4ec1e2a3a2d86e0138fbe9a8c97e76966674025fc6860e4aedab0

Contents?: true

Size: 1.9 KB

Versions: 10

Compression:

Stored size: 1.9 KB

Contents

# frozen_string_literal: true

require "uri"

module Doorkeeper
  # ActiveModel validator for redirect URI validation in according
  # to OAuth standards and Doorkeeper configuration.
  class RedirectUriValidator < ActiveModel::EachValidator
    def validate_each(record, attribute, value)
      if value.blank?
        return if Doorkeeper.config.allow_blank_redirect_uri?(record)

        record.errors.add(attribute, :blank)
      else
        value.split.each do |val|
          next if oob_redirect_uri?(val)

          uri = ::URI.parse(val)
          record.errors.add(attribute, :forbidden_uri) if forbidden_uri?(uri)
          record.errors.add(attribute, :fragment_present) unless uri.fragment.nil?
          record.errors.add(attribute, :unspecified_scheme) if unspecified_scheme?(uri)
          record.errors.add(attribute, :relative_uri) if relative_uri?(uri)
          record.errors.add(attribute, :secured_uri) if invalid_ssl_uri?(uri)
          record.errors.add(attribute, :invalid_uri) if unspecified_host?(uri)
        end
      end
    rescue URI::InvalidURIError
      record.errors.add(attribute, :invalid_uri)
    end

    private

    def oob_redirect_uri?(uri)
      Doorkeeper::OAuth::NonStandard::IETF_WG_OAUTH2_OOB_METHODS.include?(uri)
    end

    def forbidden_uri?(uri)
      Doorkeeper.config.forbid_redirect_uri.call(uri)
    end

    def unspecified_scheme?(uri)
      return true if uri.opaque.present?

      %w[localhost].include?(uri.try(:scheme))
    end

    def unspecified_host?(uri)
      uri.is_a?(URI::HTTP) && uri.host.blank?
    end

    def relative_uri?(uri)
      uri.scheme.nil? && uri.host.blank?
    end

    def invalid_ssl_uri?(uri)
      forces_ssl = Doorkeeper.config.force_ssl_in_redirect_uri
      non_https = uri.try(:scheme) == "http"

      if forces_ssl.respond_to?(:call)
        forces_ssl.call(uri) && non_https
      else
        forces_ssl && non_https
      end
    end
  end
end

Version data entries

10 entries across 10 versions & 1 rubygems

Version Path
doorkeeper-5.8.0 lib/doorkeeper/orm/active_record/redirect_uri_validator.rb
doorkeeper-5.7.1 lib/doorkeeper/orm/active_record/redirect_uri_validator.rb
doorkeeper-5.7.0 lib/doorkeeper/orm/active_record/redirect_uri_validator.rb
doorkeeper-5.6.9 lib/doorkeeper/orm/active_record/redirect_uri_validator.rb
doorkeeper-5.6.8 lib/doorkeeper/orm/active_record/redirect_uri_validator.rb
doorkeeper-5.6.7 lib/doorkeeper/orm/active_record/redirect_uri_validator.rb
doorkeeper-5.6.6 lib/doorkeeper/orm/active_record/redirect_uri_validator.rb
doorkeeper-5.6.5 lib/doorkeeper/orm/active_record/redirect_uri_validator.rb
doorkeeper-5.6.4 lib/doorkeeper/orm/active_record/redirect_uri_validator.rb
doorkeeper-5.6.3 lib/doorkeeper/orm/active_record/redirect_uri_validator.rb