##// END OF EJS Templates
Added the following permissions (#527, #585, #627):...
Jean-Philippe Lang -
r1138:1c8cf4ef8338
parent child
Show More
@@ -1,41 +1,41
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2008 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 JournalsController < ApplicationController
19 19 layout 'base'
20 20 before_filter :find_journal
21 21
22 22 def edit
23 23 if request.post?
24 24 @journal.update_attributes(:notes => params[:notes]) if params[:notes]
25 @journal.destroy if @journal.details.empty? && @journal.notes.blank?
25 26 respond_to do |format|
26 27 format.html { redirect_to :controller => 'issues', :action => 'show', :id => @journal.journalized_id }
27 28 format.js { render :action => 'update' }
28 29 end
29 return
30 30 end
31 31 end
32 32
33 33 private
34 34 def find_journal
35 35 @journal = Journal.find(params[:id])
36 36 render_403 and return false unless @journal.editable_by?(User.current)
37 37 @project = @journal.journalized.project
38 38 rescue ActiveRecord::RecordNotFound
39 39 render_404
40 40 end
41 41 end
@@ -1,37 +1,37
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2008 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 module JournalsHelper
19 19 def render_notes(journal, options={})
20 20 content = ''
21 21 editable = journal.editable_by?(User.current)
22 if editable
22 if editable && !journal.notes.blank?
23 23 links = []
24 24 links << link_to_in_place_notes_editor(image_tag('edit.png'), "journal-#{journal.id}-notes",
25 25 { :controller => 'journals', :action => 'edit', :id => journal },
26 26 :title => l(:button_edit))
27 27 content << content_tag('div', links.join(' '), :class => 'contextual')
28 28 end
29 29 content << textilizable(journal, :notes)
30 30 content_tag('div', content, :id => "journal-#{journal.id}-notes", :class => (editable ? 'wiki editable' : 'wiki'))
31 31 end
32 32
33 33 def link_to_in_place_notes_editor(text, field_id, url, options={})
34 34 onclick = "new Ajax.Request('#{url_for(url)}', {asynchronous:true, evalScripts:true, method:'get'}); return false;"
35 35 link_to text, '#', options.merge(:onclick => onclick)
36 36 end
37 37 end
@@ -1,56 +1,57
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 Journal < ActiveRecord::Base
19 19 belongs_to :journalized, :polymorphic => true
20 20 # added as a quick fix to allow eager loading of the polymorphic association
21 21 # since always associated to an issue, for now
22 22 belongs_to :issue, :foreign_key => :journalized_id
23 23
24 24 belongs_to :user
25 25 has_many :details, :class_name => "JournalDetail", :dependent => :delete_all
26 26
27 27 acts_as_searchable :columns => 'notes',
28 28 :include => :issue,
29 29 :project_key => "#{Issue.table_name}.project_id",
30 30 :date_column => "#{Issue.table_name}.created_on"
31 31
32 32 acts_as_event :title => Proc.new {|o| "#{o.issue.tracker.name} ##{o.issue.id}: #{o.issue.subject}" + ((s = o.new_status) ? " (#{s})" : '') },
33 33 :description => :notes,
34 34 :author => :user,
35 35 :url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.issue.id}}
36 36
37 37 def save
38 38 # Do not save an empty journal
39 39 (details.empty? && notes.blank?) ? false : super
40 40 end
41 41
42 42 # Returns the new status if the journal contains a status change, otherwise nil
43 43 def new_status
44 44 c = details.detect {|detail| detail.prop_key == 'status_id'}
45 45 (c && c.value) ? IssueStatus.find_by_id(c.value.to_i) : nil
46 46 end
47 47
48 48 def new_value_for(prop)
49 49 c = details.detect {|detail| detail.prop_key == prop}
50 50 c ? c.value : nil
51 51 end
52 52
53 53 def editable_by?(usr)
54 usr && usr.admin?
54 project = journalized.project
55 usr && usr.logged? && (usr.allowed_to?(:edit_issue_notes, project) || (self.user == usr && usr.allowed_to?(:edit_own_issue_notes, project)))
55 56 end
56 57 end
@@ -1,13 +1,15
1 1 <% note_id = 1 %>
2 2 <% for journal in journals %>
3 <div id="change-<%= journal.id %>">
3 4 <h4><div style="float:right;"><%= link_to "##{note_id}", :anchor => "note-#{note_id}" %></div>
4 5 <%= content_tag('a', '', :name => "note-#{note_id}")%>
5 6 <%= format_time(journal.created_on) %> - <%= journal.user.name %></h4>
6 7 <ul>
7 8 <% for detail in journal.details %>
8 9 <li><%= show_detail(detail) %></li>
9 10 <% end %>
10 11 </ul>
11 12 <%= render_notes(journal) unless journal.notes.blank? %>
13 </div>
12 14 <% note_id += 1 %>
13 15 <% end %>
@@ -1,3 +1,8
1 page.replace "journal-#{@journal.id}-notes", render_notes(@journal)
2 page.show "journal-#{@journal.id}-notes"
3 page.remove "journal-#{@journal.id}-form"
1 if @journal.frozen?
2 # journal was destroyed
3 page.remove "change-#{@journal.id}"
4 else
5 page.replace "journal-#{@journal.id}-notes", render_notes(@journal)
6 page.show "journal-#{@journal.id}-notes"
7 page.remove "journal-#{@journal.id}-form"
8 end
@@ -1,128 +1,130
1 1 require 'redmine/access_control'
2 2 require 'redmine/menu_manager'
3 3 require 'redmine/mime_type'
4 4 require 'redmine/themes'
5 5 require 'redmine/plugin'
6 6
7 7 begin
8 8 require_library_or_gem 'RMagick' unless Object.const_defined?(:Magick)
9 9 rescue LoadError
10 10 # RMagick is not available
11 11 end
12 12
13 13 REDMINE_SUPPORTED_SCM = %w( Subversion Darcs Mercurial Cvs Bazaar )
14 14
15 15 # Permissions
16 16 Redmine::AccessControl.map do |map|
17 17 map.permission :view_project, {:projects => [:show, :activity]}, :public => true
18 18 map.permission :search_project, {:search => :index}, :public => true
19 19 map.permission :edit_project, {:projects => [:settings, :edit]}, :require => :member
20 20 map.permission :select_project_modules, {:projects => :modules}, :require => :member
21 21 map.permission :manage_members, {:projects => :settings, :members => [:new, :edit, :destroy]}, :require => :member
22 22 map.permission :manage_versions, {:projects => [:settings, :add_version], :versions => [:edit, :destroy]}, :require => :member
23 23
24 24 map.project_module :issue_tracking do |map|
25 25 # Issue categories
26 26 map.permission :manage_categories, {:projects => [:settings, :add_issue_category], :issue_categories => [:edit, :destroy]}, :require => :member
27 27 # Issues
28 28 map.permission :view_issues, {:projects => [:changelog, :roadmap],
29 29 :issues => [:index, :changes, :show, :context_menu],
30 30 :versions => [:show, :status_by],
31 31 :queries => :index,
32 32 :reports => :issue_report}, :public => true
33 33 map.permission :add_issues, {:issues => :new}
34 34 map.permission :edit_issues, {:issues => [:edit, :bulk_edit, :destroy_attachment]}
35 35 map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]}
36 36 map.permission :add_issue_notes, {:issues => :edit}
37 map.permission :edit_issue_notes, {:journals => :edit}, :require => :loggedin
38 map.permission :edit_own_issue_notes, {:journals => :edit}, :require => :loggedin
37 39 map.permission :move_issues, {:issues => :move}, :require => :loggedin
38 40 map.permission :delete_issues, {:issues => :destroy}, :require => :member
39 41 # Queries
40 42 map.permission :manage_public_queries, {:queries => [:new, :edit, :destroy]}, :require => :member
41 43 map.permission :save_queries, {:queries => [:new, :edit, :destroy]}, :require => :loggedin
42 44 # Gantt & calendar
43 45 map.permission :view_gantt, :projects => :gantt
44 46 map.permission :view_calendar, :projects => :calendar
45 47 end
46 48
47 49 map.project_module :time_tracking do |map|
48 50 map.permission :log_time, {:timelog => :edit}, :require => :loggedin
49 51 map.permission :view_time_entries, :timelog => [:details, :report]
50 52 end
51 53
52 54 map.project_module :news do |map|
53 55 map.permission :manage_news, {:news => [:new, :edit, :destroy, :destroy_comment]}, :require => :member
54 56 map.permission :view_news, {:news => [:index, :show]}, :public => true
55 57 map.permission :comment_news, {:news => :add_comment}
56 58 end
57 59
58 60 map.project_module :documents do |map|
59 61 map.permission :manage_documents, {:documents => [:new, :edit, :destroy, :add_attachment, :destroy_attachment]}, :require => :loggedin
60 62 map.permission :view_documents, :documents => [:index, :show, :download]
61 63 end
62 64
63 65 map.project_module :files do |map|
64 66 map.permission :manage_files, {:projects => :add_file, :versions => :destroy_file}, :require => :loggedin
65 67 map.permission :view_files, :projects => :list_files, :versions => :download
66 68 end
67 69
68 70 map.project_module :wiki do |map|
69 71 map.permission :manage_wiki, {:wikis => [:edit, :destroy]}, :require => :member
70 72 map.permission :rename_wiki_pages, {:wiki => :rename}, :require => :member
71 73 map.permission :delete_wiki_pages, {:wiki => :destroy}, :require => :member
72 74 map.permission :view_wiki_pages, :wiki => [:index, :history, :diff, :annotate, :special]
73 75 map.permission :edit_wiki_pages, :wiki => [:edit, :preview, :add_attachment, :destroy_attachment]
74 76 end
75 77
76 78 map.project_module :repository do |map|
77 79 map.permission :manage_repository, {:repositories => [:edit, :destroy]}, :require => :member
78 80 map.permission :browse_repository, :repositories => [:show, :browse, :entry, :annotate, :changes, :diff, :stats, :graph]
79 81 map.permission :view_changesets, :repositories => [:show, :revisions, :revision]
80 82 end
81 83
82 84 map.project_module :boards do |map|
83 85 map.permission :manage_boards, {:boards => [:new, :edit, :destroy]}, :require => :member
84 86 map.permission :view_messages, {:boards => [:index, :show], :messages => [:show]}, :public => true
85 87 map.permission :add_messages, {:messages => [:new, :reply]}
86 88 map.permission :edit_messages, {:messages => :edit}, :require => :member
87 89 map.permission :delete_messages, {:messages => :destroy}, :require => :member
88 90 end
89 91 end
90 92
91 93 Redmine::MenuManager.map :top_menu do |menu|
92 94 menu.push :home, :home_url, :html => { :class => 'home' }
93 95 menu.push :my_page, { :controller => 'my', :action => 'page' }, :html => { :class => 'mypage' }, :if => Proc.new { User.current.logged? }
94 96 menu.push :projects, { :controller => 'projects', :action => 'index' }, :caption => :label_project_plural, :html => { :class => 'projects' }
95 97 menu.push :administration, { :controller => 'admin', :action => 'index' }, :html => { :class => 'admin' }, :if => Proc.new { User.current.admin? }
96 98 menu.push :help, Redmine::Info.help_url, :html => { :class => 'help' }
97 99 end
98 100
99 101 Redmine::MenuManager.map :account_menu do |menu|
100 102 menu.push :login, :signin_url, :html => { :class => 'login' }, :if => Proc.new { !User.current.logged? }
101 103 menu.push :register, { :controller => 'account', :action => 'register' }, :html => { :class => 'register' }, :if => Proc.new { !User.current.logged? && Setting.self_registration? }
102 104 menu.push :my_account, { :controller => 'my', :action => 'account' }, :html => { :class => 'myaccount' }, :if => Proc.new { User.current.logged? }
103 105 menu.push :logout, :signout_url, :html => { :class => 'logout' }, :if => Proc.new { User.current.logged? }
104 106 end
105 107
106 108 Redmine::MenuManager.map :application_menu do |menu|
107 109 # Empty
108 110 end
109 111
110 112 Redmine::MenuManager.map :project_menu do |menu|
111 113 menu.push :overview, { :controller => 'projects', :action => 'show' }
112 114 menu.push :activity, { :controller => 'projects', :action => 'activity' }
113 115 menu.push :roadmap, { :controller => 'projects', :action => 'roadmap' },
114 116 :if => Proc.new { |p| p.versions.any? }
115 117 menu.push :issues, { :controller => 'issues', :action => 'index' }, :param => :project_id, :caption => :label_issue_plural
116 118 menu.push :new_issue, { :controller => 'issues', :action => 'new' }, :param => :project_id, :caption => :label_issue_new,
117 119 :html => { :accesskey => Redmine::AccessKeys.key_for(:new_issue) }
118 120 menu.push :news, { :controller => 'news', :action => 'index' }, :param => :project_id, :caption => :label_news_plural
119 121 menu.push :documents, { :controller => 'documents', :action => 'index' }, :param => :project_id, :caption => :label_document_plural
120 122 menu.push :wiki, { :controller => 'wiki', :action => 'index', :page => nil },
121 123 :if => Proc.new { |p| p.wiki && !p.wiki.new_record? }
122 124 menu.push :boards, { :controller => 'boards', :action => 'index', :id => nil }, :param => :project_id,
123 125 :if => Proc.new { |p| p.boards.any? }, :caption => :label_board_plural
124 126 menu.push :files, { :controller => 'projects', :action => 'list_files' }, :caption => :label_attachment_plural
125 127 menu.push :repository, { :controller => 'repositories', :action => 'show' },
126 128 :if => Proc.new { |p| p.repository && !p.repository.new_record? }
127 129 menu.push :settings, { :controller => 'projects', :action => 'settings' }
128 130 end
@@ -1,51 +1,59
1 1 # redMine - project management software
2 2 # Copyright (C) 2006-2008 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 File.dirname(__FILE__) + '/../test_helper'
19 19 require 'journals_controller'
20 20
21 21 # Re-raise errors caught by the controller.
22 22 class JournalsController; def rescue_action(e) raise e end; end
23 23
24 24 class JournalsControllerTest < ActionController::TestCase
25 25 fixtures :projects, :users, :members, :roles, :issues, :journals, :journal_details, :enabled_modules
26 26
27 27 def setup
28 28 @controller = JournalsController.new
29 29 @request = ActionController::TestRequest.new
30 30 @response = ActionController::TestResponse.new
31 31 User.current = nil
32 32 end
33 33
34 34 def test_get_edit
35 35 @request.session[:user_id] = 1
36 36 xhr :get, :edit, :id => 2
37 37 assert_response :success
38 38 assert_select_rjs :insert, :after, 'journal-2-notes' do
39 39 assert_select 'form[id=journal-2-form]'
40 40 assert_select 'textarea'
41 41 end
42 42 end
43 43
44 44 def test_post_edit
45 45 @request.session[:user_id] = 1
46 46 xhr :post, :edit, :id => 2, :notes => 'Updated notes'
47 47 assert_response :success
48 48 assert_select_rjs :replace, 'journal-2-notes'
49 49 assert_equal 'Updated notes', Journal.find(2).notes
50 50 end
51
52 def test_post_edit_with_empty_notes
53 @request.session[:user_id] = 1
54 xhr :post, :edit, :id => 2, :notes => ''
55 assert_response :success
56 assert_select_rjs :remove, 'change-2'
57 assert_nil Journal.find_by_id(2)
58 end
51 59 end
General Comments 0
You need to be logged in to leave comments. Login now