]> source.dussan.org Git - redmine.git/commitdiff
Introduce permission to set a project public (#38048).
authorGo MAEDA <maeda@farend.jp>
Thu, 12 Jan 2023 02:59:54 +0000 (02:59 +0000)
committerGo MAEDA <maeda@farend.jp>
Thu, 12 Jan 2023 02:59:54 +0000 (02:59 +0000)
Patch by Felix Schäfer.

git-svn-id: https://svn.redmine.org/redmine/trunk@22038 e93f8b46-1217-0410-a6f0-8f06a7374b81

app/models/project.rb
app/views/projects/_form.html.erb
config/locales/de.yml
config/locales/en.yml
db/migrate/20221214173537_add_select_project_publicity_permission.rb [new file with mode: 0644]
lib/redmine/preparation.rb
test/fixtures/roles.yml
test/functional/projects_controller_test.rb

index d182dadceafd2f45c0babd7cad4cd2746ebd9058..80bea61d97b73084052b61a5dd48798f9fea4079 100644 (file)
@@ -823,7 +823,6 @@ class Project < ActiveRecord::Base
     'name',
     'description',
     'homepage',
-    'is_public',
     'identifier',
     'custom_field_values',
     'custom_fields',
@@ -834,6 +833,22 @@ class Project < ActiveRecord::Base
     'default_issue_query_id',
     'default_assigned_to_id')
 
+  safe_attributes(
+    'is_public',
+    :if =>
+      lambda do |project, user|
+        if project.new_record?
+          if user.admin?
+            true
+          else
+            default_member_role&.has_permission?(:select_project_publicity)
+          end
+        else
+          user.allowed_to?(:select_project_publicity, project)
+        end
+      end
+  )
+
   safe_attributes(
     'enabled_module_names',
     :if =>
index 7c988fb0e2f372c576dcb11bf871b1bc2c3de0bf..3cde415993645be2effa4c140416cebcad0e3262 100644 (file)
@@ -11,7 +11,7 @@
 <% end %></p>
 <p><%= f.text_field :homepage, :size => 60 %></p>
 <p>
-  <%= f.check_box :is_public %>
+  <%= f.check_box :is_public, :disabled => !@project.safe_attribute?(:is_public) %>
   <em class="info"><%= Setting.login_required? ? l(:text_project_is_public_non_member) : l(:text_project_is_public_anonymous) %></em>
 </p>
 
index 69513f96f4f45dff5e2115b3384730a802e1281a..9ac76f852d700407bcb594ea209e36462a5a49e9 100644 (file)
@@ -953,6 +953,7 @@ de:
   permission_rename_wiki_pages: Wiki-Seiten umbenennen
   permission_save_queries: Filter speichern
   permission_select_project_modules: Projektmodule auswählen
+  permission_select_project_publicity: Projekt als privat oder öffentlich markieren
   permission_set_issues_private: Tickets als privat oder öffentlich markieren
   permission_set_notes_private: Kommentar als privat markieren
   permission_set_own_issues_private: Eigene Tickets als privat oder öffentlich markieren
index d12c54497479ef88f3c8733ec5b9923c7afaf594..64d09c8cfd7985fa10e9b9ae4888bda0edcc8920 100644 (file)
@@ -522,6 +522,7 @@ en:
   permission_edit_project: Edit project
   permission_close_project: Close / reopen the project
   permission_delete_project: Delete the project
+  permission_select_project_publicity: Set project public or private
   permission_select_project_modules: Select project modules
   permission_manage_members: Manage members
   permission_manage_project_activities: Manage project activities
diff --git a/db/migrate/20221214173537_add_select_project_publicity_permission.rb b/db/migrate/20221214173537_add_select_project_publicity_permission.rb
new file mode 100644 (file)
index 0000000..9b3db0c
--- /dev/null
@@ -0,0 +1,15 @@
+class AddSelectProjectPublicityPermission < ActiveRecord::Migration[5.2]
+  def up
+    Role.find_each do |r|
+      r.add_permission!(:select_project_publicity) if r.permissions.include?(:edit_project)
+    end
+  end
+
+  def down
+    Role.find_each do |r|
+      r.remove_permission!(:select_project_publicity)
+    end
+  end
+
+  def run_in_request?; true end
+end
index 54b623973cd33ff2b0e0646ff4e3d8974ef91215..c51ecfdb95a1b937c42b5e1ad1dd51d9160e5b38 100644 (file)
@@ -39,6 +39,7 @@ module Redmine
         map.permission :edit_project, {:projects => [:settings, :edit, :update]}, :require => :member
         map.permission :close_project, {:projects => [:close, :reopen]}, :require => :member, :read => true
         map.permission :delete_project, {:projects => :destroy}, :require => :member, :read => true
+        map.permission :select_project_publicity, {}, :require => :member
         map.permission :select_project_modules, {:projects => :modules}, :require => :member
         map.permission :view_members, {:members => [:index, :show]}, :public => true, :read => true
         map.permission :manage_members, {:projects => :settings, :members => [:index, :show, :new, :create, :edit, :update, :destroy, :autocomplete]}, :require => :member
index 076d347ff73ea56ac436393c3c13829c97eaea42..df15c9c0fbcb988d6e6a36d533fbc082964de24e 100644 (file)
@@ -11,6 +11,7 @@ roles_001:
     - :edit_project
     - :close_project
     - :delete_project
+    - :select_project_publicity
     - :select_project_modules
     - :manage_members
     - :manage_versions
@@ -85,6 +86,7 @@ roles_002:
     ---
     - :edit_project
     - :delete_project
+    - :select_project_publicity
     - :manage_members
     - :manage_versions
     - :manage_categories
@@ -137,6 +139,7 @@ roles_003:
   permissions: |
     ---
     - :edit_project
+    - :select_project_publicity
     - :manage_members
     - :manage_versions
     - :manage_categories
index a18850e662f208f39190d746c7b8614a0e9d0412..0ac0ecc3611818e364c9aa9366818f56ebce4be6 100644 (file)
@@ -407,6 +407,22 @@ class ProjectsControllerTest < Redmine::ControllerTest
     end
   end
 
+  def test_new_by_non_admin_should_enable_setting_public_if_default_role_is_allowed_to_set_public
+    Role.non_member.add_permission!(:add_project)
+    default_role = Role.generate!(permissions: [:add_project])
+    user = User.generate!
+    @request.session[:user_id] = user.id
+
+    with_settings new_project_user_role_id: default_role.id.to_s do
+      get :new
+      assert_select 'input[name=?][disabled=disabled]', 'project[is_public]'
+
+      default_role.add_permission!(:select_project_publicity)
+      get :new
+      assert_select 'input[name=?]:not([disabled])', 'project[is_public]'
+    end
+  end
+
   def test_new_should_not_display_invalid_search_link
     @request.session[:user_id] = 1
 
@@ -504,7 +520,6 @@ class ProjectsControllerTest < Redmine::ControllerTest
           :name => "blog",
           :description => "weblog",
           :identifier => "blog",
-          :is_public => 1,
           :custom_field_values => {
             '3' => 'Beta'
           },
@@ -518,7 +533,6 @@ class ProjectsControllerTest < Redmine::ControllerTest
     project = Project.find_by_name('blog')
     assert_kind_of Project, project
     assert_equal 'weblog', project.description
-    assert_equal true, project.is_public?
     assert_equal [1, 3], project.trackers.map(&:id).sort
     assert_equal ['issue_tracking', 'news', 'repository'], project.enabled_module_names.sort
 
@@ -527,6 +541,45 @@ class ProjectsControllerTest < Redmine::ControllerTest
     assert_equal 1, project.members.size
   end
 
+  test "#create by user without select_project_publicity permission should not create a new private project" do
+    Role.non_member.add_permission! :add_project
+    default_role = Project.default_member_role
+    default_role.remove_permission!(:select_project_publicity)
+    @request.session[:user_id] = 9
+
+    post(
+      :create, :params => {
+        :project => {
+          :name => "blog",
+          :identifier => "blog",
+          :enabled_module_names => ['issue_tracking', 'news', 'repository'],
+          :is_public => 0
+        }
+      }
+    )
+
+    project = Project.find_by_name('blog')
+    assert_equal true, project.is_public?
+  end
+
+  test "#create by non-admin user with add_project and select_project_publicity permission should create a new private project" do
+    @request.session[:user_id] = 2
+
+    post(
+      :create, :params => {
+        :project => {
+          :name => "blog",
+          :identifier => "blog",
+          :enabled_module_names => ['issue_tracking', 'news', 'repository'],
+          :is_public => 0
+        }
+      }
+    )
+
+    project = Project.find_by_name('blog')
+    assert_equal false, project.is_public?
+  end
+
   test "#create by non-admin user with add_project permission should fail with parent_id" do
     Role.non_member.add_permission! :add_project
     User.find(9).update! :language => 'en'