omniauth-oauth2-generic-0.2.2/0000755000175000017500000000000013122250270017431 5ustar balasankarcbalasankarcomniauth-oauth2-generic-0.2.2/.gitignore0000644000175000017500000000014413122250270021420 0ustar balasankarcbalasankarc/.bundle/ /.yardoc /Gemfile.lock /_yardoc/ /coverage/ /doc/ /pkg/ /spec/reports/ /tmp/ .ruby-versionomniauth-oauth2-generic-0.2.2/Gemfile0000644000175000017500000000015413122250270020724 0ustar balasankarcbalasankarcsource 'https://rubygems.org' # Specify your gem's dependencies in omniauth-oauth2-generic.gemspec gemspec omniauth-oauth2-generic-0.2.2/README.md0000644000175000017500000001111513122250270020707 0ustar balasankarcbalasankarc# omniauth-oauth2-generic By [Internet Exposure](https://www.iexposure.com/) [![build](http://gitlab.iexposure.com/satorix/omniauth-oauth2-generic/badges/master/build.svg)](http://gitlab.iexposure.com/satorix/omniauth-oauth2-generic/pipelines) [![coverage](http://gitlab.iexposure.com/satorix/omniauth-oauth2-generic/badges/master/coverage.svg)](http://gitlab.iexposure.com/satorix/omniauth-oauth2-generic/pipelines) This gem provides an OmniAuth strategy for authenticating with an OAuth2 service using the authorization grant flow. ## Installation Add this line to your application's Gemfile: ```ruby gem 'omniauth-oauth2-generic' ``` ## Usage Include this gem in your client app [as you would any OmniAuth strategy](https://github.com/omniauth/omniauth#getting-started), by adding it to the middleware stack: **Rails Example: (minimum configuration)** ```ruby # config/initializers/omniauth.rb Rails.application.config.middleware.use OmniAuth::Builder do provider :oauth2_generic, "Your_OAuth_App_ID", "Your_OAuth_App_Secret", client_options: { site: 'https://your_oauth_server', # including port if necessary user_info_url: '/api/path/to/fetch/current_user/info' }, name: 'Satorix' # optional - alternate name for the strategy (appears in URLs) end ``` **Gitlab Config Example:** ```ruby # /etc/gitlab/gitlab.rb gitlab_rails['omniauth_enabled'] = true gitlab_rails['omniauth_allow_single_sign_on'] = ['oauth2_generic'] gitlab_rails['omniauth_block_auto_created_users'] = false gitlab_rails['omniauth_providers'] = [ { 'name' => 'oauth2_generic', 'app_id' => 'oauth_client_app_id', 'app_secret' => 'oauth_client_app_secret', 'args' => { client_options: { 'site' => 'https://your_oauth_server', # including port if necessary 'user_info_url' => '/api/path/to/fetch/current_user/info' }, # optionally, you can add the following two lines to "white label" the display name # of this strategy (appears in urls and Gitlab login buttons) # If you do this, you must also replace oauth2_generic, everywhere it appears above, with the new name. name: 'Satorix', # display name for this strategy strategy_class: "OmniAuth::Strategies::OAuth2Generic" # Devise-specific config option Gitlab uses to find renamed strategy } } ] ```` Now if you visit `http://yourserver/auth/oauth2_generic` (or `/auth/Satorix` for the custom name example), you should be directed to log in with your OAuth2 server. ## Configuration Options Details about the available configuration options are provided as comments in [the OAuth2Generic class](lib/omniauth/strategies/oauth2_generic.rb). Configuration options for this gem are: * **client_options** - A Hash containing options for configuring the OAuth client to point to the right URLs * **user_response_structure** - A Hash containing paths to various attributes of the user in the response that your OAuth server returns from the `user_info_url` specified in the `client_options`. * **root_path** - An Array containing each key in the path to the node that contains the user attributes (i.e. `['data', 'attributes']` for a JsonAPI-formatted response) * **id_path** - A String containing the name, or Array containing the keys in the path to the node that contains the user's ID (i.e. `['data', 'id']` for a JsonAPI-formatted response). Default: `'id'` (string values are assumed to be relative to the `root_path`) * **attributes** - A Hash containing [standard Omniauth user attributes](https://github.com/omniauth/omniauth/wiki/auth-hash-schema#schema-10-and-later) and the names/paths to them in the response, if not the standard names (this hash defaults to looking for the standard names under the specified `root_path`) **Note:** The entire raw response will also be returned in the `['extra']['raw_info']` field of the OmniAuth auth hash, regardless of the value of this option. * **redirect_url** - The URL the client will be directed to after authentication. Defaults to `http://yourserver/auth/oauth2_generic/callback` **Note:** Your OAuth server may restrict redirects to a specific list of URLs. * **name** - A String. If set, this changes the name of the strategy used in the URLs and sometimes other places (the login button in Gitlab, for instance) The hash options have default values for all keys, and your provided configuration is merged into the default, so you do not have to re-specify nested default options (although you will need to provide at least `site` and `user_info_url` in `client_options`, unless you want to use the default/example gitlab.com configuration). omniauth-oauth2-generic-0.2.2/spec/0000755000175000017500000000000013122250270020363 5ustar balasankarcbalasankarcomniauth-oauth2-generic-0.2.2/spec/strategies/0000755000175000017500000000000013122250270022535 5ustar balasankarcbalasankarcomniauth-oauth2-generic-0.2.2/spec/strategies/oauth2_generic_spec.rb0000644000175000017500000000664213122250270027002 0ustar balasankarcbalasankarcdescribe "OmniAuth::Strategies::OAuth2Generic" do before do WebMock.disable_net_connect! end context "using default options" do let(:app) do Rack::Builder.new do use OmniAuth::Test::PhonySession use OmniAuth::Strategies::OAuth2Generic, "id123", "secretabc" run lambda { |env| [404, {"Content-Type" => "text/plain"}, [env.key?("omniauth.auth").to_s]] } end.to_app end it "responds to the default auth URL (oauth2_generic)" do get "/auth/oauth2_generic" expect(last_response).to be_redirect end end context "with custom provider settings" do let(:app) do Rack::Builder.new do use OmniAuth::Test::PhonySession use OmniAuth::Strategies::OAuth2Generic, "id123", "secretabc", name: 'custom', client_options: { site: 'https://custom.example.com', user_info_url: '/custom/user_info/path', authorize_url: '/custom/authorize/path', token_url: '/custom/token/path' }, redirect_url: 'https://my_server.com/oauth/callback', user_response_structure: { root_path: 'user', attributes: {nickname: 'username'} } run lambda { |env| [404, {"Content-Type" => "applocation/json"}, [env["omniauth.auth"].to_json]] } end.to_app end describe "the auth endpoint (/auth/{name})" do before { get "/auth/custom" } it "responds to the custom auth URL" do expect(last_response).to be_redirect end it "redirects to the correct custom authorize URL" do expect(last_response.headers["Location"]).to match(%r{\Ahttps://custom.example.com/custom/authorize/path\?}) end it "passes the correct redirect URL" do expect(last_response.headers["Location"]).to match(%r{redirect_uri=https%3A%2F%2Fmy_server.com%2Foauth%2Fcallback&}) end end describe "the callback (/auth/{name}/callback)" do before do # Stub custom token URL to return a stub token stub_request(:post, "https://custom.example.com/custom/token/path"). to_return(body: {access_token: :atoken}.to_json, headers: {'Content-Type' => 'application/json'}) stub_request(:get, "https://custom.example.com/custom/user_info/path"). to_return(body: {user: {username: 'marty', id: 1}}.to_json, headers: {'Content-Type' => 'application/json'}) # request the callback (which should request said stubbed token URL) get "/auth/custom/callback", {:state => "Caulifornia"}, "rack.session" => { "omniauth.state" => "Caulifornia" } end let(:result_auth_hash) { JSON.parse(last_response.body) } it "responds to the custom callback URL and fetches a token from the custom token path" do expect(WebMock).to have_requested(:post, "https://custom.example.com/custom/token/path") end it "fetches user info from the custom user info path" do expect(WebMock).to have_requested(:get, "https://custom.example.com/custom/user_info/path") end it "sets up the auth hash for the client app" do expect(result_auth_hash['provider']).to eq 'custom' end it "parses user info correctly from the custom format" do expect(result_auth_hash['info']).to include({'nickname' => 'marty'}) expect(result_auth_hash['uid']).to eq '1' end end end endomniauth-oauth2-generic-0.2.2/spec/spec_helper.rb0000644000175000017500000000043413122250270023202 0ustar balasankarcbalasankarcrequire 'bundler/setup' Bundler.setup require 'rack/test' require 'webmock/rspec' require 'omniauth-oauth2-generic' RSpec.configure do |config| config.extend OmniAuth::Test::StrategyMacros, :type => :strategy config.include Rack::Test::Methods config.include WebMock::API end omniauth-oauth2-generic-0.2.2/bin/0000755000175000017500000000000013122250270020201 5ustar balasankarcbalasankarcomniauth-oauth2-generic-0.2.2/bin/console0000755000175000017500000000052513122250270021573 0ustar balasankarcbalasankarc#!/usr/bin/env ruby require "bundler/setup" require "omniauth/satorix" # You can add fixtures and/or initialization code here to make experimenting # with your gem easier. You can also use a different console, if you like. # (If you use this, don't forget to add pry to your Gemfile!) # require "pry" # Pry.start require "irb" IRB.start omniauth-oauth2-generic-0.2.2/bin/setup0000755000175000017500000000020313122250270021262 0ustar balasankarcbalasankarc#!/usr/bin/env bash set -euo pipefail IFS=$'\n\t' set -vx bundle install # Do any other automated setup that you need to do here omniauth-oauth2-generic-0.2.2/Rakefile0000644000175000017500000000006313122250270021075 0ustar balasankarcbalasankarcrequire "bundler/gem_tasks" task :default => :spec omniauth-oauth2-generic-0.2.2/.rspec0000644000175000017500000000006413122250270020546 0ustar balasankarcbalasankarc--require spec_helper --color --format documentationomniauth-oauth2-generic-0.2.2/omniauth-oauth2-generic.gemspec0000644000175000017500000000221613122250270025435 0ustar balasankarcbalasankarc# coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'omniauth-oauth2-generic/version' Gem::Specification.new do |spec| spec.name = "omniauth-oauth2-generic" spec.version = Omniauth::OAuth2Generic::VERSION spec.authors = ["Joe Marty"] spec.email = ["jmarty@iexposure.com"] spec.summary = %q{Generic, Configurable OmniAuth Strategy for OAuth2 providers} spec.description = spec.summary spec.homepage = "https://gitlab.com/satorix/omniauth-oauth2-generic" spec.license = "MIT" spec.files = `git ls-files -z`.split("\x0").reject do |f| f.match(%r{^(test|spec|features)/}) end spec.bindir = "bin" spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.require_paths = ["lib"] spec.add_dependency "omniauth-oauth2", "~> 1.0" spec.add_development_dependency "bundler", "~> 1.13" spec.add_development_dependency "rake", "~> 10.0" spec.add_development_dependency "rspec", "~> 3.1" spec.add_development_dependency "rack-test" spec.add_development_dependency "webmock" end omniauth-oauth2-generic-0.2.2/LICENSE.md0000644000175000017500000000207613122250270021042 0ustar balasankarcbalasankarcCopyright (C) 2017 Joe Marty, Jeff Hahn and Internet Exposure. 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: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 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.omniauth-oauth2-generic-0.2.2/lib/0000755000175000017500000000000013122250270020177 5ustar balasankarcbalasankarcomniauth-oauth2-generic-0.2.2/lib/omniauth/0000755000175000017500000000000013122250270022023 5ustar balasankarcbalasankarcomniauth-oauth2-generic-0.2.2/lib/omniauth/strategies/0000755000175000017500000000000013122250270024175 5ustar balasankarcbalasankarcomniauth-oauth2-generic-0.2.2/lib/omniauth/strategies/oauth2_generic.rb0000644000175000017500000000527513122250270027431 0ustar balasankarcbalasankarcrequire 'omniauth-oauth2' module OmniAuth module Strategies class OAuth2Generic < OmniAuth::Strategies::OAuth2 option :name, 'oauth2_generic' option :client_options, { # Defaults are set for GitLab example implementation site: 'https://gitlab.com', # The URL for your OAuth 2 server user_info_url: '/api/v3/user', # The endpoint on your OAuth 2 server that provides user info for the current user authorize_url: '/oauth/authorize', # The authorization endpoint for your OAuth server token_url: '/oauth/token' # The token request endpoint for your OAuth server } option :user_response_structure, { # info about the structure of the response from the oauth server's user_info_url (specified above) root_path: [], # The default path to the user attributes (i.e. ['data', 'attributes']) id_path: 'id', # The name or path to the user ID (i.e. ['data', 'id]'). Scalars are considered relative to `root_path`, Arrays are absolute paths. attributes: { # Alternate paths or names for any attributes that don't match the default name: 'name', # Scalars are treated as relative (i.e. 'username' would point to response['data']['attributes']['username'], given a root_path of ['data', 'attributes']) email: 'email', # Arrays are treated as absolute paths (i.e. ['included', 'contacts', 0, 'email'] would point to response['included']['contacts'][0]['email'], regardless of root_path) nickname: 'nickname', first_name: 'first_name', last_name: 'last_name', location: 'location', description: 'description', image: 'image', phone: 'phone', urls: 'urls' } } option :redirect_url uid do fetch_user_info(user_paths[:id_path]).to_s end info do user_paths[:attributes].inject({}) do |user_hash, (field, path)| value = fetch_user_info(path) user_hash[field] = value if value user_hash end end extra do { raw_info: raw_info } end def raw_info @raw_info ||= access_token.get(options.client_options[:user_info_url]).parsed end private def user_paths options.user_response_structure end def fetch_user_info(path) return nil unless path full_path = path.is_a?(Array) ? path : Array(user_paths[:root_path]) + [path] full_path.inject(raw_info) { |info, key| info[key] rescue nil } end def callback_url options.redirect_url || (full_host + script_name + callback_path) end end end end OmniAuth.config.add_camelization 'oauth2_generic', 'OAuth2Generic'omniauth-oauth2-generic-0.2.2/lib/omniauth-oauth2-generic.rb0000644000175000017500000000012713122250270025162 0ustar balasankarcbalasankarcrequire "omniauth-oauth2-generic/version" require "omniauth/strategies/oauth2_generic" omniauth-oauth2-generic-0.2.2/lib/omniauth-oauth2-generic/0000755000175000017500000000000013122250270024635 5ustar balasankarcbalasankarcomniauth-oauth2-generic-0.2.2/lib/omniauth-oauth2-generic/version.rb0000644000175000017500000000010713122250270026645 0ustar balasankarcbalasankarcmodule Omniauth module OAuth2Generic VERSION = "0.2.2" end end