Codebase list ruby-omniauth-facebook / upstream/1.6.0
Imported Upstream version 1.6.0 Nitesh A Jain 10 years ago
15 changed file(s) with 384 addition(s) and 225 deletion(s). Raw diff Collapse all Expand all
0 before_install:
1 - gem update bundler
2 - bundle --version
3 - gem update --system 2.1.11
4 - gem --version
05 rvm:
16 - 1.8.7
27 - 1.9.2
38 - 1.9.3
9 - 2.0.0
410 - jruby
5 branches:
6 only:
7 - master
0 ## 1.6.0 (2014-01-13)
1
2 Features:
3
4 - ability to specify `auth_type` per-request (#78, @sebastian-stylesaint)
5 - image dimension can be set using `image_size` option (#91, @weilu)
6 - update Facebook authorize URL to fix broken authorization (#103, @dlackty)
7 - adds `info_fields` option (#109, @bloudermilk)
8 - adds `locale` parameter (#133, @donbobka, @simi)
9 - add automatically `appsecret_proof` (#140, @nlsrchtr, @simi)
10
11 Changes:
12
13 - `NoAuthorizationCodeError` and `UnknownSignatureAlgorithmError` will now `fail!` (#117, @nchelluri)
14 - don't try to parse the signature if it's nil (#127, @oriolgual)
15
16 ## 1.5.1 (2013-11-18)
17
18 Changes:
19
20 - don't use `access_token` in URL [CVE-2013-4593](https://github.com/mkdynamic/omniauth-facebook/wiki/Access-token-vulnerability:-CVE-2013-4593) (@homakov, @mkdynamic, @simi)
21
22 ## 1.5.0 (2013-11-13)
23
24 Changes:
25
26 - remove `state` param to fix CSRF vulnerabilty [CVE-2013-4562](https://github.com/mkdynamic/omniauth-facebook/wiki/CSRF-vulnerability:-CVE-2013-4562) (@homakov, @mkdynamic, @simi)
27
28 ## 1.4.1 (2012-07-07)
29
30 Changes:
31
32 - update to omniauth-oauth2 1.1.0 for csrf protection (@mkdynamic)
33
34 ## 1.4.0 (2012-06-24)
35
36 Features:
37
38 - obey `skip_info?` config (@mkdynamic)
39 - add support of the `:auth_type` option to `:authorize_options` (#58, @JHeidinga, @mkdynamic)
40 - support `access_token` parameter as part of the callback request (#62, @steverandy)
41
42 ## 1.3.0 (2012-05-05)
43
44 Features:
45
46 - dynamic permissions in the auth params (#30, @famoseagle)
47 - add support for facebook canvas (@mkdynamic)
48 - add verified key to the info hash (#34, @ryansobol)
49 - add option to use secure url for image in auth hash (@mkdynamic)
50 - add option to specify image size (@mkdynamic)
51
52 Changes:
53
54 - have `raw_info` return an empty hash if the Facebook response returns false (#44, @brianjlandau)
55 - prevent oauth2 from interpreting Facebook's expires field as `expires_in`, when it's really `expires_at` (#39, @watsonbox)
56 - remove deprecated `offline_access` permission (@mkdynamic)
57
58 Changes:
59
60 - tidy up the `callback_url` option (@mkdynamic)
61
62 ## 1.2.0 (2012-01-06)
63
64 Features:
65
66 - add `state` to authorization params (#19, @GermanDZ)
67
68 Changes:
69
70 - lock to `rack ~> 1.3.6` (@mkdynamic)
71
72 ## 1.1.0 (2011-12-10)
73
74 Features:
75
76 - add `callback_url` option (#13, @gumayunov)
77 - support for parsing code from signed request cookie (client-side flow) (@mkdynamic)
78
79 ## 1.0.0 (2011-11-19)
80
81 Features:
82
83 - allow passing of display via option (@mkdynamic)
84
85 Bugfixes:
86
87 - fix `ten_mins_from_now` calculation (#7, @olegkovalenko)
88
89 ## 1.0.0.rc2 (2011-11-11)
90
91 Features:
92
93 - allow passing `display` parameter (@mkdynamic)
94 - included default scope (@mkdynamic)
95
96 ## 1.0.0.rc1 (2011-10-29)
97
98 - first public gem release (@mkdynamic)
0 source :rubygems
0 source 'https://rubygems.org'
11
22 gemspec
33
0 # OmniAuth Facebook  [![Build Status](http://travis-ci.org/mkdynamic/omniauth-facebook.png?branch=master)](http://travis-ci.org/mkdynamic/omniauth-facebook)
0 **NOTE: If you're running < 1.5.1, please upgrade to address 2 security vulnerabilities.
1 More details [here](https://github.com/mkdynamic/omniauth-facebook/wiki/CSRF-vulnerability:-CVE-2013-4562) and [here](https://github.com/mkdynamic/omniauth-facebook/wiki/Access-token-vulnerability:-CVE-2013-4593).**
12
2 Facebook OAuth2 Strategy for OmniAuth 1.0.
3 ---
4
5 # OmniAuth Facebook &nbsp;[![Build Status](https://secure.travis-ci.org/mkdynamic/omniauth-facebook.png?branch=master)](https://travis-ci.org/mkdynamic/omniauth-facebook)
6
7 Facebook OAuth2 Strategy for OmniAuth.
38
49 Supports the OAuth 2.0 server-side and client-side flows. Read the Facebook docs for more details: http://developers.facebook.com/docs/authentication
510
1520
1621 ## Usage
1722
18 `OmniAuth::Strategies::Facebook` is simply a Rack middleware. Read the OmniAuth 1.0 docs for detailed instructions: https://github.com/intridea/omniauth.
23 `OmniAuth::Strategies::Facebook` is simply a Rack middleware. Read the OmniAuth docs for detailed instructions: https://github.com/intridea/omniauth.
1924
2025 Here's a quick example, adding the middleware to a Rails app in `config/initializers/omniauth.rb`:
2126
3641 * `auth_type`: Optionally specifies the requested authentication features as a comma-separated list, as per https://developers.facebook.com/docs/authentication/reauthentication/.
3742 Valid values are `https` (checks for the presence of the secure cookie and asks for re-authentication if it is not present), and `reauthenticate` (asks the user to re-authenticate unconditionally). Default is `nil`.
3843 * `secure_image_url`: Set to `true` to use https for the avatar image url returned in the auth hash. Default is `false`.
39 * `image_size`: Set the size for the returned image url in the auth hash. Valid options are `square` (50x50), `small` (50 pixels wide, variable height), `normal` (100 pixels wide, variable height), or `large` (about 200 pixels wide, variable height). Default is `square` (50x50).
44 * `image_size`: Set the size for the returned image url in the auth hash. Valid options include `square` (50x50), `small` (50 pixels wide, variable height), `normal` (100 pixels wide, variable height), or `large` (about 200 pixels wide, variable height). Additionally, you can request a picture of a specific size by setting this option to a hash with `:width` and `:height` as keys. This will return an available profile picture closest to the requested size and requested aspect ratio. If only `:width` or `:height` is specified, we will return a picture whose width or height is closest to the requested size, respectively.
45 * `info_fields`: Specify exactly which fields should be returned when getting the user's info. Value should be a comma-separated string as per https://developers.facebook.com/docs/reference/api/user/ (only /me endpoint).
46 * `locale`: Specify locale which should be used when getting the user's info. Value should be locale string as per https://developers.facebook.com/docs/reference/api/locale/.
4047
4148 For example, to request `email`, `user_birthday` and `read_stream` permissions and display the authentication page in a popup window:
4249
4956
5057 ### Per-Request Options
5158
52 If you want to set the `display` format or `scope` on a per-request basis, you can just pass it to the OmniAuth request phase URL, for example: `/auth/facebook?display=popup` or `/auth/facebook?scope=email`.
53
54 You can also pass through a `state` param which will be passed along to the callback url.
59 If you want to set the `display` format, `auth_type`, or `scope` on a per-request basis, you can just pass it to the OmniAuth request phase URL, for example: `/auth/facebook?display=popup` or `/auth/facebook?scope=email`.
5560
5661 ### Custom Callback URL/Path
5762
135140
136141 Take a look at [the example Sinatra app for one option of how you can integrate with a canvas page](https://github.com/mkdynamic/omniauth-facebook/blob/master/example/config.ru).
137142
138 Bear in mind you have several options (including [authenticated referrals](https://developers.facebook.com/docs/opengraph/authentication/#referrals)). Read [the Facebook docs on canvas page authentication](https://developers.facebook.com/docs/authentication/canvas/) for more info.
143 Bear in mind you have several [options](https://developers.facebook.com/docs/opengraph/authentication). Read [the Facebook docs on canvas page authentication](https://developers.facebook.com/docs/authentication/canvas/) for more info.
139144
140145 ## Token Expiry
141146
149154
150155 ### Server-Side Flow
151156
152 If you use the server-side flow, Facebook will give you back a longer loved access token (~ 60 days).
157 If you use the server-side flow, Facebook will give you back a longer lived access token (~ 60 days).
153158
154159 If you're having issue getting a long lived token with the server-side flow, make sure to enable the 'deprecate offline_access setting' in you Facebook app config. Read the [Facebook docs about the offline_access deprecation](https://developers.facebook.com/roadmap/offline-access-removal/) for more information.
155160
157162
158163 Actively tested with the following Ruby versions:
159164
165 - MRI 2.0.0
160166 - MRI 1.9.3
161167 - MRI 1.9.2
162168 - MRI 1.8.7
163 - JRuby 1.6.5
169 - JRuby 1.7.4
164170
165 *NB.* For JRuby, you'll need to install the `jruby-openssl` gem. There's no way to automatically specify this in a Rubygem gemspec, so you need to manually add it your project's own Gemfile:
171 *NB.* For JRuby < 1.7, you'll need to install the `jruby-openssl` gem. There's no way to automatically specify this in a Rubygem gemspec, so you need to manually add it your project's own Gemfile:
166172
167173 ```ruby
168174 gem 'jruby-openssl', :platform => :jruby
Binary diff not shown
0 source :rubygems
0 source 'https://rubygems.org'
11
22 gem 'sinatra'
33 gem 'omniauth-facebook', :path => '../'
00 PATH
11 remote: ../
22 specs:
3 omniauth-facebook (1.4.0)
4 omniauth-oauth2 (~> 1.1.0)
3 omniauth-facebook (1.6.0.rc1)
4 omniauth-oauth2 (~> 1.1)
55
66 GEM
7 remote: http://rubygems.org/
7 remote: https://rubygems.org/
88 specs:
9 faraday (0.8.1)
10 multipart-post (~> 1.1)
11 hashie (1.2.0)
12 httpauth (0.1)
13 json (1.7.3)
14 jwt (0.1.4)
15 json (>= 1.2.4)
16 multi_json (1.3.6)
17 multipart-post (1.1.5)
18 oauth2 (0.8.0)
9 faraday (0.8.8)
10 multipart-post (~> 1.2.0)
11 hashie (2.0.5)
12 httpauth (0.2.0)
13 jwt (0.1.8)
14 multi_json (>= 1.5)
15 multi_json (1.8.2)
16 multipart-post (1.2.0)
17 oauth2 (0.8.1)
1918 faraday (~> 0.8)
2019 httpauth (~> 0.1)
2120 jwt (~> 0.1.4)
2221 multi_json (~> 1.0)
2322 rack (~> 1.2)
24 omniauth (1.1.0)
25 hashie (~> 1.2)
23 omniauth (1.1.4)
24 hashie (>= 1.2, < 3)
2625 rack
27 omniauth-oauth2 (1.1.0)
26 omniauth-oauth2 (1.1.1)
2827 oauth2 (~> 0.8.0)
2928 omniauth (~> 1.0)
30 rack (1.4.1)
31 rack-protection (1.2.0)
29 rack (1.5.2)
30 rack-protection (1.5.1)
3231 rack
33 sinatra (1.3.2)
34 rack (~> 1.3, >= 1.3.6)
35 rack-protection (~> 1.2)
36 tilt (~> 1.3, >= 1.3.3)
37 tilt (1.3.3)
32 sinatra (1.4.4)
33 rack (~> 1.4)
34 rack-protection (~> 1.4)
35 tilt (~> 1.3, >= 1.3.4)
36 tilt (1.4.1)
3837
3938 PLATFORMS
4039 ruby
8686 # signed_request FB sends us, asking for auth if the user has
8787 # not already granted access, or simply moving straight to the
8888 # callback where they have already granted access.
89 #
90 # we pass the state parameter which we can detect in our callback
91 # to do custom rendering/redirection for the canvas app page
92 redirect "/auth/facebook?signed_request=#{request.params['signed_request']}&state=canvas"
89 redirect "/auth/facebook?signed_request=#{request.params['signed_request']}"
9390 end
9491
9592 get '/auth/:provider/callback' do
96 # we can do something special here is +state+ param is canvas
97 # (see notes above in /canvas/ method for more details)
9893 content_type 'application/json'
9994 MultiJson.encode(request.env)
10095 end
00 module OmniAuth
11 module Facebook
2 VERSION = "1.4.1"
2 VERSION = "1.6.0"
33 end
44 end
11 require 'base64'
22 require 'openssl'
33 require 'rack/utils'
4 require 'uri'
45
56 module OmniAuth
67 module Strategies
78 class Facebook < OmniAuth::Strategies::OAuth2
89 class NoAuthorizationCodeError < StandardError; end
10 class UnknownSignatureAlgorithmError < NotImplementedError; end
911
1012 DEFAULT_SCOPE = 'email'
1113
1214 option :client_options, {
1315 :site => 'https://graph.facebook.com',
16 :authorize_url => "https://www.facebook.com/dialog/oauth",
1417 :token_url => '/oauth/access_token'
1518 }
1619
3437 'name' => raw_info['name'],
3538 'first_name' => raw_info['first_name'],
3639 'last_name' => raw_info['last_name'],
37 'image' => "#{options[:secure_image_url] ? 'https' : 'http'}://graph.facebook.com/#{uid}/picture?type=#{options[:image_size] || 'square'}",
40 'image' => image_url(uid, options),
3841 'description' => raw_info['bio'],
3942 'urls' => {
4043 'Facebook' => raw_info['link'],
5255 end
5356
5457 def raw_info
55 @raw_info ||= access_token.get('/me').parsed || {}
56 end
58 @raw_info ||= access_token.get('/me', info_options).parsed || {}
59 end
60
61 def info_options
62 params = {:appsecret_proof => appsecret_proof}
63 params.merge!({:fields => options[:info_fields]}) if options[:info_fields]
64 params.merge!({:locale => options[:locale]}) if options[:locale]
65
66 { :params => params }
67 end
68
69 def callback_phase
70 super
71 rescue NoAuthorizationCodeError => e
72 fail!(:no_authorization_code, e)
73 rescue UnknownSignatureAlgorithmError => e
74 fail!(:unknown_signature_algoruthm, e)
75 end
76
77 def request_phase
78 if signed_request_contains_access_token?
79 # If we already have an access token, we can just hit the callback URL directly and pass the signed request.
80 params = { :signed_request => raw_signed_request }
81 query = Rack::Utils.build_query(params)
82
83 url = callback_url
84 url << "?" unless url.match(/\?/)
85 url << "&" unless url.match(/[\&\?]$/)
86 url << query
87
88 redirect url
89 else
90 super
91 end
92 end
93
94 # NOTE If we're using code from the signed request then FB sets the redirect_uri to '' during the authorize
95 # phase and it must match during the access_token phase:
96 # https://github.com/facebook/php-sdk/blob/master/src/base_facebook.php#L348
97 def callback_url
98 if @authorization_code_from_signed_request
99 ''
100 else
101 options[:callback_url] || super
102 end
103 end
104
105 def access_token_options
106 options.access_token_options.inject({}) { |h,(k,v)| h[k.to_sym] = v; h }
107 end
108
109 # You can pass +display+, +scope+, or +auth_type+ params to the auth request, if you need to set them dynamically.
110 # You can also set these options in the OmniAuth config :authorize_params option.
111 #
112 # /auth/facebook?display=popup
113 def authorize_params
114 super.tap do |params|
115 %w[display scope auth_type].each do |v|
116 if request.params[v]
117 params[v.to_sym] = request.params[v]
118 end
119 end
120
121 params[:scope] ||= DEFAULT_SCOPE
122 end
123 end
124
125 # Parse signed request in order, from:
126 #
127 # 1. The request 'signed_request' param (server-side flow from canvas pages) or
128 # 2. A cookie (client-side flow via JS SDK)
129 def signed_request
130 @signed_request ||= raw_signed_request && parse_signed_request(raw_signed_request)
131 end
132
133 protected
57134
58135 def build_access_token
59 if access_token = request.params["access_token"]
60 ::OAuth2::AccessToken.from_hash(
61 client,
62 {"access_token" => access_token}.update(access_token_options)
63 )
64 elsif signed_request_contains_access_token?
136 if signed_request_contains_access_token?
65137 hash = signed_request.clone
66138 ::OAuth2::AccessToken.new(
67139 client,
75147 end
76148 end
77149
78 def request_phase
79 if signed_request_contains_access_token?
80 # if we already have an access token, we can just hit the
81 # callback URL directly and pass the signed request along
82 params = { :signed_request => raw_signed_request }
83 params[:state] = request.params['state'] if request.params['state']
84 query = Rack::Utils.build_query(params)
85
86 url = callback_url
87 url << "?" unless url.match(/\?/)
88 url << "&" unless url.match(/[\&\?]$/)
89 url << query
90
91 redirect url
92 else
93 super
94 end
95 end
96
97 # NOTE if we're using code from the signed request
98 # then FB sets the redirect_uri to '' during the authorize
99 # phase + it must match during the access_token phase:
100 # https://github.com/facebook/php-sdk/blob/master/src/base_facebook.php#L348
101 def callback_url
102 if @authorization_code_from_signed_request
103 ''
104 else
105 options[:callback_url] || super
106 end
107 end
108
109 def access_token_options
110 options.access_token_options.inject({}) { |h,(k,v)| h[k.to_sym] = v; h }
111 end
112
113 ##
114 # You can pass +display+, +state+ or +scope+ params to the auth request, if
115 # you need to set them dynamically. You can also set these options
116 # in the OmniAuth config :authorize_params option.
117 #
118 # /auth/facebook?display=popup&state=ABC
119 #
120 def authorize_params
121 super.tap do |params|
122 %w[display state scope].each do |v|
123 if request.params[v]
124 params[v.to_sym] = request.params[v]
125
126 # to support omniauth-oauth2's auto csrf protection
127 session['omniauth.state'] = params[:state] if v == 'state'
128 end
129 end
130
131 params[:scope] ||= DEFAULT_SCOPE
132 end
133 end
134
135 ##
136 # Parse signed request in order, from:
137 #
138 # 1. the request 'signed_request' param (server-side flow from canvas pages) or
139 # 2. a cookie (client-side flow via JS SDK)
140 #
141 def signed_request
142 @signed_request ||= raw_signed_request &&
143 parse_signed_request(raw_signed_request)
144 end
145
146150 private
147151
148152 def raw_signed_request
149 request.params['signed_request'] ||
150 request.cookies["fbsr_#{client.id}"]
151 end
152
153 ##
154 # If the signed_request comes from a FB canvas page and the user
155 # has already authorized your application, the JSON object will be
156 # contain the access token.
153 request.params['signed_request'] || request.cookies["fbsr_#{client.id}"]
154 end
155
156 # If the signed_request comes from a FB canvas page and the user has already authorized your application, the JSON
157 # object will be contain the access token.
157158 #
158159 # https://developers.facebook.com/docs/authentication/canvas/
159 #
160160 def signed_request_contains_access_token?
161 signed_request &&
162 signed_request['oauth_token']
163 end
164
165 ##
161 signed_request && signed_request['oauth_token']
162 end
163
166164 # Picks the authorization code in order, from:
167165 #
168 # 1. the request 'code' param (manual callback from standard server-side flow)
169 # 2. a signed request (see #signed_request for more)
170 #
166 # 1. The request 'code' param (manual callback from standard server-side flow)
167 # 2. A signed request (see #signed_request for more)
171168 def with_authorization_code!
172169 if request.params.key?('code')
173170 yield
194191
195192 def parse_signed_request(value)
196193 signature, encoded_payload = value.split('.')
194 return if signature.nil?
197195
198196 decoded_hex_signature = base64_decode_url(signature)
199197 decoded_payload = MultiJson.decode(base64_decode_url(encoded_payload))
200198
201199 unless decoded_payload['algorithm'] == 'HMAC-SHA256'
202 raise NotImplementedError, "unkown algorithm: #{decoded_payload['algorithm']}"
200 raise UnknownSignatureAlgorithmError, "unknown algorithm: #{decoded_payload['algorithm']}"
203201 end
204202
205203 if valid_signature?(client.secret, decoded_hex_signature, encoded_payload)
215213 value += '=' * (4 - value.size.modulo(4))
216214 Base64.decode64(value.tr('-_', '+/'))
217215 end
216
217 def image_url(uid, options)
218 uri_class = options[:secure_image_url] ? URI::HTTPS : URI::HTTP
219 url = uri_class.build({:host => 'graph.facebook.com', :path => "/#{uid}/picture"})
220
221 query = if options[:image_size].is_a?(String)
222 { :type => options[:image_size] }
223 elsif options[:image_size].is_a?(Hash)
224 options[:image_size]
225 end
226 url.query = Rack::Utils.build_query(query) if query
227
228 url.to_s
229 end
230
231 def appsecret_proof
232 @appsecret_proof ||= OpenSSL::HMAC.hexdigest(OpenSSL::Digest::SHA256.new, client.secret, access_token.token)
233 end
218234 end
219235 end
220236 end
00 --- !ruby/object:Gem::Specification
11 name: omniauth-facebook
22 version: !ruby/object:Gem::Version
3 version: 1.4.1
4 prerelease:
3 version: 1.6.0
54 platform: ruby
65 authors:
76 - Mark Dodwell
7 - Josef Šimánek
88 autorequire:
99 bindir: bin
1010 cert_chain: []
11 date: 2012-07-07 00:00:00.000000000 Z
11 date: 2014-01-11 00:00:00.000000000 Z
1212 dependencies:
1313 - !ruby/object:Gem::Dependency
1414 name: omniauth-oauth2
1515 requirement: !ruby/object:Gem::Requirement
16 none: false
1716 requirements:
1817 - - ~>
1918 - !ruby/object:Gem::Version
20 version: 1.1.0
19 version: '1.1'
2120 type: :runtime
2221 prerelease: false
2322 version_requirements: !ruby/object:Gem::Requirement
24 none: false
2523 requirements:
2624 - - ~>
2725 - !ruby/object:Gem::Version
28 version: 1.1.0
26 version: '1.1'
2927 - !ruby/object:Gem::Dependency
3028 name: minitest
3129 requirement: !ruby/object:Gem::Requirement
32 none: false
3330 requirements:
34 - - ! '>='
31 - - '>='
3532 - !ruby/object:Gem::Version
3633 version: '0'
3734 type: :development
3835 prerelease: false
3936 version_requirements: !ruby/object:Gem::Requirement
40 none: false
4137 requirements:
42 - - ! '>='
38 - - '>='
4339 - !ruby/object:Gem::Version
4440 version: '0'
4541 - !ruby/object:Gem::Dependency
4642 name: mocha
4743 requirement: !ruby/object:Gem::Requirement
48 none: false
4944 requirements:
50 - - ! '>='
45 - - '>='
5146 - !ruby/object:Gem::Version
5247 version: '0'
5348 type: :development
5449 prerelease: false
5550 version_requirements: !ruby/object:Gem::Requirement
56 none: false
5751 requirements:
58 - - ! '>='
52 - - '>='
5953 - !ruby/object:Gem::Version
6054 version: '0'
6155 - !ruby/object:Gem::Dependency
6256 name: rake
6357 requirement: !ruby/object:Gem::Requirement
64 none: false
6558 requirements:
66 - - ! '>='
59 - - '>='
6760 - !ruby/object:Gem::Version
6861 version: '0'
6962 type: :development
7063 prerelease: false
7164 version_requirements: !ruby/object:Gem::Requirement
72 none: false
7365 requirements:
74 - - ! '>='
66 - - '>='
7567 - !ruby/object:Gem::Version
7668 version: '0'
7769 description:
7870 email:
79 - mark@mkdynamic.co.uk
71 - mark@madeofcode.com
72 - retro@ballgag.cz
8073 executables: []
8174 extensions: []
8275 extra_rdoc_files: []
8376 files:
8477 - .gitignore
8578 - .travis.yml
79 - CHANGELOG.md
8680 - Gemfile
8781 - README.md
8882 - Rakefile
9892 - test/support/shared_examples.rb
9993 - test/test.rb
10094 homepage: https://github.com/mkdynamic/omniauth-facebook
101 licenses: []
95 licenses:
96 - MIT
97 metadata: {}
10298 post_install_message:
10399 rdoc_options: []
104100 require_paths:
105101 - lib
106102 required_ruby_version: !ruby/object:Gem::Requirement
107 none: false
108103 requirements:
109 - - ! '>='
104 - - '>='
110105 - !ruby/object:Gem::Version
111106 version: '0'
112 segments:
113 - 0
114 hash: 1875274478054024285
115107 required_rubygems_version: !ruby/object:Gem::Requirement
116 none: false
117108 requirements:
118 - - ! '>='
109 - - '>='
119110 - !ruby/object:Gem::Version
120111 version: '0'
121 segments:
122 - 0
123 hash: 1875274478054024285
124112 requirements: []
125113 rubyforge_project:
126 rubygems_version: 1.8.24
114 rubygems_version: 2.0.2
127115 signing_key:
128 specification_version: 3
129 summary: Facebook strategy for OmniAuth
116 specification_version: 4
117 summary: Facebook OAuth2 Strategy for OmniAuth
130118 test_files:
131119 - test/helper.rb
132120 - test/support/shared_examples.rb
44 Gem::Specification.new do |s|
55 s.name = 'omniauth-facebook'
66 s.version = OmniAuth::Facebook::VERSION
7 s.authors = ['Mark Dodwell']
8 s.email = ['mark@mkdynamic.co.uk']
9 s.summary = 'Facebook strategy for OmniAuth'
7 s.authors = ['Mark Dodwell', 'Josef Šimánek']
8 s.email = ['mark@madeofcode.com', 'retro@ballgag.cz']
9 s.summary = 'Facebook OAuth2 Strategy for OmniAuth'
1010 s.homepage = 'https://github.com/mkdynamic/omniauth-facebook'
11 s.license = 'MIT'
1112
1213 s.files = `git ls-files`.split("\n")
1314 s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
1415 s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
1516 s.require_paths = ['lib']
1617
17 s.add_runtime_dependency 'omniauth-oauth2', '~> 1.1.0'
18 s.add_runtime_dependency 'omniauth-oauth2', '~> 1.1'
1819
1920 s.add_development_dependency 'minitest'
2021 s.add_development_dependency 'mocha'
00 require 'bundler/setup'
11 require 'minitest/autorun'
2 require 'mocha'
2 require 'mocha/setup'
33 require 'omniauth/strategies/facebook'
44
55 OmniAuth.config.test_mode = true
2424 end
2525 end
2626
27 class TestCase < MiniTest::Unit::TestCase
27 class TestCase < Minitest::Test
2828 extend BlockTestHelper
2929 include CustomAssertions
3030 end
3535 @request.stubs(:params).returns({})
3636 @request.stubs(:cookies).returns({})
3737 @request.stubs(:env).returns({})
38 @request.stubs(:ssl?).returns(false)
3839
3940 @client_id = '123'
4041 @client_secret = '53cr3tz'
4949 assert_equal strategy.authorize_params['state'], strategy.session['omniauth.state']
5050 end
5151
52 test 'should store state in the session when present in authorize params vs. a random one' do
52 test 'should not store state in the session when present in authorize params vs. a random one' do
5353 @options = { :authorize_params => { :state => 'bar' } }
5454 refute_empty strategy.authorize_params['state']
55 assert_equal 'bar', strategy.authorize_params[:state]
55 refute_equal 'bar', strategy.authorize_params[:state]
5656 refute_empty strategy.session['omniauth.state']
57 assert_equal 'bar', strategy.session['omniauth.state']
57 refute_equal 'bar', strategy.session['omniauth.state']
5858 end
5959
60 test 'should store state in the session when present in request params vs. a random one' do
60 test 'should not store state in the session when present in request params vs. a random one' do
6161 @request.stubs(:params).returns({ 'state' => 'foo' })
6262 refute_empty strategy.authorize_params['state']
63 assert_equal 'foo', strategy.authorize_params[:state]
63 refute_equal 'foo', strategy.authorize_params[:state]
6464 refute_empty strategy.session['omniauth.state']
65 assert_equal 'foo', strategy.session['omniauth.state']
65 refute_equal 'foo', strategy.session['omniauth.state']
6666 end
6767 end
6868
1212 end
1313
1414 test 'has correct authorize url' do
15 assert_equal '/oauth/authorize', strategy.client.options[:authorize_url]
15 assert_equal 'https://www.facebook.com/dialog/oauth', strategy.client.options[:authorize_url]
1616 end
1717
1818 test 'has correct token url' do
5555 assert_equal 'touch', strategy.authorize_params[:display]
5656 end
5757
58 test 'includes state parameter from request when present' do
59 @request.stubs(:params).returns({ 'state' => 'some_state' })
58 test 'includes auth_type parameter from request when present' do
59 @request.stubs(:params).returns({ 'auth_type' => 'reauthenticate' })
6060 assert strategy.authorize_params.is_a?(Hash)
61 assert_equal 'some_state', strategy.authorize_params[:state]
61 assert_equal 'reauthenticate', strategy.authorize_params[:auth_type]
6262 end
6363
6464 test 'overrides default scope with parameter passed from request' do
100100 @options = { :secure_image_url => true }
101101 raw_info = { 'name' => 'Fred Smith', 'id' => '321' }
102102 strategy.stubs(:raw_info).returns(raw_info)
103 assert_equal 'https://graph.facebook.com/321/picture?type=square', strategy.info['image']
104 end
105
106 test 'returns the image size specified in the `image_size` option' do
103 assert_equal 'https://graph.facebook.com/321/picture', strategy.info['image']
104 end
105
106 test 'returns the image with size specified in the `image_size` option' do
107107 @options = { :image_size => 'normal' }
108108 raw_info = { 'name' => 'Fred Smith', 'id' => '321' }
109109 strategy.stubs(:raw_info).returns(raw_info)
110110 assert_equal 'http://graph.facebook.com/321/picture?type=normal', strategy.info['image']
111111 end
112
113 test 'returns the image with width and height specified in the `image_size` option' do
114 @options = { :image_size => { :width => 123, :height => 987 } }
115 raw_info = { 'name' => 'Fred Smith', 'id' => '321' }
116 strategy.stubs(:raw_info).returns(raw_info)
117 image_url = strategy.info['image']
118 path, query = image_url.split("?")
119 query_params = Hash[*query.split("&").map {|pair| pair.split("=") }.flatten]
120
121 assert_equal 'http://graph.facebook.com/321/picture', path
122 assert_equal '123', query_params['width']
123 assert_equal '987', query_params['height']
124 end
112125 end
113126
114127 class InfoTestOptionalDataPresent < StrategyTestCase
152165 assert_equal 'I am great', strategy.info['description']
153166 end
154167
155 test 'returns the square format facebook avatar url' do
168 test 'returns the facebook avatar url' do
156169 @raw_info['id'] = '321'
157 assert_equal 'http://graph.facebook.com/321/picture?type=square', strategy.info['image']
170 assert_equal 'http://graph.facebook.com/321/picture', strategy.info['image']
158171 end
159172
160173 test 'returns the Facebook link as the Facebook url' do
232245 def setup
233246 super
234247 @access_token = stub('OAuth2::AccessToken')
248 @appsecret_proof = 'appsecret_proof'
249 @options = {:appsecret_proof => @appsecret_proof}
235250 end
236251
237252 test 'performs a GET to https://graph.facebook.com/me' do
253 strategy.stubs(:appsecret_proof).returns(@appsecret_proof)
238254 strategy.stubs(:access_token).returns(@access_token)
239 @access_token.expects(:get).with('/me').returns(stub_everything('OAuth2::Response'))
255 params = {:params => @options}
256 @access_token.expects(:get).with('/me', params).returns(stub_everything('OAuth2::Response'))
257 strategy.raw_info
258 end
259
260 test 'performs a GET to https://graph.facebook.com/me with locale' do
261 @options.merge!({ :locale => 'cs_CZ' })
262 strategy.stubs(:access_token).returns(@access_token)
263 strategy.stubs(:appsecret_proof).returns(@appsecret_proof)
264 params = {:params => @options}
265 @access_token.expects(:get).with('/me', params).returns(stub_everything('OAuth2::Response'))
266 strategy.raw_info
267 end
268
269 test 'performs a GET to https://graph.facebook.com/me with info_fields' do
270 @options.merge!({:info_fields => 'about'})
271 strategy.stubs(:access_token).returns(@access_token)
272 strategy.stubs(:appsecret_proof).returns(@appsecret_proof)
273 params = {:params => {:appsecret_proof => @appsecret_proof, :fields => 'about'}}
274 @access_token.expects(:get).with('/me', params).returns(stub_everything('OAuth2::Response'))
240275 strategy.raw_info
241276 end
242277
243278 test 'returns a Hash' do
244279 strategy.stubs(:access_token).returns(@access_token)
280 strategy.stubs(:appsecret_proof).returns(@appsecret_proof)
245281 raw_response = stub('Faraday::Response')
246282 raw_response.stubs(:body).returns('{ "ohai": "thar" }')
247283 raw_response.stubs(:status).returns(200)
248284 raw_response.stubs(:headers).returns({'Content-Type' => 'application/json' })
249285 oauth2_response = OAuth2::Response.new(raw_response)
250 @access_token.stubs(:get).with('/me').returns(oauth2_response)
286 params = {:params => @options}
287 @access_token.stubs(:get).with('/me', params).returns(oauth2_response)
251288 assert_kind_of Hash, strategy.raw_info
252289 assert_equal 'thar', strategy.raw_info['ohai']
253290 end
254291
255292 test 'returns an empty hash when the response is false' do
256293 strategy.stubs(:access_token).returns(@access_token)
294 strategy.stubs(:appsecret_proof).returns(@appsecret_proof)
257295 oauth2_response = stub('OAuth2::Response', :parsed => false)
258 @access_token.stubs(:get).with('/me').returns(oauth2_response)
296 params = {:params => @options}
297 @access_token.stubs(:get).with('/me', params).returns(oauth2_response)
259298 assert_kind_of Hash, strategy.raw_info
299 assert_equal({}, strategy.raw_info)
260300 end
261301
262302 test 'should not include raw_info in extras hash when skip_info is specified' do
359399 test 'is nil' do
360400 assert_nil strategy.send(:signed_request)
361401 end
402
403 test 'throws an error on calling build_access_token' do
404 assert_equal 'must pass either a `code` parameter or a signed request (via `signed_request` parameter or a `fbsr_XXX` cookie)',
405 assert_raises(OmniAuth::Strategies::Facebook::NoAuthorizationCodeError) { strategy.send(:build_access_token) }.message
406 end
362407 end
363408
364409 class CookiePresentTest < TestCase
365 def setup
366 super
410 def setup(algo = nil)
411 super()
367412 @payload = {
368 'algorithm' => 'HMAC-SHA256',
413 'algorithm' => algo || 'HMAC-SHA256',
369414 'code' => 'm4c0d3z',
370415 'issued_at' => Time.now.to_i,
371416 'user_id' => '123456'
377422 test 'parses the access code out from the cookie' do
378423 assert_equal @payload, strategy.send(:signed_request)
379424 end
425
426 test 'throws an error if the algorithm is unknown' do
427 setup('UNKNOWN-ALGO')
428 assert_equal "unknown algorithm: UNKNOWN-ALGO", assert_raises(OmniAuth::Strategies::Facebook::UnknownSignatureAlgorithmError) { strategy.send(:signed_request) }.message
429 end
380430 end
381431
382432 class ParamPresentTest < TestCase
383 def setup
384 super
433 def setup(algo = nil)
434 super()
385435 @payload = {
386 'algorithm' => 'HMAC-SHA256',
436 'algorithm' => algo || 'HMAC-SHA256',
387437 'oauth_token' => 'XXX',
388438 'issued_at' => Time.now.to_i,
389439 'user_id' => '123456'
394444
395445 test 'parses the access code out from the param' do
396446 assert_equal @payload, strategy.send(:signed_request)
447 end
448
449 test 'throws an error if the algorithm is unknown' do
450 setup('UNKNOWN-ALGO')
451 assert_equal "unknown algorithm: UNKNOWN-ALGO", assert_raises(OmniAuth::Strategies::Facebook::UnknownSignatureAlgorithmError) { strategy.send(:signed_request) }.message
397452 end
398453 end
399454
419474 assert_equal @payload_from_param, strategy.send(:signed_request)
420475 end
421476 end
477
478 class EmptySignedRequestTest < TestCase
479 def setup
480 super
481 @request.stubs(:params).returns({'signed_request' => ''})
482 end
483
484 test 'empty param' do
485 assert_equal nil, strategy.send(:signed_request)
486 end
487 end
488
422489 end
423490
424491 class RequestPhaseWithSignedRequestTest < StrategyTestCase
464531 end
465532
466533 test 'returns a new access token from the signed request' do
467 result = strategy.build_access_token
534 result = strategy.send(:build_access_token)
468535 assert_kind_of ::OAuth2::AccessToken, result
469536 assert_equal @payload['oauth_token'], result.token
470537 end
471538
472539 test 'returns an access token with the correct expiry time' do
473 result = strategy.build_access_token
540 result = strategy.send(:build_access_token)
474541 assert_equal @payload['expires'], result.expires_at
475542 end
476543 end
477
478 class ParamsContainAccessTokenStringTest < TestCase
479 def setup
480 super
481
482 @request.stubs(:params).returns({'access_token' => 'm4c0d3z'})
483
484 strategy.stubs(:callback_url).returns('/')
485 end
486
487 test 'returns a new access token' do
488 result = strategy.build_access_token
489 assert_kind_of ::OAuth2::AccessToken, result
490 assert_equal 'm4c0d3z', result.token
491 end
492 end
493 end
544 end