/
redirect_uri_validator.rb
47 lines (39 loc) · 1.31 KB
/
redirect_uri_validator.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# frozen_string_literal: true
require 'uri'
class RedirectUriValidator < ActiveModel::EachValidator
def self.native_redirect_uri
Doorkeeper.configuration.native_redirect_uri
end
def validate_each(record, attribute, value)
if value.blank?
record.errors.add(attribute, :blank)
else
value.split.each do |val|
uri = ::URI.parse(val)
next if native_redirect_uri?(uri)
record.errors.add(attribute, :forbidden_uri) if forbidden_uri?(uri)
record.errors.add(attribute, :fragment_present) unless uri.fragment.nil?
record.errors.add(attribute, :relative_uri) if uri.scheme.nil? || uri.host.nil?
record.errors.add(attribute, :secured_uri) if invalid_ssl_uri?(uri)
end
end
rescue URI::InvalidURIError
record.errors.add(attribute, :invalid_uri)
end
private
def native_redirect_uri?(uri)
self.class.native_redirect_uri.present? && uri.to_s == self.class.native_redirect_uri.to_s
end
def forbidden_uri?(uri)
Doorkeeper.configuration.forbid_redirect_uri.call(uri)
end
def invalid_ssl_uri?(uri)
forces_ssl = Doorkeeper.configuration.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