diff options
Diffstat (limited to 'app/controllers')
-rw-r--r-- | app/controllers/admin/application_settings_controller.rb | 1 | ||||
-rw-r--r-- | app/controllers/jwt_controller.rb | 42 | ||||
-rw-r--r-- | app/controllers/oauth/applications_controller.rb | 2 | ||||
-rw-r--r-- | app/controllers/projects/git_http_controller.rb | 147 | ||||
-rw-r--r-- | app/controllers/projects/wikis_controller.rb | 2 | ||||
-rw-r--r-- | app/controllers/sessions_controller.rb | 1 |
6 files changed, 153 insertions, 42 deletions
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index 0a34a12e2a7..f4eda864aac 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -74,6 +74,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController :two_factor_grace_period, :gravatar_enabled, :sign_in_text, + :after_sign_up_text, :help_page_text, :home_page_url, :after_sign_out_path, diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb index cee3b6c43e7..131a16dad9b 100644 --- a/app/controllers/jwt_controller.rb +++ b/app/controllers/jwt_controller.rb @@ -42,46 +42,8 @@ class JwtController < ApplicationController end def authenticate_user(login, password) - # TODO: this is a copy and paste from grack_auth, - # it should be refactored in the future - - user = Gitlab::Auth.new.find(login, password) - - # If the user authenticated successfully, we reset the auth failure count - # from Rack::Attack for that IP. A client may attempt to authenticate - # with a username and blank password first, and only after it receives - # a 401 error does it present a password. Resetting the count prevents - # false positives from occurring. - # - # Otherwise, we let Rack::Attack know there was a failed authentication - # attempt from this IP. This information is stored in the Rails cache - # (Redis) and will be used by the Rack::Attack middleware to decide - # whether to block requests from this IP. - config = Gitlab.config.rack_attack.git_basic_auth - - if config.enabled - if user - # A successful login will reset the auth failure count from this IP - Rack::Attack::Allow2Ban.reset(request.ip, config) - else - banned = Rack::Attack::Allow2Ban.filter(request.ip, config) do - # Unless the IP is whitelisted, return true so that Allow2Ban - # increments the counter (stored in Rails.cache) for the IP - if config.ip_whitelist.include?(request.ip) - false - else - true - end - end - - if banned - Rails.logger.info "IP #{request.ip} failed to login " \ - "as #{login} but has been temporarily banned from Git auth" - return - end - end - end - + user = Gitlab::Auth.find_in_gitlab_or_ldap(login, password) + Gitlab::Auth.rate_limit!(request.ip, success: user.present?, login: login) user end end diff --git a/app/controllers/oauth/applications_controller.rb b/app/controllers/oauth/applications_controller.rb index c6bdd0602c1..0f54dfa4efc 100644 --- a/app/controllers/oauth/applications_controller.rb +++ b/app/controllers/oauth/applications_controller.rb @@ -32,7 +32,7 @@ class Oauth::ApplicationsController < Doorkeeper::ApplicationsController def verify_user_oauth_applications_enabled return if current_application_settings.user_oauth_applications? - redirect_to applications_profile_url + redirect_to profile_path end def set_index_vars diff --git a/app/controllers/projects/git_http_controller.rb b/app/controllers/projects/git_http_controller.rb new file mode 100644 index 00000000000..348d6cf4d96 --- /dev/null +++ b/app/controllers/projects/git_http_controller.rb @@ -0,0 +1,147 @@ +class Projects::GitHttpController < Projects::ApplicationController + attr_reader :user + + # Git clients will not know what authenticity token to send along + skip_before_action :verify_authenticity_token + skip_before_action :repository + before_action :authenticate_user + before_action :ensure_project_found! + + # GET /foo/bar.git/info/refs?service=git-upload-pack (git pull) + # GET /foo/bar.git/info/refs?service=git-receive-pack (git push) + def info_refs + if upload_pack? && upload_pack_allowed? + render_ok + elsif receive_pack? && receive_pack_allowed? + render_ok + else + render_not_found + end + end + + # POST /foo/bar.git/git-upload-pack (git pull) + def git_upload_pack + if upload_pack? && upload_pack_allowed? + render_ok + else + render_not_found + end + end + + # POST /foo/bar.git/git-receive-pack" (git push) + def git_receive_pack + if receive_pack? && receive_pack_allowed? + render_ok + else + render_not_found + end + end + + private + + def authenticate_user + return if project && project.public? && upload_pack? + + authenticate_or_request_with_http_basic do |login, password| + auth_result = Gitlab::Auth.find(login, password, project: project, ip: request.ip) + + if auth_result.type == :ci && upload_pack? + @ci = true + elsif auth_result.type == :oauth && !upload_pack? + # Not allowed + else + @user = auth_result.user + end + + ci? || user + end + end + + def ensure_project_found! + render_not_found if project.blank? + end + + def project + return @project if defined?(@project) + + project_id, _ = project_id_with_suffix + if project_id.blank? + @project = nil + else + @project = Project.find_with_namespace("#{params[:namespace_id]}/#{project_id}") + end + end + + # This method returns two values so that we can parse + # params[:project_id] (untrusted input!) in exactly one place. + def project_id_with_suffix + id = params[:project_id] || '' + + %w[.wiki.git .git].each do |suffix| + if id.end_with?(suffix) + # Be careful to only remove the suffix from the end of 'id'. + # Accidentally removing it from the middle is how security + # vulnerabilities happen! + return [id.slice(0, id.length - suffix.length), suffix] + end + end + + # Something is wrong with params[:project_id]; do not pass it on. + [nil, nil] + end + + def upload_pack? + git_command == 'git-upload-pack' + end + + def receive_pack? + git_command == 'git-receive-pack' + end + + def git_command + if action_name == 'info_refs' + params[:service] + else + action_name.dasherize + end + end + + def render_ok + render json: Gitlab::Workhorse.git_http_ok(repository, user) + end + + def repository + _, suffix = project_id_with_suffix + if suffix == '.wiki.git' + project.wiki.repository + else + project.repository + end + end + + def render_not_found + render text: 'Not Found', status: :not_found + end + + def ci? + @ci.present? + end + + def upload_pack_allowed? + return false unless Gitlab.config.gitlab_shell.upload_pack + + if user + Gitlab::GitAccess.new(user, project).download_access_check.allowed? + else + ci? || project.public? + end + end + + def receive_pack_allowed? + return false unless Gitlab.config.gitlab_shell.receive_pack + + # Skip user authorization on upload request. + # It will be done by the pre-receive hook in the repository. + user.present? + end +end diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb index 4b404eb03fa..2aa6bed0724 100644 --- a/app/controllers/projects/wikis_controller.rb +++ b/app/controllers/projects/wikis_controller.rb @@ -95,7 +95,7 @@ class Projects::WikisController < Projects::ApplicationController ext.analyze(text, author: current_user) render json: { - body: view_context.markdown(text, pipeline: :wiki, project_wiki: @project_wiki), + body: view_context.markdown(text, pipeline: :wiki, project_wiki: @project_wiki, page_slug: params[:id]), references: { users: ext.users.map(&:username) } diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index f6eedb1773c..dae8f7b1447 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -14,6 +14,7 @@ class SessionsController < Devise::SessionsController before_action :load_recaptcha def new + set_minimum_password_length if Gitlab.config.ldap.enabled @ldap_servers = Gitlab::LDAP::Config.servers else |