omniauth-myvr 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 5f392900cec4ada0165ca53f676df5a69790b042
4
+ data.tar.gz: c7d1cdd0150d4056511c459a8b106a260bd84056
5
+ SHA512:
6
+ metadata.gz: 5ab804a5b6ca562c855c4d068b119548041a711780d111f79956a0d36c2eb499aee14521875bc4c5e96b36727497cff0100f94f17d4e30a5b8347194a862c5ef
7
+ data.tar.gz: 252748d816f1168d377f60d7734ed8e73ec1f77c4f35563dea9e2062fa59deaa8751342b33f5fdab21d7a38ad93c52191c5a5bf47f700ed7e0a9c1b8b572d1f1
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .ruby-gemset
7
+ .ruby-version
8
+ .rvmrc
9
+ Gemfile.lock
10
+ InstalledFiles
11
+ _yardoc
12
+ coverage
13
+ doc/
14
+ lib/bundler/man
15
+ pkg
16
+ rdoc
17
+ spec/reports
18
+ test/tmp
19
+ test/version_tmp
20
+ tmp
21
+ .powenv
22
+ .idea/
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'rake'
6
+
7
+ group :test do
8
+ gem 'rspec', '~> 3.2'
9
+ end
data/example/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'sinatra'
4
+ gem 'omniauth-myvr', path: '/Users/cjavilla/repos/omniauth-myvr'
data/example/auth.js ADDED
@@ -0,0 +1,43 @@
1
+ // Basic hybrid auth example following the pattern at:
2
+ // https://developers.google.com/api-client-library/javascript/features/authentication#Authexample
3
+ jQuery(function() {
4
+ return $.ajax({
5
+ url: 'https://apis.google.com/js/client:plus.js?onload=gpAsyncInit',
6
+ dataType: 'script',
7
+ cache: true
8
+ });
9
+ });
10
+
11
+ window.gpAsyncInit = function() {
12
+ gapi.auth.authorize({
13
+ immediate: true,
14
+ response_type: 'code',
15
+ cookie_policy: 'single_host_origin',
16
+ client_id: 'YOUR_CLIENT_ID',
17
+ scope: 'email profile'
18
+ }, function(response) {
19
+ return;
20
+ });
21
+ $('.googleplus-login').click(function(e) {
22
+ e.preventDefault();
23
+ gapi.auth.authorize({
24
+ immediate: false,
25
+ response_type: 'code',
26
+ cookie_policy: 'single_host_origin',
27
+ client_id: 'YOUR_CLIENT_ID',
28
+ scope: 'email profile'
29
+ }, function(response) {
30
+ if (response && !response.error) {
31
+ // google authentication succeed, now post data to server.
32
+ jQuery.ajax({type: 'POST', url: "/auth/google_oauth2/callback",
33
+ data: response,
34
+ success: function(data) {
35
+ // response from server
36
+ }
37
+ });
38
+ } else {
39
+ // google authentication failed
40
+ }
41
+ });
42
+ });
43
+ };
data/example/config.ru ADDED
@@ -0,0 +1,45 @@
1
+ # Sample app for MyVR OAuth Strategy
2
+ # Make sure to setup the ENV variables MYVR_KEY and MYVR_SECRET
3
+ # Run with "bundle exec rackup"
4
+
5
+ require 'rubygems'
6
+ require 'bundler'
7
+ require 'sinatra'
8
+ require 'omniauth'
9
+ require 'omniauth-myvr'
10
+
11
+ # Do not use for production code.
12
+ # This is only to make setup easier when running through the sample.
13
+ #
14
+ # If you do have issues with certs in production code, this could help:
15
+ # http://railsapps.github.io/openssl-certificate-verify-failed.html
16
+ OpenSSL::SSL::VERIFY_PEER = OpenSSL::SSL::VERIFY_NONE
17
+
18
+ class App < Sinatra::Base
19
+ get '/' do
20
+ <<-HTML
21
+ <ul>
22
+ <li><a href='/auth/myvr'>Sign in with MyVR</a></li>
23
+ </ul>
24
+ HTML
25
+ end
26
+
27
+ get '/auth/:provider/callback' do
28
+ content_type 'text/plain'
29
+ request.env['omniauth.auth'].to_hash.inspect rescue "No Data"
30
+ end
31
+
32
+ get '/auth/failure' do
33
+ content_type 'text/plain'
34
+ request.env['omniauth.auth'].to_hash.inspect rescue "No Data"
35
+ end
36
+ end
37
+
38
+ use Rack::Session::Cookie, :secret => ENV['RACK_COOKIE_SECRET']
39
+
40
+ use OmniAuth::Builder do
41
+ # For additional provider examples please look at 'omni_auth.rb'
42
+ provider :myvr, ENV['MYVR_KEY'], ENV['MYVR_SECRET'], {}
43
+ end
44
+
45
+ run App.new
@@ -0,0 +1,45 @@
1
+ # MyVR's OAuth2 docs. Make sure you are familiar with all the options
2
+ # before attempting to configure this gem.
3
+ # https://developers.MyVR.com/accounts/docs/OAuth2Login
4
+
5
+ Rails.application.config.middleware.use OmniAuth::Builder do
6
+ # Default usage, this will give you offline access and a refresh token
7
+ # using default scopes 'email' and 'profile'
8
+ #
9
+ provider :myvr, ENV['MYVR_KEY'], ENV['MYVR_SECRET'], {
10
+ :scope => 'email,profile'
11
+ }
12
+
13
+ # Manual setup for offline access with a refresh token.
14
+ #
15
+ # provider :MYVR_oauth2, ENV['MYVR_KEY'], ENV['MYVR_SECRET'], {
16
+ # :access_type => 'offline',
17
+ # }
18
+
19
+ # Custom scope supporting youtube. If you are customizing scopes, remember
20
+ # to include the default scopes 'email' and 'profile'
21
+ #
22
+ # provider :myvr, ENV['MYVR_KEY'], ENV['MYVR_SECRET'], {
23
+ # :scope => 'http://gdata.youtube.com,email,profile,plus.me'
24
+ # }
25
+
26
+ # Custom scope for users only using MyVR for account creation/auth and do not require a refresh token.
27
+ #
28
+ # provider :MYVR_oauth2, ENV['MYVR_KEY'], ENV['MYVR_SECRET'], {
29
+ # :access_type => 'online',
30
+ # :prompt => ''
31
+ # }
32
+
33
+ # To include information about people in your circles you must include the 'plus.login' scope.
34
+ #
35
+ # provider :MYVR_oauth2, ENV['MYVR_KEY'], ENV['MYVR_SECRET'], {
36
+ # :skip_friends => false,
37
+ # :scope => "email,profile,plus.login"
38
+ # }
39
+
40
+ # If you need to acquire whether user picture is a default one or uploaded by user.
41
+ #
42
+ # provider :MYVR_oauth2, ENV['MYVR_KEY'], ENV['MYVR_SECRET'], {
43
+ # :skip_image_info => false
44
+ # }
45
+ end
@@ -0,0 +1,213 @@
1
+ require 'multi_json'
2
+ require 'jwt'
3
+ require 'omniauth/strategies/oauth2'
4
+ require 'uri'
5
+
6
+ module OmniAuth
7
+ module Strategies
8
+ class MyVROAuth < OmniAuth::Strategies::OAuth2
9
+ BASE_SCOPE_URL = "https://api.myvr.com/auth/"
10
+ BASE_SCOPES = %w[profile email openid]
11
+ DEFAULT_SCOPE = "email,profile"
12
+
13
+ option :name, 'myvr'
14
+ option :skip_friends, true
15
+ option :skip_image_info, true
16
+ option :skip_jwt, false
17
+ option :jwt_leeway, 60
18
+ option :authorize_options, [
19
+ :access_type,
20
+ :hd,
21
+ :login_hint,
22
+ :prompt,
23
+ :request_visible_actions,
24
+ :scope,
25
+ :state,
26
+ :redirect_uri,
27
+ :include_granted_scopes,
28
+ :openid_realm
29
+ ]
30
+ option :authorized_client_ids, []
31
+
32
+ option :client_options, {
33
+ :site => 'https://accounts.google.com',
34
+ :authorize_url => '/o/oauth2/auth',
35
+ :token_url => '/o/oauth2/token'
36
+ }
37
+
38
+ def authorize_params
39
+ super.tap do |params|
40
+ options[:authorize_options].each do |k|
41
+ params[k] = request.params[k.to_s] unless [nil, ''].include?(request.params[k.to_s])
42
+ end
43
+
44
+ raw_scope = params[:scope] || DEFAULT_SCOPE
45
+ scope_list = raw_scope.split(" ").map {|item| item.split(",")}.flatten
46
+ scope_list.map! { |s| s =~ /^https?:\/\// || BASE_SCOPES.include?(s) ? s : "#{BASE_SCOPE_URL}#{s}" }
47
+ params[:scope] = scope_list.join(" ")
48
+ params[:access_type] = 'offline' if params[:access_type].nil?
49
+ params['openid.realm'] = params.delete(:openid_realm) unless params[:openid_realm].nil?
50
+
51
+ session['omniauth.state'] = params[:state] if params['state']
52
+ end
53
+ end
54
+
55
+ uid { raw_info['sub'] || verified_email }
56
+
57
+ info do
58
+ prune!({
59
+ :name => raw_info['name'],
60
+ :email => verified_email,
61
+ :first_name => raw_info['given_name'],
62
+ :last_name => raw_info['family_name'],
63
+ :image => image_url,
64
+ :urls => {
65
+ 'Google' => raw_info['profile']
66
+ }
67
+ })
68
+ end
69
+
70
+ extra do
71
+ hash = {}
72
+ hash[:id_token] = access_token['id_token']
73
+ if !options[:skip_jwt] && !access_token['id_token'].nil?
74
+ hash[:id_info] = JWT.decode(
75
+ access_token['id_token'], nil, false, {
76
+ :verify_iss => true,
77
+ 'iss' => 'accounts.google.com',
78
+ :verify_aud => true,
79
+ 'aud' => options.client_id,
80
+ :verify_sub => false,
81
+ :verify_expiration => true,
82
+ :verify_not_before => true,
83
+ :verify_iat => true,
84
+ :verify_jti => false,
85
+ :leeway => options[:jwt_leeway]
86
+ }).first
87
+ end
88
+ hash[:raw_info] = raw_info unless skip_info?
89
+ hash[:raw_friend_info] = raw_friend_info(raw_info['sub']) unless skip_info? || options[:skip_friends]
90
+ hash[:raw_image_info] = raw_image_info(raw_info['sub']) unless skip_info? || options[:skip_image_info]
91
+ prune! hash
92
+ end
93
+
94
+ def raw_info
95
+ @raw_info ||= access_token.get('https://www.googleapis.com/plus/v1/people/me/openIdConnect').parsed
96
+ end
97
+
98
+ def raw_friend_info(id)
99
+ @raw_friend_info ||= access_token.get("https://www.googleapis.com/plus/v1/people/#{id}/people/visible").parsed
100
+ end
101
+
102
+ def raw_image_info(id)
103
+ @raw_image_info ||= access_token.get("https://www.googleapis.com/plus/v1/people/#{id}?fields=image").parsed
104
+ end
105
+
106
+ def custom_build_access_token
107
+ access_token =
108
+ if request.xhr? && request.params['code']
109
+ verifier = request.params['code']
110
+ client.auth_code.get_token(verifier, get_token_options('postmessage'), deep_symbolize(options.auth_token_params || {}))
111
+ elsif request.params['code'] && request.params['redirect_uri']
112
+ verifier = request.params['code']
113
+ redirect_uri = request.params['redirect_uri']
114
+ client.auth_code.get_token(verifier, get_token_options(redirect_uri), deep_symbolize(options.auth_token_params || {}))
115
+ elsif verify_token(request.params['access_token'])
116
+ ::OAuth2::AccessToken.from_hash(client, request.params.dup)
117
+ else
118
+ verifier = request.params["code"]
119
+ client.auth_code.get_token(verifier, get_token_options(callback_url), deep_symbolize(options.auth_token_params))
120
+ end
121
+
122
+ verify_hd(access_token)
123
+ access_token
124
+ end
125
+ alias_method :build_access_token, :custom_build_access_token
126
+
127
+ private
128
+
129
+ def callback_url
130
+ options[:redirect_uri] || (full_host + script_name + callback_path)
131
+ end
132
+
133
+ def get_token_options(redirect_uri)
134
+ { :redirect_uri => redirect_uri }.merge(token_params.to_hash(:symbolize_keys => true))
135
+ end
136
+
137
+ def prune!(hash)
138
+ hash.delete_if do |_, v|
139
+ prune!(v) if v.is_a?(Hash)
140
+ v.nil? || (v.respond_to?(:empty?) && v.empty?)
141
+ end
142
+ end
143
+
144
+ def verified_email
145
+ raw_info['email_verified'] ? raw_info['email'] : nil
146
+ end
147
+
148
+ def image_url
149
+ return nil unless raw_info['picture']
150
+
151
+ u = URI.parse(raw_info['picture'].gsub('https:https', 'https'))
152
+
153
+ path_index = u.path.to_s.index('/photo.jpg')
154
+
155
+ if path_index && image_size_opts_passed?
156
+ u.path.insert(path_index, image_params)
157
+ u.path = u.path.gsub('//', '/')
158
+ end
159
+
160
+ u.query = strip_unnecessary_query_parameters(u.query)
161
+
162
+ u.to_s
163
+ end
164
+
165
+ def image_size_opts_passed?
166
+ !!(options[:image_size] || options[:image_aspect_ratio])
167
+ end
168
+
169
+ def image_params
170
+ image_params = []
171
+ if options[:image_size].is_a?(Integer)
172
+ image_params << "s#{options[:image_size]}"
173
+ elsif options[:image_size].is_a?(Hash)
174
+ image_params << "w#{options[:image_size][:width]}" if options[:image_size][:width]
175
+ image_params << "h#{options[:image_size][:height]}" if options[:image_size][:height]
176
+ end
177
+ image_params << 'c' if options[:image_aspect_ratio] == 'square'
178
+
179
+ '/' + image_params.join('-')
180
+ end
181
+
182
+ def strip_unnecessary_query_parameters(query_parameters)
183
+ # strip `sz` parameter (defaults to sz=50) which overrides `image_size` options
184
+ return nil if query_parameters.nil?
185
+
186
+ params = CGI.parse(query_parameters)
187
+ stripped_params = params.delete_if { |key| key == "sz" }
188
+
189
+ # don't return an empty Hash since that would result
190
+ # in URLs with a trailing ? character: http://image.url?
191
+ return nil if stripped_params.empty?
192
+
193
+ URI.encode_www_form(stripped_params)
194
+ end
195
+
196
+ def verify_token(access_token)
197
+ return false unless access_token
198
+ raw_response = client.request(:get, 'https://www.googleapis.com/oauth2/v3/tokeninfo',
199
+ params: { access_token: access_token }).parsed
200
+ raw_response['aud'] == options.client_id || options.authorized_client_ids.include?(raw_response['aud'])
201
+ end
202
+
203
+ def verify_hd(access_token)
204
+ return true unless options.hd
205
+ @raw_info ||= access_token.get('https://www.googleapis.com/plus/v1/people/me/openIdConnect').parsed
206
+ allowed_hosted_domains = Array(options.hd)
207
+
208
+ raise CallbackError.new(:invalid_hd, "Invalid Hosted Domain") unless allowed_hosted_domains.include? @raw_info['hd']
209
+ true
210
+ end
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,7 @@
1
+ require File.join('omniauth', 'myvr')
2
+
3
+ module OmniAuth
4
+ module MyVROAuth
5
+ VERSION = '0.0.1'
6
+ end
7
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "omniauth-myvr"
6
+ s.version = "0.0.1"
7
+ s.authors = ["CJ Avilla"]
8
+ s.email = ["cjavilla@gmail.com"]
9
+ s.homepage = "https://github.com/w1zeman1p/omniauth-myvr"
10
+ s.description = %q{OmniAuth strategy for MyVR}
11
+ s.summary = s.description
12
+ s.license = "MIT"
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+
19
+ s.add_dependency 'omniauth', '>= 1.1.1'
20
+ s.add_dependency 'omniauth-oauth2', '>= 1.3.1'
21
+ s.add_development_dependency 'bundler', '~> 1.0'
22
+ end
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: omniauth-myvr
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - CJ Avilla
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-06-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: omniauth
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.1.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 1.1.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: omniauth-oauth2
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: 1.3.1
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: 1.3.1
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '1.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '1.0'
55
+ description: OmniAuth strategy for MyVR
56
+ email:
57
+ - cjavilla@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - ".gitignore"
63
+ - Gemfile
64
+ - example/Gemfile
65
+ - example/auth.js
66
+ - example/config.ru
67
+ - example/omni_auth.rb
68
+ - lib/omniauth/strategies/myvr.rb
69
+ - lib/omniauth_myvr.rb
70
+ - omniauth-myvr.gemspec
71
+ homepage: https://github.com/w1zeman1p/omniauth-myvr
72
+ licenses:
73
+ - MIT
74
+ metadata: {}
75
+ post_install_message:
76
+ rdoc_options: []
77
+ require_paths:
78
+ - lib
79
+ required_ruby_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ required_rubygems_version: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ requirements: []
90
+ rubyforge_project:
91
+ rubygems_version: 2.4.5.1
92
+ signing_key:
93
+ specification_version: 4
94
+ summary: OmniAuth strategy for MyVR
95
+ test_files: []