diff options
Diffstat (limited to 'app/controllers')
-rw-r--r-- | app/controllers/autocomplete_controller.rb | 1 | ||||
-rw-r--r-- | app/controllers/concerns/membership_actions.rb | 58 | ||||
-rw-r--r-- | app/controllers/groups/group_members_controller.rb | 29 | ||||
-rw-r--r-- | app/controllers/jwt_controller.rb | 2 | ||||
-rw-r--r-- | app/controllers/profiles/notifications_controller.rb | 23 | ||||
-rw-r--r-- | app/controllers/projects/artifacts_controller.rb | 17 | ||||
-rw-r--r-- | app/controllers/projects/builds_controller.rb | 2 | ||||
-rw-r--r-- | app/controllers/projects/commit_controller.rb | 2 | ||||
-rw-r--r-- | app/controllers/projects/environments_controller.rb | 49 | ||||
-rw-r--r-- | app/controllers/projects/git_http_controller.rb | 2 | ||||
-rw-r--r-- | app/controllers/projects/merge_requests_controller.rb | 17 | ||||
-rw-r--r-- | app/controllers/projects/pipelines_controller.rb | 2 | ||||
-rw-r--r-- | app/controllers/projects/project_members_controller.rb | 36 | ||||
-rw-r--r-- | app/controllers/projects/todos_controller.rb | 31 | ||||
-rw-r--r-- | app/controllers/projects/wikis_controller.rb | 3 | ||||
-rw-r--r-- | app/controllers/sessions_controller.rb | 2 |
16 files changed, 214 insertions, 62 deletions
diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb index 3865b2d61fd..c89678cf2d8 100644 --- a/app/controllers/autocomplete_controller.rb +++ b/app/controllers/autocomplete_controller.rb @@ -35,6 +35,7 @@ class AutocompleteController < ApplicationController project = Project.find_by_id(params[:project_id]) projects = current_user.authorized_projects + projects = projects.search(params[:search]) if params[:search].present? projects = projects.select do |project| current_user.can?(:admin_issue, project) end diff --git a/app/controllers/concerns/membership_actions.rb b/app/controllers/concerns/membership_actions.rb new file mode 100644 index 00000000000..a24273fad0b --- /dev/null +++ b/app/controllers/concerns/membership_actions.rb @@ -0,0 +1,58 @@ +module MembershipActions + extend ActiveSupport::Concern + include MembersHelper + + def request_access + membershipable.request_access(current_user) + + redirect_to polymorphic_path(membershipable), + notice: 'Your request for access has been queued for review.' + end + + def approve_access_request + @member = membershipable.members.request.find(params[:id]) + + return render_403 unless can?(current_user, action_member_permission(:update, @member), @member) + + @member.accept_request + + redirect_to polymorphic_url([membershipable, :members]) + end + + def leave + @member = membershipable.members.find_by(user_id: current_user) + return render_403 unless @member + + source_type = @member.real_source_type.humanize(capitalize: false) + + if can?(current_user, action_member_permission(:destroy, @member), @member) + notice = + if @member.request? + "Your access request to the #{source_type} has been withdrawn." + else + "You left the \"#{@member.source.human_name}\" #{source_type}." + end + @member.destroy + + redirect_to [:dashboard, @member.real_source_type.tableize], notice: notice + else + if cannot_leave? + alert = "You can not leave the \"#{@member.source.human_name}\" #{source_type}." + alert << " Transfer or delete the #{source_type}." + redirect_to polymorphic_url(membershipable), alert: alert + else + render_403 + end + end + end + + protected + + def membershipable + raise NotImplementedError + end + + def cannot_leave? + raise NotImplementedError + end +end diff --git a/app/controllers/groups/group_members_controller.rb b/app/controllers/groups/group_members_controller.rb index 48dbf656e84..d0f2e2949f0 100644 --- a/app/controllers/groups/group_members_controller.rb +++ b/app/controllers/groups/group_members_controller.rb @@ -1,11 +1,13 @@ class Groups::GroupMembersController < Groups::ApplicationController + include MembershipActions + # Authorize - before_action :authorize_admin_group_member!, except: [:index, :leave] + before_action :authorize_admin_group_member!, except: [:index, :leave, :request_access] def index @project = @group.projects.find(params[:project_id]) if params[:project_id] @members = @group.group_members - @members = @members.non_invite unless can?(current_user, :admin_group, @group) + @members = @members.non_pending unless can?(current_user, :admin_group, @group) if params[:search].present? users = @group.users.search(params[:search]).to_a @@ -58,25 +60,16 @@ class Groups::GroupMembersController < Groups::ApplicationController end end - def leave - @group_member = @group.group_members.find_by(user_id: current_user) - - if can?(current_user, :destroy_group_member, @group_member) - @group_member.destroy - - redirect_to(dashboard_groups_path, notice: "You left #{group.name} group.") - else - if @group.last_owner?(current_user) - redirect_to(dashboard_groups_path, alert: "You can not leave #{group.name} group because you're the last owner. Transfer or delete the group.") - else - return render_403 - end - end - end - protected def member_params params.require(:group_member).permit(:access_level, :user_id) end + + # MembershipActions concern + alias_method :membershipable, :group + + def cannot_leave? + @group.last_owner?(current_user) + end end diff --git a/app/controllers/jwt_controller.rb b/app/controllers/jwt_controller.rb index 131a16dad9b..014b9b43ff2 100644 --- a/app/controllers/jwt_controller.rb +++ b/app/controllers/jwt_controller.rb @@ -42,7 +42,7 @@ class JwtController < ApplicationController end def authenticate_user(login, password) - user = Gitlab::Auth.find_in_gitlab_or_ldap(login, password) + user = Gitlab::Auth.find_with_user_password(login, password) Gitlab::Auth.rate_limit!(request.ip, success: user.present?, login: login) user end diff --git a/app/controllers/profiles/notifications_controller.rb b/app/controllers/profiles/notifications_controller.rb index 18ee55c839a..40d1906a53f 100644 --- a/app/controllers/profiles/notifications_controller.rb +++ b/app/controllers/profiles/notifications_controller.rb @@ -1,12 +1,13 @@ class Profiles::NotificationsController < Profiles::ApplicationController def show - @user = current_user - @group_notifications = current_user.notification_settings.for_groups - @project_notifications = current_user.notification_settings.for_projects + @user = current_user + @group_notifications = current_user.notification_settings.for_groups + @project_notifications = current_user.notification_settings.for_projects + @global_notification_setting = current_user.global_notification_setting end def update - if current_user.update_attributes(user_params) + if current_user.update_attributes(user_params) && update_notification_settings flash[:notice] = "Notification settings saved" else flash[:alert] = "Failed to save new settings" @@ -16,6 +17,18 @@ class Profiles::NotificationsController < Profiles::ApplicationController end def user_params - params.require(:user).permit(:notification_email, :notification_level) + params.require(:user).permit(:notification_email) + end + + def global_notification_setting_params + params.require(:global_notification_setting).permit(:level) + end + + private + + def update_notification_settings + return true unless global_notification_setting_params + + current_user.global_notification_setting.update_attributes(global_notification_setting_params) end end diff --git a/app/controllers/projects/artifacts_controller.rb b/app/controllers/projects/artifacts_controller.rb index 832d7deb57d..f11c8321464 100644 --- a/app/controllers/projects/artifacts_controller.rb +++ b/app/controllers/projects/artifacts_controller.rb @@ -1,22 +1,18 @@ class Projects::ArtifactsController < Projects::ApplicationController layout 'project' before_action :authorize_read_build! + before_action :authorize_update_build!, only: [:keep] + before_action :validate_artifacts! def download unless artifacts_file.file_storage? return redirect_to artifacts_file.url end - unless artifacts_file.exists? - return render_404 - end - send_file artifacts_file.path, disposition: 'attachment' end def browse - return render_404 unless build.artifacts? - directory = params[:path] ? "#{params[:path]}/" : '' @entry = build.artifacts_metadata_entry(directory) @@ -34,8 +30,17 @@ class Projects::ArtifactsController < Projects::ApplicationController end end + def keep + build.keep_artifacts! + redirect_to namespace_project_build_path(project.namespace, project, build) + end + private + def validate_artifacts! + render_404 unless build.artifacts? + end + def build @build ||= project.builds.find_by!(id: params[:build_id]) end diff --git a/app/controllers/projects/builds_controller.rb b/app/controllers/projects/builds_controller.rb index 14c82826342..ef3051d7519 100644 --- a/app/controllers/projects/builds_controller.rb +++ b/app/controllers/projects/builds_controller.rb @@ -51,7 +51,7 @@ class Projects::BuildsController < Projects::ApplicationController return render_404 end - build = Ci::Build.retry(@build) + build = Ci::Build.retry(@build, current_user) redirect_to build_path(build) end diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb index 20637fa46fe..6751737d15e 100644 --- a/app/controllers/projects/commit_controller.rb +++ b/app/controllers/projects/commit_controller.rb @@ -46,7 +46,7 @@ class Projects::CommitController < Projects::ApplicationController def retry_builds ci_builds.latest.failed.each do |build| if build.retryable? - Ci::Build.retry(build) + Ci::Build.retry(build, current_user) end end diff --git a/app/controllers/projects/environments_controller.rb b/app/controllers/projects/environments_controller.rb new file mode 100644 index 00000000000..4b433796161 --- /dev/null +++ b/app/controllers/projects/environments_controller.rb @@ -0,0 +1,49 @@ +class Projects::EnvironmentsController < Projects::ApplicationController + layout 'project' + before_action :authorize_read_environment! + before_action :authorize_create_environment!, only: [:new, :create] + before_action :authorize_update_environment!, only: [:destroy] + before_action :environment, only: [:show, :destroy] + + def index + @environments = project.environments + end + + def show + @deployments = environment.deployments.order(id: :desc).page(params[:page]) + end + + def new + @environment = project.environments.new + end + + def create + @environment = project.environments.create(create_params) + + if @environment.persisted? + redirect_to namespace_project_environment_path(project.namespace, project, @environment) + else + render 'new' + end + end + + def destroy + if @environment.destroy + flash[:notice] = 'Environment was successfully removed.' + else + flash[:alert] = 'Failed to remove environment.' + end + + redirect_to namespace_project_environments_path(project.namespace, project) + end + + private + + def create_params + params.require(:environment).permit(:name) + end + + def environment + @environment ||= project.environments.find(params[:id]) + end +end diff --git a/app/controllers/projects/git_http_controller.rb b/app/controllers/projects/git_http_controller.rb index 348d6cf4d96..f907d63258b 100644 --- a/app/controllers/projects/git_http_controller.rb +++ b/app/controllers/projects/git_http_controller.rb @@ -43,7 +43,7 @@ class Projects::GitHttpController < Projects::ApplicationController 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) + auth_result = Gitlab::Auth.find_for_git_client(login, password, project: project, ip: request.ip) if auth_result.type == :ci && upload_pack? @ci = true diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 67e7187c10d..851822d805a 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -204,10 +204,19 @@ class Projects::MergeRequestsController < Projects::ApplicationController @merge_request.update(merge_error: nil) - if params[:merge_when_build_succeeds].present? && @merge_request.pipeline && @merge_request.pipeline.active? - MergeRequests::MergeWhenBuildSucceedsService.new(@project, current_user, merge_params) - .execute(@merge_request) - @status = :merge_when_build_succeeds + if params[:merge_when_build_succeeds].present? + if @merge_request.pipeline && @merge_request.pipeline.active? + MergeRequests::MergeWhenBuildSucceedsService.new(@project, current_user, merge_params) + .execute(@merge_request) + @status = :merge_when_build_succeeds + elsif @merge_request.pipeline.success? + # This can be triggered when a user clicks the auto merge button while + # the tests finish at about the same time + MergeWorker.perform_async(@merge_request.id, current_user.id, params) + @status = :success + else + @status = :failed + end else MergeWorker.perform_async(@merge_request.id, current_user.id, params) @status = :success diff --git a/app/controllers/projects/pipelines_controller.rb b/app/controllers/projects/pipelines_controller.rb index cac440ae53e..127bd1a4318 100644 --- a/app/controllers/projects/pipelines_controller.rb +++ b/app/controllers/projects/pipelines_controller.rb @@ -32,7 +32,7 @@ class Projects::PipelinesController < Projects::ApplicationController end def retry - pipeline.retry_failed + pipeline.retry_failed(current_user) redirect_back_or_default default: namespace_project_pipelines_path(project.namespace, project) end diff --git a/app/controllers/projects/project_members_controller.rb b/app/controllers/projects/project_members_controller.rb index cdea5f0b776..35d067cd029 100644 --- a/app/controllers/projects/project_members_controller.rb +++ b/app/controllers/projects/project_members_controller.rb @@ -1,10 +1,12 @@ class Projects::ProjectMembersController < Projects::ApplicationController + include MembershipActions + # Authorize - before_action :authorize_admin_project_member!, except: [:leave, :index] + before_action :authorize_admin_project_member!, except: [:index, :leave, :request_access] def index @project_members = @project.project_members - @project_members = @project_members.non_invite unless can?(current_user, :admin_project, @project) + @project_members = @project_members.non_pending unless can?(current_user, :admin_project, @project) if params[:search].present? users = @project.users.search(params[:search]).to_a @@ -14,9 +16,10 @@ class Projects::ProjectMembersController < Projects::ApplicationController @project_members = @project_members.order('access_level DESC') @group = @project.group + if @group @group_members = @group.group_members - @group_members = @group_members.non_invite unless can?(current_user, :admin_group, @group) + @group_members = @group_members.non_pending unless can?(current_user, :admin_group, @group) if params[:search].present? users = @group.users.search(params[:search]).to_a @@ -73,26 +76,6 @@ class Projects::ProjectMembersController < Projects::ApplicationController end end - def leave - @project_member = @project.project_members.find_by(user_id: current_user) - - if can?(current_user, :destroy_project_member, @project_member) - @project_member.destroy - - respond_to do |format| - format.html { redirect_to dashboard_projects_path, notice: "You left the project." } - format.js { head :ok } - end - else - if current_user == @project.owner - message = 'You can not leave your own project. Transfer or delete the project.' - redirect_back_or_default(default: { action: 'index' }, options: { alert: message }) - else - render_403 - end - end - end - def apply_import source_project = Project.find(params[:source_project_id]) @@ -112,4 +95,11 @@ class Projects::ProjectMembersController < Projects::ApplicationController def member_params params.require(:project_member).permit(:user_id, :access_level) end + + # MembershipActions concern + alias_method :membershipable, :project + + def cannot_leave? + current_user == @project.owner + end end diff --git a/app/controllers/projects/todos_controller.rb b/app/controllers/projects/todos_controller.rb new file mode 100644 index 00000000000..a51bd5e2b49 --- /dev/null +++ b/app/controllers/projects/todos_controller.rb @@ -0,0 +1,31 @@ +class Projects::TodosController < Projects::ApplicationController + def create + todos = TodoService.new.mark_todo(issuable, current_user) + + render json: { + todo: todos, + count: current_user.todos.pending.count, + } + end + + def update + current_user.todos.find_by_id(params[:id]).update(state: :done) + + render json: { + count: current_user.todos.pending.count, + } + end + + private + + def issuable + @issuable ||= begin + case params[:issuable_type] + when "issue" + @project.issues.find(params[:issuable_id]) + when "merge_request" + @project.merge_requests.find(params[:issuable_id]) + end + end + end +end diff --git a/app/controllers/projects/wikis_controller.rb b/app/controllers/projects/wikis_controller.rb index 2aa6bed0724..7ec1e73b3be 100644 --- a/app/controllers/projects/wikis_controller.rb +++ b/app/controllers/projects/wikis_controller.rb @@ -16,6 +16,9 @@ class Projects::WikisController < Projects::ApplicationController if @page render 'show' elsif file = @project_wiki.find_file(params[:id], params[:version_id]) + response.headers['Content-Security-Policy'] = "default-src 'none'" + response.headers['X-Content-Security-Policy'] = "default-src 'none'" + if file.on_disk? send_file file.on_disk_path, disposition: 'inline' else diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb index dae8f7b1447..17aed816cbd 100644 --- a/app/controllers/sessions_controller.rb +++ b/app/controllers/sessions_controller.rb @@ -40,7 +40,7 @@ class SessionsController < Devise::SessionsController # Handle an "initial setup" state, where there's only one user, it's an admin, # and they require a password change. def check_initial_setup - return unless User.count == 1 + return unless User.limit(2).count == 1 # Count as much 2 to know if we have exactly one user = User.admins.last |