Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/vendor
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-07-20 06:09:04 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-07-20 06:09:04 +0300
commit514ada7cc9af49117d6cf63966925e21d137933e (patch)
treebdde498a0c79644def9665fa4f7c05bc6b531295 /vendor
parentf0e9d20cd8b273b2bbefd8c2cde3f63247feb61c (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'vendor')
-rw-r--r--vendor/gems/omniauth_crowd/.gitlab-ci.yml30
-rw-r--r--vendor/gems/omniauth_crowd/Gemfile4
-rw-r--r--vendor/gems/omniauth_crowd/Gemfile.lock74
-rw-r--r--vendor/gems/omniauth_crowd/LICENSE.txt20
-rw-r--r--vendor/gems/omniauth_crowd/README.md52
-rw-r--r--vendor/gems/omniauth_crowd/Rakefile12
-rwxr-xr-xvendor/gems/omniauth_crowd/lib/omniauth/strategies/crowd.rb97
-rw-r--r--vendor/gems/omniauth_crowd/lib/omniauth/strategies/crowd/configuration.rb110
-rwxr-xr-xvendor/gems/omniauth_crowd/lib/omniauth/strategies/crowd/crowd_validator.rb186
-rw-r--r--vendor/gems/omniauth_crowd/lib/omniauth_crowd.rb1
-rw-r--r--vendor/gems/omniauth_crowd/lib/omniauth_crowd/version.rb5
-rw-r--r--vendor/gems/omniauth_crowd/omniauth_crowd.gemspec28
-rw-r--r--vendor/gems/omniauth_crowd/spec/fixtures/groups.xml8
-rw-r--r--vendor/gems/omniauth_crowd/spec/fixtures/session.xml8
-rw-r--r--vendor/gems/omniauth_crowd/spec/fixtures/success.xml11
-rwxr-xr-xvendor/gems/omniauth_crowd/spec/omniauth/strategies/crowd_spec.rb387
-rw-r--r--vendor/gems/omniauth_crowd/spec/spec_helper.rb14
17 files changed, 1047 insertions, 0 deletions
diff --git a/vendor/gems/omniauth_crowd/.gitlab-ci.yml b/vendor/gems/omniauth_crowd/.gitlab-ci.yml
new file mode 100644
index 00000000000..98e686db4e3
--- /dev/null
+++ b/vendor/gems/omniauth_crowd/.gitlab-ci.yml
@@ -0,0 +1,30 @@
+workflow:
+ rules:
+ - if: $CI_MERGE_REQUEST_ID
+
+.rspec:
+ cache:
+ key: omniauth-gitlab-ruby
+ paths:
+ - vendor/gems/omniauth_crowd/vendor/ruby
+ before_script:
+ - cd vendor/gems/omniauth_crowd
+ - ruby -v # Print out ruby version for debugging
+ - gem install bundler --no-document # Bundler is not installed with the image
+ - bundle config set --local path 'vendor' # Install dependencies into ./vendor/ruby
+ - bundle config set with 'development'
+ - bundle install -j $(nproc)
+ script:
+ - bundle exec rspec
+
+rspec-2.6:
+ image: "ruby:2.6"
+ extends: .rspec
+
+rspec-2.7:
+ image: "ruby:2.7"
+ extends: .rspec
+
+rspec-3.0:
+ image: "ruby:3.0"
+ extends: .rspec
diff --git a/vendor/gems/omniauth_crowd/Gemfile b/vendor/gems/omniauth_crowd/Gemfile
new file mode 100644
index 00000000000..e2305d86b8d
--- /dev/null
+++ b/vendor/gems/omniauth_crowd/Gemfile
@@ -0,0 +1,4 @@
+source 'http://rubygems.org'
+
+# Specify your gem's dependencies in omniauth-github.gemspec
+gemspec
diff --git a/vendor/gems/omniauth_crowd/Gemfile.lock b/vendor/gems/omniauth_crowd/Gemfile.lock
new file mode 100644
index 00000000000..0ac781e9948
--- /dev/null
+++ b/vendor/gems/omniauth_crowd/Gemfile.lock
@@ -0,0 +1,74 @@
+PATH
+ remote: .
+ specs:
+ omniauth_crowd (2.4.0)
+ activesupport
+ nokogiri (>= 1.4.4)
+ omniauth (~> 1.0, < 3)
+
+GEM
+ remote: http://rubygems.org/
+ specs:
+ activesupport (5.0.0.1)
+ concurrent-ruby (~> 1.0, >= 1.0.2)
+ i18n (~> 0.7)
+ minitest (~> 5.1)
+ tzinfo (~> 1.1)
+ addressable (2.5.2)
+ public_suffix (>= 2.0.2, < 4.0)
+ concurrent-ruby (1.0.5)
+ crack (0.4.3)
+ safe_yaml (~> 1.0.0)
+ diff-lcs (1.2.5)
+ hashdiff (0.3.6)
+ hashie (3.4.3)
+ i18n (0.8.1)
+ mini_portile2 (2.1.0)
+ minitest (5.10.1)
+ nokogiri (1.6.8.1)
+ mini_portile2 (~> 2.1.0)
+ omniauth (1.3.1)
+ hashie (>= 1.2, < 4)
+ rack (>= 1.0, < 3)
+ public_suffix (3.0.0)
+ rack (1.6.4)
+ rack-test (0.6.3)
+ rack (>= 1.0)
+ rake (10.5.0)
+ rexml (3.2.5)
+ rspec (3.0.0)
+ rspec-core (~> 3.0.0)
+ rspec-expectations (~> 3.0.0)
+ rspec-mocks (~> 3.0.0)
+ rspec-core (3.0.4)
+ rspec-support (~> 3.0.0)
+ rspec-expectations (3.0.4)
+ diff-lcs (>= 1.2.0, < 2.0)
+ rspec-support (~> 3.0.0)
+ rspec-mocks (3.0.4)
+ rspec-support (~> 3.0.0)
+ rspec-support (3.0.4)
+ safe_yaml (1.0.4)
+ thread_safe (0.3.6)
+ tzinfo (1.2.2)
+ thread_safe (~> 0.1)
+ webmock (3.0.1)
+ addressable (>= 2.3.6)
+ crack (>= 0.3.2)
+ hashdiff
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ bundler (> 1.0.0)
+ omniauth_crowd!
+ rack
+ rack-test
+ rake
+ rexml (~> 3.2.5)
+ rspec (~> 3.0.0)
+ webmock (~> 3.0.0)
+
+BUNDLED WITH
+ 2.3.15
diff --git a/vendor/gems/omniauth_crowd/LICENSE.txt b/vendor/gems/omniauth_crowd/LICENSE.txt
new file mode 100644
index 00000000000..463a011fbaf
--- /dev/null
+++ b/vendor/gems/omniauth_crowd/LICENSE.txt
@@ -0,0 +1,20 @@
+Copyright (c) 2011 Rob Di Marco
+
+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.
diff --git a/vendor/gems/omniauth_crowd/README.md b/vendor/gems/omniauth_crowd/README.md
new file mode 100644
index 00000000000..01d8119b15d
--- /dev/null
+++ b/vendor/gems/omniauth_crowd/README.md
@@ -0,0 +1,52 @@
+# omniauth_crowd
+
+This is fork of [omniauth_crowd](https://github.com/robdimarco/omniauth_crowd) to support:
+
+1. OmniAuth v1 and v2. OmniAuth v2 disables GET requests by default
+ and defaults to POST. GitLab already has patched v1 to use POST,
+ but other dependencies need to be updated:
+ https://gitlab.com/gitlab-org/gitlab/-/issues/30073.
+2. We may deprecate this library entirely in the future:
+ https://gitlab.com/gitlab-org/gitlab/-/issues/366212
+
+The omniauth_crowd library is an OmniAuth provider that supports authentication against Atlassian Crowd REST apis.
+
+[![Build Status](https://travis-ci.org/robdimarco/omniauth_crowd.svg?branch=master)](https://travis-ci.org/robdimarco/omniauth_crowd)
+
+## Helpful links
+
+* [Documentation](http://github.com/robdimarco/omniauth_crow)
+* [OmniAuth](https://github.com/intridea/omniauth/)
+* [Atlassian Crowd](http://www.atlassian.com/software/crowd/)
+* [Atlassian Crowd REST API](http://confluence.atlassian.com/display/CROWDDEV/Crowd+REST+APIs)
+
+## Install and use
+
+### 1. Add the OmniAuth Crowd REST plugin to your Gemfile
+
+ gem 'omniauth', '>= 1.0.0' # We depend on this
+ gem "omniauth_crowd"
+
+### 2. You will need to configure OmniAuth to use your crowd authentication. This is generally done in Rails in the config/initializers/omniauth.rb with...
+
+ Rails.application.config.middleware.use OmniAuth::Builder do
+ provider :crowd, :crowd_server_url=>"https://crowd.mycompanyname.com/crowd", :application_name=>"app", :application_password=>"password"
+ end
+
+You will need to supply the correct server URL, application name and password
+
+## Contributing to omniauth_crowd
+
+* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
+* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
+* Fork the project
+* Start a feature/bugfix branch
+* Commit and push until you are happy with your contribution
+* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
+* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
+
+## Copyright
+
+Copyright (c) 2011-14 Rob Di Marco. See LICENSE.txt for
+further details.
+
diff --git a/vendor/gems/omniauth_crowd/Rakefile b/vendor/gems/omniauth_crowd/Rakefile
new file mode 100644
index 00000000000..4786a6c34d1
--- /dev/null
+++ b/vendor/gems/omniauth_crowd/Rakefile
@@ -0,0 +1,12 @@
+#!/usr/bin/env rake
+require "bundler/gem_tasks"
+require 'rspec/core/rake_task'
+
+desc 'Default: run specs.'
+task :default => :spec
+
+desc "Run specs"
+RSpec::Core::RakeTask.new
+
+desc 'Run specs'
+task :default => :spec \ No newline at end of file
diff --git a/vendor/gems/omniauth_crowd/lib/omniauth/strategies/crowd.rb b/vendor/gems/omniauth_crowd/lib/omniauth/strategies/crowd.rb
new file mode 100755
index 00000000000..7e3829b9b95
--- /dev/null
+++ b/vendor/gems/omniauth_crowd/lib/omniauth/strategies/crowd.rb
@@ -0,0 +1,97 @@
+require 'omniauth'
+require 'active_support'
+require 'active_support/core_ext/object'
+module OmniAuth
+ module Strategies
+ class Crowd
+ include OmniAuth::Strategy
+
+ autoload :Configuration, 'omniauth/strategies/crowd/configuration'
+ autoload :CrowdValidator, 'omniauth/strategies/crowd/crowd_validator'
+ def initialize(app, options = {}, &block)
+ options.symbolize_keys!()
+ super(app, {:name=> :crowd}.merge(options), &block)
+ @configuration = OmniAuth::Strategies::Crowd::Configuration.new(options)
+ end
+
+ protected
+
+ def request_phase
+ if env['REQUEST_METHOD'] == 'GET'
+
+ if @configuration.use_sessions? && request.cookies[@configuration.session_cookie]
+ redirect callback_url
+ else
+ get_credentials
+ end
+
+ elsif (env['REQUEST_METHOD'] == 'POST') && (not request.params['username'])
+ get_credentials
+ else
+ session['omniauth.crowd'] = {'username' => request['username'], 'password' => request['password']}
+ redirect callback_url
+ end
+ end
+
+ def get_client_ip
+ env['HTTP_X_FORWARDED_FOR'] ? env['HTTP_X_FORWARDED_FOR'] : env['REMOTE_ADDRESS']
+ end
+
+ def get_sso_tokens
+ env['HTTP_COOKIE'].split(';').select { |val|
+ val.strip.start_with?(@configuration.session_cookie)
+ }.map { |val|
+ val.strip.split('=').last
+ }
+ end
+
+ def get_credentials
+
+ configuration = @configuration
+
+ OmniAuth::Form.build(:title => (options[:title] || "Crowd Authentication")) do
+ text_field 'Login', 'username'
+ password_field 'Password', 'password'
+
+ if configuration.use_sessions? && configuration.sso_url
+ fieldset 'SSO' do
+ html "<a href=\"#{configuration.sso_url}/users/auth/crowd/callback\">" + (configuration.sso_url_image ? "<img src=\"#{configuration.sso_url_image}\" />" : '') + "</a>"
+ end
+ end
+
+ end.to_response
+
+ end
+
+ def callback_phase
+
+ creds = session.delete 'omniauth.crowd'
+ username = creds.nil? ? nil : creds['username']
+ password = creds.nil? ? nil : creds['password']
+
+ unless creds
+ if @configuration.use_sessions? && request.cookies[@configuration.session_cookie]
+ validator = CrowdValidator.new(@configuration, username, password, get_client_ip, get_sso_tokens)
+ else
+ return fail!(:no_credentials)
+ end
+ else
+ validator = CrowdValidator.new(@configuration, username, password, get_client_ip, nil)
+ end
+
+ @user_info = validator.user_info
+
+ return fail!(:invalid_credentials) if @user_info.nil? || @user_info.empty?
+
+ super
+ end
+
+ def auth_hash
+ OmniAuth::Utils.deep_merge(super, {
+ 'uid' => @user_info.delete("user"),
+ 'info' => @user_info
+ })
+ end
+ end
+ end
+end
diff --git a/vendor/gems/omniauth_crowd/lib/omniauth/strategies/crowd/configuration.rb b/vendor/gems/omniauth_crowd/lib/omniauth/strategies/crowd/configuration.rb
new file mode 100644
index 00000000000..8816651054f
--- /dev/null
+++ b/vendor/gems/omniauth_crowd/lib/omniauth/strategies/crowd/configuration.rb
@@ -0,0 +1,110 @@
+require 'rack'
+
+module OmniAuth
+ module Strategies
+ class Crowd
+ class Configuration
+ DEFAULT_SESSION_URL = "%s/rest/usermanagement/latest/session"
+ DEFAULT_AUTHENTICATION_URL = "%s/rest/usermanagement/latest/authentication"
+ DEFAULT_USER_GROUP_URL = "%s/rest/usermanagement/latest/user/group/direct"
+ DEFAULT_CONTENT_TYPE = 'application/xml'
+ DEFAULT_SESSION_COOKIE = 'crowd.token_key'
+
+ attr_reader :crowd_application_name, :crowd_password, :disable_ssl_verification, :include_users_groups, :use_sessions, :session_url, :content_type, :session_cookie, :sso_url, :sso_url_image
+
+ alias :"disable_ssl_verification?" :disable_ssl_verification
+ alias :"include_users_groups?" :include_users_groups
+ alias :"use_sessions?" :use_sessions
+
+ # @param [Hash] params configuration options
+ # @option params [String, nil] :crowd_server_url the Crowd server root URL; probably something like
+ # `https://crowd.mycompany.com` or `https://crowd.mycompany.com/crowd`; optional.
+ # @option params [String, nil] :crowd_authentication_url (:crowd_server_url + '/rest/usermanagement/latest/authentication') the URL to which to
+ # use for authenication; optional if `:crowd_server_url` is specified,
+ # required otherwise.
+ # @option params [String, nil] :application_name the application name specified in Crowd for this application, required.
+ # @option params [String, nil] :application_password the application password specified in Crowd for this application, required.
+ # @option params [Boolean, nil] :disable_ssl_verification disable verification for SSL cert,
+ # helpful when you developing with a fake cert.
+ # @option params [Boolean, true] : include a list of user groups when getting information ont he user
+ # @option params [String, nil] :crowd_user_group_url (:crowd_server_url + '/rest/usermanagement/latest/user/group/direct') the URL to which to
+ # use for retrieving users groups optional if `:crowd_server_url` is specified, or if `:include_user_groups` is false
+ # required otherwise.
+ # @option params [Boolean, false] :use_sessions Use Crowd sessions. If the user logins with user and password create a new Crowd session. Update the session if only a session token is sent (Cookie name set by option session_cookie)
+ # @option params [String, 'crowd.token_key'] :session_cookie Session cookie name. Defaults to: 'crowd.token_key'
+ # @option params [String, nil] :sso_url URL of the external SSO page. If this parameter is defined the login form will have a link which will redirect to the SSO page. The SSO must return to the URL of the page using omniauth_crowd (Path portion '/users/auth/crowd/callback' is appended to the URL)
+ # @option params [String, nil] :sso_url_image Optional image URL to be used in SSO link in the login form
+ def initialize(params)
+ parse_params params
+ end
+
+ # Build a Crowd authentication URL from +username+.
+ #
+ # @param [String] username the username to validate
+ #
+ # @return [String] a URL like `https://crowd.myhost.com/crowd/rest/usermanagement/latest/authentication?username=USERNAME`
+ def authentication_url(username)
+ append_username @authentication_url, username
+ end
+
+ def user_group_url(username)
+ @user_group_url.nil? ? nil : append_username( @user_group_url, username)
+ end
+
+ private
+ def parse_params(options)
+ options= {:include_user_groups => true}.merge(options || {})
+ %w(application_name application_password).each do |opt|
+ raise ArgumentError.new(":#{opt} MUST be provided") if options[opt.to_sym] == ""
+ end
+ @crowd_application_name = options[:application_name]
+ @crowd_password = options[:application_password]
+ @use_sessions = options[:use_sessions]
+ @content_type = options[:content_type] || DEFAULT_CONTENT_TYPE
+ @session_cookie = options[:session_cookie] || DEFAULT_SESSION_COOKIE
+ @sso_url = options[:sso_url]
+ @sso_url_image = options[:sso_url_image]
+
+ unless options.include?(:crowd_server_url) || options.include?(:crowd_authentication_url)
+ raise ArgumentError.new("Either :crowd_server_url or :crowd_authentication_url MUST be provided")
+ end
+
+ if @use_sessions
+ @session_url = options[:crowd_session_url] || DEFAULT_SESSION_URL % options[:crowd_server_url]
+ validate_is_url 'session URL', @session_url
+ end
+ @authentication_url = options[:crowd_authentication_url] || DEFAULT_AUTHENTICATION_URL % options[:crowd_server_url]
+ validate_is_url 'authentication URL', @authentication_url
+ @disable_ssl_verification = options[:disable_ssl_verification]
+ @include_users_groups = options[:include_user_groups]
+ if @include_users_groups
+ @user_group_url = options[:crowd_user_group_url] || DEFAULT_USER_GROUP_URL % options[:crowd_server_url]
+ validate_is_url 'user group URL', @user_group_url
+ end
+
+ end
+
+ IS_NOT_URL_ERROR_MESSAGE = "%s is not a valid URL"
+
+ def validate_is_url(name, possibly_a_url)
+ url = URI.parse(possibly_a_url) rescue nil
+ raise ArgumentError.new(IS_NOT_URL_ERROR_MESSAGE % name) unless url.kind_of?(URI::HTTP)
+ end
+
+ # Adds +service+ as an URL-escaped parameter to +base+.
+ #
+ # @param [String] base the base URL
+ # @param [String] service the service (a.k.a. return-to) URL.
+ #
+ # @return [String] the new joined URL.
+ def append_username(base, username)
+ result = base.dup
+ result << (result.include?('?') ? '&' : '?')
+ result << 'username='
+ result << Rack::Utils.escape(username)
+ end
+
+ end
+ end
+ end
+end
diff --git a/vendor/gems/omniauth_crowd/lib/omniauth/strategies/crowd/crowd_validator.rb b/vendor/gems/omniauth_crowd/lib/omniauth/strategies/crowd/crowd_validator.rb
new file mode 100755
index 00000000000..319ebf5e013
--- /dev/null
+++ b/vendor/gems/omniauth_crowd/lib/omniauth/strategies/crowd/crowd_validator.rb
@@ -0,0 +1,186 @@
+require 'nokogiri'
+require 'net/http'
+require 'net/https'
+
+module OmniAuth
+ module Strategies
+ class Crowd
+ class CrowdValidator
+ AUTHENTICATION_REQUEST_BODY = "<password><value>%s</value></password>"
+ def initialize(configuration, username, password, client_ip, tokens)
+ @configuration, @username, @password, @client_ip, @tokens = configuration, username, password, client_ip, tokens
+ @authentiction_uri = URI.parse(@configuration.authentication_url(@username))
+ @session_uri = URI.parse(@configuration.session_url) if @configuration.use_sessions
+ end
+
+ def user_info
+ user_info_hash = retrieve_user_info!
+
+ if user_info_hash && @configuration.include_users_groups?
+ user_info_hash = add_user_groups!(user_info_hash)
+ else
+ user_info_hash
+ end
+
+ if user_info_hash && @configuration.use_sessions?
+ user_info_hash = set_session!(user_info_hash)
+ end
+
+ user_info_hash
+ end
+
+ private
+ def set_session!(user_info_hash)
+
+ response = nil
+
+ if user_info_hash["sso_token"]
+ response = make_session_request(user_info_hash["sso_token"])
+ else
+ response = make_session_request(nil)
+ end
+
+ if response.kind_of?(Net::HTTPSuccess) && response.body
+ doc = Nokogiri::XML(response.body)
+ user_info_hash["sso_token"] = doc.xpath('//token/text()').to_s
+ else
+ OmniAuth.logger.send(:warn, "(crowd) [set_session!] response code: #{response.code.to_s}")
+ OmniAuth.logger.send(:warn, "(crowd) [set_session!] response body: #{response.body}")
+ end
+
+ user_info_hash
+ end
+
+ def add_user_groups!(user_info_hash)
+ response = make_user_group_request(user_info_hash['user'])
+ unless response.code.to_i != 200 || response.body.nil? || response.body == ''
+ doc = Nokogiri::XML(response.body)
+ user_info_hash["groups"] = doc.xpath("//groups/group/@name").map(&:to_s)
+ end
+ user_info_hash
+ end
+
+ def retrieve_user_info!
+ response = make_authorization_request
+
+ unless response === nil
+ unless response.code.to_i != 200 || response.body.nil? || response.body == ''
+
+ doc = Nokogiri::XML(response.body)
+ result = {
+ "user" => doc.xpath("//user/@name").to_s,
+ "name" => doc.xpath("//user/display-name/text()").to_s,
+ "first_name" => doc.xpath("//user/first-name/text()").to_s,
+ "last_name" => doc.xpath("//user/last-name/text()").to_s,
+ "email" => doc.xpath("//user/email/text()").to_s
+ }
+
+ if doc.at_xpath("//token")
+ result["sso_token"] = doc.xpath("//token/text()").to_s
+ end
+
+ result
+
+ else
+ OmniAuth.logger.send(:warn, "(crowd) [retrieve_user_info!] response code: #{response.code.to_s}")
+ OmniAuth.logger.send(:warn, "(crowd) [retrieve_user_info!] response body: #{response.body}")
+ nil
+ end
+ else
+ OmniAuth.logger.send(:warn, "(crowd) [retrieve_user_info!] None of the session tokens were valid")
+ nil
+ end
+ end
+
+ def make_request(uri, body=nil)
+ http_method = body.nil? ? Net::HTTP::Get : Net::HTTP::Post
+ http = Net::HTTP.new(uri.host, uri.port)
+ http.use_ssl = uri.port == 443 || uri.instance_of?(URI::HTTPS)
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE if http.use_ssl? && @configuration.disable_ssl_verification?
+ http.start do |c|
+ req = http_method.new(uri.query.nil? ? uri.path : "#{uri.path}?#{uri.query}")
+ req.body = body if body
+ req.basic_auth @configuration.crowd_application_name, @configuration.crowd_password
+ if @configuration.content_type
+ req.add_field 'Content-Type', @configuration.content_type
+ end
+ http.request(req)
+ end
+ end
+
+ def make_user_group_request(username)
+ make_request(URI.parse(@configuration.user_group_url(username)))
+ end
+
+ def make_authorization_request
+
+ if @configuration.use_sessions? && @tokens.kind_of?(Array)
+ make_session_retrieval_request
+ else
+ make_request(@authentiction_uri, make_authentication_request_body(@password))
+ end
+ end
+
+ def make_session_request(token)
+
+ root = url = validation_factor = nil
+ doc = Nokogiri::XML::Document.new
+
+ if token === nil
+
+ url = @session_uri
+ root = doc.create_element('authentication-context')
+
+ doc.root = root
+ root.add_child(doc.create_element('username', @username))
+ root.add_child(doc.create_element('password', @password))
+
+ else
+ url = URI.parse(@session_uri.to_s() + "/#{token}")
+ end
+
+ if @configuration.use_sessions? || @client_ip
+
+ if root === nil
+ root = doc.create_element('validation-factors')
+ doc.root = root
+ else
+ root.add_child(doc.create_element('validation-factors'))
+ end
+
+ validation_factor = doc.create_element('validation-factor')
+ validation_factor.add_child(doc.create_element('name', 'remote_address'))
+ validation_factor.add_child(doc.create_element('value', @client_ip))
+
+ doc.xpath('//validation-factors').first.add_child(validation_factor)
+
+ end
+
+ make_request(url, doc.to_s)
+
+ end
+
+ # create the body using Nokogiri so proper encoding of passwords can be ensured
+ def make_authentication_request_body(password)
+ request_body = Nokogiri::XML(AUTHENTICATION_REQUEST_BODY)
+ password_value = request_body.at_css "value"
+ password_value.content = password
+ return request_body.root.to_s # return the body without the xml header
+ end
+
+ def make_session_retrieval_request
+
+ response = nil
+
+ @tokens.any? { |token|
+ response = make_request(URI.parse(@session_uri.to_s() + "/#{token}"))
+ response.code.to_i == 200 && !response.body.nil? && response.body != ''
+ }
+
+ response
+
+ end
+ end
+ end
+ end
+end
diff --git a/vendor/gems/omniauth_crowd/lib/omniauth_crowd.rb b/vendor/gems/omniauth_crowd/lib/omniauth_crowd.rb
new file mode 100644
index 00000000000..56cf75c4e36
--- /dev/null
+++ b/vendor/gems/omniauth_crowd/lib/omniauth_crowd.rb
@@ -0,0 +1 @@
+require 'omniauth/strategies/crowd' \ No newline at end of file
diff --git a/vendor/gems/omniauth_crowd/lib/omniauth_crowd/version.rb b/vendor/gems/omniauth_crowd/lib/omniauth_crowd/version.rb
new file mode 100644
index 00000000000..378fb1c9e69
--- /dev/null
+++ b/vendor/gems/omniauth_crowd/lib/omniauth_crowd/version.rb
@@ -0,0 +1,5 @@
+module OmniAuth
+ module Crowd
+ VERSION = "2.4.0"
+ end
+end
diff --git a/vendor/gems/omniauth_crowd/omniauth_crowd.gemspec b/vendor/gems/omniauth_crowd/omniauth_crowd.gemspec
new file mode 100644
index 00000000000..4963c5fef1b
--- /dev/null
+++ b/vendor/gems/omniauth_crowd/omniauth_crowd.gemspec
@@ -0,0 +1,28 @@
+# -*- encoding: utf-8 -*-
+require File.expand_path('../lib/omniauth_crowd/version', __FILE__)
+lib = File.expand_path('../lib', __FILE__)
+$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
+
+Gem::Specification.new do |gem|
+ gem.authors = ["Robert Di Marco"]
+ gem.email = ["rob@innovationontherun.com"]
+ gem.description = "This is an OmniAuth provider for Atlassian Crowd's REST API. It allows you to easily integrate your Rack application in with Atlassian Crowd."
+ gem.summary = "An OmniAuth provider for Atlassian Crowd REST API"
+ gem.homepage = "http://github.com/robdimarco/omniauth_crowd"
+ gem.files = Dir.glob("lib/**/*.*")
+ gem.test_files = Dir.glob("spec/**/**/*.*")
+ gem.name = "omniauth_crowd"
+ gem.require_paths = ["lib"]
+ gem.version = OmniAuth::Crowd::VERSION
+
+ gem.add_runtime_dependency 'omniauth', '~> 1.0', '< 3'
+ gem.add_runtime_dependency 'nokogiri', '>= 1.4.4'
+ gem.add_runtime_dependency 'activesupport', '>= 0'
+ gem.add_development_dependency(%q<rack>, [">= 0"])
+ gem.add_development_dependency(%q<rake>, [">= 0"])
+ gem.add_development_dependency(%q<rack-test>, [">= 0"])
+ gem.add_development_dependency(%q<rexml>, ["~> 3.2.5"])
+ gem.add_development_dependency(%q<rspec>, ["~> 3.0.0"])
+ gem.add_development_dependency(%q<webmock>, ["~> 3.0.0"])
+ gem.add_development_dependency(%q<bundler>, ["> 1.0.0"])
+end
diff --git a/vendor/gems/omniauth_crowd/spec/fixtures/groups.xml b/vendor/gems/omniauth_crowd/spec/fixtures/groups.xml
new file mode 100644
index 00000000000..dd71a00436d
--- /dev/null
+++ b/vendor/gems/omniauth_crowd/spec/fixtures/groups.xml
@@ -0,0 +1,8 @@
+<groups expand="group">
+<group name="Developers">
+<link rel="self" href="http://crowd.bogus.com/crowd/rest/usermanagement/latest/group?groupname=Developers"/>
+</group>
+<group name="jira-users">
+<link rel="self" href="http://crowd.bogus.com/crowd/rest/usermanagement/latest/group?groupname=jira-users"/>
+</group>
+</groups> \ No newline at end of file
diff --git a/vendor/gems/omniauth_crowd/spec/fixtures/session.xml b/vendor/gems/omniauth_crowd/spec/fixtures/session.xml
new file mode 100644
index 00000000000..42719d25f3f
--- /dev/null
+++ b/vendor/gems/omniauth_crowd/spec/fixtures/session.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<session expand="user">
+ <token>rtk8eMvqq00EiGn5iJCMZQ00</token>
+ <user name="foo">
+ <link rel="self" href="http://crowd.example.org/crowd/rest/usermanagement/latest/user?username=foo"/>
+ </user>
+ <link rel="self" href="http://crowd.example.org/crowd/rest/usermanagement/latest/session/rtk8eMvqq00EiGn5iJCMZQ00"/>
+</session> \ No newline at end of file
diff --git a/vendor/gems/omniauth_crowd/spec/fixtures/success.xml b/vendor/gems/omniauth_crowd/spec/fixtures/success.xml
new file mode 100644
index 00000000000..a2324ab6b40
--- /dev/null
+++ b/vendor/gems/omniauth_crowd/spec/fixtures/success.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<user name="foo" expand="attributes">
+ <link rel="self" href="http://crowd.example.org/crowd/rest/usermanagement/latest/user?username=foo"/>
+ <first-name>Foo</first-name>
+ <last-name>Foobaz</last-name>
+ <display-name>Foo Foobaz</display-name>
+ <email>foo@example.org</email>
+ <password><link rel="edit" href="http://crowd.example.org/crowd/rest/usermanagement/latest/user/password?username=foo"/></password>
+ <active>true</active>
+ <attributes><link rel="self" href="http://crowd.example.org/crowd/rest/usermanagement/latest/user/attribute?username=foo"/></attributes>
+</user>
diff --git a/vendor/gems/omniauth_crowd/spec/omniauth/strategies/crowd_spec.rb b/vendor/gems/omniauth_crowd/spec/omniauth/strategies/crowd_spec.rb
new file mode 100755
index 00000000000..f234ef82e76
--- /dev/null
+++ b/vendor/gems/omniauth_crowd/spec/omniauth/strategies/crowd_spec.rb
@@ -0,0 +1,387 @@
+require 'spec_helper'
+
+describe OmniAuth::Strategies::Crowd, :type=>:strategy do
+ include OmniAuth::Test::StrategyTestCase
+ def strategy
+ @crowd_server_url ||= 'https://crowd.example.org'
+ @application_name ||= 'bogus_app'
+ @application_password ||= 'bogus_app_password'
+ [OmniAuth::Strategies::Crowd, {:crowd_server_url => @crowd_server_url,
+ :application_name => @application_name,
+ :application_password => @application_password,
+ :use_sessions => @using_sessions,
+ :sso_url => @sso_url,
+ :sso_url_image => @sso_url_image
+ }]
+ end
+
+ @using_sessions = false
+ @sso_url = nil
+ @sso_url_image = nil
+ let(:config) { OmniAuth::Strategies::Crowd::Configuration.new(strategy[1]) }
+ let(:validator) { OmniAuth::Strategies::Crowd::CrowdValidator.new(config, 'foo', 'bar', nil, nil) }
+
+ describe 'Authentication Request Body' do
+
+ it 'should send password in session request' do
+ body = <<-BODY.strip
+<password>
+ <value>bar</value>
+</password>
+BODY
+ expect(validator.send(:make_authentication_request_body, 'bar')).to eq(body)
+ end
+
+ it 'should escape special characters username and password in session request' do
+ body = <<-BODY.strip
+<password>
+ <value>bar&lt;</value>
+</password>
+BODY
+ expect(validator.send(:make_authentication_request_body, 'bar<')).to eq(body)
+ end
+ end
+
+ describe 'GET /auth/crowd' do
+ it 'should show the login form' do
+ get '/auth/crowd'
+ expect(last_response).to be_ok
+ end
+ end
+
+ describe 'POST /auth/crowd' do
+ it 'should redirect to callback' do
+ post '/auth/crowd', :username=>'foo', :password=>'bar'
+ expect(last_response).to be_redirect
+ expect(last_response.headers['Location']).to eq('http://example.org/auth/crowd/callback')
+ end
+ end
+
+ describe 'GET /auth/crowd/callback without any credentials' do
+ it 'should fail' do
+ get '/auth/crowd/callback'
+ expect(last_response).to be_redirect
+ expect(last_response.headers['Location']).to match(/no_credentials/)
+ end
+ end
+
+ describe 'GET /auth/crowd/callback with credentials can be successful' do
+ context "when using authentication endpoint" do
+ before do
+ stub_request(:post, "https://crowd.example.org/rest/usermanagement/latest/authentication?username=foo").
+ to_return(:body => File.read(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'success.xml')))
+
+ stub_request(:get, "https://crowd.example.org/rest/usermanagement/latest/user/group/direct?username=foo").
+ to_return(:body => File.read(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'groups.xml')))
+
+ #Adding this to prevent Content-Type text/xml from being added back in the future
+ stub_request(:get, "https://crowd.example.org/rest/usermanagement/latest/user/group/direct?username=foo").with(:headers => {"Content-Type" => "text/xml"}).
+ to_return(:status => [415, "Unsupported Media Type"])
+ get '/auth/crowd/callback', nil, 'rack.session'=>{'omniauth.crowd'=> {"username"=>"foo", "password"=>"ba"}}
+ end
+ it 'should call through to the master app' do
+ expect(last_response.body).to eq('true')
+ end
+ it 'should have an auth hash' do
+ auth = last_request.env['omniauth.auth']
+ expect(auth).to be_kind_of(Hash)
+ end
+ it 'should have good data' do
+ auth = last_request.env['omniauth.auth']
+ expect(auth['provider']).to eq(:crowd)
+ expect(auth['uid']).to eq('foo')
+ expect(auth['info']).to be_kind_of(Hash)
+ expect(auth['info']['groups'].sort).to eq(["Developers", "jira-users"].sort)
+ end
+ end
+
+ describe "when using session endpoint" do
+ before do
+ @using_sessions = true
+ stub_request(:post, "https://crowd.example.org/rest/usermanagement/latest/authentication?username=foo").
+ to_return(:body => File.read(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'success.xml')))
+ stub_request(:post, "https://crowd.example.org/rest/usermanagement/latest/session").
+ to_return(:status => 201, :body => File.read(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'session.xml')))
+ stub_request(:get, "https://crowd.example.org/rest/usermanagement/latest/user/group/direct?username=foo").
+ to_return(:body => File.read(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'groups.xml')))
+ end
+
+ after { @using_sessions = false }
+
+ it 'should call through to the master app' do
+ get '/auth/crowd/callback', nil, 'rack.session'=>{'omniauth.crowd'=> {"username"=>"foo", "password"=>"ba"}}
+ expect(last_response.body).to eq('true')
+ end
+
+ it 'should have an auth hash' do
+ get '/auth/crowd/callback', nil, 'rack.session'=>{'omniauth.crowd'=> {"username"=>"foo", "password"=>"ba"}}
+ expect(last_request.env['omniauth.auth']).to be_kind_of(Hash)
+ end
+
+ it 'should have good data' do
+ get '/auth/crowd/callback', nil, 'rack.session'=>{'omniauth.crowd'=> {"username"=>"foo", "password"=>"ba"}}
+ auth = last_request.env['omniauth.auth']
+ expect(auth['provider']).to eq(:crowd)
+ expect(auth['uid']).to eq('foo')
+ expect(auth['info']).to be_kind_of(Hash)
+ expect(auth['info']['sso_token']).to eq('rtk8eMvqq00EiGn5iJCMZQ00')
+ expect(auth['info']['groups'].sort).to eq(["Developers", "jira-users"].sort)
+ end
+ end
+ end
+
+ describe 'GET /auth/crowd/callback with credentials will fail' do
+ before do
+ stub_request(:post, "https://crowd.example.org/rest/usermanagement/latest/authentication?username=foo").
+ to_return(:status=>400)
+ get '/auth/crowd/callback', nil, 'rack.session'=>{'omniauth.crowd'=> {"username"=>"foo", "password"=>"ba"}}
+ end
+ it 'should fail' do
+ expect(last_response).to be_redirect
+ expect(last_response.headers['Location']).to match(/invalid_credentials/)
+ end
+ end
+
+ describe 'GET /auth/crowd without credentials will redirect to login form' do
+
+ sso_url = 'https://foo.bar'
+
+ before do
+ @using_sessions = true
+ @sso_url = sso_url
+ end
+
+ it 'should have the SSO button in the response body' do
+
+ found_legend = found_anchor = nil
+
+ get '/auth/crowd'
+
+ Nokogiri::HTML(last_response.body).xpath('//html/body/form/fieldset/*').each do |element|
+
+ if element.name === 'legend' && element.content() === 'SSO'
+ found_legend = true
+ elsif element.name === 'a' && element.attr('href') === "#{sso_url}/users/auth/crowd/callback"
+ found_anchor = true
+ end
+ end
+
+ expect(found_legend).to(be(true))
+ expect(found_anchor).to(be(true))
+
+ end
+
+ after do
+ @using_sessions = false
+ @sso_url = nil
+ end
+
+ end
+
+ describe 'GET /auth/crowd without credentials will redirect to login form which has custom image in the SSO link' do
+
+ sso_url = 'https://foo.bar'
+ sso_url_image = 'https://foo.bar/image.png'
+
+ before do
+ @using_sessions = true
+ @sso_url = sso_url
+ @sso_url_image = 'https://foo.bar/image.png'
+ end
+
+ it 'should have the SSO button with a custom image in the response body' do
+
+ found_legend = found_anchor = found_image = false
+
+ get '/auth/crowd'
+
+ Nokogiri::HTML(last_response.body).xpath('//html/body/form/fieldset/*').each do |element|
+
+ if element.name === 'legend' && element.content() === 'SSO'
+ found_legend = true
+ elsif element.name === 'a' && element.attr('href') === "#{sso_url}/users/auth/crowd/callback"
+
+ found_anchor = true
+
+ if element.children.length === 1 && element.children.first.name === 'img' && element.children.first.attr('src') === sso_url_image
+ found_image = true
+ end
+
+ end
+ end
+
+ expect(found_legend).to(be(true))
+ expect(found_anchor).to(be(true))
+ expect(found_image).to(be(true))
+
+ end
+
+ after do
+ @using_sessions = false
+ @sso_url = nil
+ @sso_url_image = nil
+ end
+
+ end
+
+ describe 'GET /auth/crowd without credentials but with SSO cookie will redirect to callback' do
+
+ sso_url = 'https://foo.bar'
+
+ before do
+
+ @using_sessions = true
+ @sso_url = sso_url
+
+ set_cookie('crowd.token_key=foobar')
+
+ end
+
+ it 'should redirect to callback' do
+ get '/auth/crowd'
+ expect(last_response).to be_redirect
+ expect(last_response.headers['Location']).to eq('http://example.org/auth/crowd/callback')
+ end
+
+ after do
+
+ @using_sessions = false
+ @sso_url = nil
+
+ clear_cookies()
+
+ end
+
+ end
+
+ describe 'POST /auth/crowd/callback without credentials but with SSO cookie will redirect to login form because session is invalid' do
+
+ sso_url = 'https://foo.bar'
+ token = 'foobar'
+
+ before do
+
+ @using_sessions = true
+ @sso_url = sso_url
+
+ stub_request(:get, "https://crowd.example.org/rest/usermanagement/latest/session/#{token}").
+ to_return(:status => [404])
+
+ set_cookie("crowd.token_key=#{token}")
+
+ end
+
+ it 'should redirect to login form' do
+ post '/auth/crowd/callback'
+ expect(last_response).to be_redirect
+ expect(last_response.headers['Location']).to match(/invalid_credentials/)
+ end
+
+ after do
+
+ @using_sessions = false
+ @sso_url = nil
+
+ clear_cookies()
+
+ end
+
+ end
+
+ describe 'GET /auth/crowd/callback without credentials but with SSO cookie will succeed' do
+
+ sso_url = 'https://foo.bar'
+ token = 'rtk8eMvqq00EiGn5iJCMZQ00'
+
+ before do
+
+ @using_sessions = true
+ @sso_url = sso_url
+
+ stub_request(:get, "https://crowd.example.org/rest/usermanagement/latest/session/#{token}").
+ to_return(:status => 200, :body => File.read(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'session.xml')))
+ stub_request(:post, "https://crowd.example.org/rest/usermanagement/latest/session/#{token}").
+ to_return(:status => 200)
+ stub_request(:get, "https://crowd.example.org/rest/usermanagement/latest/user/group/direct?username=foo").
+ to_return(:body => File.read(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'groups.xml')))
+
+ set_cookie("crowd.token_key=#{token}")
+
+ end
+
+ it 'should return user data' do
+
+ auth = nil
+
+ get '/auth/crowd/callback'
+
+ auth = last_request.env['omniauth.auth']
+
+ expect(auth['provider']).to eq(:crowd)
+ expect(auth['uid']).to eq('foo')
+ expect(auth['info']).to be_kind_of(Hash)
+ expect(auth['info']['groups'].sort).to eq(["Developers", "jira-users"].sort)
+
+ end
+
+ after do
+
+ @using_sessions = false
+ @sso_url = nil
+
+ clear_cookies()
+
+ end
+
+ end
+
+ describe 'GET /auth/crowd/callback without credentials but with multiple SSO cookies will succeed because one of them is valid' do
+
+ sso_url = 'https://foo.bar'
+
+ before do
+
+ @using_sessions = true
+ @sso_url = sso_url
+
+ stub_request(:get, "https://crowd.example.org/rest/usermanagement/latest/session/foo").
+ to_return(:status => 404)
+ stub_request(:get, "https://crowd.example.org/rest/usermanagement/latest/session/fubar").
+ to_return(:status => 404)
+ stub_request(:get, "https://crowd.example.org/rest/usermanagement/latest/session/rtk8eMvqq00EiGn5iJCMZQ00").
+ to_return(:status => 200, :body => File.read(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'session.xml')))
+ stub_request(:post, "https://crowd.example.org/rest/usermanagement/latest/session/rtk8eMvqq00EiGn5iJCMZQ00").
+ to_return(:status => 200)
+ stub_request(:get, "https://crowd.example.org/rest/usermanagement/latest/user/group/direct?username=foo").
+ to_return(:body => File.read(File.join(File.dirname(__FILE__), '..', '..', 'fixtures', 'groups.xml')))
+
+ header('Cookie', "crowd.token_key=foo;crowd.token_key=rtk8eMvqq00EiGn5iJCMZQ00;crowd.token_key=fubar")
+
+ end
+
+ it 'should return user data' do
+
+ auth = nil
+
+ get '/auth/crowd/callback'
+
+ auth = last_request.env['omniauth.auth']
+
+ expect(auth['provider']).to eq(:crowd)
+ expect(auth['uid']).to eq('foo')
+ expect(auth['info']).to be_kind_of(Hash)
+ expect(auth['info']['groups'].sort).to eq(["Developers", "jira-users"].sort)
+
+ end
+
+ after do
+
+ @using_sessions = false
+ @sso_url = nil
+
+ header('Cookie', nil)
+
+ end
+
+ end
+end
diff --git a/vendor/gems/omniauth_crowd/spec/spec_helper.rb b/vendor/gems/omniauth_crowd/spec/spec_helper.rb
new file mode 100644
index 00000000000..13683c95062
--- /dev/null
+++ b/vendor/gems/omniauth_crowd/spec/spec_helper.rb
@@ -0,0 +1,14 @@
+require 'bundler/setup'
+Bundler.setup
+require 'rack/test'
+require 'webmock'
+require 'webmock/rspec'
+require 'nokogiri'
+
+require 'omniauth_crowd'
+RSpec.configure do |config|
+ WebMock.disable_net_connect!
+ config.include Rack::Test::Methods
+ config.raise_errors_for_deprecations!
+end
+