This repository was archived by the owner on Oct 16, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 41
/
Copy pathconfig.rb
152 lines (132 loc) · 4.9 KB
/
config.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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
require 'uri'
module Warden
module GitHub
# This class encapsulates the configuration of the strategy. A strategy can
# be configured through Warden::Manager by defining a scope's default. Thus,
# it is possible to use the same strategy with different configurations by
# using multiple scopes.
#
# To configure a scope, use #scope_defaults inside the Warden::Manager
# config block. The first arg is the name of the scope (the default is
# :default, so use that to configure the default scope), the second arg is
# an options hash which should contain:
#
# - :strategies : An array of strategies to use for this scope. Since this
# strategy is called :github, include it in the array.
#
# - :config : A hash containing the configs that are used for OAuth.
# Valid parameters include :client_id, :client_secret,
# :scope, :redirect_uri. Please refer to the OAuth
# documentation of the GitHub API for the meaning of these
# parameters.
#
# If :client_id or :client_secret are not specified, they
# will be fetched from ENV['GITHUB_CLIENT_ID'] and
# ENV['GITHUB_CLIENT_SECRET'], respectively.
#
# :scope defaults to nil.
#
# If no :redirect_uri is specified, the current path will
# be used. If a path is specified it will be appended to
# the request host, forming a valid URL.
#
# Examples
#
# use Warden::Manager do |config|
# config.failure_app = BadAuthentication
#
# # The following line doesn't specify any custom configurations, thus
# # the default scope will be using the implict client_id,
# # client_secret, and redirect_uri.
# config.default_strategies :github
#
# # This configures an additional scope that uses the github strategy
# # with custom configuration.
# config.scope_defaults :admin, config: { client_id: 'foobar',
# client_secret: 'barfoo',
# scope: 'user,repo',
# redirect_uri: '/admin/oauth/callback' }
# end
class Config
BadConfig = Class.new(StandardError)
include ::Warden::Mixins::Common
attr_reader :env, :warden_scope
def initialize(env, warden_scope)
@env = env
@warden_scope = warden_scope
end
def client_id
custom_config[:client_id] ||
deprecated_config(:github_client_id) ||
ENV['GITHUB_CLIENT_ID'] ||
fail(BadConfig, 'Missing client_id configuration.')
end
def client_secret
custom_config[:client_secret] ||
deprecated_config(:github_secret) ||
ENV['GITHUB_CLIENT_SECRET'] ||
fail(BadConfig, 'Missing client_secret configuration.')
end
def redirect_uri
uri_or_path =
custom_config[:redirect_uri] ||
deprecated_config(:github_callback_url) ||
request.path
normalized_uri(uri_or_path).to_s
end
def scope
custom_config[:scope] || deprecated_config(:github_scopes)
end
def to_hash
{ client_id: client_id,
client_secret: client_secret,
redirect_uri: redirect_uri,
scope: scope }
end
private
def custom_config
@custom_config ||=
env['warden'].
config[:scope_defaults].
fetch(warden_scope, {}).
fetch(:config, {})
end
def deprecated_config(name)
env['warden'].config[name].tap do |config|
unless config.nil?
warn "[warden-github] Deprecated configuration #{name} used. Please refer to the README for updated configuration instructions."
end
end
end
def normalized_uri(uri_or_path)
uri = URI(request.url)
uri.path = extract_path(URI(uri_or_path))
uri.query = nil
uri.fragment = nil
correct_scheme(uri)
end
def extract_path(uri)
path = uri.path
if path.start_with?('/')
path
else
"/#{path}"
end
end
def https_forwarded_proto?
env['HTTP_X_FORWARDED_PROTO'] &&
env['HTTP_X_FORWARDED_PROTO'].split(',')[0] == "https"
end
def correct_scheme(uri)
if uri.scheme != 'https' && https_forwarded_proto?
uri.scheme = 'https'
# Reparsing will use a different URI subclass, namely URI::HTTPS which
# knows the default port for https and strips it if present.
uri = URI(uri.to_s)
end
uri.port = nil if uri.port == 80
URI(uri.to_s)
end
end
end
end