OpenAuth2 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,182 @@
1
+ module OpenAuth2
2
+
3
+ # Used to make GET/POST requests to OAuth server.
4
+ class Client
5
+ extend DelegateToConfig
6
+ include Connection
7
+
8
+ # Use it to set @config. Will raise error if no @config or wrong
9
+ # @config. We rely on Config for all Options info, so its important
10
+ # it is set right.
11
+ #
12
+ # Yields: self.
13
+ #
14
+ # Accepts:
15
+ # config: (optional) OpenAuth2::Config object
16
+ #
17
+ # Examples:
18
+ # config = OpenAuth2::Config.new do |c|
19
+ # c.provider = :facebook
20
+ # end
21
+ #
22
+ # # set via block
23
+ # OpenAuth2::Client.new do |c|
24
+ # c.config = config
25
+ # end
26
+ #
27
+ # # or pass it as an argument
28
+ # OpenAuth2::Client.new(config)
29
+ #
30
+ # Returns: self.
31
+ #
32
+ def initialize(config=nil)
33
+ @config = config
34
+
35
+ yield self if block_given?
36
+ raise_config_setter_errors
37
+
38
+ # endpoint is where the api requests are made
39
+ @faraday_url = endpoint
40
+
41
+ self
42
+ end
43
+
44
+ # Yields: self, use it to set/change config after #initialize.
45
+ # Mainly for setting access_token and refresh_token. Will raise
46
+ # Config related errors same as #initialize.
47
+ #
48
+ # Examples:
49
+ # client = OpenAuth2::Client.new
50
+ #
51
+ # client.configure do |c|
52
+ # c.access_token = :access_token
53
+ # c.refresh_token = :refresh_token
54
+ # end
55
+ #
56
+ # Returns: self.
57
+ #
58
+ def configure
59
+ yield self
60
+ raise_config_setter_errors
61
+
62
+ self
63
+ end
64
+
65
+ # We use this to get & refresh access/refresh tokens.
66
+ #
67
+ # Returns: Token object.
68
+ #
69
+ def token
70
+ @token ||= Token.new(config)
71
+ end
72
+
73
+ # Examples:
74
+ # client.build_code_url
75
+ # #=> 'http://...'
76
+ #
77
+ # # or
78
+ # client.build_code_url(:scope => 'publish_stream')
79
+ #
80
+ # Accepts:
81
+ # params: (optional) Hash of additional config to be bundled into
82
+ # the url.
83
+ #
84
+ # Returns: String (url).
85
+ #
86
+ def build_code_url(params={})
87
+ token.build_code_url(params)
88
+ end
89
+
90
+ # Makes GET request to OAuth server via Faraday. If access_token
91
+ # is available, we pass that along to identify ourselves.
92
+ #
93
+ # Accepts:
94
+ # hash
95
+ # :path - (required)
96
+ #
97
+ # Examples:
98
+ # client.get(:path => '/cocacola')
99
+ # client.get(:path => '/cocacola', :limit => 1)
100
+ #
101
+ # Returns: Faraday response object.
102
+ #
103
+ def get(hash)
104
+ connection.get do |conn|
105
+ path = hash.delete(:path)
106
+
107
+ if path_prefix
108
+ path = "#{path_prefix}#{path}"
109
+ end
110
+
111
+ hash.merge!(:access_token => access_token) if access_token
112
+
113
+ conn.url(path, hash)
114
+ end
115
+ end
116
+
117
+ # Makes POST request to OAuth server via Faraday.
118
+ #
119
+ # Accepts:
120
+ # hash
121
+ # :path - (required)
122
+ # :content_type - (optional)
123
+ # :body - (optional)
124
+ #
125
+ # Examples:
126
+ # # using query params (fb uses this)
127
+ # client.post(:path => "/me/feed?message='From OpenAuth2'")
128
+ #
129
+ # # using body (google uses this)
130
+ # body = JSON.dump(:message => "From OpenAuth2)
131
+ # client.post(:path => "/me/feed,
132
+ # :body => body,
133
+ # :content_type => 'application/json')
134
+ #
135
+ # Returns: Faraday response object.
136
+ #
137
+ def post(hash)
138
+ connection.post do |conn|
139
+ if hash[:content_type]
140
+ conn.headers["Content-Type"] = hash[:content_type]
141
+ end
142
+
143
+ conn.url(hash[:path], :access_token => access_token)
144
+ conn.body = hash[:body]
145
+ end
146
+ end
147
+
148
+ # Makes request to OAuth server via Faraday#run_request. It takes
149
+ # Hash since I can never remember the order in which to pass the
150
+ # arguments.
151
+ #
152
+ # Accepts:
153
+ # hash
154
+ # :verb - (required) GET/POST etc.
155
+ # :path - (required)
156
+ # :body - (optional)
157
+ # :header - (optional)
158
+ #
159
+ # Examples:
160
+ # # public GET request
161
+ # path = "https://graph.facebook.com/cocacola"
162
+ # client.run_request(verb: :get, path: path, body: nil, header: nil)
163
+ #
164
+ # # private GET request
165
+ # path = "/me/likes?access_token=..."
166
+ # client.run_request(verb: :get, path: path, body: nil, header: nil)
167
+ #
168
+ # Returns: Faraday response object.
169
+ #
170
+ def run_request(hash)
171
+ connection.run_request(hash[:verb], hash[:path], hash[:body],
172
+ hash[:header])
173
+ end
174
+
175
+ private
176
+
177
+ def raise_config_setter_errors
178
+ raise NoConfigObject unless config
179
+ raise UnknownConfigObject unless config.is_a?(OpenAuth2::Config)
180
+ end
181
+ end
182
+ end
@@ -0,0 +1,102 @@
1
+ module OpenAuth2
2
+
3
+ # Holds the info required to make a valid request to an OAuth server.
4
+ class Config
5
+ attr_accessor *Provider::Base::Keys
6
+ attr_reader :provider, :provider_const, :provider_string
7
+
8
+ # Sets provider to default.
9
+ #
10
+ # Yields: self, use it to set config.
11
+ #
12
+ # Examples:
13
+ # OpenAuth2::Config.new do |c|
14
+ # c.provider = :default
15
+ # end
16
+ #
17
+ # Returns: self.
18
+ #
19
+ def initialize
20
+ set_default_as_provider
21
+
22
+ yield self if block_given?
23
+ end
24
+
25
+ # Yields: self, use it to set/change config after #initialize.
26
+ #
27
+ # Examples:
28
+ # config = OpenAuth2::Config.new
29
+ #
30
+ # config.configure do |c|
31
+ # c.provider = :google
32
+ # end
33
+ #
34
+ # Returns: self.
35
+ #
36
+ def configure
37
+ yield self if block_given?
38
+ end
39
+
40
+ # Finds provider's module & copies its Options key/values to here.
41
+ #
42
+ # Accepts:
43
+ # name - String/Symbol/Constant.
44
+ #
45
+ def provider=(name)
46
+ set_provider_vars(name)
47
+ copy_provider_keys
48
+ end
49
+
50
+ # Removes all overwritten config & resets provider to default.
51
+ def reset_provider
52
+ remove_instance_vars
53
+ set_default_as_provider
54
+ end
55
+
56
+ def parse(response_body)
57
+ @provider_const.parse(self, response_body)
58
+ end
59
+
60
+ private
61
+
62
+ def set_default_as_provider
63
+ self.provider = :default
64
+ end
65
+
66
+ def set_provider_vars(name)
67
+ @provider = name
68
+ @provider_string = name.to_s
69
+ @provider_const = constantize_provider_string
70
+ end
71
+
72
+ def constantize_provider_string
73
+ provider_string = @provider_string.camelize
74
+ full_string = "OpenAuth2::Provider::#{provider_string}"
75
+
76
+ @provider_const = full_string.constantize
77
+ rescue NameError => error
78
+ if error.to_s =~ /uninitialized constant/
79
+ raise UnknownProvider, "Known Providers: #{known_providers}"
80
+ end
81
+ end
82
+
83
+ def known_providers
84
+ known_providers = OpenAuth2::Provider.constants
85
+ known_providers.delete(:Base)
86
+
87
+ known_providers
88
+ end
89
+
90
+ def copy_provider_keys
91
+ @provider_const::Options.each do |key,value|
92
+ instance_variable_set("@#{key}", value)
93
+ end
94
+ end
95
+
96
+ def remove_instance_vars
97
+ instance_variables.each do |var|
98
+ remove_instance_variable var
99
+ end
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,38 @@
1
+ module OpenAuth2
2
+
3
+ # Client/Token use this to make the actual requests to OAuth server.
4
+ # Since some OAuth servers have seperate endpoints for authorization
5
+ # & api requests, we use @faraday_url to store that info.
6
+ #
7
+ module Connection
8
+ def self.included(base)
9
+ base.class_eval do
10
+ attr_accessor :faraday_url
11
+ end
12
+ end
13
+
14
+ # Yields: Faraday object, so user can choose choose their own
15
+ # middleware.
16
+ #
17
+ # Examples:
18
+ # config = OpenAuth2::Config.new
19
+ # client = OpenAuth2::Client.new(config)
20
+ #
21
+ # client.connection do |c|
22
+ # c.response :logger
23
+ # end
24
+ #
25
+ # Returns: Faraday object.
26
+ #
27
+ def connection
28
+ @connection ||= Faraday.new(:url => @faraday_url) do |builder|
29
+ builder.request :url_encoded
30
+ builder.adapter :net_http
31
+ end
32
+
33
+ yield @connection if block_given?
34
+
35
+ @connection
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,25 @@
1
+ module OpenAuth2
2
+
3
+ # Helper module that Client/Token extend so they can have access to
4
+ # Options methods. We delegate those methods to @config, which should
5
+ # contain Config object.
6
+ #
7
+ module DelegateToConfig
8
+ def self.extended(base)
9
+ base.send(:attr_accessor, :config)
10
+ base.delegate_to_config
11
+ end
12
+
13
+ def delegate_to_config
14
+ OpenAuth2::Provider::Base::Keys.each do |key|
15
+ define_method(key) do
16
+ @config.send(key)
17
+ end
18
+
19
+ define_method("#{key}=") do |value|
20
+ @config.send("#{key}=", value)
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,21 @@
1
+ # Contains various providers & their config info stored in Options hash.
2
+ # When user sets a provider, we copy over its Options to Config.
3
+ #
4
+ # The reason for this setup is b/c various OAuth servers accept &
5
+ # return different options & values. This way users can contribute
6
+ # their own providers, i.e. a very simple plugin system.
7
+ #
8
+ # Acceptable providers are modules defined under OpenAuth2::Provider,
9
+ # have Options hash.
10
+ #
11
+ # Examples:
12
+ # module OpenAuth2::Providers::YourProviderName
13
+ # Options = {
14
+ # :authorize_url => 'https://your_provider_name.com'
15
+ # }
16
+ # end
17
+ #
18
+ module OpenAuth2
19
+ module Provider
20
+ end
21
+ end
@@ -0,0 +1,31 @@
1
+ module OpenAuth2
2
+ module Provider
3
+
4
+ # Contains all possible Options keys. Config allows only the ones
5
+ # specified here.
6
+ #
7
+ module Base
8
+ Keys = [
9
+ :client_id,
10
+ :client_secret,
11
+ :code,
12
+ :authorize_url,
13
+ :redirect_uri,
14
+ :code_url,
15
+ :authorize_path,
16
+ :token_path,
17
+ :access_token,
18
+ :refresh_token,
19
+ :response_type,
20
+ :access_token_grant_name,
21
+ :refresh_token_grant_name,
22
+ :refresh_token_name,
23
+ :scope,
24
+ :endpoint,
25
+ :path_prefix,
26
+ :token_expires_at,
27
+ :token_arrived_at,
28
+ ]
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,18 @@
1
+ module OpenAuth2
2
+ module Provider
3
+
4
+ # Contains the default Options, which is copied to Config on
5
+ # #initialize. We can then choose another provider or overwrite
6
+ # them individually.
7
+ #
8
+ module Default
9
+ Options = {
10
+ :response_type => 'code',
11
+ :access_token_grant_name => 'authorization_code',
12
+ :refresh_token_grant_name => 'refresh_token',
13
+ :refresh_token_name => :refresh_token,
14
+ :scope => [],
15
+ }
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,23 @@
1
+ module OpenAuth2
2
+ module Provider
3
+ module Facebook
4
+ Options = {
5
+ :authorize_url => 'https://graph.facebook.com',
6
+ :code_url => 'https://www.facebook.com',
7
+ :refresh_token_grant_name => 'fb_exchange_token',
8
+ :refresh_token_name => 'fb_exchange_token',
9
+ :authorize_path => '/dialog/oauth',
10
+ :token_path => 'oauth/access_token',
11
+ :endpoint => 'https://graph.facebook.com'
12
+ }
13
+
14
+ def self.parse(config, response_body)
15
+ access_token = response_body.gsub('access_token=', '')
16
+ config.access_token = access_token
17
+ config.refresh_token = access_token
18
+ config.token_arrived_at = Time.now
19
+ config.token_expires_at = "60 days?"
20
+ end
21
+ end
22
+ end
23
+ end