##// END OF EJS Templates
r18551@gaspard (orig r1815): jplang | 2008-09-13 18:45:01 +0200...
Nicolas Chuche -
r1842:3810bac939d6
parent child
Show More
@@ -0,0 +1,13
1 class AddWiewWikiEditsPermission < ActiveRecord::Migration
2 def self.up
3 Role.find(:all).each do |r|
4 r.add_permission!(:view_wiki_edits) if r.has_permission?(:view_wiki_pages)
5 end
6 end
7
8 def self.down
9 Role.find(:all).each do |r|
10 r.remove_permission!(:view_wiki_edits)
11 end
12 end
13 end
@@ -1,203 +1,208
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require 'diff'
19 19
20 20 class WikiController < ApplicationController
21 21 before_filter :find_wiki, :authorize
22 22
23 23 verify :method => :post, :only => [:destroy, :destroy_attachment, :protect], :redirect_to => { :action => :index }
24 24
25 25 helper :attachments
26 26 include AttachmentsHelper
27 27
28 28 # display a page (in editing mode if it doesn't exist)
29 29 def index
30 30 page_title = params[:page]
31 31 @page = @wiki.find_or_new_page(page_title)
32 32 if @page.new_record?
33 33 if User.current.allowed_to?(:edit_wiki_pages, @project)
34 34 edit
35 35 render :action => 'edit'
36 36 else
37 37 render_404
38 38 end
39 39 return
40 40 end
41 if params[:version] && !User.current.allowed_to?(:view_wiki_edits, @project)
42 # Redirects user to the current version if he's not allowed to view previous versions
43 redirect_to :version => nil
44 return
45 end
41 46 @content = @page.content_for_version(params[:version])
42 47 if params[:export] == 'html'
43 48 export = render_to_string :action => 'export', :layout => false
44 49 send_data(export, :type => 'text/html', :filename => "#{@page.title}.html")
45 50 return
46 51 elsif params[:export] == 'txt'
47 52 send_data(@content.text, :type => 'text/plain', :filename => "#{@page.title}.txt")
48 53 return
49 54 end
50 55 @editable = editable?
51 56 render :action => 'show'
52 57 end
53 58
54 59 # edit an existing page or a new one
55 60 def edit
56 61 @page = @wiki.find_or_new_page(params[:page])
57 62 return render_403 unless editable?
58 63 @page.content = WikiContent.new(:page => @page) if @page.new_record?
59 64
60 65 @content = @page.content_for_version(params[:version])
61 66 @content.text = "h1. #{@page.pretty_title}" if @content.text.blank?
62 67 # don't keep previous comment
63 68 @content.comments = nil
64 69 if request.post?
65 70 if !@page.new_record? && @content.text == params[:content][:text]
66 71 # don't save if text wasn't changed
67 72 redirect_to :action => 'index', :id => @project, :page => @page.title
68 73 return
69 74 end
70 75 #@content.text = params[:content][:text]
71 76 #@content.comments = params[:content][:comments]
72 77 @content.attributes = params[:content]
73 78 @content.author = User.current
74 79 # if page is new @page.save will also save content, but not if page isn't a new record
75 80 if (@page.new_record? ? @page.save : @content.save)
76 81 redirect_to :action => 'index', :id => @project, :page => @page.title
77 82 end
78 83 end
79 84 rescue ActiveRecord::StaleObjectError
80 85 # Optimistic locking exception
81 86 flash[:error] = l(:notice_locking_conflict)
82 87 end
83 88
84 89 # rename a page
85 90 def rename
86 91 @page = @wiki.find_page(params[:page])
87 92 return render_403 unless editable?
88 93 @page.redirect_existing_links = true
89 94 # used to display the *original* title if some AR validation errors occur
90 95 @original_title = @page.pretty_title
91 96 if request.post? && @page.update_attributes(params[:wiki_page])
92 97 flash[:notice] = l(:notice_successful_update)
93 98 redirect_to :action => 'index', :id => @project, :page => @page.title
94 99 end
95 100 end
96 101
97 102 def protect
98 103 page = @wiki.find_page(params[:page])
99 104 page.update_attribute :protected, params[:protected]
100 105 redirect_to :action => 'index', :id => @project, :page => page.title
101 106 end
102 107
103 108 # show page history
104 109 def history
105 110 @page = @wiki.find_page(params[:page])
106 111
107 112 @version_count = @page.content.versions.count
108 113 @version_pages = Paginator.new self, @version_count, per_page_option, params['p']
109 114 # don't load text
110 115 @versions = @page.content.versions.find :all,
111 116 :select => "id, author_id, comments, updated_on, version",
112 117 :order => 'version DESC',
113 118 :limit => @version_pages.items_per_page + 1,
114 119 :offset => @version_pages.current.offset
115 120
116 121 render :layout => false if request.xhr?
117 122 end
118 123
119 124 def diff
120 125 @page = @wiki.find_page(params[:page])
121 126 @diff = @page.diff(params[:version], params[:version_from])
122 127 render_404 unless @diff
123 128 end
124 129
125 130 def annotate
126 131 @page = @wiki.find_page(params[:page])
127 132 @annotate = @page.annotate(params[:version])
128 133 end
129 134
130 135 # remove a wiki page and its history
131 136 def destroy
132 137 @page = @wiki.find_page(params[:page])
133 138 return render_403 unless editable?
134 139 @page.destroy if @page
135 140 redirect_to :action => 'special', :id => @project, :page => 'Page_index'
136 141 end
137 142
138 143 # display special pages
139 144 def special
140 145 page_title = params[:page].downcase
141 146 case page_title
142 147 # show pages index, sorted by title
143 148 when 'page_index', 'date_index'
144 149 # eager load information about last updates, without loading text
145 150 @pages = @wiki.pages.find :all, :select => "#{WikiPage.table_name}.*, #{WikiContent.table_name}.updated_on",
146 151 :joins => "LEFT JOIN #{WikiContent.table_name} ON #{WikiContent.table_name}.page_id = #{WikiPage.table_name}.id",
147 152 :order => 'title'
148 153 @pages_by_date = @pages.group_by {|p| p.updated_on.to_date}
149 154 @pages_by_parent_id = @pages.group_by(&:parent_id)
150 155 # export wiki to a single html file
151 156 when 'export'
152 157 @pages = @wiki.pages.find :all, :order => 'title'
153 158 export = render_to_string :action => 'export_multiple', :layout => false
154 159 send_data(export, :type => 'text/html', :filename => "wiki.html")
155 160 return
156 161 else
157 162 # requested special page doesn't exist, redirect to default page
158 163 redirect_to :action => 'index', :id => @project, :page => nil and return
159 164 end
160 165 render :action => "special_#{page_title}"
161 166 end
162 167
163 168 def preview
164 169 page = @wiki.find_page(params[:page])
165 170 # page is nil when previewing a new page
166 171 return render_403 unless page.nil? || editable?(page)
167 172 if page
168 173 @attachements = page.attachments
169 174 @previewed = page.content
170 175 end
171 176 @text = params[:content][:text]
172 177 render :partial => 'common/preview'
173 178 end
174 179
175 180 def add_attachment
176 181 @page = @wiki.find_page(params[:page])
177 182 return render_403 unless editable?
178 183 attach_files(@page, params[:attachments])
179 184 redirect_to :action => 'index', :page => @page.title
180 185 end
181 186
182 187 def destroy_attachment
183 188 @page = @wiki.find_page(params[:page])
184 189 return render_403 unless editable?
185 190 @page.attachments.find(params[:attachment_id]).destroy
186 191 redirect_to :action => 'index', :page => @page.title
187 192 end
188 193
189 194 private
190 195
191 196 def find_wiki
192 197 @project = Project.find(params[:id])
193 198 @wiki = @project.wiki
194 199 render_404 unless @wiki
195 200 rescue ActiveRecord::RecordNotFound
196 201 render_404
197 202 end
198 203
199 204 # Returns true if the current user is allowed to edit the page, otherwise false
200 205 def editable?(page = @page)
201 206 page.editable_by?(User.current)
202 207 end
203 208 end
@@ -1,142 +1,147
1 1 # redMine - project management software
2 2 # Copyright (C) 2006 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 class Role < ActiveRecord::Base
19 19 # Built-in roles
20 20 BUILTIN_NON_MEMBER = 1
21 21 BUILTIN_ANONYMOUS = 2
22 22
23 23 named_scope :builtin, lambda { |*args|
24 24 compare = 'not' if args.first == true
25 25 { :conditions => "#{compare} builtin = 0" }
26 26 }
27 27
28 28 before_destroy :check_deletable
29 29 has_many :workflows, :dependent => :delete_all do
30 30 def copy(role)
31 31 raise "Can not copy workflow from a #{role.class}" unless role.is_a?(Role)
32 32 raise "Can not copy workflow from/to an unsaved role" if proxy_owner.new_record? || role.new_record?
33 33 clear
34 34 connection.insert "INSERT INTO workflows (tracker_id, old_status_id, new_status_id, role_id)" +
35 35 " SELECT tracker_id, old_status_id, new_status_id, #{proxy_owner.id}" +
36 36 " FROM workflows" +
37 37 " WHERE role_id = #{role.id}"
38 38 end
39 39 end
40 40
41 41 has_many :members
42 42 acts_as_list
43 43
44 44 serialize :permissions, Array
45 45 attr_protected :builtin
46 46
47 47 validates_presence_of :name
48 48 validates_uniqueness_of :name
49 49 validates_length_of :name, :maximum => 30
50 50 validates_format_of :name, :with => /^[\w\s\'\-]*$/i
51 51
52 52 def permissions
53 53 read_attribute(:permissions) || []
54 54 end
55 55
56 56 def permissions=(perms)
57 57 perms = perms.collect {|p| p.to_sym unless p.blank? }.compact.uniq if perms
58 58 write_attribute(:permissions, perms)
59 59 end
60 60
61 61 def add_permission!(*perms)
62 62 self.permissions = [] unless permissions.is_a?(Array)
63 63
64 64 permissions_will_change!
65 65 perms.each do |p|
66 66 p = p.to_sym
67 67 permissions << p unless permissions.include?(p)
68 68 end
69 69 save!
70 70 end
71 71
72 72 def remove_permission!(*perms)
73 73 return unless permissions.is_a?(Array)
74 74 permissions_will_change!
75 75 perms.each { |p| permissions.delete(p.to_sym) }
76 76 save!
77 77 end
78 78
79 # Returns true if the role has the given permission
80 def has_permission?(perm)
81 !permissions.nil? && permissions.include?(perm.to_sym)
82 end
83
79 84 def <=>(role)
80 85 position <=> role.position
81 86 end
82 87
83 88 # Return true if the role is a builtin role
84 89 def builtin?
85 90 self.builtin != 0
86 91 end
87 92
88 93 # Return true if the role is a project member role
89 94 def member?
90 95 !self.builtin?
91 96 end
92 97
93 98 # Return true if role is allowed to do the specified action
94 99 # action can be:
95 100 # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit')
96 101 # * a permission Symbol (eg. :edit_project)
97 102 def allowed_to?(action)
98 103 if action.is_a? Hash
99 104 allowed_actions.include? "#{action[:controller]}/#{action[:action]}"
100 105 else
101 106 allowed_permissions.include? action
102 107 end
103 108 end
104 109
105 110 # Return all the permissions that can be given to the role
106 111 def setable_permissions
107 112 setable_permissions = Redmine::AccessControl.permissions - Redmine::AccessControl.public_permissions
108 113 setable_permissions -= Redmine::AccessControl.members_only_permissions if self.builtin == BUILTIN_NON_MEMBER
109 114 setable_permissions -= Redmine::AccessControl.loggedin_only_permissions if self.builtin == BUILTIN_ANONYMOUS
110 115 setable_permissions
111 116 end
112 117
113 118 # Find all the roles that can be given to a project member
114 119 def self.find_all_givable
115 120 find(:all, :conditions => {:builtin => 0}, :order => 'position')
116 121 end
117 122
118 123 # Return the builtin 'non member' role
119 124 def self.non_member
120 125 find(:first, :conditions => {:builtin => BUILTIN_NON_MEMBER}) || raise('Missing non-member builtin role.')
121 126 end
122 127
123 128 # Return the builtin 'anonymous' role
124 129 def self.anonymous
125 130 find(:first, :conditions => {:builtin => BUILTIN_ANONYMOUS}) || raise('Missing anonymous builtin role.')
126 131 end
127 132
128 133
129 134 private
130 135 def allowed_permissions
131 136 @allowed_permissions ||= permissions + Redmine::AccessControl.public_permissions.collect {|p| p.name}
132 137 end
133 138
134 139 def allowed_actions
135 140 @actions_allowed ||= allowed_permissions.inject([]) { |actions, permission| actions += Redmine::AccessControl.allowed_actions(permission) }.flatten
136 141 end
137 142
138 143 def check_deletable
139 144 raise "Can't delete role" if members.any?
140 145 raise "Can't delete builtin role" if builtin?
141 146 end
142 147 end
@@ -1,89 +1,89
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2007 Jean-Philippe Lang
3 3 #
4 4 # This program is free software; you can redistribute it and/or
5 5 # modify it under the terms of the GNU General Public License
6 6 # as published by the Free Software Foundation; either version 2
7 7 # of the License, or (at your option) any later version.
8 8 #
9 9 # This program is distributed in the hope that it will be useful,
10 10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 12 # GNU General Public License for more details.
13 13 #
14 14 # You should have received a copy of the GNU General Public License
15 15 # along with this program; if not, write to the Free Software
16 16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 17
18 18 require 'zlib'
19 19
20 20 class WikiContent < ActiveRecord::Base
21 21 set_locking_column :version
22 22 belongs_to :page, :class_name => 'WikiPage', :foreign_key => 'page_id'
23 23 belongs_to :author, :class_name => 'User', :foreign_key => 'author_id'
24 24 validates_presence_of :text
25 25
26 26 acts_as_versioned
27 27 class Version
28 28 belongs_to :page, :class_name => '::WikiPage', :foreign_key => 'page_id'
29 29 belongs_to :author, :class_name => '::User', :foreign_key => 'author_id'
30 30 attr_protected :data
31 31
32 32 acts_as_event :title => Proc.new {|o| "#{l(:label_wiki_edit)}: #{o.page.title} (##{o.version})"},
33 33 :description => :comments,
34 34 :datetime => :updated_on,
35 35 :type => 'wiki-page',
36 36 :url => Proc.new {|o| {:controller => 'wiki', :id => o.page.wiki.project_id, :page => o.page.title, :version => o.version}}
37 37
38 acts_as_activity_provider :type => 'wiki_pages',
38 acts_as_activity_provider :type => 'wiki_edits',
39 39 :timestamp => "#{WikiContent.versioned_table_name}.updated_on",
40 :permission => :view_wiki_pages,
40 :permission => :view_wiki_edits,
41 41 :find_options => {:select => "#{WikiContent.versioned_table_name}.updated_on, #{WikiContent.versioned_table_name}.comments, " +
42 42 "#{WikiContent.versioned_table_name}.#{WikiContent.version_column}, #{WikiPage.table_name}.title, " +
43 43 "#{WikiContent.versioned_table_name}.page_id, #{WikiContent.versioned_table_name}.author_id, " +
44 44 "#{WikiContent.versioned_table_name}.id",
45 45 :joins => "LEFT JOIN #{WikiPage.table_name} ON #{WikiPage.table_name}.id = #{WikiContent.versioned_table_name}.page_id " +
46 46 "LEFT JOIN #{Wiki.table_name} ON #{Wiki.table_name}.id = #{WikiPage.table_name}.wiki_id " +
47 47 "LEFT JOIN #{Project.table_name} ON #{Project.table_name}.id = #{Wiki.table_name}.project_id"}
48 48
49 49 def text=(plain)
50 50 case Setting.wiki_compression
51 51 when 'gzip'
52 52 begin
53 53 self.data = Zlib::Deflate.deflate(plain, Zlib::BEST_COMPRESSION)
54 54 self.compression = 'gzip'
55 55 rescue
56 56 self.data = plain
57 57 self.compression = ''
58 58 end
59 59 else
60 60 self.data = plain
61 61 self.compression = ''
62 62 end
63 63 plain
64 64 end
65 65
66 66 def text
67 67 @text ||= case compression
68 68 when 'gzip'
69 69 Zlib::Inflate.inflate(data)
70 70 else
71 71 # uncompressed data
72 72 data
73 73 end
74 74 end
75 75
76 76 def project
77 77 page.project
78 78 end
79 79
80 80 # Returns the previous version or nil
81 81 def previous
82 82 @previous ||= WikiContent::Version.find(:first,
83 83 :order => 'version DESC',
84 84 :include => :author,
85 85 :conditions => ["wiki_content_id = ? AND version < ?", wiki_content_id, version])
86 86 end
87 87 end
88 88
89 89 end
@@ -1,59 +1,59
1 1 <div class="contextual">
2 2 <% if @editable %>
3 3 <%= link_to_if_authorized(l(:button_edit), {:action => 'edit', :page => @page.title}, :class => 'icon icon-edit', :accesskey => accesskey(:edit)) if @content.version == @page.content.version %>
4 4 <%= link_to_if_authorized(l(:button_lock), {:action => 'protect', :page => @page.title, :protected => 1}, :method => :post, :class => 'icon icon-lock') if !@page.protected? %>
5 5 <%= link_to_if_authorized(l(:button_unlock), {:action => 'protect', :page => @page.title, :protected => 0}, :method => :post, :class => 'icon icon-unlock') if @page.protected? %>
6 6 <%= link_to_if_authorized(l(:button_rename), {:action => 'rename', :page => @page.title}, :class => 'icon icon-move') if @content.version == @page.content.version %>
7 7 <%= link_to_if_authorized(l(:button_delete), {:action => 'destroy', :page => @page.title}, :method => :post, :confirm => l(:text_are_you_sure), :class => 'icon icon-del') %>
8 8 <%= link_to_if_authorized(l(:button_rollback), {:action => 'edit', :page => @page.title, :version => @content.version }, :class => 'icon icon-cancel') if @content.version < @page.content.version %>
9 9 <% end %>
10 <%= link_to(l(:label_history), {:action => 'history', :page => @page.title}, :class => 'icon icon-history') %>
10 <%= link_to_if_authorized(l(:label_history), {:action => 'history', :page => @page.title}, :class => 'icon icon-history') %>
11 11 </div>
12 12
13 13 <%= breadcrumb(@page.ancestors.reverse.collect {|parent| link_to h(parent.pretty_title), {:page => parent.title}}) %>
14 14
15 15 <% if @content.version != @page.content.version %>
16 16 <p>
17 17 <%= link_to(('&#171; ' + l(:label_previous)), :action => 'index', :page => @page.title, :version => (@content.version - 1)) + " - " if @content.version > 1 %>
18 18 <%= "#{l(:label_version)} #{@content.version}/#{@page.content.version}" %>
19 19 <%= '(' + link_to('diff', :controller => 'wiki', :action => 'diff', :page => @page.title, :version => @content.version) + ')' if @content.version > 1 %> -
20 20 <%= link_to((l(:label_next) + ' &#187;'), :action => 'index', :page => @page.title, :version => (@content.version + 1)) + " - " if @content.version < @page.content.version %>
21 21 <%= link_to(l(:label_current_version), :action => 'index', :page => @page.title) %>
22 22 <br />
23 23 <em><%= @content.author ? @content.author.name : "anonyme" %>, <%= format_time(@content.updated_on) %> </em><br />
24 24 <%=h @content.comments %>
25 25 </p>
26 26 <hr />
27 27 <% end %>
28 28
29 29 <%= render(:partial => "wiki/content", :locals => {:content => @content}) %>
30 30
31 31 <%= link_to_attachments @page.attachments, :delete_url => ((@editable && authorize_for('wiki', 'destroy_attachment')) ? {:controller => 'wiki', :action => 'destroy_attachment', :page => @page.title} : nil) %>
32 32
33 33 <% if @editable && authorize_for('wiki', 'add_attachment') %>
34 34 <p><%= link_to l(:label_attachment_new), {}, :onclick => "Element.show('add_attachment_form'); Element.hide(this); Element.scrollTo('add_attachment_form'); return false;",
35 35 :id => 'attach_files_link' %></p>
36 36 <% form_tag({ :controller => 'wiki', :action => 'add_attachment', :page => @page.title }, :multipart => true, :id => "add_attachment_form", :style => "display:none;") do %>
37 37 <div class="box">
38 38 <p><%= render :partial => 'attachments/form' %></p>
39 39 </div>
40 40 <%= submit_tag l(:button_add) %>
41 41 <%= link_to l(:button_cancel), {}, :onclick => "Element.hide('add_attachment_form'); Element.show('attach_files_link'); return false;" %>
42 42 <% end %>
43 43 <% end %>
44 44
45 45 <p class="other-formats">
46 46 <%= l(:label_export_to) %>
47 47 <span><%= link_to 'HTML', {:page => @page.title, :export => 'html', :version => @content.version}, :class => 'html' %></span>
48 48 <span><%= link_to 'TXT', {:page => @page.title, :export => 'txt', :version => @content.version}, :class => 'text' %></span>
49 49 </p>
50 50
51 51 <% content_for :header_tags do %>
52 52 <%= stylesheet_link_tag 'scm' %>
53 53 <% end %>
54 54
55 55 <% content_for :sidebar do %>
56 56 <%= render :partial => 'sidebar' %>
57 57 <% end %>
58 58
59 59 <% html_title @page.pretty_title %>
@@ -1,150 +1,151
1 1 require 'redmine/access_control'
2 2 require 'redmine/menu_manager'
3 3 require 'redmine/activity'
4 4 require 'redmine/mime_type'
5 5 require 'redmine/core_ext'
6 6 require 'redmine/themes'
7 7 require 'redmine/hook'
8 8 require 'redmine/plugin'
9 9
10 10 begin
11 11 require_library_or_gem 'RMagick' unless Object.const_defined?(:Magick)
12 12 rescue LoadError
13 13 # RMagick is not available
14 14 end
15 15
16 16 REDMINE_SUPPORTED_SCM = %w( Subversion Darcs Mercurial Cvs Bazaar Git Filesystem )
17 17
18 18 # Permissions
19 19 Redmine::AccessControl.map do |map|
20 20 map.permission :view_project, {:projects => [:show, :activity]}, :public => true
21 21 map.permission :search_project, {:search => :index}, :public => true
22 22 map.permission :edit_project, {:projects => [:settings, :edit]}, :require => :member
23 23 map.permission :select_project_modules, {:projects => :modules}, :require => :member
24 24 map.permission :manage_members, {:projects => :settings, :members => [:new, :edit, :destroy]}, :require => :member
25 25 map.permission :manage_versions, {:projects => [:settings, :add_version], :versions => [:edit, :destroy]}, :require => :member
26 26
27 27 map.project_module :issue_tracking do |map|
28 28 # Issue categories
29 29 map.permission :manage_categories, {:projects => [:settings, :add_issue_category], :issue_categories => [:edit, :destroy]}, :require => :member
30 30 # Issues
31 31 map.permission :view_issues, {:projects => [:changelog, :roadmap],
32 32 :issues => [:index, :changes, :show, :context_menu],
33 33 :versions => [:show, :status_by],
34 34 :queries => :index,
35 35 :reports => :issue_report}, :public => true
36 36 map.permission :add_issues, {:issues => :new}
37 37 map.permission :edit_issues, {:issues => [:edit, :reply, :bulk_edit, :destroy_attachment]}
38 38 map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]}
39 39 map.permission :add_issue_notes, {:issues => [:edit, :reply]}
40 40 map.permission :edit_issue_notes, {:journals => :edit}, :require => :loggedin
41 41 map.permission :edit_own_issue_notes, {:journals => :edit}, :require => :loggedin
42 42 map.permission :move_issues, {:issues => :move}, :require => :loggedin
43 43 map.permission :delete_issues, {:issues => :destroy}, :require => :member
44 44 # Queries
45 45 map.permission :manage_public_queries, {:queries => [:new, :edit, :destroy]}, :require => :member
46 46 map.permission :save_queries, {:queries => [:new, :edit, :destroy]}, :require => :loggedin
47 47 # Gantt & calendar
48 48 map.permission :view_gantt, :issues => :gantt
49 49 map.permission :view_calendar, :issues => :calendar
50 50 # Watchers
51 51 map.permission :view_issue_watchers, {}
52 52 map.permission :add_issue_watchers, {:watchers => :new}
53 53 end
54 54
55 55 map.project_module :time_tracking do |map|
56 56 map.permission :log_time, {:timelog => :edit}, :require => :loggedin
57 57 map.permission :view_time_entries, :timelog => [:details, :report]
58 58 map.permission :edit_time_entries, {:timelog => [:edit, :destroy]}, :require => :member
59 59 map.permission :edit_own_time_entries, {:timelog => [:edit, :destroy]}, :require => :loggedin
60 60 end
61 61
62 62 map.project_module :news do |map|
63 63 map.permission :manage_news, {:news => [:new, :edit, :destroy, :destroy_comment]}, :require => :member
64 64 map.permission :view_news, {:news => [:index, :show]}, :public => true
65 65 map.permission :comment_news, {:news => :add_comment}
66 66 end
67 67
68 68 map.project_module :documents do |map|
69 69 map.permission :manage_documents, {:documents => [:new, :edit, :destroy, :add_attachment, :destroy_attachment]}, :require => :loggedin
70 70 map.permission :view_documents, :documents => [:index, :show, :download]
71 71 end
72 72
73 73 map.project_module :files do |map|
74 74 map.permission :manage_files, {:projects => :add_file, :versions => :destroy_file}, :require => :loggedin
75 75 map.permission :view_files, :projects => :list_files, :versions => :download
76 76 end
77 77
78 78 map.project_module :wiki do |map|
79 79 map.permission :manage_wiki, {:wikis => [:edit, :destroy]}, :require => :member
80 80 map.permission :rename_wiki_pages, {:wiki => :rename}, :require => :member
81 81 map.permission :delete_wiki_pages, {:wiki => :destroy}, :require => :member
82 map.permission :view_wiki_pages, :wiki => [:index, :history, :diff, :annotate, :special]
82 map.permission :view_wiki_pages, :wiki => [:index, :special]
83 map.permission :view_wiki_edits, :wiki => [:history, :diff, :annotate]
83 84 map.permission :edit_wiki_pages, :wiki => [:edit, :preview, :add_attachment, :destroy_attachment]
84 85 map.permission :protect_wiki_pages, {:wiki => :protect}, :require => :member
85 86 end
86 87
87 88 map.project_module :repository do |map|
88 89 map.permission :manage_repository, {:repositories => [:edit, :destroy]}, :require => :member
89 90 map.permission :browse_repository, :repositories => [:show, :browse, :entry, :annotate, :changes, :diff, :stats, :graph]
90 91 map.permission :view_changesets, :repositories => [:show, :revisions, :revision]
91 92 map.permission :commit_access, {}
92 93 end
93 94
94 95 map.project_module :boards do |map|
95 96 map.permission :manage_boards, {:boards => [:new, :edit, :destroy]}, :require => :member
96 97 map.permission :view_messages, {:boards => [:index, :show], :messages => [:show]}, :public => true
97 98 map.permission :add_messages, {:messages => [:new, :reply, :quote]}
98 99 map.permission :edit_messages, {:messages => :edit}, :require => :member
99 100 map.permission :delete_messages, {:messages => :destroy}, :require => :member
100 101 end
101 102 end
102 103
103 104 Redmine::MenuManager.map :top_menu do |menu|
104 105 menu.push :home, :home_path, :html => { :class => 'home' }
105 106 menu.push :my_page, { :controller => 'my', :action => 'page' }, :html => { :class => 'mypage' }, :if => Proc.new { User.current.logged? }
106 107 menu.push :projects, { :controller => 'projects', :action => 'index' }, :caption => :label_project_plural, :html => { :class => 'projects' }
107 108 menu.push :administration, { :controller => 'admin', :action => 'index' }, :html => { :class => 'admin' }, :if => Proc.new { User.current.admin? }, :last => true
108 109 menu.push :help, Redmine::Info.help_url, :html => { :class => 'help' }, :last => true
109 110 end
110 111
111 112 Redmine::MenuManager.map :account_menu do |menu|
112 113 menu.push :login, :signin_path, :html => { :class => 'login' }, :if => Proc.new { !User.current.logged? }
113 114 menu.push :register, { :controller => 'account', :action => 'register' }, :html => { :class => 'register' }, :if => Proc.new { !User.current.logged? && Setting.self_registration? }
114 115 menu.push :my_account, { :controller => 'my', :action => 'account' }, :html => { :class => 'myaccount' }, :if => Proc.new { User.current.logged? }
115 116 menu.push :logout, :signout_path, :html => { :class => 'logout' }, :if => Proc.new { User.current.logged? }
116 117 end
117 118
118 119 Redmine::MenuManager.map :application_menu do |menu|
119 120 # Empty
120 121 end
121 122
122 123 Redmine::MenuManager.map :project_menu do |menu|
123 124 menu.push :overview, { :controller => 'projects', :action => 'show' }
124 125 menu.push :activity, { :controller => 'projects', :action => 'activity' }
125 126 menu.push :roadmap, { :controller => 'projects', :action => 'roadmap' },
126 127 :if => Proc.new { |p| p.versions.any? }
127 128 menu.push :issues, { :controller => 'issues', :action => 'index' }, :param => :project_id, :caption => :label_issue_plural
128 129 menu.push :new_issue, { :controller => 'issues', :action => 'new' }, :param => :project_id, :caption => :label_issue_new,
129 130 :html => { :accesskey => Redmine::AccessKeys.key_for(:new_issue) }
130 131 menu.push :news, { :controller => 'news', :action => 'index' }, :param => :project_id, :caption => :label_news_plural
131 132 menu.push :documents, { :controller => 'documents', :action => 'index' }, :param => :project_id, :caption => :label_document_plural
132 133 menu.push :wiki, { :controller => 'wiki', :action => 'index', :page => nil },
133 134 :if => Proc.new { |p| p.wiki && !p.wiki.new_record? }
134 135 menu.push :boards, { :controller => 'boards', :action => 'index', :id => nil }, :param => :project_id,
135 136 :if => Proc.new { |p| p.boards.any? }, :caption => :label_board_plural
136 137 menu.push :files, { :controller => 'projects', :action => 'list_files' }, :caption => :label_attachment_plural
137 138 menu.push :repository, { :controller => 'repositories', :action => 'show' },
138 139 :if => Proc.new { |p| p.repository && !p.repository.new_record? }
139 140 menu.push :settings, { :controller => 'projects', :action => 'settings' }, :last => true
140 141 end
141 142
142 143 Redmine::Activity.map do |activity|
143 144 activity.register :issues, :class_name => %w(Issue Journal)
144 145 activity.register :changesets
145 146 activity.register :news
146 147 activity.register :documents, :class_name => %w(Document Attachment)
147 148 activity.register :files, :class_name => 'Attachment'
148 activity.register :wiki_pages, :class_name => 'WikiContent::Version', :default => false
149 activity.register :wiki_edits, :class_name => 'WikiContent::Version', :default => false
149 150 activity.register :messages, :default => false
150 151 end
@@ -1,167 +1,172
1 1 ---
2 2 roles_001:
3 3 name: Manager
4 4 id: 1
5 5 builtin: 0
6 6 permissions: |
7 7 ---
8 8 - :edit_project
9 9 - :manage_members
10 10 - :manage_versions
11 11 - :manage_categories
12 12 - :add_issues
13 13 - :edit_issues
14 14 - :manage_issue_relations
15 15 - :add_issue_notes
16 16 - :move_issues
17 17 - :delete_issues
18 18 - :view_issue_watchers
19 19 - :add_issue_watchers
20 20 - :manage_public_queries
21 21 - :save_queries
22 22 - :view_gantt
23 23 - :view_calendar
24 24 - :log_time
25 25 - :view_time_entries
26 26 - :edit_time_entries
27 27 - :delete_time_entries
28 28 - :manage_news
29 29 - :comment_news
30 30 - :view_documents
31 31 - :manage_documents
32 32 - :view_wiki_pages
33 - :view_wiki_edits
33 34 - :edit_wiki_pages
34 35 - :protect_wiki_pages
35 36 - :delete_wiki_pages
36 37 - :rename_wiki_pages
37 38 - :add_messages
38 39 - :edit_messages
39 40 - :delete_messages
40 41 - :manage_boards
41 42 - :view_files
42 43 - :manage_files
43 44 - :browse_repository
44 45 - :view_changesets
45 46
46 47 position: 1
47 48 roles_002:
48 49 name: Developer
49 50 id: 2
50 51 builtin: 0
51 52 permissions: |
52 53 ---
53 54 - :edit_project
54 55 - :manage_members
55 56 - :manage_versions
56 57 - :manage_categories
57 58 - :add_issues
58 59 - :edit_issues
59 60 - :manage_issue_relations
60 61 - :add_issue_notes
61 62 - :move_issues
62 63 - :delete_issues
63 64 - :view_issue_watchers
64 65 - :save_queries
65 66 - :view_gantt
66 67 - :view_calendar
67 68 - :log_time
68 69 - :view_time_entries
69 70 - :edit_own_time_entries
70 71 - :manage_news
71 72 - :comment_news
72 73 - :view_documents
73 74 - :manage_documents
74 75 - :view_wiki_pages
76 - :view_wiki_edits
75 77 - :edit_wiki_pages
76 78 - :protect_wiki_pages
77 79 - :delete_wiki_pages
78 80 - :add_messages
79 81 - :manage_boards
80 82 - :view_files
81 83 - :manage_files
82 84 - :browse_repository
83 85 - :view_changesets
84 86
85 87 position: 2
86 88 roles_003:
87 89 name: Reporter
88 90 id: 3
89 91 builtin: 0
90 92 permissions: |
91 93 ---
92 94 - :edit_project
93 95 - :manage_members
94 96 - :manage_versions
95 97 - :manage_categories
96 98 - :add_issues
97 99 - :edit_issues
98 100 - :manage_issue_relations
99 101 - :add_issue_notes
100 102 - :move_issues
101 103 - :view_issue_watchers
102 104 - :save_queries
103 105 - :view_gantt
104 106 - :view_calendar
105 107 - :log_time
106 108 - :view_time_entries
107 109 - :manage_news
108 110 - :comment_news
109 111 - :view_documents
110 112 - :manage_documents
111 113 - :view_wiki_pages
114 - :view_wiki_edits
112 115 - :edit_wiki_pages
113 116 - :delete_wiki_pages
114 117 - :add_messages
115 118 - :manage_boards
116 119 - :view_files
117 120 - :manage_files
118 121 - :browse_repository
119 122 - :view_changesets
120 123
121 124 position: 3
122 125 roles_004:
123 126 name: Non member
124 127 id: 4
125 128 builtin: 1
126 129 permissions: |
127 130 ---
128 131 - :add_issues
129 132 - :edit_issues
130 133 - :manage_issue_relations
131 134 - :add_issue_notes
132 135 - :move_issues
133 136 - :save_queries
134 137 - :view_gantt
135 138 - :view_calendar
136 139 - :log_time
137 140 - :view_time_entries
138 141 - :comment_news
139 142 - :view_documents
140 143 - :manage_documents
141 144 - :view_wiki_pages
145 - :view_wiki_edits
142 146 - :edit_wiki_pages
143 147 - :add_messages
144 148 - :view_files
145 149 - :manage_files
146 150 - :browse_repository
147 151 - :view_changesets
148 152
149 153 position: 4
150 154 roles_005:
151 155 name: Anonymous
152 156 id: 5
153 157 builtin: 2
154 158 permissions: |
155 159 ---
156 160 - :add_issue_notes
157 161 - :view_gantt
158 162 - :view_calendar
159 163 - :view_time_entries
160 164 - :view_documents
161 165 - :view_wiki_pages
166 - :view_wiki_edits
162 167 - :view_files
163 168 - :browse_repository
164 169 - :view_changesets
165 170
166 171 position: 5
167 172 No newline at end of file
General Comments 0
You need to be logged in to leave comments. Login now