wikis_controller.rb 3.54 KB
Newer Older
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
1 2
require 'project_wiki'

3
class Projects::WikisController < Projects::ApplicationController
4
  before_action :authorize_read_wiki!
5
  before_action :authorize_create_wiki!, only: [:edit, :create, :history]
6 7
  before_action :authorize_admin_wiki!, only: :destroy
  before_action :load_project_wiki
8

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
9
  def pages
10
    @wiki_pages = Kaminari.paginate_array(@project_wiki.pages).page(params[:page])
11
    @wiki_entries = WikiPage.group_by_directory(@wiki_pages)
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
12 13
  end

Valery Sizov's avatar
Valery Sizov committed
14
  def show
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
15
    @page = @project_wiki.find_page(params[:id], params[:version_id])
16

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
17
    if @page
18
      render 'show'
19
    elsif file = @project_wiki.find_file(params[:id], params[:version_id])
20 21 22
      response.headers['Content-Security-Policy'] = "default-src 'none'"
      response.headers['X-Content-Security-Policy'] = "default-src 'none'"

23 24 25 26 27 28 29 30 31 32
      if file.on_disk?
        send_file file.on_disk_path, disposition: 'inline'
      else
        send_data(
          file.raw_data,
          type: file.mime_type,
          disposition: 'inline',
          filename: file.name
        )
      end
33
    else
34
      return render('empty') unless can?(current_user, :create_wiki, @project)
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
35 36
      @page = WikiPage.new(@project_wiki)
      @page.title = params[:id]
37 38

      render 'edit'
Valery Sizov's avatar
Valery Sizov committed
39 40 41 42
    end
  end

  def edit
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
43
    @page = @project_wiki.find_page(params[:id])
44 45 46
  end

  def update
47
    return render('empty') unless can?(current_user, :create_wiki, @project)
48

49 50
    @page = @project_wiki.find_page(params[:id])

51
    if @page = WikiPages::UpdateService.new(@project, current_user, wiki_params).execute(@page)
52 53 54 55
      redirect_to(
        namespace_project_wiki_path(@project.namespace, @project, @page),
        notice: 'Wiki was successfully updated.'
      )
56 57 58
    else
      render 'edit'
    end
59 60 61
  rescue WikiPage::PageChangedError
    @conflict = true
    render 'edit'
Valery Sizov's avatar
Valery Sizov committed
62 63 64
  end

  def create
65
    @page = WikiPages::CreateService.new(@project, current_user, wiki_params).execute
66

67
    if @page.persisted?
Vinnie Okada's avatar
Vinnie Okada committed
68 69 70 71
      redirect_to(
        namespace_project_wiki_path(@project.namespace, @project, @page),
        notice: 'Wiki was successfully updated.'
      )
72 73
    else
      render action: "edit"
Valery Sizov's avatar
Valery Sizov committed
74 75
    end
  end
Valery Sizov's avatar
Valery Sizov committed
76 77

  def history
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
78
    @page = @project_wiki.find_page(params[:id])
79

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
80
    unless @page
Vinnie Okada's avatar
Vinnie Okada committed
81 82 83 84
      redirect_to(
        namespace_project_wiki_path(@project.namespace, @project, :home),
        notice: "Page not found"
      )
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
85
    end
Valery Sizov's avatar
Valery Sizov committed
86
  end
87

Valery Sizov's avatar
Valery Sizov committed
88
  def destroy
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
89
    @page = @project_wiki.find_page(params[:id])
90
    WikiPages::DestroyService.new(@project, current_user).execute(@page)
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
91

Vinnie Okada's avatar
Vinnie Okada committed
92 93 94 95
    redirect_to(
      namespace_project_wiki_path(@project.namespace, @project, :home),
      notice: "Page was successfully deleted"
    )
96
  end
Valery Sizov's avatar
Valery Sizov committed
97

98
  def preview_markdown
99 100
    text = params[:text]

101 102
    ext = Gitlab::ReferenceExtractor.new(@project, current_user)
    ext.analyze(text, author: current_user)
103 104

    render json: {
105
      body: view_context.markdown(text, pipeline: :wiki, project_wiki: @project_wiki, page_slug: params[:id]),
106 107 108 109 110 111
      references: {
        users: ext.users.map(&:username)
      }
    }
  end

112
  def git_access
Valery Sizov's avatar
Valery Sizov committed
113
  end
114 115 116

  private

Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
117 118
  def load_project_wiki
    @project_wiki = ProjectWiki.new(@project, current_user)
119 120

    # Call #wiki to make sure the Wiki Repo is initialized
Dmitriy Zaporozhets's avatar
Dmitriy Zaporozhets committed
121
    @project_wiki.wiki
122

123
    @sidebar_wiki_entries = WikiPage.group_by_directory(@project_wiki.pages.first(15))
124
  rescue ProjectWiki::CouldNotCreateWikiError
125
    flash[:notice] = "Could not create Wiki Repository at this time. Please try again later."
126
    redirect_to project_path(@project)
127 128 129 130
    return false
  end

  def wiki_params
131
    params[:wiki].slice(:title, :content, :format, :message, :last_commit_sha)
132
  end
Valery Sizov's avatar
Valery Sizov committed
133
end