##// END OF EJS Templates
Create role by copy (#9258)....
Jean-Philippe Lang -
r10102:ca7498c2d6cc
parent child
Show More
@@ -1,99 +1,102
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class RolesController < ApplicationController
18 class RolesController < ApplicationController
19 layout 'admin'
19 layout 'admin'
20
20
21 before_filter :require_admin, :except => :index
21 before_filter :require_admin, :except => :index
22 before_filter :require_admin_or_api_request, :only => :index
22 before_filter :require_admin_or_api_request, :only => :index
23 before_filter :find_role, :only => [:edit, :update, :destroy]
23 before_filter :find_role, :only => [:edit, :update, :destroy]
24 accept_api_auth :index
24 accept_api_auth :index
25
25
26 def index
26 def index
27 respond_to do |format|
27 respond_to do |format|
28 format.html {
28 format.html {
29 @role_pages, @roles = paginate :roles, :per_page => 25, :order => 'builtin, position'
29 @role_pages, @roles = paginate :roles, :per_page => 25, :order => 'builtin, position'
30 render :action => "index", :layout => false if request.xhr?
30 render :action => "index", :layout => false if request.xhr?
31 }
31 }
32 format.api {
32 format.api {
33 @roles = Role.givable.all
33 @roles = Role.givable.all
34 }
34 }
35 end
35 end
36 end
36 end
37
37
38 def new
38 def new
39 # Prefills the form with 'Non member' role permissions
39 # Prefills the form with 'Non member' role permissions by default
40 @role = Role.new(params[:role] || {:permissions => Role.non_member.permissions})
40 @role = Role.new(params[:role] || {:permissions => Role.non_member.permissions})
41 if params[:copy].present? && @copy_from = Role.find_by_id(params[:copy])
42 @role.copy_from(@copy_from)
43 end
41 @roles = Role.sorted.all
44 @roles = Role.sorted.all
42 end
45 end
43
46
44 def create
47 def create
45 @role = Role.new(params[:role])
48 @role = Role.new(params[:role])
46 if request.post? && @role.save
49 if request.post? && @role.save
47 # workflow copy
50 # workflow copy
48 if !params[:copy_workflow_from].blank? && (copy_from = Role.find_by_id(params[:copy_workflow_from]))
51 if !params[:copy_workflow_from].blank? && (copy_from = Role.find_by_id(params[:copy_workflow_from]))
49 @role.workflow_rules.copy(copy_from)
52 @role.workflow_rules.copy(copy_from)
50 end
53 end
51 flash[:notice] = l(:notice_successful_create)
54 flash[:notice] = l(:notice_successful_create)
52 redirect_to :action => 'index'
55 redirect_to :action => 'index'
53 else
56 else
54 @roles = Role.sorted.all
57 @roles = Role.sorted.all
55 render :action => 'new'
58 render :action => 'new'
56 end
59 end
57 end
60 end
58
61
59 def edit
62 def edit
60 end
63 end
61
64
62 def update
65 def update
63 if request.put? and @role.update_attributes(params[:role])
66 if request.put? and @role.update_attributes(params[:role])
64 flash[:notice] = l(:notice_successful_update)
67 flash[:notice] = l(:notice_successful_update)
65 redirect_to :action => 'index'
68 redirect_to :action => 'index'
66 else
69 else
67 render :action => 'edit'
70 render :action => 'edit'
68 end
71 end
69 end
72 end
70
73
71 def destroy
74 def destroy
72 @role.destroy
75 @role.destroy
73 redirect_to :action => 'index'
76 redirect_to :action => 'index'
74 rescue
77 rescue
75 flash[:error] = l(:error_can_not_remove_role)
78 flash[:error] = l(:error_can_not_remove_role)
76 redirect_to :action => 'index'
79 redirect_to :action => 'index'
77 end
80 end
78
81
79 def permissions
82 def permissions
80 @roles = Role.sorted.all
83 @roles = Role.sorted.all
81 @permissions = Redmine::AccessControl.permissions.select { |p| !p.public? }
84 @permissions = Redmine::AccessControl.permissions.select { |p| !p.public? }
82 if request.post?
85 if request.post?
83 @roles.each do |role|
86 @roles.each do |role|
84 role.permissions = params[:permissions][role.id.to_s]
87 role.permissions = params[:permissions][role.id.to_s]
85 role.save
88 role.save
86 end
89 end
87 flash[:notice] = l(:notice_successful_update)
90 flash[:notice] = l(:notice_successful_update)
88 redirect_to :action => 'index'
91 redirect_to :action => 'index'
89 end
92 end
90 end
93 end
91
94
92 private
95 private
93
96
94 def find_role
97 def find_role
95 @role = Role.find(params[:id])
98 @role = Role.find(params[:id])
96 rescue ActiveRecord::RecordNotFound
99 rescue ActiveRecord::RecordNotFound
97 render_404
100 render_404
98 end
101 end
99 end
102 end
@@ -1,194 +1,203
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 class Role < ActiveRecord::Base
18 class Role < ActiveRecord::Base
19 # Custom coder for the permissions attribute that should be an
19 # Custom coder for the permissions attribute that should be an
20 # array of symbols. Rails 3 uses Psych which can be *unbelievably*
20 # array of symbols. Rails 3 uses Psych which can be *unbelievably*
21 # slow on some platforms (eg. mingw32).
21 # slow on some platforms (eg. mingw32).
22 class PermissionsAttributeCoder
22 class PermissionsAttributeCoder
23 def self.load(str)
23 def self.load(str)
24 str.to_s.scan(/:([a-z0-9_]+)/).flatten.map(&:to_sym)
24 str.to_s.scan(/:([a-z0-9_]+)/).flatten.map(&:to_sym)
25 end
25 end
26
26
27 def self.dump(value)
27 def self.dump(value)
28 YAML.dump(value)
28 YAML.dump(value)
29 end
29 end
30 end
30 end
31
31
32 # Built-in roles
32 # Built-in roles
33 BUILTIN_NON_MEMBER = 1
33 BUILTIN_NON_MEMBER = 1
34 BUILTIN_ANONYMOUS = 2
34 BUILTIN_ANONYMOUS = 2
35
35
36 ISSUES_VISIBILITY_OPTIONS = [
36 ISSUES_VISIBILITY_OPTIONS = [
37 ['all', :label_issues_visibility_all],
37 ['all', :label_issues_visibility_all],
38 ['default', :label_issues_visibility_public],
38 ['default', :label_issues_visibility_public],
39 ['own', :label_issues_visibility_own]
39 ['own', :label_issues_visibility_own]
40 ]
40 ]
41
41
42 scope :sorted, order("#{table_name}.builtin ASC, #{table_name}.position ASC")
42 scope :sorted, order("#{table_name}.builtin ASC, #{table_name}.position ASC")
43 scope :givable, order("#{table_name}.position ASC").where(:builtin => 0)
43 scope :givable, order("#{table_name}.position ASC").where(:builtin => 0)
44 scope :builtin, lambda { |*args|
44 scope :builtin, lambda { |*args|
45 compare = (args.first == true ? 'not' : '')
45 compare = (args.first == true ? 'not' : '')
46 where("#{compare} builtin = 0")
46 where("#{compare} builtin = 0")
47 }
47 }
48
48
49 before_destroy :check_deletable
49 before_destroy :check_deletable
50 has_many :workflow_rules, :dependent => :delete_all do
50 has_many :workflow_rules, :dependent => :delete_all do
51 def copy(source_role)
51 def copy(source_role)
52 WorkflowRule.copy(nil, source_role, nil, proxy_association.owner)
52 WorkflowRule.copy(nil, source_role, nil, proxy_association.owner)
53 end
53 end
54 end
54 end
55
55
56 has_many :member_roles, :dependent => :destroy
56 has_many :member_roles, :dependent => :destroy
57 has_many :members, :through => :member_roles
57 has_many :members, :through => :member_roles
58 acts_as_list
58 acts_as_list
59
59
60 serialize :permissions, ::Role::PermissionsAttributeCoder
60 serialize :permissions, ::Role::PermissionsAttributeCoder
61 attr_protected :builtin
61 attr_protected :builtin
62
62
63 validates_presence_of :name
63 validates_presence_of :name
64 validates_uniqueness_of :name
64 validates_uniqueness_of :name
65 validates_length_of :name, :maximum => 30
65 validates_length_of :name, :maximum => 30
66 validates_inclusion_of :issues_visibility,
66 validates_inclusion_of :issues_visibility,
67 :in => ISSUES_VISIBILITY_OPTIONS.collect(&:first),
67 :in => ISSUES_VISIBILITY_OPTIONS.collect(&:first),
68 :if => lambda {|role| role.respond_to?(:issues_visibility)}
68 :if => lambda {|role| role.respond_to?(:issues_visibility)}
69
69
70 # Copies attributes from another role, arg can be an id or a Role
71 def copy_from(arg, options={})
72 return unless arg.present?
73 role = arg.is_a?(Role) ? arg : Role.find_by_id(arg.to_s)
74 self.attributes = role.attributes.dup.except("id", "name", "position", "builtin", "permissions")
75 self.permissions = role.permissions.dup
76 self
77 end
78
70 def permissions=(perms)
79 def permissions=(perms)
71 perms = perms.collect {|p| p.to_sym unless p.blank? }.compact.uniq if perms
80 perms = perms.collect {|p| p.to_sym unless p.blank? }.compact.uniq if perms
72 write_attribute(:permissions, perms)
81 write_attribute(:permissions, perms)
73 end
82 end
74
83
75 def add_permission!(*perms)
84 def add_permission!(*perms)
76 self.permissions = [] unless permissions.is_a?(Array)
85 self.permissions = [] unless permissions.is_a?(Array)
77
86
78 permissions_will_change!
87 permissions_will_change!
79 perms.each do |p|
88 perms.each do |p|
80 p = p.to_sym
89 p = p.to_sym
81 permissions << p unless permissions.include?(p)
90 permissions << p unless permissions.include?(p)
82 end
91 end
83 save!
92 save!
84 end
93 end
85
94
86 def remove_permission!(*perms)
95 def remove_permission!(*perms)
87 return unless permissions.is_a?(Array)
96 return unless permissions.is_a?(Array)
88 permissions_will_change!
97 permissions_will_change!
89 perms.each { |p| permissions.delete(p.to_sym) }
98 perms.each { |p| permissions.delete(p.to_sym) }
90 save!
99 save!
91 end
100 end
92
101
93 # Returns true if the role has the given permission
102 # Returns true if the role has the given permission
94 def has_permission?(perm)
103 def has_permission?(perm)
95 !permissions.nil? && permissions.include?(perm.to_sym)
104 !permissions.nil? && permissions.include?(perm.to_sym)
96 end
105 end
97
106
98 def <=>(role)
107 def <=>(role)
99 if role
108 if role
100 if builtin == role.builtin
109 if builtin == role.builtin
101 position <=> role.position
110 position <=> role.position
102 else
111 else
103 builtin <=> role.builtin
112 builtin <=> role.builtin
104 end
113 end
105 else
114 else
106 -1
115 -1
107 end
116 end
108 end
117 end
109
118
110 def to_s
119 def to_s
111 name
120 name
112 end
121 end
113
122
114 def name
123 def name
115 case builtin
124 case builtin
116 when 1; l(:label_role_non_member, :default => read_attribute(:name))
125 when 1; l(:label_role_non_member, :default => read_attribute(:name))
117 when 2; l(:label_role_anonymous, :default => read_attribute(:name))
126 when 2; l(:label_role_anonymous, :default => read_attribute(:name))
118 else; read_attribute(:name)
127 else; read_attribute(:name)
119 end
128 end
120 end
129 end
121
130
122 # Return true if the role is a builtin role
131 # Return true if the role is a builtin role
123 def builtin?
132 def builtin?
124 self.builtin != 0
133 self.builtin != 0
125 end
134 end
126
135
127 # Return true if the role is a project member role
136 # Return true if the role is a project member role
128 def member?
137 def member?
129 !self.builtin?
138 !self.builtin?
130 end
139 end
131
140
132 # Return true if role is allowed to do the specified action
141 # Return true if role is allowed to do the specified action
133 # action can be:
142 # action can be:
134 # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit')
143 # * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit')
135 # * a permission Symbol (eg. :edit_project)
144 # * a permission Symbol (eg. :edit_project)
136 def allowed_to?(action)
145 def allowed_to?(action)
137 if action.is_a? Hash
146 if action.is_a? Hash
138 allowed_actions.include? "#{action[:controller]}/#{action[:action]}"
147 allowed_actions.include? "#{action[:controller]}/#{action[:action]}"
139 else
148 else
140 allowed_permissions.include? action
149 allowed_permissions.include? action
141 end
150 end
142 end
151 end
143
152
144 # Return all the permissions that can be given to the role
153 # Return all the permissions that can be given to the role
145 def setable_permissions
154 def setable_permissions
146 setable_permissions = Redmine::AccessControl.permissions - Redmine::AccessControl.public_permissions
155 setable_permissions = Redmine::AccessControl.permissions - Redmine::AccessControl.public_permissions
147 setable_permissions -= Redmine::AccessControl.members_only_permissions if self.builtin == BUILTIN_NON_MEMBER
156 setable_permissions -= Redmine::AccessControl.members_only_permissions if self.builtin == BUILTIN_NON_MEMBER
148 setable_permissions -= Redmine::AccessControl.loggedin_only_permissions if self.builtin == BUILTIN_ANONYMOUS
157 setable_permissions -= Redmine::AccessControl.loggedin_only_permissions if self.builtin == BUILTIN_ANONYMOUS
149 setable_permissions
158 setable_permissions
150 end
159 end
151
160
152 # Find all the roles that can be given to a project member
161 # Find all the roles that can be given to a project member
153 def self.find_all_givable
162 def self.find_all_givable
154 Role.givable.all
163 Role.givable.all
155 end
164 end
156
165
157 # Return the builtin 'non member' role. If the role doesn't exist,
166 # Return the builtin 'non member' role. If the role doesn't exist,
158 # it will be created on the fly.
167 # it will be created on the fly.
159 def self.non_member
168 def self.non_member
160 find_or_create_system_role(BUILTIN_NON_MEMBER, 'Non member')
169 find_or_create_system_role(BUILTIN_NON_MEMBER, 'Non member')
161 end
170 end
162
171
163 # Return the builtin 'anonymous' role. If the role doesn't exist,
172 # Return the builtin 'anonymous' role. If the role doesn't exist,
164 # it will be created on the fly.
173 # it will be created on the fly.
165 def self.anonymous
174 def self.anonymous
166 find_or_create_system_role(BUILTIN_ANONYMOUS, 'Anonymous')
175 find_or_create_system_role(BUILTIN_ANONYMOUS, 'Anonymous')
167 end
176 end
168
177
169 private
178 private
170
179
171 def allowed_permissions
180 def allowed_permissions
172 @allowed_permissions ||= permissions + Redmine::AccessControl.public_permissions.collect {|p| p.name}
181 @allowed_permissions ||= permissions + Redmine::AccessControl.public_permissions.collect {|p| p.name}
173 end
182 end
174
183
175 def allowed_actions
184 def allowed_actions
176 @actions_allowed ||= allowed_permissions.inject([]) { |actions, permission| actions += Redmine::AccessControl.allowed_actions(permission) }.flatten
185 @actions_allowed ||= allowed_permissions.inject([]) { |actions, permission| actions += Redmine::AccessControl.allowed_actions(permission) }.flatten
177 end
186 end
178
187
179 def check_deletable
188 def check_deletable
180 raise "Can't delete role" if members.any?
189 raise "Can't delete role" if members.any?
181 raise "Can't delete builtin role" if builtin?
190 raise "Can't delete builtin role" if builtin?
182 end
191 end
183
192
184 def self.find_or_create_system_role(builtin, name)
193 def self.find_or_create_system_role(builtin, name)
185 role = where(:builtin => builtin).first
194 role = where(:builtin => builtin).first
186 if role.nil?
195 if role.nil?
187 role = create(:name => name, :position => 0) do |r|
196 role = create(:name => name, :position => 0) do |r|
188 r.builtin = builtin
197 r.builtin = builtin
189 end
198 end
190 raise "Unable to create the #{name} role." if role.new_record?
199 raise "Unable to create the #{name} role." if role.new_record?
191 end
200 end
192 role
201 role
193 end
202 end
194 end
203 end
@@ -1,30 +1,30
1 <%= error_messages_for 'role' %>
1 <%= error_messages_for 'role' %>
2
2
3 <div class="box tabular">
3 <div class="box tabular">
4 <% unless @role.builtin? %>
4 <% unless @role.builtin? %>
5 <p><%= f.text_field :name, :required => true %></p>
5 <p><%= f.text_field :name, :required => true %></p>
6 <p><%= f.check_box :assignable %></p>
6 <p><%= f.check_box :assignable %></p>
7 <% end %>
7 <% end %>
8 <p><%= f.select :issues_visibility, Role::ISSUES_VISIBILITY_OPTIONS.collect {|v| [l(v.last), v.first]} %></p>
8 <p><%= f.select :issues_visibility, Role::ISSUES_VISIBILITY_OPTIONS.collect {|v| [l(v.last), v.first]} %></p>
9 <% if @role.new_record? && @roles.any? %>
9 <% if @role.new_record? && @roles.any? %>
10 <p><label for="copy_workflow_from"><%= l(:label_copy_workflow_from) %></label>
10 <p><label for="copy_workflow_from"><%= l(:label_copy_workflow_from) %></label>
11 <%= select_tag(:copy_workflow_from, content_tag("option") + options_from_collection_for_select(@roles, :id, :name)) %></p>
11 <%= select_tag(:copy_workflow_from, content_tag("option") + options_from_collection_for_select(@roles, :id, :name, params[:copy_workflow_from] || @copy_from.try(:id))) %></p>
12 <% end %>
12 <% end %>
13 </div>
13 </div>
14
14
15 <h3><%= l(:label_permissions) %></h3>
15 <h3><%= l(:label_permissions) %></h3>
16 <div class="box tabular" id="permissions">
16 <div class="box tabular" id="permissions">
17 <% perms_by_module = @role.setable_permissions.group_by {|p| p.project_module.to_s} %>
17 <% perms_by_module = @role.setable_permissions.group_by {|p| p.project_module.to_s} %>
18 <% perms_by_module.keys.sort.each do |mod| %>
18 <% perms_by_module.keys.sort.each do |mod| %>
19 <fieldset><legend><%= mod.blank? ? l(:label_project) : l_or_humanize(mod, :prefix => 'project_module_') %></legend>
19 <fieldset><legend><%= mod.blank? ? l(:label_project) : l_or_humanize(mod, :prefix => 'project_module_') %></legend>
20 <% perms_by_module[mod].each do |permission| %>
20 <% perms_by_module[mod].each do |permission| %>
21 <label class="floating">
21 <label class="floating">
22 <%= check_box_tag 'role[permissions][]', permission.name, (@role.permissions.include? permission.name) %>
22 <%= check_box_tag 'role[permissions][]', permission.name, (@role.permissions.include? permission.name) %>
23 <%= l_or_humanize(permission.name, :prefix => 'permission_') %>
23 <%= l_or_humanize(permission.name, :prefix => 'permission_') %>
24 </label>
24 </label>
25 <% end %>
25 <% end %>
26 </fieldset>
26 </fieldset>
27 <% end %>
27 <% end %>
28 <br /><%= check_all_links 'permissions' %>
28 <br /><%= check_all_links 'permissions' %>
29 <%= hidden_field_tag 'role[permissions][]', '' %>
29 <%= hidden_field_tag 'role[permissions][]', '' %>
30 </div>
30 </div>
@@ -1,33 +1,34
1 <div class="contextual">
1 <div class="contextual">
2 <%= link_to l(:label_role_new), new_role_path, :class => 'icon icon-add' %>
2 <%= link_to l(:label_role_new), new_role_path, :class => 'icon icon-add' %>
3 <%= link_to l(:label_permissions_report), {:action => 'permissions'}, :class => 'icon icon-summary' %>
3 <%= link_to l(:label_permissions_report), {:action => 'permissions'}, :class => 'icon icon-summary' %>
4 </div>
4 </div>
5
5
6 <h2><%=l(:label_role_plural)%></h2>
6 <h2><%=l(:label_role_plural)%></h2>
7
7
8 <table class="list">
8 <table class="list">
9 <thead><tr>
9 <thead><tr>
10 <th><%=l(:label_role)%></th>
10 <th><%=l(:label_role)%></th>
11 <th><%=l(:button_sort)%></th>
11 <th><%=l(:button_sort)%></th>
12 <th></th>
12 <th></th>
13 </tr></thead>
13 </tr></thead>
14 <tbody>
14 <tbody>
15 <% for role in @roles %>
15 <% for role in @roles %>
16 <tr class="<%= cycle("odd", "even") %>">
16 <tr class="<%= cycle("odd", "even") %>">
17 <td><%= content_tag(role.builtin? ? 'em' : 'span', link_to(h(role.name), edit_role_path(role))) %></td>
17 <td><%= content_tag(role.builtin? ? 'em' : 'span', link_to(h(role.name), edit_role_path(role))) %></td>
18 <td align="center" style="width:15%;">
18 <td align="center" style="width:15%;">
19 <% unless role.builtin? %>
19 <% unless role.builtin? %>
20 <%= reorder_links('role', {:action => 'update', :id => role}, :put) %>
20 <%= reorder_links('role', {:action => 'update', :id => role}, :put) %>
21 <% end %>
21 <% end %>
22 </td>
22 </td>
23 <td class="buttons">
23 <td class="buttons">
24 <%= link_to l(:button_copy), new_role_path(:copy => role), :class => 'icon icon-copy' %>
24 <%= delete_link role_path(role) unless role.builtin? %>
25 <%= delete_link role_path(role) unless role.builtin? %>
25 </td>
26 </td>
26 </tr>
27 </tr>
27 <% end %>
28 <% end %>
28 </tbody>
29 </tbody>
29 </table>
30 </table>
30
31
31 <p class="pagination"><%= pagination_links_full @role_pages %></p>
32 <p class="pagination"><%= pagination_links_full @role_pages %></p>
32
33
33 <% html_title(l(:label_role_plural)) -%>
34 <% html_title(l(:label_role_plural)) -%>
@@ -1,186 +1,211
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class RolesControllerTest < ActionController::TestCase
20 class RolesControllerTest < ActionController::TestCase
21 fixtures :roles, :users, :members, :member_roles, :workflows, :trackers
21 fixtures :roles, :users, :members, :member_roles, :workflows, :trackers
22
22
23 def setup
23 def setup
24 @controller = RolesController.new
24 @controller = RolesController.new
25 @request = ActionController::TestRequest.new
25 @request = ActionController::TestRequest.new
26 @response = ActionController::TestResponse.new
26 @response = ActionController::TestResponse.new
27 User.current = nil
27 User.current = nil
28 @request.session[:user_id] = 1 # admin
28 @request.session[:user_id] = 1 # admin
29 end
29 end
30
30
31 def test_index
31 def test_index
32 get :index
32 get :index
33 assert_response :success
33 assert_response :success
34 assert_template 'index'
34 assert_template 'index'
35
35
36 assert_not_nil assigns(:roles)
36 assert_not_nil assigns(:roles)
37 assert_equal Role.find(:all, :order => 'builtin, position'), assigns(:roles)
37 assert_equal Role.find(:all, :order => 'builtin, position'), assigns(:roles)
38
38
39 assert_tag :tag => 'a', :attributes => { :href => '/roles/1/edit' },
39 assert_tag :tag => 'a', :attributes => { :href => '/roles/1/edit' },
40 :content => 'Manager'
40 :content => 'Manager'
41 end
41 end
42
42
43 def test_new
43 def test_new
44 get :new
44 get :new
45 assert_response :success
45 assert_response :success
46 assert_template 'new'
46 assert_template 'new'
47 end
47 end
48
48
49 def test_new_with_copy
50 copy_from = Role.find(2)
51
52 get :new, :copy => copy_from.id.to_s
53 assert_response :success
54 assert_template 'new'
55
56 role = assigns(:role)
57 assert_equal copy_from.permissions, role.permissions
58
59 assert_select 'form' do
60 # blank name
61 assert_select 'input[name=?][value=]', 'role[name]'
62 # edit_project permission checked
63 assert_select 'input[type=checkbox][name=?][value=edit_project][checked=checked]', 'role[permissions][]'
64 # add_project permission not checked
65 assert_select 'input[type=checkbox][name=?][value=add_project]', 'role[permissions][]'
66 assert_select 'input[type=checkbox][name=?][value=add_project][checked=checked]', 'role[permissions][]', 0
67 # workflow copy selected
68 assert_select 'select[name=?]', 'copy_workflow_from' do
69 assert_select 'option[value=2][selected=selected]'
70 end
71 end
72 end
73
49 def test_create_with_validaton_failure
74 def test_create_with_validaton_failure
50 post :create, :role => {:name => '',
75 post :create, :role => {:name => '',
51 :permissions => ['add_issues', 'edit_issues', 'log_time', ''],
76 :permissions => ['add_issues', 'edit_issues', 'log_time', ''],
52 :assignable => '0'}
77 :assignable => '0'}
53
78
54 assert_response :success
79 assert_response :success
55 assert_template 'new'
80 assert_template 'new'
56 assert_tag :tag => 'div', :attributes => { :id => 'errorExplanation' }
81 assert_tag :tag => 'div', :attributes => { :id => 'errorExplanation' }
57 end
82 end
58
83
59 def test_create_without_workflow_copy
84 def test_create_without_workflow_copy
60 post :create, :role => {:name => 'RoleWithoutWorkflowCopy',
85 post :create, :role => {:name => 'RoleWithoutWorkflowCopy',
61 :permissions => ['add_issues', 'edit_issues', 'log_time', ''],
86 :permissions => ['add_issues', 'edit_issues', 'log_time', ''],
62 :assignable => '0'}
87 :assignable => '0'}
63
88
64 assert_redirected_to '/roles'
89 assert_redirected_to '/roles'
65 role = Role.find_by_name('RoleWithoutWorkflowCopy')
90 role = Role.find_by_name('RoleWithoutWorkflowCopy')
66 assert_not_nil role
91 assert_not_nil role
67 assert_equal [:add_issues, :edit_issues, :log_time], role.permissions
92 assert_equal [:add_issues, :edit_issues, :log_time], role.permissions
68 assert !role.assignable?
93 assert !role.assignable?
69 end
94 end
70
95
71 def test_create_with_workflow_copy
96 def test_create_with_workflow_copy
72 post :create, :role => {:name => 'RoleWithWorkflowCopy',
97 post :create, :role => {:name => 'RoleWithWorkflowCopy',
73 :permissions => ['add_issues', 'edit_issues', 'log_time', ''],
98 :permissions => ['add_issues', 'edit_issues', 'log_time', ''],
74 :assignable => '0'},
99 :assignable => '0'},
75 :copy_workflow_from => '1'
100 :copy_workflow_from => '1'
76
101
77 assert_redirected_to '/roles'
102 assert_redirected_to '/roles'
78 role = Role.find_by_name('RoleWithWorkflowCopy')
103 role = Role.find_by_name('RoleWithWorkflowCopy')
79 assert_not_nil role
104 assert_not_nil role
80 assert_equal Role.find(1).workflow_rules.size, role.workflow_rules.size
105 assert_equal Role.find(1).workflow_rules.size, role.workflow_rules.size
81 end
106 end
82
107
83 def test_edit
108 def test_edit
84 get :edit, :id => 1
109 get :edit, :id => 1
85 assert_response :success
110 assert_response :success
86 assert_template 'edit'
111 assert_template 'edit'
87 assert_equal Role.find(1), assigns(:role)
112 assert_equal Role.find(1), assigns(:role)
88 end
113 end
89
114
90 def test_edit_invalid_should_respond_with_404
115 def test_edit_invalid_should_respond_with_404
91 get :edit, :id => 999
116 get :edit, :id => 999
92 assert_response 404
117 assert_response 404
93 end
118 end
94
119
95 def test_update
120 def test_update
96 put :update, :id => 1,
121 put :update, :id => 1,
97 :role => {:name => 'Manager',
122 :role => {:name => 'Manager',
98 :permissions => ['edit_project', ''],
123 :permissions => ['edit_project', ''],
99 :assignable => '0'}
124 :assignable => '0'}
100
125
101 assert_redirected_to '/roles'
126 assert_redirected_to '/roles'
102 role = Role.find(1)
127 role = Role.find(1)
103 assert_equal [:edit_project], role.permissions
128 assert_equal [:edit_project], role.permissions
104 end
129 end
105
130
106 def test_update_with_failure
131 def test_update_with_failure
107 put :update, :id => 1, :role => {:name => ''}
132 put :update, :id => 1, :role => {:name => ''}
108 assert_response :success
133 assert_response :success
109 assert_template 'edit'
134 assert_template 'edit'
110 end
135 end
111
136
112 def test_destroy
137 def test_destroy
113 r = Role.create!(:name => 'ToBeDestroyed', :permissions => [:view_wiki_pages])
138 r = Role.create!(:name => 'ToBeDestroyed', :permissions => [:view_wiki_pages])
114
139
115 delete :destroy, :id => r
140 delete :destroy, :id => r
116 assert_redirected_to '/roles'
141 assert_redirected_to '/roles'
117 assert_nil Role.find_by_id(r.id)
142 assert_nil Role.find_by_id(r.id)
118 end
143 end
119
144
120 def test_destroy_role_in_use
145 def test_destroy_role_in_use
121 delete :destroy, :id => 1
146 delete :destroy, :id => 1
122 assert_redirected_to '/roles'
147 assert_redirected_to '/roles'
123 assert_equal 'This role is in use and cannot be deleted.', flash[:error]
148 assert_equal 'This role is in use and cannot be deleted.', flash[:error]
124 assert_not_nil Role.find_by_id(1)
149 assert_not_nil Role.find_by_id(1)
125 end
150 end
126
151
127 def test_get_permissions
152 def test_get_permissions
128 get :permissions
153 get :permissions
129 assert_response :success
154 assert_response :success
130 assert_template 'permissions'
155 assert_template 'permissions'
131
156
132 assert_not_nil assigns(:roles)
157 assert_not_nil assigns(:roles)
133 assert_equal Role.find(:all, :order => 'builtin, position'), assigns(:roles)
158 assert_equal Role.find(:all, :order => 'builtin, position'), assigns(:roles)
134
159
135 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
160 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
136 :name => 'permissions[3][]',
161 :name => 'permissions[3][]',
137 :value => 'add_issues',
162 :value => 'add_issues',
138 :checked => 'checked' }
163 :checked => 'checked' }
139
164
140 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
165 assert_tag :tag => 'input', :attributes => { :type => 'checkbox',
141 :name => 'permissions[3][]',
166 :name => 'permissions[3][]',
142 :value => 'delete_issues',
167 :value => 'delete_issues',
143 :checked => nil }
168 :checked => nil }
144 end
169 end
145
170
146 def test_post_permissions
171 def test_post_permissions
147 post :permissions, :permissions => { '0' => '', '1' => ['edit_issues'], '3' => ['add_issues', 'delete_issues']}
172 post :permissions, :permissions => { '0' => '', '1' => ['edit_issues'], '3' => ['add_issues', 'delete_issues']}
148 assert_redirected_to '/roles'
173 assert_redirected_to '/roles'
149
174
150 assert_equal [:edit_issues], Role.find(1).permissions
175 assert_equal [:edit_issues], Role.find(1).permissions
151 assert_equal [:add_issues, :delete_issues], Role.find(3).permissions
176 assert_equal [:add_issues, :delete_issues], Role.find(3).permissions
152 assert Role.find(2).permissions.empty?
177 assert Role.find(2).permissions.empty?
153 end
178 end
154
179
155 def test_clear_all_permissions
180 def test_clear_all_permissions
156 post :permissions, :permissions => { '0' => '' }
181 post :permissions, :permissions => { '0' => '' }
157 assert_redirected_to '/roles'
182 assert_redirected_to '/roles'
158 assert Role.find(1).permissions.empty?
183 assert Role.find(1).permissions.empty?
159 end
184 end
160
185
161 def test_move_highest
186 def test_move_highest
162 put :update, :id => 3, :role => {:move_to => 'highest'}
187 put :update, :id => 3, :role => {:move_to => 'highest'}
163 assert_redirected_to '/roles'
188 assert_redirected_to '/roles'
164 assert_equal 1, Role.find(3).position
189 assert_equal 1, Role.find(3).position
165 end
190 end
166
191
167 def test_move_higher
192 def test_move_higher
168 position = Role.find(3).position
193 position = Role.find(3).position
169 put :update, :id => 3, :role => {:move_to => 'higher'}
194 put :update, :id => 3, :role => {:move_to => 'higher'}
170 assert_redirected_to '/roles'
195 assert_redirected_to '/roles'
171 assert_equal position - 1, Role.find(3).position
196 assert_equal position - 1, Role.find(3).position
172 end
197 end
173
198
174 def test_move_lower
199 def test_move_lower
175 position = Role.find(2).position
200 position = Role.find(2).position
176 put :update, :id => 2, :role => {:move_to => 'lower'}
201 put :update, :id => 2, :role => {:move_to => 'lower'}
177 assert_redirected_to '/roles'
202 assert_redirected_to '/roles'
178 assert_equal position + 1, Role.find(2).position
203 assert_equal position + 1, Role.find(2).position
179 end
204 end
180
205
181 def test_move_lowest
206 def test_move_lowest
182 put :update, :id => 2, :role => {:move_to => 'lowest'}
207 put :update, :id => 2, :role => {:move_to => 'lowest'}
183 assert_redirected_to '/roles'
208 assert_redirected_to '/roles'
184 assert_equal Role.count, Role.find(2).position
209 assert_equal Role.count, Role.find(2).position
185 end
210 end
186 end
211 end
@@ -1,133 +1,145
1 # Redmine - project management software
1 # Redmine - project management software
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
2 # Copyright (C) 2006-2012 Jean-Philippe Lang
3 #
3 #
4 # This program is free software; you can redistribute it and/or
4 # This program is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU General Public License
5 # modify it under the terms of the GNU General Public License
6 # as published by the Free Software Foundation; either version 2
6 # as published by the Free Software Foundation; either version 2
7 # of the License, or (at your option) any later version.
7 # of the License, or (at your option) any later version.
8 #
8 #
9 # This program is distributed in the hope that it will be useful,
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
12 # GNU General Public License for more details.
13 #
13 #
14 # You should have received a copy of the GNU General Public License
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17
17
18 require File.expand_path('../../test_helper', __FILE__)
18 require File.expand_path('../../test_helper', __FILE__)
19
19
20 class RoleTest < ActiveSupport::TestCase
20 class RoleTest < ActiveSupport::TestCase
21 fixtures :roles, :workflows
21 fixtures :roles, :workflows
22
22
23 def test_sorted_scope
23 def test_sorted_scope
24 assert_equal Role.all.sort, Role.sorted.all
24 assert_equal Role.all.sort, Role.sorted.all
25 end
25 end
26
26
27 def test_givable_scope
27 def test_givable_scope
28 assert_equal Role.all.reject(&:builtin?).sort, Role.givable.all
28 assert_equal Role.all.reject(&:builtin?).sort, Role.givable.all
29 end
29 end
30
30
31 def test_builtin_scope
31 def test_builtin_scope
32 assert_equal Role.all.select(&:builtin?).sort, Role.builtin(true).all.sort
32 assert_equal Role.all.select(&:builtin?).sort, Role.builtin(true).all.sort
33 assert_equal Role.all.reject(&:builtin?).sort, Role.builtin(false).all.sort
33 assert_equal Role.all.reject(&:builtin?).sort, Role.builtin(false).all.sort
34 end
34 end
35
35
36 def test_copy_from
37 role = Role.find(1)
38 copy = Role.new.copy_from(role)
39
40 assert_nil copy.id
41 assert_equal '', copy.name
42 assert_equal role.permissions, copy.permissions
43
44 copy.name = 'Copy'
45 assert copy.save
46 end
47
36 def test_copy_workflows
48 def test_copy_workflows
37 source = Role.find(1)
49 source = Role.find(1)
38 assert_equal 90, source.workflow_rules.size
50 assert_equal 90, source.workflow_rules.size
39
51
40 target = Role.new(:name => 'Target')
52 target = Role.new(:name => 'Target')
41 assert target.save
53 assert target.save
42 target.workflow_rules.copy(source)
54 target.workflow_rules.copy(source)
43 target.reload
55 target.reload
44 assert_equal 90, target.workflow_rules.size
56 assert_equal 90, target.workflow_rules.size
45 end
57 end
46
58
47 def test_permissions_should_be_unserialized_with_its_coder
59 def test_permissions_should_be_unserialized_with_its_coder
48 Role::PermissionsAttributeCoder.expects(:load).once
60 Role::PermissionsAttributeCoder.expects(:load).once
49 Role.find(1).permissions
61 Role.find(1).permissions
50 end
62 end
51
63
52 def test_add_permission
64 def test_add_permission
53 role = Role.find(1)
65 role = Role.find(1)
54 size = role.permissions.size
66 size = role.permissions.size
55 role.add_permission!("apermission", "anotherpermission")
67 role.add_permission!("apermission", "anotherpermission")
56 role.reload
68 role.reload
57 assert role.permissions.include?(:anotherpermission)
69 assert role.permissions.include?(:anotherpermission)
58 assert_equal size + 2, role.permissions.size
70 assert_equal size + 2, role.permissions.size
59 end
71 end
60
72
61 def test_remove_permission
73 def test_remove_permission
62 role = Role.find(1)
74 role = Role.find(1)
63 size = role.permissions.size
75 size = role.permissions.size
64 perm = role.permissions[0..1]
76 perm = role.permissions[0..1]
65 role.remove_permission!(*perm)
77 role.remove_permission!(*perm)
66 role.reload
78 role.reload
67 assert ! role.permissions.include?(perm[0])
79 assert ! role.permissions.include?(perm[0])
68 assert_equal size - 2, role.permissions.size
80 assert_equal size - 2, role.permissions.size
69 end
81 end
70
82
71 def test_name
83 def test_name
72 I18n.locale = 'fr'
84 I18n.locale = 'fr'
73 assert_equal 'Manager', Role.find(1).name
85 assert_equal 'Manager', Role.find(1).name
74 assert_equal 'Anonyme', Role.anonymous.name
86 assert_equal 'Anonyme', Role.anonymous.name
75 assert_equal 'Non membre', Role.non_member.name
87 assert_equal 'Non membre', Role.non_member.name
76 end
88 end
77
89
78 def test_find_all_givable
90 def test_find_all_givable
79 assert_equal Role.all.reject(&:builtin?).sort, Role.find_all_givable
91 assert_equal Role.all.reject(&:builtin?).sort, Role.find_all_givable
80 end
92 end
81
93
82 context "#anonymous" do
94 context "#anonymous" do
83 should "return the anonymous role" do
95 should "return the anonymous role" do
84 role = Role.anonymous
96 role = Role.anonymous
85 assert role.builtin?
97 assert role.builtin?
86 assert_equal Role::BUILTIN_ANONYMOUS, role.builtin
98 assert_equal Role::BUILTIN_ANONYMOUS, role.builtin
87 end
99 end
88
100
89 context "with a missing anonymous role" do
101 context "with a missing anonymous role" do
90 setup do
102 setup do
91 Role.delete_all("builtin = #{Role::BUILTIN_ANONYMOUS}")
103 Role.delete_all("builtin = #{Role::BUILTIN_ANONYMOUS}")
92 end
104 end
93
105
94 should "create a new anonymous role" do
106 should "create a new anonymous role" do
95 assert_difference('Role.count') do
107 assert_difference('Role.count') do
96 Role.anonymous
108 Role.anonymous
97 end
109 end
98 end
110 end
99
111
100 should "return the anonymous role" do
112 should "return the anonymous role" do
101 role = Role.anonymous
113 role = Role.anonymous
102 assert role.builtin?
114 assert role.builtin?
103 assert_equal Role::BUILTIN_ANONYMOUS, role.builtin
115 assert_equal Role::BUILTIN_ANONYMOUS, role.builtin
104 end
116 end
105 end
117 end
106 end
118 end
107
119
108 context "#non_member" do
120 context "#non_member" do
109 should "return the non-member role" do
121 should "return the non-member role" do
110 role = Role.non_member
122 role = Role.non_member
111 assert role.builtin?
123 assert role.builtin?
112 assert_equal Role::BUILTIN_NON_MEMBER, role.builtin
124 assert_equal Role::BUILTIN_NON_MEMBER, role.builtin
113 end
125 end
114
126
115 context "with a missing non-member role" do
127 context "with a missing non-member role" do
116 setup do
128 setup do
117 Role.delete_all("builtin = #{Role::BUILTIN_NON_MEMBER}")
129 Role.delete_all("builtin = #{Role::BUILTIN_NON_MEMBER}")
118 end
130 end
119
131
120 should "create a new non-member role" do
132 should "create a new non-member role" do
121 assert_difference('Role.count') do
133 assert_difference('Role.count') do
122 Role.non_member
134 Role.non_member
123 end
135 end
124 end
136 end
125
137
126 should "return the non-member role" do
138 should "return the non-member role" do
127 role = Role.non_member
139 role = Role.non_member
128 assert role.builtin?
140 assert role.builtin?
129 assert_equal Role::BUILTIN_NON_MEMBER, role.builtin
141 assert_equal Role::BUILTIN_NON_MEMBER, role.builtin
130 end
142 end
131 end
143 end
132 end
144 end
133 end
145 end
General Comments 0
You need to be logged in to leave comments. Login now