Commit 8141110e authored by Jean-Philippe Lang's avatar Jean-Philippe Lang

Ability to allow non-admin users to create projects (#1007).

This can be enabled in permissions settings. A non-admin user who creates a project is automatically added as a project member (the first role is given, TODO: make this given role configurable).
Projects can be added from the public projects list.

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@2750 e93f8b46-1217-0410-a6f0-8f06a7374b81
parent 9c9dc6e8
......@@ -114,10 +114,15 @@ class ApplicationController < ActionController::Base
end
# Authorize the user for the requested action
def authorize(ctrl = params[:controller], action = params[:action])
allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @project)
def authorize(ctrl = params[:controller], action = params[:action], global = false)
allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @project, :global => global)
allowed ? true : deny_access
end
# Authorize the user for the requested action outside a project
def authorize_global(ctrl = params[:controller], action = params[:action], global = true)
authorize(ctrl, action, global)
end
# make sure that the user is a member of the project (or admin) if project is private
# used as a before_filter for actions that do not require any particular permission on the project
......
......@@ -26,7 +26,8 @@ class ProjectsController < ApplicationController
before_filter :find_project, :except => [ :index, :list, :add, :copy, :activity ]
before_filter :find_optional_project, :only => :activity
before_filter :authorize, :except => [ :index, :list, :add, :copy, :archive, :unarchive, :destroy, :activity ]
before_filter :require_admin, :only => [ :add, :copy, :archive, :unarchive, :destroy ]
before_filter :authorize_global, :only => :add
before_filter :require_admin, :only => [ :copy, :archive, :unarchive, :destroy ]
accept_key_auth :activity
after_filter :only => [:add, :edit, :archive, :unarchive, :destroy] do |controller|
......@@ -75,9 +76,14 @@ class ProjectsController < ApplicationController
@project.enabled_module_names = params[:enabled_modules]
if @project.save
@project.set_parent!(params[:project]['parent_id']) if User.current.admin? && params[:project].has_key?('parent_id')
# Add current user as a project member if he is not admin
unless User.current.admin?
m = Member.new(:user => User.current, :roles => Role.builtin(false).find(:all, :order => 'position', :limit => 1))
@project.members << m
end
flash[:notice] = l(:notice_successful_create)
redirect_to :controller => 'admin', :action => 'projects'
end
redirect_to :controller => 'projects', :action => 'settings', :id => @project
end
end
end
......
......@@ -277,6 +277,9 @@ class User < ActiveRecord::Base
roles.detect {|role| (project.is_public? || role.member?) && role.allowed_to?(action)}
elsif options[:global]
# Admin users are always authorized
return true if admin?
# authorize if user has at least one role that has this permission
roles = memberships.collect {|m| m.roles}.flatten.uniq
roles.detect {|r| r.allowed_to?(action)} || (self.logged? ? Role.non_member.allowed_to?(action) : Role.anonymous.allowed_to?(action))
......
<div class="contextual">
<%= link_to(l(:label_project_new), {:controller => 'projects', :action => 'add'}, :class => 'icon icon-add') + ' |' if User.current.admin? %>
<%= link_to(l(:label_project_new), {:controller => 'projects', :action => 'add'}, :class => 'icon icon-add') + ' |' if User.current.allowed_to?(:add_project, nil, :global => true) %>
<%= link_to l(:label_issue_view_all), { :controller => 'issues' } %> |
<%= link_to l(:label_overall_activity), { :controller => 'projects', :action => 'activity' }%>
</div>
......
......@@ -796,3 +796,4 @@ bg:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -829,3 +829,4 @@ bs:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -799,3 +799,4 @@ ca:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -802,3 +802,4 @@ cs:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -829,3 +829,4 @@ da:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -828,3 +828,4 @@ de:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -292,6 +292,7 @@ en:
setting_openid: Allow OpenID login and registration
setting_password_min_length: Minimum password length
permission_add_project: Create project
permission_edit_project: Edit project
permission_select_project_modules: Select project modules
permission_manage_members: Manage members
......
......@@ -849,3 +849,4 @@ es:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -839,3 +839,4 @@ fi:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -324,6 +324,7 @@ fr:
setting_openid: "Autoriser l'authentification et l'enregistrement OpenID"
setting_password_min_length: Longueur minimum des mots de passe
permission_add_project: Créer un projet
permission_edit_project: Modifier le projet
permission_select_project_modules: Choisir les modules
permission_manage_members: Gérer les members
......
......@@ -828,3 +828,4 @@ gl:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -811,3 +811,4 @@ he:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -834,3 +834,4 @@
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -814,3 +814,4 @@ it:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -827,3 +827,4 @@ ja:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -858,3 +858,4 @@ ko:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -839,3 +839,4 @@ lt:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -784,3 +784,4 @@ nl:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -801,3 +801,4 @@
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -832,3 +832,4 @@ pl:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -834,3 +834,4 @@ pt-BR:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -820,3 +820,4 @@ pt:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -799,3 +799,4 @@ ro:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -926,3 +926,4 @@ ru:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -800,3 +800,4 @@ sk:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -798,3 +798,4 @@ sl:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -822,3 +822,4 @@
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -856,3 +856,4 @@ sv:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -799,3 +799,4 @@ th:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -835,3 +835,4 @@ tr:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -798,3 +798,4 @@ uk:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -868,3 +868,4 @@ vi:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -906,3 +906,4 @@
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -831,3 +831,4 @@ zh:
mail_body_wiki_content_added: The '{{page}}' wiki page has been added by {{author}}.
label_wiki_content_updated: Wiki page updated
mail_body_wiki_content_updated: The '{{page}}' wiki page has been updated by {{author}}.
permission_add_project: Create project
......@@ -20,6 +20,7 @@ REDMINE_SUPPORTED_SCM = %w( Subversion Darcs Mercurial Cvs Bazaar Git Filesystem
Redmine::AccessControl.map do |map|
map.permission :view_project, {:projects => [:show, :activity]}, :public => true
map.permission :search_project, {:search => :index}, :public => true
map.permission :add_project, {:projects => :add}, :require => :loggedin
map.permission :edit_project, {:projects => [:settings, :edit]}, :require => :member
map.permission :select_project_modules, {:projects => :modules}, :require => :member
map.permission :manage_members, {:projects => :settings, :members => [:new, :edit, :destroy, :autocomplete_for_member_login]}, :require => :member
......
......@@ -5,6 +5,7 @@ roles_001:
builtin: 0
permissions: |
---
- :add_project
- :edit_project
- :manage_members
- :manage_versions
......
......@@ -89,6 +89,56 @@ class ProjectsControllerTest < Test::Unit::TestCase
)
end
def test_get_add
@request.session[:user_id] = 1
get :add
assert_response :success
assert_template 'add'
end
def test_get_add_by_non_admin
@request.session[:user_id] = 2
get :add
assert_response :success
assert_template 'add'
end
def test_post_add
@request.session[:user_id] = 1
post :add, :project => { :name => "blog",
:description => "weblog",
:identifier => "blog",
:is_public => 1,
:custom_field_values => { '3' => 'Beta' }
}
assert_redirected_to '/projects/blog/settings'
project = Project.find_by_name('blog')
assert_kind_of Project, project
assert_equal 'weblog', project.description
assert_equal true, project.is_public?
end
def test_post_add_by_non_admin
@request.session[:user_id] = 2
post :add, :project => { :name => "blog",
:description => "weblog",
:identifier => "blog",
:is_public => 1,
:custom_field_values => { '3' => 'Beta' }
}
assert_redirected_to '/projects/blog/settings'
project = Project.find_by_name('blog')
assert_kind_of Project, project
assert_equal 'weblog', project.description
assert_equal true, project.is_public?
# User should be added as a project member
assert User.find(2).member_of?(project)
assert_equal 1, project.members.size
end
def test_show_routing
assert_routing(
{:method => :get, :path => '/projects/test'},
......
......@@ -39,28 +39,4 @@ class AdminTest < ActionController::IntegrationTest
locked_user = User.try_to_login("psmith", "psmith09")
assert_equal nil, locked_user
end
def test_add_project
log_user("admin", "admin")
get "projects/new"
assert_response :success
assert_template "projects/add"
post "projects", :project => { :name => "blog",
:description => "weblog",
:identifier => "blog",
:is_public => 1,
:custom_field_values => { '3' => 'Beta' }
}
assert_redirected_to "admin/projects"
assert_equal 'Successful creation.', flash[:notice]
project = Project.find_by_name("blog")
assert_kind_of Project, project
assert_equal "weblog", project.description
assert_equal true, project.is_public?
get "admin/projects"
assert_response :success
assert_template "admin/projects"
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment