├── .gitignore ├── .rubocop-https---raw-githubusercontent-com-tmilewski-rubocop-defaults-master-rubocop-yml ├── .rubocop.yml ├── .travis.yml ├── Gemfile ├── README.md ├── Rakefile ├── lib ├── omniauth-uber.rb └── omniauth │ ├── strategies │ └── uber.rb │ └── uber │ └── version.rb ├── omniauth-uber.gemspec └── spec ├── app.rb ├── omniauth └── strategies │ └── uber_spec.rb └── spec_helper.rb /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | .yardoc 6 | Gemfile.lock 7 | InstalledFiles 8 | _yardoc 9 | coverage 10 | doc/ 11 | lib/bundler/man 12 | pkg 13 | rdoc 14 | spec/reports 15 | test/tmp 16 | test/version_tmp 17 | tmp 18 | .env 19 | .rspec 20 | -------------------------------------------------------------------------------- /.rubocop-https---raw-githubusercontent-com-tmilewski-rubocop-defaults-master-rubocop-yml: -------------------------------------------------------------------------------- 1 | # see https://github.com/bbatsov/rubocop/blob/master/config/default.yml 2 | # for default configuration 3 | 4 | AllCops: 5 | TargetRubyVersion: 2.4 6 | DisplayCopNames: true 7 | Exclude: 8 | - 'db/schema.rb' 9 | - 'bin/*' 10 | - 'vendor/**/*' 11 | 12 | Rails: 13 | Enabled: true 14 | 15 | Documentation: 16 | Enabled: false 17 | 18 | Metrics/LineLength: 19 | Max: 125 20 | Exclude: 21 | - 'db/migrate/*' 22 | - 'config/initializers/devise.rb' 23 | 24 | Metrics/MethodLength: 25 | CountComments: false 26 | Max: 10 27 | Exclude: 28 | - 'db/migrate/*' 29 | 30 | Metrics/ModuleLength: 31 | CountComments: false 32 | Max: 100 33 | 34 | Metrics/AbcSize: 35 | # The ABC size is a calculated magnitude, so this number can be a Fixnum or a Float. 36 | # http://c2.com/cgi/wiki?AbcMetric 37 | Max: 15 38 | 39 | Metrics/CyclomaticComplexity: 40 | # http://www.rubydoc.info/github/bbatsov/rubocop/Rubocop/Cop/Style/CyclomaticComplexity 41 | Max: 6 42 | 43 | Metrics/PerceivedComplexity: 44 | # http://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Metrics/PerceivedComplexity 45 | Max: 7 46 | 47 | Metrics/ClassLength: 48 | CountComments: false 49 | Max: 100 50 | 51 | Style/MultilineMethodCallIndentation: 52 | EnforcedStyle: indented 53 | 54 | Style/FrozenStringLiteralComment: 55 | Enabled: false 56 | 57 | Style/ClassAndModuleChildren: 58 | Enabled: false 59 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | inherit_from: 2 | - https://raw.githubusercontent.com/tmilewski/rubocop-defaults/master/rubocop.yml 3 | 4 | Style/FileName: 5 | Enabled: false 6 | 7 | AllCops: 8 | Exclude: 9 | - 'tmp/**/*' 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | bundler_args: --without development 2 | before_install: gem update bundler 3 | cache: bundler 4 | env: 5 | global: 6 | - JRUBY_OPTS="$JRUBY_OPTS --debug" 7 | language: ruby 8 | rvm: 9 | - 2.2.6 10 | - 2.3.3 11 | - 2.4.1 12 | - ruby-head 13 | matrix: 14 | allow_failures: 15 | - rvm: ruby-head 16 | fast_finish: true 17 | sudo: false 18 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gem 'rake' 4 | 5 | group :development do 6 | gem 'rubocop', '>= 0.48.1' 7 | end 8 | 9 | group :test do 10 | gem 'coveralls', require: false 11 | gem 'rack-test' 12 | gem 'rspec', '~> 3.6.0' 13 | gem 'simplecov', require: false 14 | end 15 | 16 | gemspec 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | omniauth-uber 2 | ============== 3 | 4 | [![Gem Version](https://badge.fury.io/rb/omniauth-uber.svg)](http://badge.fury.io/rb/omniauth-uber) 5 | [![Build Status](https://travis-ci.org/omniauth/omniauth-uber.svg?branch=master)](https://travis-ci.org/omniauth/omniauth-uber) 6 | 7 | Uber OAuth2 Strategy for OmniAuth 1.x and supports the OAuth 2.0 server-side flow. 8 | 9 | You may view the Uber API documentation [here](https://developer.uber.com/v1/auth/#oauth-2-0). 10 | 11 | ## Installation 12 | 13 | Add to your `Gemfile`: 14 | 15 | ```ruby 16 | gem 'omniauth-uber' 17 | ``` 18 | 19 | Then `bundle install`. 20 | 21 | 22 | ## Usage 23 | 24 | `OmniAuth::Strategies::Uber` is simply Rack middleware. Read the OmniAuth 1.0 docs for detailed instructions: https://github.com/intridea/omniauth. 25 | 26 | Here's a quick example, adding the middleware to a Rails app in `config/initializers/omniauth.rb`: 27 | 28 | ```ruby 29 | Rails.application.config.middleware.use OmniAuth::Builder do 30 | provider :uber, ENV['UBER_CLIENT_ID'], ENV['UBER_CLIENT_SECRET'] 31 | end 32 | ``` 33 | 34 | ## Configuration 35 | 36 | Currently, there is only one configuration option that needs to be set: 37 | 38 | * `scope`: A *space separated* list of permissions you want to request from the user (e.g: `profile history request`). All scopes documented by *Uber* are working. Default: `profile` 39 | 40 | ```ruby 41 | Rails.application.config.middleware.use OmniAuth::Builder do 42 | provider :uber, ENV['UBER_CLIENT_ID'], ENV['UBER_CLIENT_SECRET'], :scope => 'profile history' 43 | end 44 | 45 | ``` 46 | 47 | ## Scope Details 48 | 49 | * `profile`: Access the basic profile information on a user's Uber account including their first name, email address, and profile picture. 50 | * `history`: Pull trip data including the locations, times, and product type of a user's historical pickups and drop-offs. 51 | * `request`: Allow for trip requests 52 | * ... see *Uber* developer documentation for more scopes 53 | 54 | ## Auth Hash 55 | 56 | Here's an example *Auth Hash* available in `request.env['omniauth.auth']`: 57 | 58 | ```ruby 59 | { 60 | provider: 'uber', 61 | uid: 'xxxxxx-yyyyy-zzzz-aaaa-bbbbbbbbbb', 62 | info: { 63 | email: 'foo@bar.com', 64 | first_name: 'Tom', 65 | last_name: 'Milewski', 66 | picture: 'https://d1w2poirtb3as9.cloudfront.net/default.jpeg', 67 | promo_code: 'xxxxx', 68 | }, 69 | credentials: { 70 | token: 'ABCDEF...', 71 | refresh_token: 'ABCDEF...', 72 | expires: true 73 | }, 74 | extra: { 75 | email: 'foo@bar.com', 76 | first_name: 'Tom', 77 | last_name: 'Milewski', 78 | picture: 'https://d1w2poirtb3as9.cloudfront.net/default.jpeg', 79 | promo_code: 'xxxxx', 80 | uuid: 'xxxxxx-yyyyy-zzzz-aaaa-bbbbbbbbbb' 81 | } 82 | } 83 | ``` 84 | 85 | ## Supported Ruby Versions 86 | `omniauth-uber` is tested under 2.2.6, 2.3.3, 2.4.1, and ruby-head. 87 | 88 | ## Versioning 89 | This library aims to adhere to [Semantic Versioning 2.0.0][semver]. Violations 90 | of this scheme should be reported as bugs. Specifically, if a minor or patch 91 | version is released that breaks backward compatibility, that version should be 92 | immediately yanked and/or a new version should be immediately released that 93 | restores compatibility. Breaking changes to the public API will only be 94 | introduced with new major versions. As a result of this policy, you can (and 95 | should) specify a dependency on this gem using the [Pessimistic Version 96 | Constraint][pvc] with two digits of precision. For example: 97 | 98 | spec.add_dependency 'omniauth-uber', '~> 1.0' 99 | 100 | [semver]: http://semver.org/ 101 | [pvc]: http://docs.rubygems.org/read/chapter/16#page74 102 | 103 | 104 | ## License 105 | 106 | Copyright (c) 2014-2017 by Tom Milewski 107 | 108 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 109 | 110 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 111 | 112 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 113 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | require 'bundler/gem_tasks' 3 | require 'rspec/core/rake_task' 4 | RSpec::Core::RakeTask.new(:spec) 5 | 6 | task test: :spec 7 | 8 | begin 9 | require 'rubocop/rake_task' 10 | RuboCop::RakeTask.new 11 | rescue LoadError 12 | task :rubocop do 13 | $stderr.puts 'Rubocop is disabled' 14 | end 15 | end 16 | 17 | task default: %i[spec rubocop] 18 | -------------------------------------------------------------------------------- /lib/omniauth-uber.rb: -------------------------------------------------------------------------------- 1 | require 'omniauth/uber/version' 2 | require 'omniauth/strategies/uber' 3 | -------------------------------------------------------------------------------- /lib/omniauth/strategies/uber.rb: -------------------------------------------------------------------------------- 1 | require 'omniauth-oauth2' 2 | 3 | module OmniAuth 4 | module Strategies 5 | class Uber < OmniAuth::Strategies::OAuth2 6 | DEFAULT_SCOPE = 'profile'.freeze 7 | 8 | option :client_options, site: 'https://api.uber.com', 9 | authorize_url: 'https://login.uber.com/oauth/authorize', 10 | token_url: 'https://login.uber.com/oauth/token' 11 | 12 | uid { raw_info['uuid'] } 13 | 14 | info do 15 | { 16 | first_name: raw_info['first_name'], 17 | last_name: raw_info['last_name'], 18 | email: raw_info['email'], 19 | picture: raw_info['picture'], 20 | promo_code: raw_info['promo_code'] 21 | } 22 | end 23 | 24 | extra do 25 | { 26 | raw_info: raw_info 27 | } 28 | end 29 | 30 | def raw_info 31 | @raw_info ||= access_token.get('/v1/me').parsed || {} 32 | end 33 | 34 | def request_phase 35 | options[:authorize_params] = { 36 | client_id: options['client_id'], 37 | response_type: 'code', 38 | scopes: (options['scope'] || DEFAULT_SCOPE) 39 | } 40 | 41 | super 42 | end 43 | end 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /lib/omniauth/uber/version.rb: -------------------------------------------------------------------------------- 1 | module OmniAuth 2 | module Uber 3 | VERSION = '1.1.0'.freeze 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /omniauth-uber.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | 3 | $LOAD_PATH.push File.expand_path('../lib', __FILE__) 4 | require 'omniauth/uber/version' 5 | 6 | Gem::Specification.new do |s| 7 | s.name = 'omniauth-uber' 8 | s.version = OmniAuth::Uber::VERSION 9 | s.authors = ['Tom Milewski'] 10 | s.email = ['tmilewski@gmail.com'] 11 | s.summary = 'Uber strategy for OmniAuth' 12 | s.description = 'Uber strategy for OmniAuth v1.2' 13 | s.homepage = 'https://github.com/tmilewski/omniauth-uber' 14 | s.license = 'MIT' 15 | 16 | s.files = `git ls-files`.split("\n") 17 | s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n") 18 | s.executables = `git ls-files -- bin/*`.split("\n").collect { |f| File.basename(f) } 19 | s.require_paths = ['lib'] 20 | 21 | s.add_runtime_dependency 'omniauth', '~> 1.2' 22 | s.add_runtime_dependency 'omniauth-oauth2', '~> 1.1' 23 | 24 | s.add_development_dependency 'dotenv', '>= 2.0' 25 | s.add_development_dependency 'sinatra', '>= 2.0' 26 | end 27 | -------------------------------------------------------------------------------- /spec/app.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path('..', __FILE__) 2 | $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) 3 | 4 | require 'dotenv' 5 | require 'sinatra' 6 | require 'omniauth' 7 | require 'omniauth-uber' 8 | 9 | Dotenv.load 10 | 11 | enable :sessions 12 | 13 | use OmniAuth::Builder do 14 | provider :uber, ENV['CLIENT_ID'], ENV['CLIENT_SECRET'] # , :scope => 'profile' 15 | end 16 | 17 | get '/' do 18 | <<-HTML 19 | Sign in with Uber 20 | HTML 21 | end 22 | 23 | get '/auth/failure' do 24 | env['omniauth.error'].to_s 25 | end 26 | 27 | get '/auth/:name/callback' do 28 | auth = request.env['omniauth.auth'] 29 | 30 | puts %( 31 | >> UID 32 | #{auth.uid.inspect} 33 | 34 | >> CREDENTIALS 35 | #{auth.credentials.inspect} 36 | 37 | >> INFO 38 | #{auth.info.inspect} 39 | # 40 | >> EXTRA 41 | #{auth.extra.inspect} 42 | ) 43 | 44 | 'Check logs for user information.' 45 | end 46 | -------------------------------------------------------------------------------- /spec/omniauth/strategies/uber_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe OmniAuth::Strategies::Uber do 4 | subject do 5 | @subject ||= begin 6 | @options ||= {} 7 | args = ['client_id', 'client_secret', @options].compact 8 | OmniAuth::Strategies::Uber.new(*args) 9 | end 10 | end 11 | 12 | context 'client options' do 13 | it 'should have correct name' do 14 | expect(subject.options.name).to eq('uber') 15 | end 16 | 17 | it 'should have correct site' do 18 | expect(subject.options.client_options.site).to eq('https://api.uber.com') 19 | end 20 | 21 | it 'should have correct authorize url' do 22 | expect(subject.options.client_options.authorize_url).to eq('https://login.uber.com/oauth/authorize') 23 | end 24 | 25 | it 'should have correct access token url' do 26 | expect(subject.options.client_options.token_url).to eq('https://login.uber.com/oauth/token') 27 | end 28 | 29 | it 'should indicate that the provider ignores the state parameted' do 30 | expect(subject.options.provider_ignores_state).to eq false 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift File.expand_path('..', __FILE__) 2 | $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__) 3 | 4 | require 'rspec' 5 | require 'simplecov' 6 | SimpleCov.start 7 | 8 | require 'omniauth' 9 | require 'omniauth-uber' 10 | 11 | RSpec.configure do |config| 12 | config.extend OmniAuth::Test::StrategyMacros, type: :strategy 13 | end 14 | --------------------------------------------------------------------------------