projects_controller.rb 6.24 KB
Newer Older
1
class ProjectsController < Projects::ApplicationController
2 3
  include ExtractsPath

4
  before_action :authenticate_user!, except: [:show, :activity]
5 6
  before_action :project, except: [:new, :create]
  before_action :repository, except: [:new, :create]
7
  before_action :assign_ref_vars, :tree, only: [:show], if: :repo_exists?
gitlabhq's avatar
gitlabhq committed
8 9

  # Authorize
10
  before_action :authorize_admin_project!, only: [:edit, :update, :housekeeping]
11
  before_action :event_filter, only: [:show, :activity]
gitlabhq's avatar
gitlabhq committed
12

13
  layout :determine_layout
Cyril's avatar
Cyril committed
14

15
  def index
16
    redirect_to(current_user ? root_path : explore_root_path)
17 18
  end

gitlabhq's avatar
gitlabhq committed
19 20 21 22 23
  def new
    @project = Project.new
  end

  def edit
24
    render 'edit'
gitlabhq's avatar
gitlabhq committed
25 26 27
  end

  def create
28
    @project = ::Projects::CreateService.new(current_user, project_params).execute
gitlabhq's avatar
gitlabhq committed
29

30
    if @project.saved?
Vinnie Okada's avatar
Vinnie Okada committed
31
      redirect_to(
32
        project_path(@project),
33
        notice: "Project '#{@project.name}' was successfully created."
Vinnie Okada's avatar
Vinnie Okada committed
34
      )
35 36
    else
      render 'new'
gitlabhq's avatar
gitlabhq committed
37 38
    end
  end
gitlabhq's avatar
gitlabhq committed
39

gitlabhq's avatar
gitlabhq committed
40
  def update
41
    status = ::Projects::UpdateService.new(@project, current_user, project_params).execute
42

gitlabhq's avatar
gitlabhq committed
43
    respond_to do |format|
44
      if status
45
        flash[:notice] = "Project '#{@project.name}' was successfully updated."
Vinnie Okada's avatar
Vinnie Okada committed
46 47
        format.html do
          redirect_to(
48
            edit_project_path(@project),
49
            notice: "Project '#{@project.name}' was successfully updated."
Vinnie Okada's avatar
Vinnie Okada committed
50 51
          )
        end
Nihad Abbasov's avatar
Nihad Abbasov committed
52
        format.js
gitlabhq's avatar
gitlabhq committed
53
      else
54
        format.html { render 'edit' }
Nihad Abbasov's avatar
Nihad Abbasov committed
55
        format.js
gitlabhq's avatar
gitlabhq committed
56
      end
gitlabhq's avatar
gitlabhq committed
57
    end
58
  end
59

60
  def transfer
61 62
    return access_denied! unless can?(current_user, :change_namespace, @project)

63 64 65 66 67
    namespace = Namespace.find_by(id: params[:new_namespace_id])
    ::Projects::TransferService.new(project, current_user).execute(namespace)

    if @project.errors[:new_namespace].present?
      flash[:alert] = @project.errors[:new_namespace].first
skv-headless's avatar
skv-headless committed
68
    end
gitlabhq's avatar
gitlabhq committed
69 70
  end

71
  def remove_fork
72 73
    return access_denied! unless can?(current_user, :remove_fork_project, @project)

74
    if ::Projects::UnlinkForkService.new(@project, current_user).execute
Douwe Maan's avatar
Douwe Maan committed
75
      flash[:notice] = 'The fork relationship has been removed.'
76 77 78
    end
  end

79 80 81 82 83 84 85 86 87 88
  def activity
    respond_to do |format|
      format.html
      format.json do
        load_events
        pager_json('events/_events', @events.count)
      end
    end
  end

gitlabhq's avatar
gitlabhq committed
89
  def show
90
    if @project.import_in_progress?
Vinnie Okada's avatar
Vinnie Okada committed
91
      redirect_to namespace_project_import_path(@project.namespace, @project)
92 93 94
      return
    end

95 96 97 98
    if @project.pending_delete?
      flash[:alert] = "Project queued for delete."
    end

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
99
    respond_to do |format|
Nihad Abbasov's avatar
Nihad Abbasov committed
100
      format.html do
101 102
        if @project.repository_exists?
          if @project.empty_repo?
103
            render 'projects/empty'
104
          else
Douwe Maan's avatar
Douwe Maan committed
105
            if current_user
106
              @membership = @project.team.find_member(current_user.id)
107
            end
Douwe Maan's avatar
Douwe Maan committed
108

109
            render :show
110
          end
111
        else
112
          render 'projects/no_repo'
113
        end
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
114
      end
115

116 117 118 119
      format.atom do
        load_events
        render layout: false
      end
120 121 122
    end
  end

gitlabhq's avatar
gitlabhq committed
123
  def destroy
124
    return access_denied! unless can?(current_user, :remove_project, @project)
125

126 127
    ::Projects::DestroyService.new(@project, current_user, {}).pending_delete!
    flash[:alert] = "Project '#{@project.name}' will be deleted."
gitlabhq's avatar
gitlabhq committed
128

129
    redirect_to dashboard_projects_path
130 131
  rescue Projects::DestroyService::DestroyError => ex
    redirect_to edit_project_path(@project), alert: ex.message
gitlabhq's avatar
gitlabhq committed
132
  end
133

134
  def autocomplete_sources
Marin Jankovski's avatar
Marin Jankovski committed
135 136
    note_type = params['type']
    note_id = params['type_id']
137
    autocomplete = ::Projects::AutocompleteService.new(@project, current_user)
Douwe Maan's avatar
Douwe Maan committed
138
    participants = ::Projects::ParticipantsService.new(@project, current_user).execute(note_type, note_id)
139

140
    @suggestions = {
141
      emojis: AwardEmoji.urls,
142 143
      issues: autocomplete.issues,
      mergerequests: autocomplete.merge_requests,
144
      members: participants
145 146 147
    }

    respond_to do |format|
148
      format.json { render json: @suggestions }
149 150
    end
  end
151

152
  def archive
153
    return access_denied! unless can?(current_user, :archive_project, @project)
Douwe Maan's avatar
Douwe Maan committed
154

155
    @project.archive!
156 157

    respond_to do |format|
158
      format.html { redirect_to project_path(@project) }
159 160 161 162
    end
  end

  def unarchive
163
    return access_denied! unless can?(current_user, :archive_project, @project)
Douwe Maan's avatar
Douwe Maan committed
164

165
    @project.unarchive!
166 167

    respond_to do |format|
168
      format.html { redirect_to project_path(@project) }
169 170
    end
  end
171 172

  def housekeeping
173 174 175 176 177 178 179 180 181 182 183
    ::Projects::HousekeepingService.new(@project).execute

    redirect_to(
      project_path(@project),
      notice: "Housekeeping successfully started"
    )
  rescue ::Projects::HousekeepingService::LeaseTaken => ex
    redirect_to(
      edit_project_path(@project),
      alert: ex.to_s
    )
184
  end
185

Ciro Santilli's avatar
Ciro Santilli committed
186 187
  def toggle_star
    current_user.toggle_star(@project)
188
    @project.reload
189 190

    render json: {
191
      star_count: @project.star_count
192
    }
Ciro Santilli's avatar
Ciro Santilli committed
193 194
  end

195
  def markdown_preview
196
    text = params[:text]
197

198
    ext = Gitlab::ReferenceExtractor.new(@project, current_user, current_user)
199 200 201 202 203 204 205 206
    ext.analyze(text)

    render json: {
      body:       view_context.markdown(text),
      references: {
        users: ext.users.map(&:username)
      }
    }
207 208
  end

209 210
  private

211 212 213 214 215 216 217 218
  def determine_layout
    if [:new, :create].include?(action_name.to_sym)
      'application'
    elsif [:edit, :update].include?(action_name.to_sym)
      'project_settings'
    else
      'project'
    end
219
  end
220

221 222 223 224 225 226 227
  def load_events
    @events = @project.events.recent
    @events = event_filter.apply_filter(@events).with_associations
    limit = (params[:limit] || 20).to_i
    @events = @events.limit(limit).offset(params[:offset] || 0)
  end

228 229
  def project_params
    params.require(:project).permit(
Kamil Trzcinski's avatar
Kamil Trzcinski committed
230
      :name, :path, :description, :issues_tracker, :tag_list, :runners_token,
231
      :issues_enabled, :merge_requests_enabled, :snippets_enabled, :issues_tracker_id, :default_branch,
232
      :wiki_enabled, :visibility_level, :import_url, :last_activity_at, :namespace_id, :avatar,
233
      :builds_enabled, :build_allow_git_fetch, :build_timeout_in_minutes, :build_coverage_regex,
234
      :public_builds,
235 236
    )
  end
237

238 239 240 241
  def repo_exists?
    project.repository_exists? && !project.empty_repo?
  end

Marin Jankovski's avatar
Marin Jankovski committed
242
  # Override get_id from ExtractsPath, which returns the branch and file path
Douwe Maan's avatar
Douwe Maan committed
243
  # for the blob/tree, which in this case is just the root of the default branch.
244 245 246
  def get_id
    project.repository.root_ref
  end
gitlabhq's avatar
gitlabhq committed
247
end