Project

General

Profile

Feature #23997 » 0001-per-role-visibility-settings-for-project-and-version.patch

updated patch - Jens Krämer, 2016-10-05 11:06

View differences:

app/models/project.rb
570 570
    end
571 571
  end
572 572

  
573
  def visible_custom_field_values(user = nil)
574
    user ||= User.current
575
    custom_field_values.select do |value|
576
      value.custom_field.visible_by?(project, user)
577
    end
578
  end
579

  
573 580
  def project
574 581
    self
575 582
  end
app/models/project_custom_field.rb
19 19
  def type_name
20 20
    :label_project_plural
21 21
  end
22

  
23
  def visible_by?(project, user=User.current)
24
    super || (roles & user.roles_for_project(project)).present?
25
  end
26

  
27
  def validate_custom_field
28
    super
29
    errors.add(:base, l(:label_role_plural) + ' ' + l('activerecord.errors.messages.blank')) unless visible? || roles.present?
30
  end
31

  
32
  def visibility_by_project_condition(project_key=nil, user=User.current, id_column=nil)
33
    project_key = 'projects.id' if project_key.blank?
34
    super project_key, user, id_column
35
  end
22 36
end
app/models/version.rb
68 68
    'custom_field_values',
69 69
    'custom_fields'
70 70

  
71
  def safe_attributes=(attrs, user = User.current)
72
    return unless attrs.is_a?(Hash)
73

  
74
    attrs = delete_unsafe_attributes(attrs, user)
75
    return if attrs.empty?
76

  
77
    if attrs['custom_field_values'].present?
78
      editable_custom_field_ids = editable_custom_field_values(user).map {|v| v.custom_field_id.to_s}
79
      attrs['custom_field_values'].reject! {|k, v| !editable_custom_field_ids.include?(k.to_s)}
80
    end
81

  
82
    if attrs['custom_fields'].present?
83
      editable_custom_field_ids = editable_custom_field_values(user).map {|v| v.custom_field_id.to_s}
84
      attrs['custom_fields'].reject! {|c| !editable_custom_field_ids.include?(c['id'].to_s)}
85
    end
86

  
87
    # mass-assignment security bypass
88
    assign_attributes attrs, :without_protection => true
89
  end
90

  
91
  # Returns the custom_field_values that can be edited by the given user
92
  def editable_custom_field_values(user=nil)
93
    visible_custom_field_values(user)
94
  end
95

  
71 96
  # Returns true if +user+ or current user is allowed to view the version
72 97
  def visible?(user=User.current)
73 98
    user.allowed_to?(:view_issues, self.project)
74 99
  end
75 100

  
101
  def visible_custom_field_values(user = nil)
102
    user ||= User.current
103
    custom_field_values.select do |value|
104
      value.custom_field.visible_by?(project, user)
105
    end
106
  end
107

  
76 108
  # Version files have same visibility as project files
77 109
  def attachments_visible?(*args)
78 110
    project.present? && project.attachments_visible?(*args)
app/models/version_custom_field.rb
19 19
  def type_name
20 20
    :label_version_plural
21 21
  end
22

  
23
  def visible_by?(project, user=User.current)
24
    super || (roles & user.roles_for_project(project)).present?
25
  end
26

  
27
  def validate_custom_field
28
    super
29
    errors.add(:base, l(:label_role_plural) + ' ' + l('activerecord.errors.messages.blank')) unless visible? || roles.present?
30
  end
22 31
end
app/views/custom_fields/_form.html.erb
32 32
    <% if @custom_field.format.searchable_supported %>
33 33
    <p><%= f.check_box :searchable %></p>
34 34
    <% end %>
35
    <p>
36
      <label><%= l(:field_visible) %></label>
37
      <label class="block">
38
        <%= radio_button_tag 'custom_field[visible]', 1, @custom_field.visible?, :id => 'custom_field_visible_on',
39
              :data => {:disables => '.custom_field_role input'} %>
40
        <%= l(:label_visibility_public) %>
41
      </label>
42
      <label class="block">
43
        <%= radio_button_tag 'custom_field[visible]', 0, !@custom_field.visible?, :id => 'custom_field_visible_off',
44
              :data => {:enables => '.custom_field_role input'} %>
45
        <%= l(:label_visibility_roles) %>:
46
      </label>
47
      <% Role.givable.sorted.each do |role| %>
48
        <label class="block custom_field_role" style="padding-left:2em;">
49
          <%= check_box_tag 'custom_field[role_ids][]', role.id, @custom_field.roles.include?(role), :id => nil %>
50
          <%= role.name %>
51
        </label>
52
      <% end %>
53
      <%= hidden_field_tag 'custom_field[role_ids][]', '' %>
54
    </p>
35
    <%= render :partial => 'visibility_by_role_selector' %>
55 36

  
56 37
<% when "UserCustomField" %>
57 38
    <p><%= f.check_box :is_required %></p>
......
61 42

  
62 43
<% when "ProjectCustomField" %>
63 44
    <p><%= f.check_box :is_required %></p>
64
    <p><%= f.check_box :visible %></p>
65 45
    <% if @custom_field.format.searchable_supported %>
66 46
    <p><%= f.check_box :searchable %></p>
67 47
    <% end %>
68 48
    <p><%= f.check_box :is_filter %></p>
49
    <%= render :partial => 'visibility_by_role_selector' %>
69 50

  
70 51
<% when "VersionCustomField" %>
71 52
    <p><%= f.check_box :is_required %></p>
72 53
    <p><%= f.check_box :is_filter %></p>
54
    <%= render :partial => 'visibility_by_role_selector' %>
73 55

  
74 56
<% when "GroupCustomField" %>
75 57
    <p><%= f.check_box :is_required %></p>
app/views/custom_fields/_visibility_by_role_selector.html.erb
1
<p>
2
  <label><%= l(:field_visible) %></label>
3
  <label class="block">
4
    <%= radio_button_tag 'custom_field[visible]', 1, @custom_field.visible?, :id => 'custom_field_visible_on',
5
          :data => {:disables => '.custom_field_role input'} %>
6
    <%= l(:label_visibility_public) %>
7
  </label>
8
  <label class="block">
9
    <%= radio_button_tag 'custom_field[visible]', 0, !@custom_field.visible?, :id => 'custom_field_visible_off',
10
          :data => {:enables => '.custom_field_role input'} %>
11
    <%= l(:label_visibility_roles) %>:
12
  </label>
13
  <% Role.givable.sorted.each do |role| %>
14
    <label class="block custom_field_role" style="padding-left:2em;">
15
      <%= check_box_tag 'custom_field[role_ids][]', role.id, @custom_field.roles.include?(role), :id => nil %>
16
      <%= role.name %>
17
    </label>
18
  <% end %>
19
  <%= hidden_field_tag 'custom_field[role_ids][]', '' %>
20
</p>
21

  
app/views/projects/_form.html.erb
26 26

  
27 27
<%= wikitoolbar_for 'project_description' %>
28 28

  
29
<% @project.custom_field_values.each do |value| %>
29
<% @project.visible_custom_field_values.each do |value| %>
30 30
  <p><%= custom_field_tag_with_label :project, value %></p>
31 31
<% end %>
32 32
<%= call_hook(:view_projects_form, :project => @project, :form => f) %>
app/views/versions/_form.html.erb
11 11
<p><%= f.date_field :effective_date, :size => 10 %><%= calendar_for('version_effective_date') %></p>
12 12
<p><%= f.select :sharing, @version.allowed_sharings.collect {|v| [format_version_sharing(v), v]} %></p>
13 13

  
14
<% @version.custom_field_values.each do |value| %>
14
<% @version.visible_custom_field_values.each do |value| %>
15 15
  <p><%= custom_field_tag_with_label :version, value %></p>
16 16
<% end %>
17 17

  
app/views/versions/index.api.rsb
10 10
      api.due_date    version.effective_date
11 11
      api.sharing     version.sharing
12 12

  
13
      render_api_custom_values version.custom_field_values, api
13
      render_api_custom_values version.visible_custom_field_values, api
14 14

  
15 15
      api.created_on version.created_on
16 16
      api.updated_on version.updated_on
app/views/versions/show.api.rsb
8 8
  api.due_date    @version.effective_date
9 9
  api.sharing     @version.sharing
10 10

  
11
  render_api_custom_values @version.custom_field_values, api
11
  render_api_custom_values @version.visible_custom_field_values, api
12 12

  
13 13
  api.created_on @version.created_on
14 14
  api.updated_on @version.updated_on
(2-2/4)