summaryrefslogtreecommitdiffstats
path: root/app/models
diff options
context:
space:
mode:
authorJean-Philippe Lang <jp_lang@yahoo.fr>2007-09-14 11:34:08 +0000
committerJean-Philippe Lang <jp_lang@yahoo.fr>2007-09-14 11:34:08 +0000
commit21c97c6a1376a38a3951c57069317c17c81029f8 (patch)
tree8d38f129585767d4c1eb2c78d0b9b978aff14d70 /app/models
parent29348fafb7ca43cb00ef80f29e61167647df0cd8 (diff)
downloadredmine-21c97c6a1376a38a3951c57069317c17c81029f8.tar.gz
redmine-21c97c6a1376a38a3951c57069317c17c81029f8.zip
Added project module concept.
A project module (eg. issue tracking, news, wiki,...) is a set of permissions that can enabled/disabled at project level. For each project, modules can be enabled on the project settings view ('Modules' tab). This requires a specific permission: 'Select project modules' (if this permission is turned off, only Redmine administrators can choose which modules a project uses). When applying this migration, all modules are enabled for all existing projects. git-svn-id: http://redmine.rubyforge.org/svn/trunk@725 e93f8b46-1217-0410-a6f0-8f06a7374b81
Diffstat (limited to 'app/models')
-rw-r--r--app/models/enabled_module.rb23
-rw-r--r--app/models/project.rb36
-rw-r--r--app/models/user.rb5
3 files changed, 63 insertions, 1 deletions
diff --git a/app/models/enabled_module.rb b/app/models/enabled_module.rb
new file mode 100644
index 000000000..3c05c76c1
--- /dev/null
+++ b/app/models/enabled_module.rb
@@ -0,0 +1,23 @@
+# redMine - project management software
+# Copyright (C) 2006-2007 Jean-Philippe Lang
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+
+class EnabledModule < ActiveRecord::Base
+ belongs_to :project
+
+ validates_presence_of :name
+ validates_uniqueness_of :name, :scope => :project_id
+end
diff --git a/app/models/project.rb b/app/models/project.rb
index fa975c435..fb5c63fe2 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -23,6 +23,7 @@ class Project < ActiveRecord::Base
has_many :members, :dependent => :delete_all, :include => :user, :conditions => "#{User.table_name}.status=#{User::STATUS_ACTIVE}"
has_many :users, :through => :members
has_many :custom_values, :dependent => :delete_all, :as => :customized
+ has_many :enabled_modules, :dependent => :delete_all
has_many :issues, :dependent => :destroy, :order => "#{Issue.table_name}.created_on DESC", :include => [:status, :tracker]
has_many :issue_changes, :through => :issues, :source => :journals
has_many :versions, :dependent => :destroy, :order => "#{Version.table_name}.effective_date DESC, #{Version.table_name}.name DESC"
@@ -38,7 +39,7 @@ class Project < ActiveRecord::Base
has_and_belongs_to_many :custom_fields, :class_name => 'IssueCustomField', :join_table => "#{table_name_prefix}custom_fields_projects#{table_name_suffix}", :association_foreign_key => 'custom_field_id'
acts_as_tree :order => "name", :counter_cache => true
- attr_protected :status
+ attr_protected :status, :enabled_module_names
validates_presence_of :name, :description, :identifier
validates_uniqueness_of :name, :identifier
@@ -121,10 +122,43 @@ class Project < ActiveRecord::Base
def <=>(project)
name <=> project.name
end
+
+ def allows_to?(action)
+ if action.is_a? Hash
+ allowed_actions.include? "#{action[:controller]}/#{action[:action]}"
+ else
+ allowed_permissions.include? action
+ end
+ end
+
+ def module_enabled?(module_name)
+ module_name = module_name.to_s
+ enabled_modules.detect {|m| m.name == module_name}
+ end
+
+ def enabled_module_names=(module_names)
+ enabled_modules.clear
+ module_names = [] unless module_names && module_names.is_a?(Array)
+ module_names.each do |name|
+ enabled_modules << EnabledModule.new(:name => name.to_s)
+ end
+ end
protected
def validate
errors.add(parent_id, " must be a root project") if parent and parent.parent
errors.add_to_base("A project with subprojects can't be a subproject") if parent and children.size > 0
end
+
+private
+ def allowed_permissions
+ @allowed_permissions ||= begin
+ module_names = enabled_modules.collect {|m| m.name}
+ Redmine::AccessControl.modules_permissions(module_names).collect {|p| p.name}
+ end
+ end
+
+ def allowed_actions
+ @actions_allowed ||= allowed_permissions.inject([]) { |actions, permission| actions += Redmine::AccessControl.allowed_actions(permission) }.flatten
+ end
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 4cb8da1f9..e4c397a51 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -178,8 +178,13 @@ class User < ActiveRecord::Base
# * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit')
# * a permission Symbol (eg. :edit_project)
def allowed_to?(action, project)
+ # No action allowed on archived projects
return false unless project.active?
+ # No action allowed on disabled modules
+ return false unless project.allows_to?(action)
+ # Admin users are authorized for anything else
return true if admin?
+
role = role_for_project(project)
return false unless role
role.allowed_to?(action) && (project.is_public? || role.member?)