Project

General

Profile

Feature #1040 » draft-feature-1040-r20825.patch

Mizuki ISHIKAWA, 2021-03-19 02:31

View differences:

app/controllers/wiki_controller.rb
33 33
# TODO: still being worked on
34 34
class WikiController < ApplicationController
35 35
  default_search_scope :wiki_pages
36
  before_action :find_wiki, :authorize
36
  before_action :find_wiki, :authorize_global
37 37
  before_action :find_existing_or_new_page, :only => [:show, :edit]
38 38
  before_action :find_existing_page, :only => [:rename, :protect, :history, :diff, :annotate, :add_attachment, :destroy, :destroy_version]
39 39
  before_action :find_attachments, :only => [:preview]
......
41 41

  
42 42
  helper :attachments
43 43
  include AttachmentsHelper
44
  include WikiHelper
44 45
  helper :watchers
45 46
  include Redmine::Export::PDF
46 47

  
47 48
  # List of pages, sorted alphabetically and by parent (hierarchy)
48 49
  def index
50
    authorize if params[:project_id]
49 51
    load_pages_for_index
50 52

  
51 53
    respond_to do |format|
......
72 74
      @page.title = '' unless editable?
73 75
      @page.validate
74 76
      if @page.errors[:title].blank?
75
        path = project_wiki_page_path(@project, @page.title, :parent => params[:parent])
77
        path = wiki_page_action_path('show', @page, {:parent => params[:parent]})
76 78
        respond_to do |format|
77 79
          format.html {redirect_to path}
78 80
          format.js   {render :js => "window.location = #{path.to_json}"}
......
83 85

  
84 86
  # display a page (in editing mode if it doesn't exist)
85 87
  def show
86
    if params[:version] && !User.current.allowed_to?(:view_wiki_edits, @project)
88
    if params[:version] && !@wiki.allowed_to_permission?(:view_wiki_edits)
87 89
      deny_access
88 90
      return
89 91
    end
90 92
    @content = @page.content_for_version(params[:version])
91 93
    if @content.nil?
92
      if User.current.allowed_to?(:edit_wiki_pages, @project) && editable? && !api_request?
94
      if @wiki.allowed_to_permission?(:view_wiki_edits) && editable? && !api_request?
93 95
        edit
94 96
        render :action => 'edit'
95 97
      else
......
186 188
      respond_to do |format|
187 189
        format.html do
188 190
          anchor = @section ? "section-#{@section}" : nil
189
          redirect_to project_wiki_page_path(@project, @page.title, :anchor => anchor)
191
          redirect_to wiki_page_action_path('show', @page, {:anchor => anchor})
190 192
        end
191 193
        format.api do
192 194
          if was_new_page
193
            render :action => 'show', :status => :created, :location => project_wiki_page_path(@project, @page.title)
195
            render :action => 'show', :status => :created, :location => wiki_page_action_path('show', @page)
194 196
          else
195 197
            render_api_ok
196 198
          end
......
224 226
    @page.safe_attributes = params[:wiki_page]
225 227
    if request.post? && @page.save
226 228
      flash[:notice] = l(:notice_successful_update)
227
      redirect_to project_wiki_page_path(@page.project, @page.title)
229
      redirect_to wiki_page_action_path('show', @page)
228 230
    end
229 231
  end
230 232

  
231 233
  def protect
232 234
    @page.update_attribute :protected, params[:protected]
233
    redirect_to project_wiki_page_path(@project, @page.title)
235
    redirect_to wiki_page_action_path('show', @page)
234 236
  end
235 237

  
236 238
  # show page history
......
300 302

  
301 303
    if content = @page.content.versions.find_by_version(params[:version])
302 304
      content.destroy
303
      redirect_to_referer_or history_project_wiki_page_path(@project, @page.title)
305
      redirect_to_referer_or wiki_page_action_path('history', @page)
304 306
    else
305 307
      render_404
306 308
    end
......
346 348
  private
347 349

  
348 350
  def find_wiki
349
    @project = Project.find(params[:project_id])
350
    @wiki = @project.wiki
351
    if params[:project_id]
352
      @project = Project.find(params[:project_id])
353
      @wiki = @project.wiki
354
    else
355
      @wiki = Wiki.find_by(:project_id => nil)
356
      Wiki.create(:project => nil, :start_page => 'Wiki') if @wiki.nil?
357
    end
351 358
    render_404 unless @wiki
352 359
  rescue ActiveRecord::RecordNotFound
353 360
    render_404
354 361
  end
355 362

  
363
  def global_wiki?
364
    @wiki.project.nil?
365
  end
366

  
356 367
  # Finds the requested page or a new page if it doesn't exist
357 368
  def find_existing_or_new_page
358 369
    @page = @wiki.find_or_new_page(params[:id])
app/helpers/application_helper.rb
209 209
      lambda do |wiki_page|
210 210
        link_to(
211 211
          wiki_page.pretty_title,
212
          project_wiki_page_path(wiki_page.project, wiki_page.title)
212
          url_for({:controller => 'wiki', :action => 'show', project_id: wiki_page.project, id: wiki_page.title})
213 213
        )
214 214
      end
215 215
  }
......
296 296
    end
297 297
  end
298 298

  
299
  def wiki_page_path(page, options={})
300
    url_for({:controller => 'wiki', :action => 'show', :project_id => page.project,
301
             :id => page.title}.merge(options))
302
  end
303

  
304 299
  def thumbnail_tag(attachment)
305 300
    thumbnail_size = Setting.thumbnails_size.to_i
306 301
    link_to(
......
959 954
          next link_to(title.present? ? title.html_safe : h(page), url, :class => 'wiki-page')
960 955
        end
961 956

  
962
        if page =~ /^([^\:]+)\:(.*)$/
957
        if page =~ /^(.*)\:(.*)$/
963 958
          identifier, page = $1, $2
964 959
          link_project = Project.find_by_identifier(identifier) || Project.find_by_name(identifier)
965 960
          title ||= identifier if page.blank?
966 961
        end
967

  
968
        if link_project && link_project.wiki && User.current.allowed_to?(:view_wiki_pages, link_project)
962
        wiki = Wiki.find_by(:project => link_project)
963
        if wiki && wiki.allowed_to_permission?(:view_wiki_pages) &&
964
          (link_project || (wiki.global? && link_project.nil?))
969 965
          # extract anchor
970 966
          anchor = nil
971 967
          if page =~ /^(.+?)\#(.+)$/
......
973 969
          end
974 970
          anchor = sanitize_anchor_name(anchor) if anchor.present?
975 971
          # check if page exists
976
          wiki_page = link_project.wiki.find_page(page)
972
          wiki_page = wiki.find_page(page)
977 973
          url =
978 974
            if anchor.present? && wiki_page.present? &&
979 975
                 (obj.is_a?(WikiContent) || obj.is_a?(WikiContent::Version)) &&
app/helpers/wiki_helper.rb
63 63
  def wiki_page_edit_cancel_path(page)
64 64
    if page.new_record?
65 65
      if parent = page.parent
66
        project_wiki_page_path(parent.project, parent.title)
66
        wiki_page_action_path('show', parent)
67 67
      else
68
        project_wiki_index_path(page.project)
68
        if page.project
69
          project_wiki_index_path(page.project)
70
        else
71
          wiki_index_path
72
        end
69 73
      end
70 74
    else
71
      project_wiki_page_path(page.project, page.title)
75
      wiki_page_action_path('show', page)
72 76
    end
73 77
  end
74 78

  
79
  def wiki_page_action_path(action_name, page=nil, options={})
80
    url_for({:controller => 'wiki', :action => action_name, :project_id => (page.wiki.project if page), :id => (page.title if page)}.merge(options))
81
  end
82

  
75 83
  def wiki_content_update_info(content)
76 84
    l(:label_updated_time_by, :author => link_to_user(content.author), :age => time_tag(content.updated_on)).html_safe
77 85
  end
app/models/wiki.rb
34 34
  safe_attributes 'start_page'
35 35

  
36 36
  def visible?(user=User.current)
37
    !user.nil? && user.allowed_to?(:view_wiki_pages, project)
37
    !user.nil? && user.allowed_to?(:view_wiki_pages, project, global: self.global?)
38 38
  end
39 39

  
40 40
  # Returns the wiki page that acts as the sidebar content
......
85 85
  #   Wiki.find_page("foo:bar")
86 86
  def self.find_page(title, options = {})
87 87
    project = options[:project]
88
    if title.to_s =~ %r{^([^\:]+)\:(.*)$}
88
    if title.to_s =~ %r{^(.*):(.*)$}
89 89
      project_identifier, title = $1, $2
90 90
      project = Project.find_by_identifier(project_identifier) || Project.find_by_name(project_identifier)
91 91
    end
92
    if project && project.wiki
93
      page = project.wiki.find_page(title)
92
    wiki = project_identifier.present? ? (project && project.wiki) : Wiki.find_by(project: nil)
93
    if wiki
94
      page = wiki.find_page(title)
94 95
      if page && page.content
95 96
        page
96 97
      end
......
105 106
    title = (title.slice(0..0).upcase + (title.slice(1..-1) || '')) if title
106 107
    title
107 108
  end
109

  
110
  def global?
111
    self.project.nil?
112
  end
113

  
114
  def allowed_to_permission?(permission, user=User.current)
115
    user.allowed_to?(permission, self.project, :global => self.global?)
116
  end
117

  
118
  def allowed_to_action?(action)
119
    User.current.allowed_to?({:controller => 'wiki', :action => action}, self.project, :global => self.global?)
120
  end
108 121
end
app/models/wiki_page.rb
85 85
  end
86 86

  
87 87
  def visible?(user=User.current)
88
    !user.nil? && user.allowed_to?(:view_wiki_pages, project)
88
    !user.nil? &&
89
      user.allowed_to?(:view_wiki_pages, self.project, global: self.wiki.global?)
90
  end
91

  
92
  def attachments_visible?(user=User.current)
93
    (respond_to?(:visible?) ? visible?(user) : true) &&
94
      user.allowed_to?(self.class.attachable_options[:view_permission], self.project, global: self.wiki.global?)
89 95
  end
90 96

  
91 97
  def title=(value)
......
210 216

  
211 217
  # Returns true if usr is allowed to edit the page, otherwise false
212 218
  def editable_by?(usr)
213
    !protected? || usr.allowed_to?(:protect_wiki_pages, wiki.project)
219
    !protected? || self.wiki.allowed_to_permission?(:protect_wiki_pages)
214 220
  end
215 221

  
216 222
  def attachments_deletable?(usr=User.current)
app/views/wiki/_new_modal.html.erb
1 1
<h3 class="title"><%=l(:label_wiki_page_new)%></h3>
2 2

  
3 3
<%= labelled_form_for :page, @page,
4
            :url => new_project_wiki_page_path(@project),
4
            :url => wiki_page_action_path('new', @page),
5 5
            :method => 'post',
6 6
            :remote => true do |f| %>
7 7

  
app/views/wiki/annotate.html.erb
6 6

  
7 7
<%= wiki_page_breadcrumb(@page) %>
8 8

  
9
<%= title [@page.pretty_title, project_wiki_page_path(@page.project, @page.title, :version => nil)],
10
      [l(:label_history), history_project_wiki_page_path(@page.project, @page.title)],
9
<%= title [@page.pretty_title, wiki_page_action_path('show', @page, {:version => nil})],
10
      [l(:label_history), wiki_page_action_path('history', @page)],
11 11
      "#{l(:label_version)} #{@annotate.content.version}" %>
12 12

  
13 13
<p>
app/views/wiki/date_index.html.erb
1 1
<div class="contextual">
2 2
<% if User.current.allowed_to?(:edit_wiki_pages, @project) %>
3
<%= link_to l(:label_wiki_page_new), new_project_wiki_page_path(@project), :remote => true, :class => 'icon icon-add' %>
3
<%= link_to l(:label_wiki_page_new), wiki_page_action_path('new', @page), :remote => true, :class => 'icon icon-add' %>
4 4
<% end %>
5 5
<%= watcher_link(@wiki, User.current) %>
6 6
<% if User.current.allowed_to?(:manage_wiki, @project) %>
app/views/wiki/diff.html.erb
5 5

  
6 6
<%= wiki_page_breadcrumb(@page) %>
7 7

  
8
<%= title [@page.pretty_title, project_wiki_page_path(@page.project, @page.title, :version => nil)],
9
      [l(:label_history), history_project_wiki_page_path(@page.project, @page.title)],
8
<%= title [@page.pretty_title, wiki_page_action_path('show', @page, {:version => nil})],
9
      [l(:label_history), wiki_page_action_path('history', @page)],
10 10
      "#{l(:label_revision)} #{@diff.content_to.version}" %>
11 11

  
12 12
<p>
app/views/wiki/edit.html.erb
63 63
  <%= submit_tag l(:button_save) %>
64 64
  <%= link_to l(:button_cancel), wiki_page_edit_cancel_path(@page) %>
65 65
 </p>
66
<%= wikitoolbar_for 'content_text', preview_project_wiki_page_path(:project_id => @project, :id => @page.title) %>
66
<%= wikitoolbar_for 'content_text', wiki_page_action_path('preview', @page) %>
67 67
<% end %>
68 68

  
69 69
<% content_for :header_tags do %>
app/views/wiki/history.html.erb
1 1
<%= wiki_page_breadcrumb(@page) %>
2 2

  
3
<%= title [@page.pretty_title, project_wiki_page_path(@page.project, @page.title, :version => nil)], l(:label_history) %>
3
<%= title [@page.pretty_title, wiki_page_action_path('show', @page, {:version => nil})], l(:label_history) %>
4 4

  
5 5
<%= form_tag({:controller => 'wiki', :action => 'diff',
6 6
              :project_id => @page.project, :id => @page.title},
......
31 31
    <td class="comments"><%= ver.comments %></td>
32 32
    <td class="buttons">
33 33
      <%= link_to l(:button_annotate), :action => 'annotate', :id => @page.title, :version => ver.version %>
34
      <%= delete_link wiki_page_path(@page, :version => ver.version) if User.current.allowed_to?(:delete_wiki_pages, @page.project) && @version_count > 1 %>
34
      <%= delete_link wiki_page_action_path('show', @page, {:version => ver.version}) if @page.wiki.allowed_to_permission?(:delete_wiki_pages) && @version_count > 1 %>
35 35
    </td>
36 36
</tr>
37 37
<% line_num += 1 %>
app/views/wiki/index.html.erb
1 1
<div class="contextual">
2 2
<% if User.current.allowed_to?(:edit_wiki_pages, @project) %>
3
<%= link_to l(:label_wiki_page_new), new_project_wiki_page_path(@project), :remote => true, :class => 'icon icon-add' %>
3
<%= link_to l(:label_wiki_page_new), wiki_page_action_path('new'), :remote => true, :class => 'icon icon-add' %>
4 4
<% end %>
5 5
<%= watcher_link(@wiki, User.current) %>
6 6
<% if User.current.allowed_to?(:manage_wiki, @project) %>
app/views/wiki/new.html.erb
1 1
<%= title l(:label_wiki_page_new) %>
2 2

  
3 3
<%= labelled_form_for :page, @page,
4
            :url => new_project_wiki_page_path(@project) do |f| %>
4
            :url => wiki_page_action_path('new', @page) do |f| %>
5 5

  
6 6
  <%= render_error_messages @page.errors.full_messages_for(:title) %>
7 7

  
app/views/wiki/rename.html.erb
30 30
<%= javascript_tag do %>
31 31
$('#wiki_page_wiki_id').change(function() {
32 32
  $.ajax({
33
    url: '<%= rename_project_wiki_page_path(@wiki, :format => 'js') %>',
33
    url: '<%= wiki_page_action_path('rename', @page, {:format => 'js'}) %>',
34 34
    type: 'get',
35 35
    data: { 'wiki_page[wiki_id]': $('#wiki_page_wiki_id').val() }
36 36
  });
app/views/wiki/show.html.erb
2 2

  
3 3
<% if @editable %>
4 4
<% if @content.current_version? %>
5
  <%= link_to_if_authorized(l(:button_edit), {:action => 'edit', :id => @page.title}, :class => 'icon icon-edit', :accesskey => accesskey(:edit)) %>
5
  <%= link_to(l(:button_edit), {:action => 'edit', :id => @page.title}, :class => 'icon icon-edit', :accesskey => accesskey(:edit)) if @page.wiki.allowed_to_action?('edit') %>
6 6
  <%= watcher_link(@page, User.current) %>
7 7
<% end %>
8 8
<% end %>
9 9

  
10 10
  <%= actions_dropdown do %>
11
    <%= link_to_if_authorized(l(:label_history), {:action => 'history', :id => @page.title}, :class => 'icon icon-history') %>
11
    <%= link_to(l(:label_history), {:action => 'history', :id => @page.title}, :class => 'icon icon-history') if @page.wiki.allowed_to_action?('history') %>
12 12

  
13 13
    <% if @editable %>
14 14
    <% if @content.current_version? %>
15
      <%= link_to_if_authorized(l(:button_lock), {:action => 'protect', :id => @page.title, :protected => 1}, :method => :post, :class => 'icon icon-lock') if !@page.protected? %>
16
      <%= link_to_if_authorized(l(:button_unlock), {:action => 'protect', :id => @page.title, :protected => 0}, :method => :post, :class => 'icon icon-unlock') if @page.protected? %>
17
      <%= link_to_if_authorized(l(:button_rename), {:action => 'rename', :id => @page.title}, :class => 'icon icon-move') %>
18
      <%= link_to_if_authorized(l(:button_delete), {:action => 'destroy', :id => @page.title}, :method => :delete, :data => {:confirm => l(:text_are_you_sure)}, :class => 'icon icon-del') %>
15
      <%= link_to(l(:button_lock), {:action => 'protect', :id => @page.title, :protected => 1}, :method => :post, :class => 'icon icon-lock') if !@page.protected? && @page.wiki.allowed_to_action?('protect') %>
16
      <%= link_to(l(:button_unlock), {:action => 'protect', :id => @page.title, :protected => 0}, :method => :post, :class => 'icon icon-unlock') if @page.protected? && @page.wiki.allowed_to_action?('protect') %>
17
      <%= link_to(l(:button_rename), {:action => 'rename', :id => @page.title}, :class => 'icon icon-move') if @page.wiki.allowed_to_action?('rename') %>
18
      <%= link_to(l(:button_delete), {:action => 'destroy', :id => @page.title}, :method => :delete, :data => {:confirm => l(:text_are_you_sure)}, :class => 'icon icon-del') if @page.wiki.allowed_to_action?('destroy') %>
19 19
    <% else %>
20
      <%= link_to_if_authorized(l(:button_rollback), {:action => 'edit', :id => @page.title, :version => @content.version }, :class => 'icon icon-cancel') %>
20
      <%= link_to(l(:button_rollback), {:action => 'edit', :id => @page.title, :version => @content.version }, :class => 'icon icon-cancel') if @page.wiki.allowed_to_action?('edit') %>
21 21
    <% end %>
22 22
    <% end %>
23 23

  
24 24
    <% if User.current.allowed_to?(:edit_wiki_pages, @project) %>
25
      <%= link_to l(:label_wiki_page_new), new_project_wiki_page_path(@project, :parent => @page.title), :remote => true, :class => 'icon icon-add' %>
25
      <%= link_to l(:label_wiki_page_new), wiki_page_action_path('new', @page, {:parent => @page.title}), :remote => true, :class => 'icon icon-add' %>
26 26
    <% end %>
27 27
  <% end %>
28 28
</div>
......
30 30
<%= wiki_page_breadcrumb(@page) %>
31 31

  
32 32
<% unless @content.current_version? %>
33
  <%= title [@page.pretty_title, project_wiki_page_path(@page.project, @page.title, :version => nil)],
34
        [l(:label_history), history_project_wiki_page_path(@page.project, @page.title)],
33
  <%= title [@page.pretty_title, wiki_page_action_path('show', @page, {:version => nil})],
34
        [l(:label_history), wiki_page_action_path('history', @page)],
35 35
        "#{l(:label_revision)} #{@content.version}" %>
36 36

  
37 37
    <p>
config/locales/ja.yml
300 300
  field_attr_firstname: 名の属性
301 301
  field_attr_lastname: 姓の属性
302 302
  field_attr_mail: メールアドレスの属性
303
  field_onthefly: ユーザーが存在しなければ作成
303
  field_onthefly: あわせてユーザーを作成
304 304
  field_start_date: 開始日
305 305
  field_done_ratio: 進捗率
306 306
  field_auth_source: 認証方式
config/routes.rb
206 206
    get 'wiki/:id/:version/annotate', :to => 'wiki#annotate'
207 207
    get 'wiki/:id/:version/diff', :to => 'wiki#diff'
208 208
  end
209
  match 'wiki/index', :controller => 'wiki', :action => 'index', :via => :get
210
  resources :wiki, :except => [:index, :create, :show], :as => 'wiki_page' do
211
    member do
212
      get 'wiki', :as => 'show_wiki_page'
213
      get 'rename'
214
      post 'rename'
215
      get 'history'
216
      get 'diff'
217
      match 'preview', :via => [:post, :put, :patch]
218
      post 'protect'
219
      post 'add_attachment'
220
    end
221
    collection do
222
      get 'export'
223
      get 'date_index'
224
      post 'new'
225
    end
226
  end
227
  match 'wiki', :controller => 'wiki', :action => 'show', :via => :get
228
  get 'wiki/:id/:version', :to => 'wiki#show', :constraints => {:version => /\d+/}
229
  delete 'wiki/:id/:version', :to => 'wiki#destroy_version'
230
  get 'wiki/:id/:version/annotate', :to => 'wiki#annotate'
231
  get 'wiki/:id/:version/diff', :to => 'wiki#diff'
232
  match 'wiki/:id/destroy', :to => 'wikis#destroy', :via => [:get, :post]
209 233

  
210 234
  resources :issues do
211 235
    member do
db/migrate/20200729083854_allow_wiki_project_id_to_be_nil.rb
1
class AllowWikiProjectIdToBeNil < ActiveRecord::Migration[5.2]
2
  def up
3
   change_column_null :wikis, :project_id, true
4
  end
5
  def down
6
    change_column_null :wikis, :project_id, false
7
  end
8
end
lib/redmine.rb
279 279
      end,
280 280
    :caption => :label_news_plural
281 281
  )
282
  menu.push(
283
    :wiki,
284
    {:controller => 'wiki', :action => 'show'},
285
    :if =>
286
      Proc.new do
287
        User.current.allowed_to?(:view_wiki_pages, nil, :global => true)
288
      end,
289
    :caption => :label_wiki
290
  )
282 291
end
283 292

  
284 293
Redmine::MenuManager.map :admin_menu do |menu|
lib/redmine/wiki_formatting/macros.rb
207 207
        else
208 208
          raise t(:error_childpages_macro_no_argument)
209 209
        end
210
        raise t(:error_page_not_found) if page.nil? || !User.current.allowed_to?(:view_wiki_pages, page.wiki.project)
211

  
210
        raise t(:error_page_not_found) if page.nil? || !User.current.allowed_to?(:view_wiki_pages, page.wiki.project, global: page.wiki.global?)
212 211
        pages = page.self_and_descendants(options[:depth]).group_by(&:parent_id)
213 212
        render_page_hierarchy(pages, options[:parent] ? page.parent_id : page.id)
214 213
      end
......
218 217
             "{{include(projectname:Foo)}} -- to include a page of a specific project wiki"
219 218
      macro :include do |obj, args|
220 219
        page = Wiki.find_page(args.first.to_s, :project => @project)
221
        raise t(:error_page_not_found) if page.nil? || !User.current.allowed_to?(:view_wiki_pages, page.wiki.project)
222

  
220
        raise t(:error_page_not_found) if page.nil? || !User.current.allowed_to?(:view_wiki_pages, page.wiki.project, global: page.wiki.global?)
223 221
        @included_wiki_pages ||= []
224 222
        raise t(:error_circular_inclusion) if @included_wiki_pages.include?(page.id)
225 223

  
(2-2/2)