diff options
Diffstat (limited to 'app/controllers')
-rw-r--r-- | app/controllers/concerns/issuable_collections.rb | 12 | ||||
-rw-r--r-- | app/controllers/concerns/issues_action.rb | 2 | ||||
-rw-r--r-- | app/controllers/concerns/merge_requests_action.rb | 2 | ||||
-rw-r--r-- | app/controllers/import/github_controller.rb | 7 | ||||
-rw-r--r-- | app/controllers/jwt_controller.rb | 36 | ||||
-rw-r--r-- | app/controllers/projects/builds_controller.rb | 6 | ||||
-rw-r--r-- | app/controllers/projects/cycle_analytics_controller.rb | 67 | ||||
-rw-r--r-- | app/controllers/projects/git_http_client_controller.rb | 64 | ||||
-rw-r--r-- | app/controllers/projects/git_http_controller.rb | 2 | ||||
-rw-r--r-- | app/controllers/projects/issues_controller.rb | 13 | ||||
-rw-r--r-- | app/controllers/projects/merge_requests_controller.rb | 12 | ||||
-rw-r--r-- | app/controllers/sent_notifications_controller.rb | 7 |
12 files changed, 169 insertions, 61 deletions
diff --git a/app/controllers/concerns/issuable_collections.rb b/app/controllers/concerns/issuable_collections.rb index b5e79099e39..4a447735fa7 100644 --- a/app/controllers/concerns/issuable_collections.rb +++ b/app/controllers/concerns/issuable_collections.rb @@ -13,10 +13,18 @@ module IssuableCollections issues_finder.execute end + def all_issues_collection + IssuesFinder.new(current_user, filter_params_all).execute + end + def merge_requests_collection merge_requests_finder.execute end + def all_merge_requests_collection + MergeRequestsFinder.new(current_user, filter_params_all).execute + end + def issues_finder @issues_finder ||= issuable_finder_for(IssuesFinder) end @@ -54,6 +62,10 @@ module IssuableCollections @filter_params end + def filter_params_all + @filter_params_all ||= filter_params.merge(state: 'all', sort: nil) + end + def set_default_scope params[:scope] = 'all' if params[:scope].blank? end diff --git a/app/controllers/concerns/issues_action.rb b/app/controllers/concerns/issues_action.rb index b89fb94be6e..eced9d9d678 100644 --- a/app/controllers/concerns/issues_action.rb +++ b/app/controllers/concerns/issues_action.rb @@ -10,6 +10,8 @@ module IssuesAction .preload(:author, :project) .page(params[:page]) + @all_issues = all_issues_collection.non_archived + respond_to do |format| format.html format.atom { render layout: false } diff --git a/app/controllers/concerns/merge_requests_action.rb b/app/controllers/concerns/merge_requests_action.rb index a1b0eee37f9..729763169e2 100644 --- a/app/controllers/concerns/merge_requests_action.rb +++ b/app/controllers/concerns/merge_requests_action.rb @@ -9,5 +9,7 @@ module MergeRequestsAction .non_archived .preload(:author, :target_project) .page(params[:page]) + + @all_merge_requests = all_merge_requests_collection.non_archived end end diff --git a/app/controllers/import/github_controller.rb b/app/controllers/import/github_controller.rb index 8c6bdd16383..ee7d498c59c 100644 --- a/app/controllers/import/github_controller.rb +++ b/app/controllers/import/github_controller.rb @@ -40,11 +40,12 @@ class Import::GithubController < Import::BaseController def create @repo_id = params[:repo_id].to_i repo = client.repo(@repo_id) - @project_name = repo.name - @target_namespace = find_or_create_namespace(repo.owner.login, client.user.login) + @project_name = params[:new_name].presence || repo.name + namespace_path = params[:target_namespace].presence || current_user.namespace_path + @target_namespace = find_or_create_namespace(namespace_path, current_user.namespace_path) if current_user.can?(:create_projects, @target_namespace) - @project = Gitlab::GithubImport::ProjectCreator.new(repo, @target_namespace, current_user, access_params).execute + @project = Gitlab::GithubImport::ProjectCreator.new(repo, @project_name, @target_namespace, current_user, access_params).execute else render 'unauthorized' end diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb index 66ebdcc37a7..06d96774754 100644 --- a/app/controllers/jwt_controller.rb +++ b/app/controllers/jwt_controller.rb @@ -11,7 +11,10 @@ class JwtController < ApplicationController service = SERVICES[params[:service]] return head :not_found unless service - result = service.new(@project, @user, auth_params).execute + @authentication_result ||= Gitlab::Auth::Result.new + + result = service.new(@authentication_result.project, @authentication_result.actor, auth_params). + execute(authentication_abilities: @authentication_result.authentication_abilities) render json: result, status: result[:http_status] end @@ -20,30 +23,23 @@ class JwtController < ApplicationController def authenticate_project_or_user authenticate_with_http_basic do |login, password| - # if it's possible we first try to authenticate project with login and password - @project = authenticate_project(login, password) - return if @project - - @user = authenticate_user(login, password) - return if @user + @authentication_result = Gitlab::Auth.find_for_git_client(login, password, project: nil, ip: request.ip) - render_403 + render_403 unless @authentication_result.success? && + (@authentication_result.actor.nil? || @authentication_result.actor.is_a?(User)) end + rescue Gitlab::Auth::MissingPersonalTokenError + render_missing_personal_token end - def auth_params - params.permit(:service, :scope, :account, :client_id) + def render_missing_personal_token + render plain: "HTTP Basic: Access denied\n" \ + "You have 2FA enabled, please use a personal access token for Git over HTTP.\n" \ + "You can generate one at #{profile_personal_access_tokens_url}", + status: 401 end - def authenticate_project(login, password) - if login == 'gitlab-ci-token' - Project.with_builds_enabled.find_by(runners_token: password) - end - end - - def authenticate_user(login, password) - user = Gitlab::Auth.find_with_user_password(login, password) - Gitlab::Auth.rate_limit!(request.ip, success: user.present?, login: login) - user + def auth_params + params.permit(:service, :scope, :account, :client_id) end end diff --git a/app/controllers/projects/builds_controller.rb b/app/controllers/projects/builds_controller.rb index 6069e620ba2..fbe391fc58c 100644 --- a/app/controllers/projects/builds_controller.rb +++ b/app/controllers/projects/builds_controller.rb @@ -35,7 +35,11 @@ class Projects::BuildsController < Projects::ApplicationController respond_to do |format| format.html format.json do - render json: @build.to_json(methods: :trace_html) + render json: { + id: @build.id, + status: @build.status, + trace_html: @build.trace_html + } end end end diff --git a/app/controllers/projects/cycle_analytics_controller.rb b/app/controllers/projects/cycle_analytics_controller.rb new file mode 100644 index 00000000000..16a7b1fc6e2 --- /dev/null +++ b/app/controllers/projects/cycle_analytics_controller.rb @@ -0,0 +1,67 @@ +class Projects::CycleAnalyticsController < Projects::ApplicationController + include ActionView::Helpers::DateHelper + include ActionView::Helpers::TextHelper + + before_action :authorize_read_cycle_analytics! + + def show + @cycle_analytics = CycleAnalytics.new(@project, from: parse_start_date) + + respond_to do |format| + format.html + format.json { render json: cycle_analytics_json } + end + end + + private + + def parse_start_date + case cycle_analytics_params[:start_date] + when '30' then 30.days.ago + when '90' then 90.days.ago + else 90.days.ago + end + end + + def cycle_analytics_params + return {} unless params[:cycle_analytics].present? + + { start_date: params[:cycle_analytics][:start_date] } + end + + def cycle_analytics_json + cycle_analytics_view_data = [[:issue, "Issue", "Time before an issue gets scheduled"], + [:plan, "Plan", "Time before an issue starts implementation"], + [:code, "Code", "Time until first merge request"], + [:test, "Test", "Total test time for all commits/merges"], + [:review, "Review", "Time between merge request creation and merge/close"], + [:staging, "Staging", "From merge request merge until deploy to production"], + [:production, "Production", "From issue creation until deploy to production"]] + + stats = cycle_analytics_view_data.reduce([]) do |stats, (stage_method, stage_text, stage_description)| + value = @cycle_analytics.send(stage_method).presence + + stats << { + title: stage_text, + description: stage_description, + value: value && !value.zero? ? distance_of_time_in_words(value) : nil + } + stats + end + + issues = @cycle_analytics.summary.new_issues + commits = @cycle_analytics.summary.commits + deploys = @cycle_analytics.summary.deploys + + summary = [ + { title: "New Issue".pluralize(issues), value: issues }, + { title: "Commit".pluralize(commits), value: commits }, + { title: "Deploy".pluralize(deploys), value: deploys } + ] + + { + summary: summary, + stats: stats + } + end +end diff --git a/app/controllers/projects/git_http_client_controller.rb b/app/controllers/projects/git_http_client_controller.rb index f5ce63fdfed..cbfd3cab3dd 100644 --- a/app/controllers/projects/git_http_client_controller.rb +++ b/app/controllers/projects/git_http_client_controller.rb @@ -4,7 +4,11 @@ class Projects::GitHttpClientController < Projects::ApplicationController include ActionController::HttpAuthentication::Basic include KerberosSpnegoHelper - attr_reader :user + attr_reader :authentication_result + + delegate :actor, :authentication_abilities, to: :authentication_result, allow_nil: true + + alias_method :user, :actor # Git clients will not know what authenticity token to send along skip_before_action :verify_authenticity_token @@ -15,32 +19,25 @@ class Projects::GitHttpClientController < Projects::ApplicationController private def authenticate_user + @authentication_result = Gitlab::Auth::Result.new + if project && project.public? && download_request? return # Allow access end if allow_basic_auth? && basic_auth_provided? login, password = user_name_and_password(request) - auth_result = Gitlab::Auth.find_for_git_client(login, password, project: project, ip: request.ip) - - if auth_result.type == :ci && download_request? - @ci = true - elsif auth_result.type == :oauth && !download_request? - # Not allowed - elsif auth_result.type == :missing_personal_token - render_missing_personal_token - return # Render above denied access, nothing left to do - else - @user = auth_result.user - end - if ci? || user + if handle_basic_authentication(login, password) return # Allow access end elsif allow_kerberos_spnego_auth? && spnego_provided? - @user = find_kerberos_user + user = find_kerberos_user if user + @authentication_result = Gitlab::Auth::Result.new( + user, nil, :kerberos, Gitlab::Auth.full_authentication_abilities) + send_final_spnego_response return # Allow access end @@ -48,6 +45,8 @@ class Projects::GitHttpClientController < Projects::ApplicationController send_challenges render plain: "HTTP Basic: Access denied\n", status: 401 + rescue Gitlab::Auth::MissingPersonalTokenError + render_missing_personal_token end def basic_auth_provided? @@ -114,8 +113,41 @@ class Projects::GitHttpClientController < Projects::ApplicationController render plain: 'Not Found', status: :not_found end + def handle_basic_authentication(login, password) + @authentication_result = Gitlab::Auth.find_for_git_client( + login, password, project: project, ip: request.ip) + + return false unless @authentication_result.success? + + if download_request? + authentication_has_download_access? + else + authentication_has_upload_access? + end + end + def ci? - @ci.present? + authentication_result.ci?(project) + end + + def lfs_deploy_token? + authentication_result.lfs_deploy_token?(project) + end + + def authentication_has_download_access? + has_authentication_ability?(:download_code) || has_authentication_ability?(:build_download_code) + end + + def authentication_has_upload_access? + has_authentication_ability?(:push_code) + end + + def has_authentication_ability?(capability) + (authentication_abilities || []).include?(capability) + end + + def authentication_project + authentication_result.project end def verify_workhorse_api! diff --git a/app/controllers/projects/git_http_controller.rb b/app/controllers/projects/git_http_controller.rb index 9805705c4e3..662d38b10a5 100644 --- a/app/controllers/projects/git_http_controller.rb +++ b/app/controllers/projects/git_http_controller.rb @@ -86,7 +86,7 @@ class Projects::GitHttpController < Projects::GitHttpClientController end def access - @access ||= Gitlab::GitAccess.new(user, project, 'http') + @access ||= Gitlab::GitAccess.new(user, project, 'http', authentication_abilities: authentication_abilities) end def access_check diff --git a/app/controllers/projects/issues_controller.rb b/app/controllers/projects/issues_controller.rb index de02e28e384..19b8b1576c4 100644 --- a/app/controllers/projects/issues_controller.rb +++ b/app/controllers/projects/issues_controller.rb @@ -23,20 +23,13 @@ class Projects::IssuesController < Projects::ApplicationController respond_to :html def index - terms = params['issue_search'] @issues = issues_collection - - if terms.present? - if terms =~ /\A#(\d+)\z/ - @issues = @issues.where(iid: $1) - else - @issues = @issues.full_search(terms) - end - end - @issues = @issues.page(params[:page]) + @labels = @project.labels.where(title: params[:label_name]) + @all_issues = all_issues_collection + respond_to do |format| format.html format.atom { render layout: false } diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 0288ee87717..e972376df4c 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -31,22 +31,14 @@ class Projects::MergeRequestsController < Projects::ApplicationController before_action :authorize_can_resolve_conflicts!, only: [:conflicts, :resolve_conflicts] def index - terms = params['issue_search'] @merge_requests = merge_requests_collection - - if terms.present? - if terms =~ /\A[#!](\d+)\z/ - @merge_requests = @merge_requests.where(iid: $1) - else - @merge_requests = @merge_requests.full_search(terms) - end - end - @merge_requests = @merge_requests.page(params[:page]) @merge_requests = @merge_requests.preload(:target_project) @labels = @project.labels.where(title: params[:label_name]) + @all_merge_requests = all_merge_requests_collection + respond_to do |format| format.html format.json do diff --git a/app/controllers/sent_notifications_controller.rb b/app/controllers/sent_notifications_controller.rb index 7271c933b9b..3085ff33aba 100644 --- a/app/controllers/sent_notifications_controller.rb +++ b/app/controllers/sent_notifications_controller.rb @@ -3,12 +3,19 @@ class SentNotificationsController < ApplicationController def unsubscribe @sent_notification = SentNotification.for(params[:id]) + return render_404 unless @sent_notification && @sent_notification.unsubscribable? + return unsubscribe_and_redirect if current_user || params[:force] + end + private + + def unsubscribe_and_redirect noteable = @sent_notification.noteable noteable.unsubscribe(@sent_notification.recipient) flash[:notice] = "You have been unsubscribed from this thread." + if current_user case noteable when Issue |