diff --git a/Gemfile b/Gemfile
index e3eba484a15620ff7f58f094de80f8a4bb853e54..eab184c371cb11284d4d287f491ac9b7eb87742b 100644
--- a/Gemfile
+++ b/Gemfile
@@ -44,7 +44,7 @@ gem 'omniauth-dingtalk-oauth2', '~> 1.0'
 gem 'omniauth-alicloud', '~> 1.0.1'
 gem 'omniauth-facebook', '~> 4.0.0'
 gem 'omniauth-github', '~> 1.4'
-gem 'omniauth-gitlab', '~> 1.0.2'
+gem 'omniauth-gitlab', '~> 4.0.0', path: 'vendor/gems/omniauth-gitlab' # See vendor/gems/omniauth-gitlab/README.md
 gem 'omniauth-google-oauth2', '~> 0.6.0'
 gem 'omniauth-oauth2-generic', '~> 0.2.2'
 gem 'omniauth-saml', '~> 1.10'
diff --git a/Gemfile.lock b/Gemfile.lock
index aea6f448587e44df185f08fc5063ace5d99eda7b..fafdd1ad81779ca22bc33514c7955ca944171f67 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -12,6 +12,13 @@ PATH
       connection_pool (~> 2.0)
       mail (~> 2.7)
 
+PATH
+  remote: vendor/gems/omniauth-gitlab
+  specs:
+    omniauth-gitlab (4.0.0)
+      omniauth (~> 1.0)
+      omniauth-oauth2 (~> 1.7.1)
+
 GEM
   remote: https://rubygems.org/
   specs:
@@ -872,9 +879,6 @@ GEM
     omniauth-github (1.4.0)
       omniauth (~> 1.5)
       omniauth-oauth2 (>= 1.4.0, < 2.0)
-    omniauth-gitlab (1.0.3)
-      omniauth (~> 1.0)
-      omniauth-oauth2 (~> 1.0)
     omniauth-google-oauth2 (0.6.0)
       jwt (>= 2.0)
       omniauth (>= 1.1.1)
@@ -1623,7 +1627,7 @@ DEPENDENCIES
   omniauth-dingtalk-oauth2 (~> 1.0)
   omniauth-facebook (~> 4.0.0)
   omniauth-github (~> 1.4)
-  omniauth-gitlab (~> 1.0.2)
+  omniauth-gitlab (~> 4.0.0)!
   omniauth-google-oauth2 (~> 0.6.0)
   omniauth-oauth2-generic (~> 0.2.2)
   omniauth-salesforce (~> 1.0.5)
diff --git a/vendor/gems/omniauth-gitlab/.gitignore b/vendor/gems/omniauth-gitlab/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..062d4acf0a95b9436f2c93e31c01c69e13a5a512
--- /dev/null
+++ b/vendor/gems/omniauth-gitlab/.gitignore
@@ -0,0 +1,17 @@
+*.gem
+*.rbc
+.bundle
+.config
+.yardoc
+.rvmrc
+InstalledFiles
+_yardoc
+coverage
+doc/
+lib/bundler/man
+pkg
+rdoc
+spec/reports
+test/tmp
+test/version_tmp
+tmp
diff --git a/vendor/gems/omniauth-gitlab/Gemfile b/vendor/gems/omniauth-gitlab/Gemfile
new file mode 100644
index 0000000000000000000000000000000000000000..ad0c84b6ac8c05f72d7afd6bbe87d1d0a951b7e8
--- /dev/null
+++ b/vendor/gems/omniauth-gitlab/Gemfile
@@ -0,0 +1,4 @@
+source 'https://rubygems.org'
+
+# Specify your gem's dependencies in omniauth-gitlab.gemspec
+gemspec
diff --git a/vendor/gems/omniauth-gitlab/Gemfile.lock b/vendor/gems/omniauth-gitlab/Gemfile.lock
new file mode 100644
index 0000000000000000000000000000000000000000..b5979104080a56b319957856e03b1b0c38700cda
--- /dev/null
+++ b/vendor/gems/omniauth-gitlab/Gemfile.lock
@@ -0,0 +1,73 @@
+PATH
+  remote: .
+  specs:
+    omniauth-gitlab (4.0.0)
+      omniauth (~> 1.0)
+      omniauth-oauth2 (~> 1.7.1)
+
+GEM
+  remote: https://rubygems.org/
+  specs:
+    diff-lcs (1.5.0)
+    docile (1.4.0)
+    faraday (2.3.0)
+      faraday-net_http (~> 2.0)
+      ruby2_keywords (>= 0.0.4)
+    faraday-net_http (2.0.3)
+    hashie (5.0.0)
+    jwt (2.4.1)
+    multi_xml (0.6.0)
+    oauth2 (2.0.1)
+      faraday (>= 0.17.3, < 3.0)
+      jwt (>= 1.0, < 3.0)
+      multi_xml (~> 0.5)
+      rack (>= 1.2, < 3)
+      rash_alt (>= 0.4, < 1)
+      version_gem (~> 1.0)
+    omniauth (1.9.1)
+      hashie (>= 3.4.6)
+      rack (>= 1.6.2, < 3)
+    omniauth-oauth2 (1.7.3)
+      oauth2 (>= 1.4, < 3)
+      omniauth (>= 1.9, < 3)
+    rack (2.2.3.1)
+    rake (13.0.6)
+    rash_alt (0.4.12)
+      hashie (>= 3.4)
+    rspec (3.11.0)
+      rspec-core (~> 3.11.0)
+      rspec-expectations (~> 3.11.0)
+      rspec-mocks (~> 3.11.0)
+    rspec-core (3.11.0)
+      rspec-support (~> 3.11.0)
+    rspec-expectations (3.11.0)
+      diff-lcs (>= 1.2.0, < 2.0)
+      rspec-support (~> 3.11.0)
+    rspec-its (1.3.0)
+      rspec-core (>= 3.0.0)
+      rspec-expectations (>= 3.0.0)
+    rspec-mocks (3.11.1)
+      diff-lcs (>= 1.2.0, < 2.0)
+      rspec-support (~> 3.11.0)
+    rspec-support (3.11.0)
+    ruby2_keywords (0.0.5)
+    simplecov (0.21.2)
+      docile (~> 1.1)
+      simplecov-html (~> 0.11)
+      simplecov_json_formatter (~> 0.1)
+    simplecov-html (0.12.3)
+    simplecov_json_formatter (0.1.4)
+    version_gem (1.0.0)
+
+PLATFORMS
+  ruby
+
+DEPENDENCIES
+  omniauth-gitlab!
+  rake (>= 12.0)
+  rspec (~> 3.1)
+  rspec-its (~> 1.0)
+  simplecov
+
+BUNDLED WITH
+   2.3.15
diff --git a/vendor/gems/omniauth-gitlab/LICENSE.txt b/vendor/gems/omniauth-gitlab/LICENSE.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ccdae5ea15c7cd78c31c92bff91f2316426e7fcd
--- /dev/null
+++ b/vendor/gems/omniauth-gitlab/LICENSE.txt
@@ -0,0 +1,22 @@
+Copyright (c) 2013 ssein
+
+MIT License
+
+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.
\ No newline at end of file
diff --git a/vendor/gems/omniauth-gitlab/README.md b/vendor/gems/omniauth-gitlab/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..f22f14266f62f7fbbfdec5faaefd464918fd41f6
--- /dev/null
+++ b/vendor/gems/omniauth-gitlab/README.md
@@ -0,0 +1,94 @@
+# Omniauth::Gitlab
+
+This is fork of [omniauth-gitlab](https://github.com/linchus/omniauth-gitlab) 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. [`oauth2`](https://github.com/oauth-xx/oauth2) v1.4.9 and up.
+   [v1.4.9 fixed relative URL handling](https://github.com/oauth-xx/oauth2/pull/469).
+
+   However, this breaks the default GitLab.com configuration and
+   existing configurations that use the `/api/v4` suffix in the `site`
+   parameter.
+   [omniauth-gitlab v4.0.0 fixed the first issue](https://github.com/linchus/omniauth-gitlab/pull/22),
+   but the second issue requires an admin to update `site` to drop the suffix.
+
+   This fork restores backwards compatibility that was removed in omniauth-gitlab v2.0.0:
+   https://github.com/linchus/omniauth-gitlab/commit/bb4cec2c9f8f067fdfe1f9aa219973e5d8e4a0a3
+
+[![Join the chat at https://gitter.im/linchus/omniauth-gitlab](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/linchus/omniauth-gitlab?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
+
+This is the OAuth2 strategy for authenticating to your GitLab service.
+
+## Requirements
+
+Gitlab 7.7.0+
+ 
+## Installation
+
+Add this line to your application's Gemfile:
+
+    gem 'omniauth-gitlab'
+
+And then execute:
+
+    $ bundle
+
+Or install it yourself as:
+
+    $ gem install omniauth-gitlab
+
+## Basic Usage
+
+    use OmniAuth::Builder do
+      provider :gitlab, ENV['GITLAB_KEY'], ENV['GITLAB_SECRET']
+    end
+
+## Standalone Usage
+
+    use OmniAuth::Builder do
+      provider :gitlab, ENV['GITLAB_KEY'], ENV['GITLAB_SECRET'],
+        {
+           client_options: {
+             site: 'https://gitlab.YOURDOMAIN.com/api/v4'
+           }
+        }
+    end
+
+## Custom scopes
+
+By default, the `api` scope is requested and must be allowed in GitLab's application configuration. To use different scopes:
+
+    use OmniAuth::Builder do
+      provider :gitlab, ENV['GITLAB_KEY'], ENV['GITLAB_SECRET'], scope: 'read_user openid'
+    end
+
+Requesting a scope that is not configured will result the error "The requested scope is invalid, unknown, or malformed.".
+
+## Old API version
+
+API V3 will be unsupported from GitLab 9.5 and will be removed in GitLab 9.5 or later.
+
+[https://gitlab.com/help/api/v3_to_v4.md](https://gitlab.com/help/api/v3_to_v4.md)
+
+If you use GitLab 9.0 and below you could configure V3 API:
+
+    use OmniAuth::Builder do
+      provider :gitlab, ENV['GITLAB_KEY'], ENV['GITLAB_SECRET'],
+        {
+           client_options: {
+             site: 'https://gitlab.YOURDOMAIN.com/api/v3'
+           }
+        }
+    end
+
+## Contributing
+
+1. Fork it
+2. Create your feature branch (`git checkout -b my-new-feature`)
+3. Commit your changes (`git commit -am 'Add some feature'`)
+4. Push to the branch (`git push origin my-new-feature`)
+5. Create new Pull Request
diff --git a/vendor/gems/omniauth-gitlab/Rakefile b/vendor/gems/omniauth-gitlab/Rakefile
new file mode 100644
index 0000000000000000000000000000000000000000..db953c9a1c5e66102b29c6e890bf0472b51ba8bb
--- /dev/null
+++ b/vendor/gems/omniauth-gitlab/Rakefile
@@ -0,0 +1,7 @@
+require 'bundler/gem_tasks'
+require 'rspec/core/rake_task'
+
+RSpec::Core::RakeTask.new
+
+desc 'Run specs'
+task default: :spec
diff --git a/vendor/gems/omniauth-gitlab/lib/omniauth-gitlab.rb b/vendor/gems/omniauth-gitlab/lib/omniauth-gitlab.rb
new file mode 100644
index 0000000000000000000000000000000000000000..dfe9d2131c94fd35ea313611d238e34f51072524
--- /dev/null
+++ b/vendor/gems/omniauth-gitlab/lib/omniauth-gitlab.rb
@@ -0,0 +1,2 @@
+require 'omniauth-gitlab/version'
+require 'omniauth/strategies/gitlab'
diff --git a/vendor/gems/omniauth-gitlab/lib/omniauth-gitlab/version.rb b/vendor/gems/omniauth-gitlab/lib/omniauth-gitlab/version.rb
new file mode 100644
index 0000000000000000000000000000000000000000..6465d4ca1996357a3e2a7dd54a5e547b368f7fa6
--- /dev/null
+++ b/vendor/gems/omniauth-gitlab/lib/omniauth-gitlab/version.rb
@@ -0,0 +1,5 @@
+module Omniauth
+  module Gitlab
+    VERSION = '4.0.0'
+  end
+end
diff --git a/vendor/gems/omniauth-gitlab/lib/omniauth/strategies/gitlab.rb b/vendor/gems/omniauth-gitlab/lib/omniauth/strategies/gitlab.rb
new file mode 100644
index 0000000000000000000000000000000000000000..19ee02e78c4c09c4bfb6670ecfdabf343daa18cf
--- /dev/null
+++ b/vendor/gems/omniauth-gitlab/lib/omniauth/strategies/gitlab.rb
@@ -0,0 +1,46 @@
+# frozen_string_literal: true
+
+require 'omniauth-oauth2'
+
+module OmniAuth
+  module Strategies
+    class GitLab < OmniAuth::Strategies::OAuth2
+      API_SUFFIX_REGEX = %r{/api/v(\d+)/?$}.freeze
+
+      option :client_options, site: 'https://gitlab.com'
+
+      option :redirect_url
+
+      uid { raw_info['id'].to_s }
+
+      info do
+        {
+          name: raw_info['name'],
+          username: raw_info['username'],
+          email: raw_info['email'],
+          image: raw_info['avatar_url']
+        }
+      end
+
+      extra do
+        { raw_info: raw_info }
+      end
+
+      def raw_info
+        @raw_info ||= access_token.get(user_endpoint_url).parsed
+      end
+
+      private
+
+      def user_endpoint_url
+        options.client_options.site.match(API_SUFFIX_REGEX) ? 'user' : 'api/v4/user'
+      end
+
+      def callback_url
+        options.redirect_url || (full_host + script_name + callback_path)
+      end
+    end
+  end
+end
+
+OmniAuth.config.add_camelization 'gitlab', 'GitLab'
diff --git a/vendor/gems/omniauth-gitlab/omniauth-gitlab.gemspec b/vendor/gems/omniauth-gitlab/omniauth-gitlab.gemspec
new file mode 100644
index 0000000000000000000000000000000000000000..036c20277192388c123b3b5c5b0a46a5b9e5f2e6
--- /dev/null
+++ b/vendor/gems/omniauth-gitlab/omniauth-gitlab.gemspec
@@ -0,0 +1,26 @@
+# -*- encoding: utf-8 -*-
+lib = File.expand_path('../lib', __FILE__)
+$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
+require 'omniauth-gitlab/version'
+
+Gem::Specification.new do |gem|
+  gem.name          = 'omniauth-gitlab'
+  gem.version       = Omniauth::Gitlab::VERSION
+  gem.authors       = ['Sergey Sein']
+  gem.email         = ['linchus@gmail.com']
+  gem.description   = 'This is the strategy for authenticating to your GitLab service'
+  gem.summary       = 'This is the strategy for authenticating to your GitLab service'
+  gem.homepage      = 'https://github.com/linchus/omniauth-gitlab'
+
+  gem.files         = `git ls-files`.split($/)
+  gem.executables   = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
+  gem.test_files    = gem.files.grep(%r{^(test|spec|features)/})
+  gem.require_paths = ['lib']
+
+  gem.add_dependency 'omniauth', '~> 1.0'
+  gem.add_dependency 'omniauth-oauth2', '~> 1.7.1'
+  gem.add_development_dependency 'rspec', '~> 3.1'
+  gem.add_development_dependency 'rspec-its', '~> 1.0'
+  gem.add_development_dependency 'simplecov'
+  gem.add_development_dependency 'rake', '>= 12.0'
+end
diff --git a/vendor/gems/omniauth-gitlab/spec/omniauth/strategies/gitlab_spec.rb b/vendor/gems/omniauth-gitlab/spec/omniauth/strategies/gitlab_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..a599386b26c634e9d7c72c3543da329bd48eb1ad
--- /dev/null
+++ b/vendor/gems/omniauth-gitlab/spec/omniauth/strategies/gitlab_spec.rb
@@ -0,0 +1,80 @@
+require 'spec_helper'
+
+describe OmniAuth::Strategies::GitLab do
+  let(:access_token) { double('AccessToken') }
+  let(:parsed_response) { double('ParsedResponse') }
+  let(:response) { double('Response', parsed: parsed_response) }
+
+  let(:enterprise_site) { 'https://some.other.site.com' }
+
+  let(:gitlab_service) { OmniAuth::Strategies::GitLab.new({}) }
+  let(:enterprise) do
+    OmniAuth::Strategies::GitLab.new(
+      'GITLAB_KEY',
+      'GITLAB_SECRET',
+      client_options: { site: enterprise_site },
+      redirect_url: 'http://localhost:9292/callback_url'
+    )
+  end
+
+  subject { gitlab_service }
+
+  before(:each) do
+    allow(subject).to receive(:access_token).and_return(access_token)
+  end
+
+  describe 'client options' do
+    context 'with defaults' do
+      subject { gitlab_service.options.client_options }
+
+      its(:site) { is_expected.to eq 'https://gitlab.com' }
+    end
+
+    context 'with override' do
+      subject { enterprise.options.client_options }
+
+      its(:site) { is_expected.to eq enterprise_site }
+    end
+  end
+
+  describe 'redirect_url' do
+    context 'with defaults' do
+      subject { gitlab_service.options }
+      its(:redirect_url) { is_expected.to be_nil }
+    end
+
+    context 'with customs' do
+      subject { enterprise.options }
+      its(:redirect_url) { is_expected.to eq 'http://localhost:9292/callback_url' }
+    end
+  end
+
+  describe '#raw_info' do
+    context 'with new configuration' do
+      it 'sent request to current user endpoint' do
+        expect(access_token).to receive(:get).with('api/v4/user').and_return(response)
+        expect(subject.raw_info).to eq(parsed_response)
+      end
+    end
+
+    context 'with old style configuration' do
+      let(:enterprise_site) { 'https://some.other.site.com/api/v4' }
+
+      subject { enterprise }
+
+      it 'sent request to current user endpoint' do
+        expect(access_token).to receive(:get).with('user').and_return(response)
+        expect(subject.raw_info).to eq(parsed_response)
+      end
+
+      context 'with a trailing slash' do
+        let(:enterprise_site) { 'https://some.other.site.com/api/v4/' }
+
+        it 'sent request to current user endpoint' do
+          expect(access_token).to receive(:get).with('user').and_return(response)
+          expect(subject.raw_info).to eq(parsed_response)
+        end
+      end
+    end
+  end
+end
diff --git a/vendor/gems/omniauth-gitlab/spec/spec_helper.rb b/vendor/gems/omniauth-gitlab/spec/spec_helper.rb
new file mode 100644
index 0000000000000000000000000000000000000000..38553547e98b29f93623497cdedde5bb7c929a54
--- /dev/null
+++ b/vendor/gems/omniauth-gitlab/spec/spec_helper.rb
@@ -0,0 +1,8 @@
+$LOAD_PATH.unshift File.expand_path('..', __FILE__)
+$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
+require 'simplecov'
+SimpleCov.start
+require 'rspec'
+require 'rspec/its'
+require 'omniauth'
+require 'omniauth-gitlab'