Permissions management was rewritten. Some permissions can now be specifically defined for non member and anonymous users. This migration: * is irreversible (please, don't forget to *backup* your database before upgrading) * resets role's permissions (go to "Admin -> Roles & Permissions" to set them after upgrading) git-svn-id: http://redmine.rubyforge.org/svn/trunk@674 e93f8b46-1217-0410-a6f0-8f06a7374b81tags/0.6.0
@@ -22,7 +22,6 @@ class AccountController < ApplicationController | |||
# prevents login action to be filtered by check_if_login_required application scope filter | |||
skip_before_filter :check_if_login_required, :only => [:login, :lost_password, :register] | |||
before_filter :require_login, :only => :logout | |||
# Show user's account | |||
def show | |||
@@ -31,7 +30,7 @@ class AccountController < ApplicationController | |||
# show only public projects and private projects that the logged in user is also a member of | |||
@memberships = @user.memberships.select do |membership| | |||
membership.project.is_public? || (logged_in_user && logged_in_user.role_for_project(membership.project)) | |||
membership.project.is_public? || (User.current.role_for_project(membership.project)) | |||
end | |||
rescue ActiveRecord::RecordNotFound | |||
render_404 | |||
@@ -41,12 +40,12 @@ class AccountController < ApplicationController | |||
def login | |||
if request.get? | |||
# Logout user | |||
self.logged_in_user = nil | |||
self.logged_user = nil | |||
else | |||
# Authenticate user | |||
user = User.try_to_login(params[:login], params[:password]) | |||
if user | |||
self.logged_in_user = user | |||
self.logged_user = user | |||
# generate a key and set cookie if autologin | |||
if params[:autologin] && Setting.autologin? | |||
token = Token.create(:user => user, :action => 'autologin') | |||
@@ -62,8 +61,8 @@ class AccountController < ApplicationController | |||
# Log out current user and redirect to welcome page | |||
def logout | |||
cookies.delete :autologin | |||
Token.delete_all(["user_id = ? AND action = ?", logged_in_user.id, "autologin"]) if logged_in_user | |||
self.logged_in_user = nil | |||
Token.delete_all(["user_id = ? AND action = ?", User.current.id, 'autologin']) if User.current.logged? | |||
self.logged_user = nil | |||
redirect_to :controller => 'welcome' | |||
end | |||
@@ -140,4 +139,15 @@ class AccountController < ApplicationController | |||
end | |||
end | |||
end | |||
private | |||
def logged_user=(user) | |||
if user && user.is_a?(User) | |||
User.current = user | |||
session[:user_id] = user.id | |||
else | |||
User.current = User.anonymous | |||
session[:user_id] = nil | |||
end | |||
end | |||
end |
@@ -46,14 +46,6 @@ class AdminController < ApplicationController | |||
end | |||
def mail_options | |||
@actions = Permission.find(:all, :conditions => ["mail_option=?", true]) || [] | |||
if request.post? | |||
@actions.each { |a| | |||
a.mail_enabled = (params[:action_ids] || []).include? a.id.to_s | |||
a.save | |||
} | |||
flash.now[:notice] = l(:notice_successful_update) | |||
end | |||
end | |||
def test_email | |||
@@ -61,8 +53,8 @@ class AdminController < ApplicationController | |||
# Force ActionMailer to raise delivery errors so we can catch it | |||
ActionMailer::Base.raise_delivery_errors = true | |||
begin | |||
@test = Mailer.deliver_test(logged_in_user) | |||
flash[:notice] = l(:notice_email_sent, logged_in_user.mail) | |||
@test = Mailer.deliver_test(User.current) | |||
flash[:notice] = l(:notice_email_sent, User.current.mail) | |||
rescue Exception => e | |||
flash[:error] = l(:notice_email_error, e.message) | |||
end |
@@ -16,48 +16,47 @@ | |||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
class ApplicationController < ActionController::Base | |||
before_filter :check_if_login_required, :set_localization | |||
before_filter :user_setup, :check_if_login_required, :set_localization | |||
filter_parameter_logging :password | |||
REDMINE_SUPPORTED_SCM.each do |scm| | |||
require_dependency "repository/#{scm.underscore}" | |||
end | |||
def logged_in_user=(user) | |||
@logged_in_user = user | |||
session[:user_id] = (user ? user.id : nil) | |||
def logged_in_user | |||
User.current.logged? ? User.current : nil | |||
end | |||
def logged_in_user | |||
def current_role | |||
@current_role ||= User.current.role_for_project(@project) | |||
end | |||
def user_setup | |||
if session[:user_id] | |||
@logged_in_user ||= User.find(session[:user_id]) | |||
# existing session | |||
User.current = User.find(session[:user_id]) | |||
elsif cookies[:autologin] && Setting.autologin? | |||
# auto-login feature | |||
User.current = User.find_by_autologin_key(autologin_key) | |||
elsif params[:key] && accept_key_auth_actions.include?(params[:action]) | |||
# RSS key authentication | |||
User.current = User.find_by_rss_key(params[:key]) | |||
else | |||
nil | |||
User.current = User.anonymous | |||
end | |||
end | |||
# Returns the role that the logged in user has on the current project | |||
# or nil if current user is not a member of the project | |||
def logged_in_user_membership | |||
@user_membership ||= logged_in_user.role_for_project(@project) | |||
end | |||
# check if login is globally required to access the application | |||
def check_if_login_required | |||
# no check needed if user is already logged in | |||
return true if logged_in_user | |||
# auto-login feature | |||
autologin_key = cookies[:autologin] | |||
if autologin_key && Setting.autologin? | |||
self.logged_in_user = User.find_by_autologin_key(autologin_key) | |||
end | |||
return true if User.current.logged? | |||
require_login if Setting.login_required? | |||
end | |||
def set_localization | |||
lang = begin | |||
if self.logged_in_user and self.logged_in_user.language and !self.logged_in_user.language.empty? and GLoc.valid_languages.include? self.logged_in_user.language.to_sym | |||
self.logged_in_user.language | |||
if !User.current.language.blank? and GLoc.valid_languages.include? User.current.language.to_sym | |||
User.current.language | |||
elsif request.env['HTTP_ACCEPT_LANGUAGE'] | |||
accept_lang = parse_qvalues(request.env['HTTP_ACCEPT_LANGUAGE']).first.split('-').first | |||
if accept_lang and !accept_lang.empty? and GLoc.valid_languages.include? accept_lang.to_sym | |||
@@ -71,7 +70,7 @@ class ApplicationController < ActionController::Base | |||
end | |||
def require_login | |||
unless self.logged_in_user | |||
if !User.current.logged? | |||
store_location | |||
redirect_to :controller => "account", :action => "login" | |||
return false | |||
@@ -81,34 +80,17 @@ class ApplicationController < ActionController::Base | |||
def require_admin | |||
return unless require_login | |||
unless self.logged_in_user.admin? | |||
if !User.current.admin? | |||
render_403 | |||
return false | |||
end | |||
true | |||
end | |||
# authorizes the user for the requested action. | |||
# Authorize the user for the requested action | |||
def authorize(ctrl = params[:controller], action = params[:action]) | |||
unless @project.active? | |||
@project = nil | |||
render_404 | |||
return false | |||
end | |||
# check if action is allowed on public projects | |||
if @project.is_public? and Permission.allowed_to_public "%s/%s" % [ ctrl, action ] | |||
return true | |||
end | |||
# if action is not public, force login | |||
return unless require_login | |||
# admin is always authorized | |||
return true if self.logged_in_user.admin? | |||
# if not admin, check membership permission | |||
if logged_in_user_membership and Permission.allowed_to_role( "%s/%s" % [ ctrl, action ], logged_in_user_membership ) | |||
return true | |||
end | |||
render_403 | |||
false | |||
allowed = User.current.allowed_to?({:controller => ctrl, :action => action}, @project) | |||
allowed ? true : (User.current.logged? ? render_403 : require_login) | |||
end | |||
# make sure that the user is a member of the project (or admin) if project is private | |||
@@ -119,11 +101,8 @@ class ApplicationController < ActionController::Base | |||
render_404 | |||
return false | |||
end | |||
return true if @project.is_public? | |||
return false unless logged_in_user | |||
return true if logged_in_user.admin? || logged_in_user_membership | |||
render_403 | |||
false | |||
return true if @project.is_public? || User.current.member_of?(@project) || User.current.admin? | |||
User.current.logged? ? render_403 : require_login | |||
end | |||
# store current uri in session. | |||
@@ -154,6 +133,21 @@ class ApplicationController < ActionController::Base | |||
render :template => "common/404", :layout => true, :status => 404 | |||
return false | |||
end | |||
def render_feed(items, options={}) | |||
@items = items.sort {|x,y| y.event_datetime <=> x.event_datetime } | |||
@title = options[:title] || Setting.app_title | |||
render :template => "common/feed.atom.rxml", :layout => false, :content_type => 'application/atom+xml' | |||
end | |||
def self.accept_key_auth(*actions) | |||
actions = actions.flatten.map(&:to_s) | |||
write_inheritable_attribute('accept_key_auth_actions', actions) | |||
end | |||
def accept_key_auth_actions | |||
self.class.read_inheritable_attribute('accept_key_auth_actions') || [] | |||
end | |||
# qvalues http header parser | |||
# code taken from webrick | |||
@@ -173,4 +167,4 @@ class ApplicationController < ActionController::Base | |||
end | |||
return tmp | |||
end | |||
end | |||
end |
@@ -17,9 +17,7 @@ | |||
class BoardsController < ApplicationController | |||
layout 'base' | |||
before_filter :find_project | |||
before_filter :authorize, :except => [:index, :show] | |||
before_filter :check_project_privacy, :only => [:index, :show] | |||
before_filter :find_project, :authorize | |||
helper :messages | |||
include MessagesHelper |
@@ -52,7 +52,7 @@ class DocumentsController < ApplicationController | |||
a = Attachment.create(:container => @document, :file => file, :author => logged_in_user) | |||
@attachments << a unless a.new_record? | |||
} if params[:attachments] and params[:attachments].is_a? Array | |||
Mailer.deliver_attachments_add(@attachments) if !@attachments.empty? and Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled? | |||
Mailer.deliver_attachments_add(@attachments) if !@attachments.empty? #and Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled? | |||
redirect_to :action => 'show', :id => @document | |||
end | |||
@@ -72,8 +72,15 @@ class IssuesController < ApplicationController | |||
unless params[:notes].empty? | |||
journal = @issue.init_journal(self.logged_in_user, params[:notes]) | |||
if @issue.save | |||
params[:attachments].each { |file| | |||
next unless file.size > 0 | |||
a = Attachment.create(:container => @issue, :file => file, :author => logged_in_user) | |||
journal.details << JournalDetail.new(:property => 'attachment', | |||
:prop_key => a.id, | |||
:value => a.filename) unless a.new_record? | |||
} if params[:attachments] and params[:attachments].is_a? Array | |||
flash[:notice] = l(:notice_successful_update) | |||
Mailer.deliver_issue_edit(journal) if Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled? | |||
Mailer.deliver_issue_edit(journal) #if Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled? | |||
redirect_to :action => 'show', :id => @issue | |||
return | |||
end | |||
@@ -100,14 +107,14 @@ class IssuesController < ApplicationController | |||
} if params[:attachments] and params[:attachments].is_a? Array | |||
# Log time | |||
if logged_in_user.authorized_to(@project, "timelog/edit") | |||
if current_role.allowed_to?(:log_time) | |||
@time_entry ||= TimeEntry.new(:project => @project, :issue => @issue, :user => logged_in_user, :spent_on => Date.today) | |||
@time_entry.attributes = params[:time_entry] | |||
@time_entry.save | |||
end | |||
flash[:notice] = l(:notice_successful_update) | |||
Mailer.deliver_issue_edit(journal) if Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled? | |||
Mailer.deliver_issue_edit(journal) #if Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled? | |||
redirect_to :action => 'show', :id => @issue | |||
end | |||
rescue ActiveRecord::StaleObjectError | |||
@@ -124,23 +131,6 @@ class IssuesController < ApplicationController | |||
redirect_to :controller => 'projects', :action => 'list_issues', :id => @project | |||
end | |||
def add_attachment | |||
# Save the attachments | |||
@attachments = [] | |||
journal = @issue.init_journal(self.logged_in_user) | |||
params[:attachments].each { |file| | |||
next unless file.size > 0 | |||
a = Attachment.create(:container => @issue, :file => file, :author => logged_in_user) | |||
@attachments << a unless a.new_record? | |||
journal.details << JournalDetail.new(:property => 'attachment', | |||
:prop_key => a.id, | |||
:value => a.filename) unless a.new_record? | |||
} if params[:attachments] and params[:attachments].is_a? Array | |||
journal.save if journal.details.any? | |||
Mailer.deliver_attachments_add(@attachments) if !@attachments.empty? and Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled? | |||
redirect_to :action => 'show', :id => @issue | |||
end | |||
def destroy_attachment | |||
a = @issue.attachments.find(params[:attachment_id]) | |||
a.destroy |
@@ -17,8 +17,7 @@ | |||
class MessagesController < ApplicationController | |||
layout 'base' | |||
before_filter :find_project, :check_project_privacy | |||
before_filter :require_login, :only => [:new, :reply] | |||
before_filter :find_project, :authorize | |||
verify :method => :post, :only => [ :reply, :destroy ], :redirect_to => { :action => :show } | |||
@@ -22,6 +22,7 @@ class ProjectsController < ApplicationController | |||
before_filter :find_project, :except => [ :index, :list, :add ] | |||
before_filter :authorize, :except => [ :index, :list, :add, :archive, :unarchive, :destroy ] | |||
before_filter :require_admin, :only => [ :add, :archive, :unarchive, :destroy ] | |||
accept_key_auth :activity, :calendar | |||
cache_sweeper :project_sweeper, :only => [ :add, :edit, :archive, :unarchive, :destroy ] | |||
cache_sweeper :issue_sweeper, :only => [ :add_issue ] | |||
@@ -97,8 +98,7 @@ class ProjectsController < ApplicationController | |||
@trackers = Tracker.find(:all, :order => 'position') | |||
@open_issues_by_tracker = Issue.count(:group => :tracker, :joins => "INNER JOIN #{IssueStatus.table_name} ON #{IssueStatus.table_name}.id = #{Issue.table_name}.status_id", :conditions => ["project_id=? and #{IssueStatus.table_name}.is_closed=?", @project.id, false]) | |||
@total_issues_by_tracker = Issue.count(:group => :tracker, :conditions => ["project_id=?", @project.id]) | |||
@key = logged_in_user.get_or_create_rss_key.value if logged_in_user | |||
@key = User.current.rss_key | |||
end | |||
def settings | |||
@@ -224,7 +224,7 @@ class ProjectsController < ApplicationController | |||
Attachment.create(:container => @document, :file => a, :author => logged_in_user) unless a.size == 0 | |||
} if params[:attachments] and params[:attachments].is_a? Array | |||
flash[:notice] = l(:notice_successful_create) | |||
Mailer.deliver_document_add(@document) if Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled? | |||
Mailer.deliver_document_add(@document) #if Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled? | |||
redirect_to :action => 'list_documents', :id => @project | |||
end | |||
end | |||
@@ -268,7 +268,7 @@ class ProjectsController < ApplicationController | |||
if @issue.save | |||
@attachments.each(&:save) | |||
flash[:notice] = l(:notice_successful_create) | |||
Mailer.deliver_issue_add(@issue) if Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled? | |||
Mailer.deliver_issue_add(@issue) #if Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled? | |||
redirect_to :action => 'list_issues', :id => @project | |||
end | |||
end | |||
@@ -383,7 +383,7 @@ class ProjectsController < ApplicationController | |||
redirect_to :action => 'list_issues', :id => @project and return unless @issues | |||
@projects = [] | |||
# find projects to which the user is allowed to move the issue | |||
@logged_in_user.memberships.each {|m| @projects << m.project if Permission.allowed_to_role("projects/move_issues", m.role)} | |||
User.current.memberships.each {|m| @projects << m.project if m.role.allowed_to?(:controller => 'projects', :action => 'move_issues')} | |||
# issue can be moved to any tracker | |||
@trackers = Tracker.find(:all) | |||
if request.post? and params[:new_project_id] and params[:new_tracker_id] | |||
@@ -424,7 +424,11 @@ class ProjectsController < ApplicationController | |||
# Show news list of @project | |||
def list_news | |||
@news_pages, @news = paginate :news, :per_page => 10, :conditions => ["project_id=?", @project.id], :include => :author, :order => "#{News.table_name}.created_on DESC" | |||
render :action => "list_news", :layout => false if request.xhr? | |||
respond_to do |format| | |||
format.html { render :layout => false if request.xhr? } | |||
format.atom { render_feed(@news, :title => "#{@project.name}: #{l(:label_news_plural)}") } | |||
end | |||
end | |||
def add_file | |||
@@ -437,7 +441,7 @@ class ProjectsController < ApplicationController | |||
a = Attachment.create(:container => @version, :file => file, :author => logged_in_user) | |||
@attachments << a unless a.new_record? | |||
} if params[:attachments] and params[:attachments].is_a? Array | |||
Mailer.deliver_attachments_add(@attachments) if !@attachments.empty? and Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled? | |||
Mailer.deliver_attachments_add(@attachments) if !@attachments.empty? #and Permission.find_by_controller_and_action(params[:controller], params[:action]).mail_enabled? | |||
redirect_to :controller => 'projects', :action => 'list_files', :id => @project | |||
end | |||
@versions = @project.versions.sort | |||
@@ -471,80 +475,67 @@ class ProjectsController < ApplicationController | |||
@year ||= Date.today.year | |||
@month ||= Date.today.month | |||
@date_from = Date.civil(@year, @month, 1) | |||
@date_to = @date_from >> 1 | |||
case params[:format] | |||
when 'rss' | |||
# 30 last days | |||
@date_from = Date.today - 30 | |||
@date_to = Date.today + 1 | |||
else | |||
# current month | |||
@date_from = Date.civil(@year, @month, 1) | |||
@date_to = @date_from >> 1 | |||
end | |||
@events_by_day = Hash.new { |h,k| h[k] = [] } | |||
@event_types = %w(issues news attachments documents wiki_edits revisions) | |||
@event_types.delete('wiki_edits') unless @project.wiki | |||
@event_types.delete('changesets') unless @project.repository | |||
unless params[:show_issues] == "0" | |||
@project.issues.find(:all, :include => [:author], :conditions => ["#{Issue.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to] ).each { |i| | |||
@events_by_day[i.created_on.to_date] << i | |||
} | |||
@project.issue_changes.find(:all, :include => :details, :conditions => ["(#{Journal.table_name}.created_on BETWEEN ? AND ?) AND (#{JournalDetail.table_name}.prop_key = 'status_id')", @date_from, @date_to] ).each { |i| | |||
@events_by_day[i.created_on.to_date] << i | |||
} | |||
@show_issues = 1 | |||
@scope = @event_types.select {|t| params["show_#{t}"]} | |||
# default events if none is specified in parameters | |||
@scope = (@event_types - %w(wiki_edits))if @scope.empty? | |||
@events = [] | |||
if @scope.include?('issues') | |||
@events += @project.issues.find(:all, :include => [:author, :tracker], :conditions => ["#{Issue.table_name}.created_on>=? and #{Issue.table_name}.created_on<=?", @date_from, @date_to] ) | |||
end | |||
unless params[:show_news] == "0" | |||
@project.news.find(:all, :conditions => ["#{News.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to], :include => :author ).each { |i| | |||
@events_by_day[i.created_on.to_date] << i | |||
} | |||
@show_news = 1 | |||
if @scope.include?('news') | |||
@events += @project.news.find(:all, :conditions => ["#{News.table_name}.created_on>=? and #{News.table_name}.created_on<=?", @date_from, @date_to], :include => :author ) | |||
end | |||
unless params[:show_files] == "0" | |||
Attachment.find(:all, :select => "#{Attachment.table_name}.*", | |||
:joins => "LEFT JOIN #{Version.table_name} ON #{Version.table_name}.id = #{Attachment.table_name}.container_id", | |||
:conditions => ["#{Attachment.table_name}.container_type='Version' and #{Version.table_name}.project_id=? and #{Attachment.table_name}.created_on BETWEEN ? AND ? ", @project.id, @date_from, @date_to], | |||
:include => :author ).each { |i| | |||
@events_by_day[i.created_on.to_date] << i | |||
} | |||
@show_files = 1 | |||
if @scope.include?('attachments') | |||
@events += Attachment.find(:all, :select => "#{Attachment.table_name}.*", :joins => "LEFT JOIN #{Version.table_name} ON #{Version.table_name}.id = #{Attachment.table_name}.container_id", :conditions => ["#{Attachment.table_name}.container_type='Version' and #{Version.table_name}.project_id=? and #{Attachment.table_name}.created_on>=? and #{Attachment.table_name}.created_on<=?", @project.id, @date_from, @date_to], :include => :author ) | |||
end | |||
unless params[:show_documents] == "0" | |||
@project.documents.find(:all, :conditions => ["#{Document.table_name}.created_on BETWEEN ? AND ?", @date_from, @date_to] ).each { |i| | |||
@events_by_day[i.created_on.to_date] << i | |||
} | |||
Attachment.find(:all, :select => "attachments.*", | |||
:joins => "LEFT JOIN #{Document.table_name} ON #{Document.table_name}.id = #{Attachment.table_name}.container_id", | |||
:conditions => ["#{Attachment.table_name}.container_type='Document' and #{Document.table_name}.project_id=? and #{Attachment.table_name}.created_on BETWEEN ? AND ? ", @project.id, @date_from, @date_to], | |||
:include => :author ).each { |i| | |||
@events_by_day[i.created_on.to_date] << i | |||
} | |||
@show_documents = 1 | |||
if @scope.include?('documents') | |||
@events += @project.documents.find(:all, :conditions => ["#{Document.table_name}.created_on>=? and #{Document.table_name}.created_on<=?", @date_from, @date_to] ) | |||
@events += Attachment.find(:all, :select => "attachments.*", :joins => "LEFT JOIN #{Document.table_name} ON #{Document.table_name}.id = #{Attachment.table_name}.container_id", :conditions => ["#{Attachment.table_name}.container_type='Document' and #{Document.table_name}.project_id=? and #{Attachment.table_name}.created_on>=? and #{Attachment.table_name}.created_on<=?", @project.id, @date_from, @date_to], :include => :author ) | |||
end | |||
unless @project.wiki.nil? || params[:show_wiki_edits] == "0" | |||
if @scope.include?('wiki_edits') && @project.wiki | |||
select = "#{WikiContent.versioned_table_name}.updated_on, #{WikiContent.versioned_table_name}.comments, " + | |||
"#{WikiContent.versioned_table_name}.#{WikiContent.version_column}, #{WikiPage.table_name}.title" | |||
"#{WikiContent.versioned_table_name}.#{WikiContent.version_column}, #{WikiPage.table_name}.title, " + | |||
"#{WikiContent.versioned_table_name}.page_id, #{WikiContent.versioned_table_name}.author_id, " + | |||
"#{WikiContent.versioned_table_name}.id" | |||
joins = "LEFT JOIN #{WikiPage.table_name} ON #{WikiPage.table_name}.id = #{WikiContent.versioned_table_name}.page_id " + | |||
"LEFT JOIN #{Wiki.table_name} ON #{Wiki.table_name}.id = #{WikiPage.table_name}.wiki_id " | |||
conditions = ["#{Wiki.table_name}.project_id = ? AND #{WikiContent.versioned_table_name}.updated_on BETWEEN ? AND ?", | |||
@project.id, @date_from, @date_to] | |||
WikiContent.versioned_class.find(:all, :select => select, :joins => joins, :conditions => conditions).each { |i| | |||
# We provide this alias so all events can be treated in the same manner | |||
def i.created_on | |||
self.updated_on | |||
end | |||
@events_by_day[i.created_on.to_date] << i | |||
} | |||
@show_wiki_edits = 1 | |||
@events += WikiContent.versioned_class.find(:all, :select => select, :joins => joins, :conditions => conditions) | |||
end | |||
unless @project.repository.nil? || params[:show_changesets] == "0" | |||
@project.repository.changesets.find(:all, :conditions => ["#{Changeset.table_name}.committed_on BETWEEN ? AND ?", @date_from, @date_to]).each { |i| | |||
def i.created_on | |||
self.committed_on | |||
end | |||
@events_by_day[i.created_on.to_date] << i | |||
} | |||
@show_changesets = 1 | |||
if @scope.include?('revisions') && @project.repository | |||
@events += @project.repository.changesets.find(:all, :conditions => ["#{Changeset.table_name}.committed_on BETWEEN ? AND ?", @date_from, @date_to]) | |||
end | |||
render :layout => false if request.xhr? | |||
@events_by_day = @events.group_by(&:event_date) | |||
respond_to do |format| | |||
format.html { render :layout => false if request.xhr? } | |||
format.atom { render_feed(@events, :title => "#{@project.name}: #{l(:label_activity)}") } | |||
end | |||
end | |||
def calendar | |||
@@ -630,7 +621,7 @@ class ProjectsController < ApplicationController | |||
def feeds | |||
@queries = @project.queries.find :all, :conditions => ["is_public=? or user_id=?", true, (logged_in_user ? logged_in_user.id : 0)] | |||
@key = logged_in_user.get_or_create_rss_key.value if logged_in_user | |||
@key = User.current.rss_key | |||
end | |||
private |
@@ -16,9 +16,8 @@ | |||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
class QueriesController < ApplicationController | |||
layout 'base' | |||
before_filter :require_login, :except => :index | |||
before_filter :find_project, :check_project_privacy | |||
layout 'base' | |||
before_filter :find_project, :authorize | |||
def index | |||
@queries = @project.queries.find(:all, | |||
@@ -31,7 +30,7 @@ class QueriesController < ApplicationController | |||
@query.project = @project | |||
@query.user = logged_in_user | |||
@query.executed_by = logged_in_user | |||
@query.is_public = false unless logged_in_user.authorized_to(@project, 'projects/add_query') | |||
@query.is_public = false unless current_role.allowed_to?(:manage_pulic_queries) | |||
params[:fields].each do |field| | |||
@query.add_filter(field, params[:operators][field], params[:values][field]) | |||
@@ -52,7 +51,7 @@ class QueriesController < ApplicationController | |||
@query.add_filter(field, params[:operators][field], params[:values][field]) | |||
end if params[:fields] | |||
@query.attributes = params[:query] | |||
@query.is_public = false unless logged_in_user.authorized_to(@project, 'projects/add_query') | |||
@query.is_public = false unless current_role.allowed_to?(:manage_pulic_queries) | |||
if @query.save | |||
flash[:notice] = l(:notice_successful_update) |
@@ -22,8 +22,8 @@ require 'digest/sha1' | |||
class RepositoriesController < ApplicationController | |||
layout 'base' | |||
before_filter :find_project, :except => [:update_form] | |||
before_filter :authorize, :except => [:update_form, :stats, :graph] | |||
before_filter :check_project_privacy, :only => [:stats, :graph] | |||
before_filter :authorize, :except => [:update_form] | |||
accept_key_auth :revisions | |||
def show | |||
# check if new revisions have been committed in the repository | |||
@@ -57,7 +57,10 @@ class RepositoriesController < ApplicationController | |||
:limit => @changeset_pages.items_per_page, | |||
:offset => @changeset_pages.current.offset) | |||
render :action => "revisions", :layout => false if request.xhr? | |||
respond_to do |format| | |||
format.html { render :layout => false if request.xhr? } | |||
format.atom { render_feed(@changesets, :title => "#{@project.name}: #{l(:label_revision_plural)}") } | |||
end | |||
end | |||
def entry |
@@ -28,40 +28,35 @@ class RolesController < ApplicationController | |||
end | |||
def list | |||
@role_pages, @roles = paginate :roles, :per_page => 25, :order => "position" | |||
@role_pages, @roles = paginate :roles, :per_page => 25, :order => 'builtin, position' | |||
render :action => "list", :layout => false if request.xhr? | |||
end | |||
def new | |||
@role = Role.new(params[:role]) | |||
if request.post? | |||
@role.permissions = Permission.find(params[:permission_ids]) if params[:permission_ids] | |||
if @role.save | |||
flash[:notice] = l(:notice_successful_create) | |||
redirect_to :action => 'list' | |||
end | |||
if request.post? && @role.save | |||
flash[:notice] = l(:notice_successful_create) | |||
redirect_to :action => 'list' | |||
end | |||
@permissions = Permission.find(:all, :conditions => ["is_public=?", false], :order => 'sort ASC') | |||
@permissions = @role.setable_permissions | |||
end | |||
def edit | |||
@role = Role.find(params[:id]) | |||
if request.post? and @role.update_attributes(params[:role]) | |||
@role.permissions = Permission.find(params[:permission_ids] || []) | |||
Permission.allowed_to_role_expired | |||
flash[:notice] = l(:notice_successful_update) | |||
redirect_to :action => 'list' | |||
end | |||
@permissions = Permission.find(:all, :conditions => ["is_public=?", false], :order => 'sort ASC') | |||
@permissions = @role.setable_permissions | |||
end | |||
def destroy | |||
@role = Role.find(params[:id]) | |||
unless @role.members.empty? | |||
flash[:error] = 'Some members have this role. Can\'t delete it.' | |||
else | |||
#unless @role.members.empty? | |||
# flash[:error] = 'Some members have this role. Can\'t delete it.' | |||
#else | |||
@role.destroy | |||
end | |||
#end | |||
redirect_to :action => 'list' | |||
end | |||
@@ -95,19 +90,19 @@ class RolesController < ApplicationController | |||
flash[:notice] = l(:notice_successful_update) | |||
end | |||
end | |||
@roles = Role.find(:all, :order => 'position') | |||
@roles = Role.find(:all, :order => 'builtin, position') | |||
@trackers = Tracker.find(:all, :order => 'position') | |||
@statuses = IssueStatus.find(:all, :include => :workflows, :order => 'position') | |||
end | |||
def report | |||
@roles = Role.find(:all, :order => 'position') | |||
@permissions = Permission.find :all, :conditions => ["is_public=?", false], :order => 'sort' | |||
@roles = Role.find(:all, :order => 'builtin, position') | |||
@permissions = Redmine::AccessControl.permissions.select { |p| !p.public? } | |||
if request.post? | |||
@roles.each do |role| | |||
role.permissions = Permission.find(params[:permission_ids] ? (params[:permission_ids][role.id.to_s] || []) : [] ) | |||
role.permissions = params[:permissions][role.id.to_s] | |||
role.save | |||
end | |||
Permission.allowed_to_role_expired | |||
flash[:notice] = l(:notice_successful_update) | |||
redirect_to :action => 'list' | |||
end |
@@ -16,11 +16,8 @@ | |||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
class TimelogController < ApplicationController | |||
layout 'base' | |||
before_filter :find_project | |||
before_filter :authorize, :only => :edit | |||
before_filter :check_project_privacy, :except => :edit | |||
layout 'base' | |||
before_filter :find_project, :authorize | |||
helper :sort | |||
include SortHelper |
@@ -87,7 +87,7 @@ class UsersController < ApplicationController | |||
end | |||
end | |||
@auth_sources = AuthSource.find(:all) | |||
@roles = Role.find(:all, :order => 'position') | |||
@roles = Role.find_all_givable | |||
@projects = Project.find(:all, :order => 'name', :conditions => "status=#{Project::STATUS_ACTIVE}") - @user.projects | |||
@membership ||= Member.new | |||
end |
@@ -20,7 +20,7 @@ class WatchersController < ApplicationController | |||
before_filter :require_login, :find_project, :check_project_privacy | |||
def add | |||
user = logged_in_user | |||
user = User.current | |||
@watched.add_watcher(user) | |||
respond_to do |format| | |||
format.html { render :text => 'Watcher added.', :layout => true } | |||
@@ -29,7 +29,7 @@ class WatchersController < ApplicationController | |||
end | |||
def remove | |||
user = logged_in_user | |||
user = User.current | |||
@watched.remove_watcher(user) | |||
respond_to do |format| | |||
format.html { render :text => 'Watcher removed.', :layout => true } |
@@ -21,7 +21,5 @@ class WelcomeController < ApplicationController | |||
def index | |||
@news = News.latest logged_in_user | |||
@projects = Project.latest logged_in_user | |||
@key = logged_in_user.get_or_create_rss_key.value if logged_in_user | |||
end | |||
end |
@@ -19,8 +19,7 @@ require 'diff' | |||
class WikiController < ApplicationController | |||
layout 'base' | |||
before_filter :find_wiki, :check_project_privacy | |||
before_filter :authorize, :only => [:destroy, :add_attachment, :destroy_attachment] | |||
before_filter :find_wiki, :authorize | |||
verify :method => :post, :only => [:destroy, :destroy_attachment], :redirect_to => { :action => :index } | |||
@@ -25,32 +25,18 @@ end | |||
module ApplicationHelper | |||
# Return current logged in user or nil | |||
def loggedin? | |||
@logged_in_user | |||
def current_role | |||
@current_role ||= User.current.role_for_project(@project) | |||
end | |||
# Return true if user is logged in and is admin, otherwise false | |||
def admin_loggedin? | |||
@logged_in_user and @logged_in_user.admin? | |||
end | |||
# Return true if user is authorized for controller/action, otherwise false | |||
def authorize_for(controller, action) | |||
# check if action is allowed on public projects | |||
if @project.is_public? and Permission.allowed_to_public "%s/%s" % [ controller, action ] | |||
return true | |||
end | |||
# check if user is authorized | |||
if @logged_in_user and (@logged_in_user.admin? or Permission.allowed_to_role( "%s/%s" % [ controller, action ], @logged_in_user.role_for_project(@project) ) ) | |||
return true | |||
end | |||
return false | |||
def authorize_for(controller, action) | |||
User.current.allowed_to?({:controller => controller, :action => action}, @project) | |||
end | |||
# Display a link if user is authorized | |||
def link_to_if_authorized(name, options = {}, html_options = nil, *parameters_for_method_reference) | |||
link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller], options[:action]) | |||
link_to(name, options, html_options, *parameters_for_method_reference) if authorize_for(options[:controller] || params[:controller], options[:action]) | |||
end | |||
# Display a link to user's account page |
@@ -175,4 +175,12 @@ module ProjectsHelper | |||
gc.draw(imgl) | |||
imgl | |||
end if Object.const_defined?(:Magick) | |||
def new_issue_selector | |||
trackers = Tracker.find(:all, :order => 'position') | |||
form_tag({:controller => 'projects', :action => 'add_issue', :id => @project}, :method => :get) + | |||
select_tag('tracker_id', '<option></option' + options_from_collection_for_select(trackers, 'id', 'name'), | |||
:onchange => "if (this.value != '') {this.form.submit()}") + | |||
end_form_tag | |||
end | |||
end |
@@ -21,7 +21,7 @@ module WatchersHelper | |||
end | |||
def watcher_link(object, user) | |||
return '' unless user && object.respond_to?('watched_by?') | |||
return '' unless user && user.logged? && object.respond_to?('watched_by?') | |||
watched = object.watched_by?(user) | |||
url = {:controller => 'watchers', | |||
:action => (watched ? 'remove' : 'add'), |
@@ -24,7 +24,11 @@ class Attachment < ActiveRecord::Base | |||
validates_presence_of :container, :filename | |||
validates_length_of :filename, :maximum => 255 | |||
validates_length_of :disk_filename, :maximum => 255 | |||
acts_as_event :title => :filename, | |||
:description => :filename, | |||
:url => Proc.new {|o| {:controller => 'attachment', :action => 'download', :id => o.id}} | |||
cattr_accessor :storage_path | |||
@@storage_path = "#{RAILS_ROOT}/files" | |||
@@ -19,6 +19,12 @@ class Changeset < ActiveRecord::Base | |||
belongs_to :repository | |||
has_many :changes, :dependent => :delete_all | |||
has_and_belongs_to_many :issues | |||
acts_as_event :title => Proc.new {|o| "#{l(:label_revision)} #{o.revision}" + (o.comments.blank? ? '' : (': ' + o.comments))}, | |||
:description => :comments, | |||
:datetime => :committed_on, | |||
:author => :committer, | |||
:url => Proc.new {|o| {:controller => 'repositories', :action => 'revision', :id => o.repository.project_id, :rev => o.revision}} | |||
validates_presence_of :repository_id, :revision, :committed_on, :commit_date | |||
validates_numericality_of :revision, :only_integer => true |
@@ -20,6 +20,8 @@ class Document < ActiveRecord::Base | |||
belongs_to :category, :class_name => "Enumeration", :foreign_key => "category_id" | |||
has_many :attachments, :as => :container, :dependent => :destroy | |||
acts_as_event :url => Proc.new {|o| {:controller => 'documents', :action => 'show', :id => o.id}} | |||
validates_presence_of :project, :title, :category | |||
validates_length_of :title, :maximum => 60 | |||
end |
@@ -36,6 +36,8 @@ class Issue < ActiveRecord::Base | |||
has_many :relations_to, :class_name => 'IssueRelation', :foreign_key => 'issue_to_id', :dependent => :delete_all | |||
acts_as_watchable | |||
acts_as_event :title => Proc.new {|o| "#{o.tracker.name} ##{o.id}: #{o.subject}"}, | |||
:url => Proc.new {|o| {:controller => 'issues', :action => 'show', :id => o.id}} | |||
validates_presence_of :subject, :description, :priority, :tracker, :author, :status | |||
validates_length_of :subject, :maximum => 255 |
@@ -31,7 +31,7 @@ class MailHandler < ActionMailer::Base | |||
user = User.find_active(:first, :conditions => {:mail => email.from.first}) | |||
return unless user | |||
# check permission | |||
return unless Permission.allowed_to_role("issues/add_note", user.role_for_project(issue.project)) | |||
return unless user.allowed_to?(:add_issue_notes, issue.project) | |||
# add the note | |||
issue.init_journal(user, email.body.chomp) |
@@ -23,6 +23,10 @@ class Member < ActiveRecord::Base | |||
validates_presence_of :role, :user, :project | |||
validates_uniqueness_of :user_id, :scope => :project_id | |||
def validate | |||
errors.add :role_id, :activerecord_error_invalid if role && !role.member? | |||
end | |||
def name | |||
self.user.name | |||
end |
@@ -23,7 +23,9 @@ class News < ActiveRecord::Base | |||
validates_presence_of :title, :description | |||
validates_length_of :title, :maximum => 60 | |||
validates_length_of :summary, :maximum => 255 | |||
acts_as_event :url => Proc.new {|o| {:controller => 'news', :action => 'show', :id => o.id}} | |||
# returns latest news for projects visible by user | |||
def self.latest(user=nil, count=5) | |||
find(:all, :limit => count, :conditions => Project.visible_by(user), :include => [ :author, :project ], :order => "#{News.table_name}.created_on DESC") |
@@ -1,68 +0,0 @@ | |||
# redMine - project management software | |||
# Copyright (C) 2006 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 Permission < ActiveRecord::Base | |||
has_and_belongs_to_many :roles | |||
validates_presence_of :controller, :action, :description | |||
GROUPS = { | |||
100 => :label_project, | |||
200 => :label_member_plural, | |||
300 => :label_version_plural, | |||
400 => :label_issue_category_plural, | |||
600 => :label_query_plural, | |||
1000 => :label_issue_plural, | |||
1100 => :label_news_plural, | |||
1200 => :label_document_plural, | |||
1300 => :label_attachment_plural, | |||
1400 => :label_repository, | |||
1500 => :label_time_tracking, | |||
1700 => :label_wiki_page_plural, | |||
2000 => :label_board_plural | |||
}.freeze | |||
@@cached_perms_for_public = nil | |||
@@cached_perms_for_roles = nil | |||
def name | |||
self.controller + "/" + self.action | |||
end | |||
def group_id | |||
(self.sort / 100)*100 | |||
end | |||
def self.allowed_to_public(action) | |||
@@cached_perms_for_public ||= find(:all, :conditions => ["is_public=?", true]).collect {|p| "#{p.controller}/#{p.action}"} | |||
@@cached_perms_for_public.include? action | |||
end | |||
def self.allowed_to_role(action, role) | |||
@@cached_perms_for_roles ||= | |||
begin | |||
perms = {} | |||
find(:all, :include => :roles).each {|p| perms.store "#{p.controller}/#{p.action}", p.roles.collect {|r| r.id } } | |||
perms | |||
end | |||
allowed_to_public(action) or (role && @@cached_perms_for_roles[action] && @@cached_perms_for_roles[action].include?(role.id)) | |||
end | |||
def self.allowed_to_role_expired | |||
@@cached_perms_for_roles = nil | |||
end | |||
end |
@@ -78,7 +78,7 @@ class Query < ActiveRecord::Base | |||
def editable_by?(user) | |||
return false unless user | |||
return true if !is_public && self.user_id == user.id | |||
is_public && user.authorized_to(project, "projects/add_query") | |||
is_public && user.allowed_to?(:manage_pulic_queries, project) | |||
end | |||
def available_filters |
@@ -16,23 +16,93 @@ | |||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
class Role < ActiveRecord::Base | |||
before_destroy :check_integrity | |||
has_and_belongs_to_many :permissions | |||
# Built-in roles | |||
BUILTIN_NON_MEMBER = 1 | |||
BUILTIN_ANONYMOUS = 2 | |||
before_destroy :check_deletable | |||
has_many :workflows, :dependent => :delete_all | |||
has_many :members | |||
acts_as_list | |||
serialize :permissions | |||
attr_protected :builtin | |||
validates_presence_of :name | |||
validates_uniqueness_of :name | |||
validates_length_of :name, :maximum => 30 | |||
validates_format_of :name, :with => /^[\w\s\'\-]*$/i | |||
def permissions | |||
read_attribute(:permissions) || [] | |||
end | |||
def permissions=(perms) | |||
perms = perms.collect {|p| p.to_sym unless p.blank? }.compact if perms | |||
write_attribute(:permissions, perms) | |||
end | |||
def <=>(role) | |||
position <=> role.position | |||
end | |||
# Return true if the role is a builtin role | |||
def builtin? | |||
self.builtin != 0 | |||
end | |||
# Return true if the role is a project member role | |||
def member? | |||
!self.builtin? | |||
end | |||
# Return true if role is allowed to do the specified action | |||
# action can be: | |||
# * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit') | |||
# * a permission Symbol (eg. :edit_project) | |||
def allowed_to?(action) | |||
if action.is_a? Hash | |||
allowed_actions.include? "#{action[:controller]}/#{action[:action]}" | |||
else | |||
allowed_permissions.include? action | |||
end | |||
end | |||
# Return all the permissions that can be given to the role | |||
def setable_permissions | |||
setable_permissions = Redmine::AccessControl.permissions - Redmine::AccessControl.public_permissions | |||
setable_permissions -= Redmine::AccessControl.members_only_permissions if self.builtin == BUILTIN_NON_MEMBER | |||
setable_permissions -= Redmine::AccessControl.loggedin_only_permissions if self.builtin == BUILTIN_ANONYMOUS | |||
setable_permissions | |||
end | |||
# Find all the roles that can be given to a project member | |||
def self.find_all_givable | |||
find(:all, :conditions => {:builtin => 0}, :order => 'position') | |||
end | |||
# Return the builtin 'non member' role | |||
def self.non_member | |||
find(:first, :conditions => {:builtin => BUILTIN_NON_MEMBER}) || raise('Missing non-member builtin role.') | |||
end | |||
# Return the builtin 'anonymous' role | |||
def self.anonymous | |||
find(:first, :conditions => {:builtin => BUILTIN_ANONYMOUS}) || raise('Missing anonymous builtin role.') | |||
end | |||
private | |||
def check_integrity | |||
raise "Can't delete role" if Member.find(:first, :conditions =>["role_id=?", self.id]) | |||
def allowed_permissions | |||
@allowed_permissions ||= permissions + Redmine::AccessControl.public_permissions.collect {|p| p.name} | |||
end | |||
def allowed_actions | |||
@actions_allowed ||= allowed_permissions.inject([]) { |actions, permission| actions += Redmine::AccessControl.allowed_actions(permission) }.flatten | |||
end | |||
def check_deletable | |||
raise "Can't delete role" if members.any? | |||
raise "Can't delete builtin role" if builtin? | |||
end | |||
end |
@@ -28,7 +28,7 @@ class User < ActiveRecord::Base | |||
has_many :custom_values, :dependent => :delete_all, :as => :customized | |||
has_many :issue_categories, :foreign_key => 'assigned_to_id', :dependent => :nullify | |||
has_one :preference, :dependent => :destroy, :class_name => 'UserPreference' | |||
has_one :rss_key, :dependent => :destroy, :class_name => 'Token', :conditions => "action='feeds'" | |||
has_one :rss_token, :dependent => :destroy, :class_name => 'Token', :conditions => "action='feeds'" | |||
belongs_to :auth_source | |||
attr_accessor :password, :password_confirmation | |||
@@ -121,24 +121,14 @@ class User < ActiveRecord::Base | |||
User.hash_password(clear_password) == self.hashed_password | |||
end | |||
def role_for_project(project) | |||
return nil unless project | |||
member = memberships.detect {|m| m.project_id == project.id} | |||
member ? member.role : nil | |||
end | |||
def authorized_to(project, action) | |||
return true if self.admin? | |||
role = role_for_project(project) | |||
role && Permission.allowed_to_role(action, role) | |||
end | |||
def pref | |||
self.preference ||= UserPreference.new(:user => self) | |||
end | |||
def get_or_create_rss_key | |||
self.rss_key || Token.create(:user => self, :action => 'feeds') | |||
# Return user's RSS key (a 40 chars long string), used to access feeds | |||
def rss_key | |||
token = self.rss_token || Token.create(:user => self, :action => 'feeds') | |||
token.value | |||
end | |||
def self.find_by_rss_key(key) | |||
@@ -155,9 +145,72 @@ class User < ActiveRecord::Base | |||
lastname == user.lastname ? firstname <=> user.firstname : lastname <=> user.lastname | |||
end | |||
def to_s | |||
name | |||
end | |||
def logged? | |||
true | |||
end | |||
# Return user's role for project | |||
def role_for_project(project) | |||
# No role on archived projects | |||
return nil unless project && project.active? | |||
# Find project membership | |||
membership = memberships.detect {|m| m.project_id == project.id} | |||
if membership | |||
membership.role | |||
elsif logged? | |||
Role.non_member | |||
else | |||
Role.anonymous | |||
end | |||
end | |||
# Return true if the user is a member of project | |||
def member_of?(project) | |||
role_for_project(project).member? | |||
end | |||
# Return true if the user is allowed to do the specified action on project | |||
# action can be: | |||
# * a parameter-like Hash (eg. :controller => 'projects', :action => 'edit') | |||
# * a permission Symbol (eg. :edit_project) | |||
def allowed_to?(action, project) | |||
return false unless project.active? | |||
return true if admin? | |||
role = role_for_project(project) | |||
return false unless role | |||
role.allowed_to?(action) && (project.is_public? || role.member?) | |||
end | |||
def self.current=(user) | |||
@current_user = user | |||
end | |||
def self.current | |||
@current_user ||= AnonymousUser.new | |||
end | |||
def self.anonymous | |||
AnonymousUser.new | |||
end | |||
private | |||
# Return password digest | |||
def self.hash_password(clear_password) | |||
Digest::SHA1.hexdigest(clear_password || "") | |||
end | |||
end | |||
class AnonymousUser < User | |||
def logged? | |||
false | |||
end | |||
# Anonymous user has no RSS key | |||
def rss_key | |||
nil | |||
end | |||
end |
@@ -28,7 +28,12 @@ class WikiContent < ActiveRecord::Base | |||
belongs_to :page, :class_name => 'WikiPage', :foreign_key => 'page_id' | |||
belongs_to :author, :class_name => 'User', :foreign_key => 'author_id' | |||
attr_protected :data | |||
acts_as_event :title => Proc.new {|o| "#{l(:label_wiki_edit)}: #{o.page.title} (##{o.version})"}, | |||
:description => :comments, | |||
:datetime => :updated_on, | |||
:url => Proc.new {|o| {:controller => 'wiki', :id => o.page.wiki.project_id, :page => o.page.title, :version => o.version}} | |||
def text=(plain) | |||
case Setting.wiki_compression | |||
when 'gzip' |
@@ -1,26 +1,3 @@ | |||
<h2><%=l(:field_mail_notification)%></h2> | |||
<% form_tag({:action => 'mail_options'}, :id => 'mail_options_form') do %> | |||
<div class="box"> | |||
<p><%=l(:text_select_mail_notifications)%></p> | |||
<% actions = @actions.group_by {|p| p.group_id } %> | |||
<% actions.keys.sort.each do |group_id| %> | |||
<fieldset style="margin-top: 6px;"><legend><strong><%= l(Permission::GROUPS[group_id]) %></strong></legend> | |||
<% actions[group_id].each do |p| %> | |||
<div style="width:170px;float:left;"><%= check_box_tag "action_ids[]", p.id, p.mail_enabled? %> | |||
<%= l(p.description.to_sym) %> | |||
</div> | |||
<% end %> | |||
<div class="clear"></div> | |||
</fieldset> | |||
<% end %> | |||
<br /> | |||
<%= check_all_links('mail_options_form') %> | |||
</div> | |||
<p><%= submit_tag l(:button_save) %></p> | |||
<% end %> | |||
<%= link_to l(:label_send_test_email), :action => 'test_email' %> |
@@ -1,6 +1,6 @@ | |||
<div class="contextual"> | |||
<%= link_to l(:label_message_new), {:controller => 'messages', :action => 'new', :board_id => @board}, :class => "icon icon-add" %> | |||
<%= watcher_tag(@board, @logged_in_user) %> | |||
<%= link_to_if_authorized l(:label_message_new), {:controller => 'messages', :action => 'new', :board_id => @board}, :class => "icon icon-add" %> | |||
<%= watcher_tag(@board, User.current) %> | |||
</div> | |||
<h2><%=h @board.name %></h2> |
@@ -0,0 +1,26 @@ | |||
xml.instruct! | |||
xml.feed "xmlns" => "http://www.w3.org/2005/Atom" do | |||
xml.title @title | |||
xml.link "rel" => "self", "href" => url_for(params.merge({:format => nil, :only_path => false})) | |||
xml.link "rel" => "alternate", "href" => url_for(:controller => 'welcome', :only_path => false) | |||
xml.id url_for(:controller => 'welcome', :only_path => false) | |||
xml.updated((@items.first ? @items.first.event_datetime : Time.now).xmlschema) | |||
xml.author { xml.name "#{Setting.app_title}" } | |||
xml.generator(:uri => Redmine::Info.url, :version => Redmine::VERSION) { xml.text! "#{Redmine::Info.name} #{Redmine::VERSION}" } | |||
@items.each do |item| | |||
xml.entry do | |||
xml.title truncate(item.event_title, 100) | |||
xml.link "rel" => "alternate", "href" => url_for(item.event_url(:only_path => false)) | |||
xml.id url_for(item.event_url(:only_path => false)) | |||
xml.updated item.event_datetime.xmlschema | |||
author = item.event_author | |||
xml.author do | |||
xml.name(author.is_a?(User) ? author.name : author) | |||
xml.email(author.mail) if author.is_a?(User) | |||
end if author | |||
xml.content "type" => "html" do | |||
xml.text! textilizable(item.event_description) | |||
end | |||
end | |||
end | |||
end |
@@ -58,7 +58,7 @@ end %> | |||
<div class="contextual"> | |||
<%= link_to_if_authorized l(:button_edit), {:controller => 'issues', :action => 'edit', :id => @issue}, :class => 'icon icon-edit' %> | |||
<%= link_to_if_authorized l(:button_log_time), {:controller => 'timelog', :action => 'edit', :issue_id => @issue}, :class => 'icon icon-time' %> | |||
<%= watcher_tag(@issue, @logged_in_user) %> | |||
<%= watcher_tag(@issue, User.current) %> | |||
<%= link_to_if_authorized l(:button_move), {:controller => 'projects', :action => 'move_issues', :id => @project, "issue_ids[]" => @issue.id }, :class => 'icon icon-move' %> | |||
<%= link_to_if_authorized l(:button_delete), {:controller => 'issues', :action => 'destroy', :id => @issue}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %> | |||
</div> | |||
@@ -81,6 +81,13 @@ end %> | |||
</div> | |||
<% end %> | |||
<% if @issue.attachments.any? %> | |||
<div class="box"> | |||
<h3><%=l(:label_attachment_plural)%></h3> | |||
<%= link_to_attachments @issue.attachments, :delete_url => (authorize_for('issues', 'destroy_attachment') ? {:controller => 'issues', :action => 'destroy_attachment', :id => @issue} : nil) %> | |||
</div> | |||
<% end %> | |||
<% if @journals.any? %> | |||
<div id="history" class="box"> | |||
<h3><%=l(:label_history)%></h3> | |||
@@ -88,26 +95,14 @@ end %> | |||
</div> | |||
<% end %> | |||
<div class="box"> | |||
<h3><%=l(:label_attachment_plural)%></h3> | |||
<%= link_to_attachments @issue.attachments, :delete_url => (authorize_for('issues', 'destroy_attachment') ? {:controller => 'issues', :action => 'destroy_attachment', :id => @issue} : nil) %> | |||
<% if authorize_for('issues', 'add_attachment') %> | |||
<p><%= toggle_link l(:label_attachment_new), "add_attachment_form" %></p> | |||
<% form_tag({ :controller => 'issues', :action => 'add_attachment', :id => @issue }, :multipart => true, :class => "tabular", :id => "add_attachment_form", :style => "display:none;") do %> | |||
<%= render :partial => 'attachments/form' %> | |||
<%= submit_tag l(:button_add) %> | |||
<% end %> | |||
<% end %> | |||
</div> | |||
<% if authorize_for('issues', 'add_note') %> | |||
<div class="box"> | |||
<h3><%= l(:label_add_note) %></h3> | |||
<% form_tag({:controller => 'issues', :action => 'add_note', :id => @issue}, :class => "tabular" ) do %> | |||
<% form_tag({:controller => 'issues', :action => 'add_note', :id => @issue}, :class => "tabular", :multipart => true) do %> | |||
<p><label for="notes"><%=l(:field_notes)%></label> | |||
<%= text_area_tag 'notes', '', :cols => 60, :rows => 10, :class => 'wiki-edit' %></p> | |||
<%= wikitoolbar_for 'notes' %> | |||
<%= render :partial => 'attachments/form' %> | |||
<%= submit_tag l(:button_add) %> | |||
<% end %> | |||
</div> |
@@ -27,7 +27,7 @@ | |||
<h2><%= Setting.app_subtitle %></h2> | |||
</div> | |||
<div style="float: right; padding-right: 1em; padding-top: 0.2em;"> | |||
<% if loggedin? %><small><%=l(:label_logged_as)%> <strong><%= @logged_in_user.login %></strong> -</small><% end %> | |||
<% if User.current.logged? %><small><%=l(:label_logged_as)%> <strong><%= User.current.login %></strong> -</small><% end %> | |||
<small><%= toggle_link l(:label_search), 'quick-search-form', :focus => 'quick-search-input' %></small> | |||
<% form_tag({:controller => 'search', :action => 'index', :id => @project}, :method => :get, :id => 'quick-search-form', :style => "display:none;" ) do %> | |||
<%= text_field_tag 'q', @question, :size => 15, :class => 'small', :id => 'quick-search-input' %> | |||
@@ -40,27 +40,23 @@ | |||
<li><%= link_to l(:label_home), { :controller => 'welcome' }, :class => "icon icon-home" %></li> | |||
<li><%= link_to l(:label_my_page), { :controller => 'my', :action => 'page'}, :class => "icon icon-mypage" %></li> | |||
<% if loggedin? and @logged_in_user.memberships.any? %> | |||
<% if User.current.memberships.any? %> | |||
<li class="submenu"><%= link_to l(:label_project_plural), { :controller => 'projects' }, :class => "icon icon-projects", :onmouseover => "buttonMouseover(event, 'menuAllProjects');" %></li> | |||
<% else %> | |||
<li><%= link_to l(:label_project_plural), { :controller => 'projects' }, :class => "icon icon-projects" %></li> | |||
<% end %> | |||
<% unless @project.nil? || @project.id.nil? %> | |||
<li class="submenu"><%= link_to @project.name, { :controller => 'projects', :action => 'show', :id => @project }, :class => "icon icon-projects", :onmouseover => "buttonMouseover(event, 'menuProject');" %></li> | |||
<% end %> | |||
<% if loggedin? %> | |||
<% if User.current.logged? %> | |||
<li><%= link_to l(:label_my_account), { :controller => 'my', :action => 'account' }, :class => "icon icon-user" %></li> | |||
<% end %> | |||
<% if admin_loggedin? %> | |||
<% if User.current.admin? %> | |||
<li class="submenu"><%= link_to l(:label_administration), { :controller => 'admin' }, :class => "icon icon-admin", :onmouseover => "buttonMouseover(event, 'menuAdmin');" %></li> | |||
<% end %> | |||
<li class="right"><%= link_to l(:label_help), { :controller => 'help', :ctrl => params[:controller], :page => params[:action] }, :onclick => "window.open(this.href); return false;", :class => "icon icon-help" %></li> | |||
<% if loggedin? %> | |||
<% if User.current.logged? %> | |||
<li class="right"><%= link_to l(:label_logout), { :controller => 'account', :action => 'logout' }, :class => "icon icon-user" %></li> | |||
<% else %> | |||
<li class="right"><%= link_to l(:label_login), { :controller => 'account', :action => 'login' }, :class => "icon icon-user" %></li> | |||
@@ -68,71 +64,28 @@ | |||
</ul> | |||
</div> | |||
<% if admin_loggedin? %> | |||
<% if User.current.admin? %> | |||
<%= render :partial => 'admin/menu' %> | |||
<% end %> | |||
<% unless @project.nil? || @project.id.nil? %> | |||
<div id="menuProject" class="menu" onmouseover="menuMouseover(event)"> | |||
<%= link_to l(:label_calendar), {:controller => 'projects', :action => 'calendar', :id => @project }, :class => "menuItem" %> | |||
<%= link_to l(:label_gantt), {:controller => 'projects', :action => 'gantt', :id => @project }, :class => "menuItem" %> | |||
<%= link_to l(:label_issue_plural), {:controller => 'projects', :action => 'list_issues', :id => @project }, :class => "menuItem" %> | |||
<% if @project && authorize_for('projects', 'add_issue') %> | |||
<a class="menuItem" href="#" onmouseover="menuItemMouseover(event,'menuNewIssue');" onclick="this.blur(); return false;"><span class="menuItemText"><%= l(:label_issue_new) %></span><span class="menuItemArrow">▶</span></a> | |||
<% end %> | |||
<%= link_to l(:label_report_plural), {:controller => 'reports', :action => 'issue_report', :id => @project }, :class => "menuItem" %> | |||
<%= link_to l(:label_activity), {:controller => 'projects', :action => 'activity', :id => @project }, :class => "menuItem" %> | |||
<%= link_to l(:label_news_plural), {:controller => 'projects', :action => 'list_news', :id => @project }, :class => "menuItem" %> | |||
<%= link_to l(:label_change_log), {:controller => 'projects', :action => 'changelog', :id => @project }, :class => "menuItem" %> | |||
<%= link_to l(:label_roadmap), {:controller => 'projects', :action => 'roadmap', :id => @project }, :class => "menuItem" %> | |||
<%= link_to l(:label_document_plural), {:controller => 'projects', :action => 'list_documents', :id => @project }, :class => "menuItem" %> | |||
<%= link_to l(:label_wiki), {:controller => 'wiki', :id => @project, :page => nil }, :class => "menuItem" if @project.wiki and !@project.wiki.new_record? %> | |||
<%= link_to l(:label_board_plural), {:controller => 'boards', :action => 'index', :project_id => @project, :id => nil }, :class => "menuItem" unless @project.boards.empty? %> | |||
<%= link_to l(:label_attachment_plural), {:controller => 'projects', :action => 'list_files', :id => @project }, :class => "menuItem" %> | |||
<%= link_to l(:label_search), {:controller => 'search', :action => 'index', :id => @project }, :class => "menuItem" %> | |||
<%= link_to l(:label_repository), {:controller => 'repositories', :action => 'show', :id => @project}, :class => "menuItem" if @project.repository and !@project.repository.new_record? %> | |||
<%= link_to_if_authorized l(:label_settings), {:controller => 'projects', :action => 'settings', :id => @project }, :class => "menuItem" %> | |||
</div> | |||
<% end %> | |||
<% if @project && authorize_for('projects', 'add_issue') %> | |||
<div id="menuNewIssue" class="menu" onmouseover="menuMouseover(event)"> | |||
<% Tracker.find(:all, :order => 'position').each do |tracker| %> | |||
<%= link_to tracker.name, {:controller => 'projects', :action => 'add_issue', :id => @project, :tracker_id => tracker}, :class => "menuItem" %> | |||
<% end %> | |||
</div> | |||
<% end %> | |||
<% if loggedin? and @logged_in_user.memberships.any? %> | |||
<% if User.current.memberships.any? %> | |||
<div id="menuAllProjects" class="menu" onmouseover="menuMouseover(event)"> | |||
<%= link_to l(:label_project_all), {:controller => 'projects' }, :class => "menuItem" %> | |||
<% @logged_in_user.memberships.find(:all, :limit => 20).each do |membership| %> | |||
<% User.current.memberships.find(:all, :limit => 20).each do |membership| %> | |||
<%= link_to membership.project.name, {:controller => 'projects',:action => 'show', :id => membership.project }, :class => "menuItem" %> | |||
<% end %> | |||
</div> | |||
<% end %> | |||
<div id="subcontent"> | |||
<% unless @project.nil? || @project.id.nil? %> | |||
<div id="subcontent"> | |||
<% if @project && !@project.new_record? %> | |||
<h2><%= @project.name %></h2> | |||
<ul class="menublock"> | |||
<li><%= link_to l(:label_overview), :controller => 'projects', :action => 'show', :id => @project %></li> | |||
<li><%= link_to l(:label_calendar), :controller => 'projects', :action => 'calendar', :id => @project %></li> | |||
<li><%= link_to l(:label_gantt), :controller => 'projects', :action => 'gantt', :id => @project %></li> | |||
<li><%= link_to l(:label_issue_plural), :controller => 'projects', :action => 'list_issues', :id => @project %></li> | |||
<li><%= link_to l(:label_report_plural), :controller => 'reports', :action => 'issue_report', :id => @project %></li> | |||
<li><%= link_to l(:label_activity), :controller => 'projects', :action => 'activity', :id => @project %></li> | |||
<li><%= link_to l(:label_news_plural), :controller => 'projects', :action => 'list_news', :id => @project %></li> | |||
<li><%= link_to l(:label_change_log), :controller => 'projects', :action => 'changelog', :id => @project %></li> | |||
<li><%= link_to l(:label_roadmap), :controller => 'projects', :action => 'roadmap', :id => @project %></li> | |||
<li><%= link_to l(:label_document_plural), :controller => 'projects', :action => 'list_documents', :id => @project %></li> | |||
<%= content_tag("li", link_to(l(:label_wiki), :controller => 'wiki', :id => @project, :page => nil)) if @project.wiki and !@project.wiki.new_record? %> | |||
<%= content_tag("li", link_to(l(:label_board_plural), :controller => 'boards', :action => 'index', :project_id => @project, :id => nil)) unless @project.boards.empty? %> | |||
<li><%= link_to l(:label_attachment_plural), :controller => 'projects', :action => 'list_files', :id => @project %></li> | |||
<li><%= link_to l(:label_search), :controller => 'search', :action => 'index', :id => @project %></li> | |||
<%= content_tag("li", link_to(l(:label_repository), :controller => 'repositories', :action => 'show', :id => @project)) if @project.repository and !@project.repository.new_record? %> | |||
<li><%= link_to_if_authorized l(:label_settings), :controller => 'projects', :action => 'settings', :id => @project %></li> | |||
<% Redmine::MenuManager.allowed_items(:project_menu, current_role).each do |item| %> | |||
<% unless item.condition && !item.condition.call(@project) %> | |||
<li><%= link_to l(item.name), {item.param => @project}.merge(item.url) %></li> | |||
<% end %> | |||
<% end %> | |||
</ul> | |||
<% end %> | |||
</div> |
@@ -13,7 +13,7 @@ | |||
<div class="wiki"><p><%= textilizable message.content %></p></div> | |||
<% end %> | |||
<% if @logged_in_user %> | |||
<% if authorize_for('messages', 'reply') %> | |||
<p><%= toggle_link l(:button_reply), "reply", :focus => "reply_content" %></p> | |||
<div id="reply" style="display:none;"> | |||
<%= error_messages_for 'message' %> |
@@ -4,7 +4,7 @@ | |||
<!--[form:project]--> | |||
<p><%= f.text_field :name, :required => true %><br /><em><%= l(:text_caracters_maximum, 30) %></em></p> | |||
<% if admin_loggedin? and !@root_projects.empty? %> | |||
<% if User.current.admin? and !@root_projects.empty? %> | |||
<p><%= f.select :parent_id, (@root_projects.collect {|p| [p.name, p.id]}), { :include_blank => true } %></p> | |||
<% end %> | |||
@@ -1,5 +1,5 @@ | |||
<%= error_messages_for 'member' %> | |||
<% roles = Role.find(:all, :order => 'position') %> | |||
<% roles = Role.find_all_givable %> | |||
<% users = User.find_active(:all) - @project.users %> | |||
<table class="list"> |
@@ -5,14 +5,11 @@ | |||
<% form_tag do %> | |||
<p><%= select_month(@month, :prefix => "month", :discard_type => true) %> | |||
<%= select_year(@year, :prefix => "year", :discard_type => true) %></p> | |||
<p> | |||
<%= check_box_tag 'show_issues', 1, @show_issues %><%= hidden_field_tag 'show_issues', 0, :id => nil %> <%=l(:label_issue_plural)%><br /> | |||
<% if @project.repository %><%= check_box_tag 'show_changesets', 1, @show_changesets %><%= hidden_field_tag 'show_changesets', 0, :id => nil %> <%=l(:label_revision_plural)%><br /><% end %> | |||
<%= check_box_tag 'show_news', 1, @show_news %><%= hidden_field_tag 'show_news', 0, :id => nil %> <%=l(:label_news_plural)%><br /> | |||
<%= check_box_tag 'show_files', 1, @show_files %><%= hidden_field_tag 'show_files', 0, :id => nil %> <%=l(:label_attachment_plural)%><br /> | |||
<%= check_box_tag 'show_documents', 1, @show_documents %><%= hidden_field_tag 'show_documents', 0, :id => nil %> <%=l(:label_document_plural)%><br /> | |||
<% if @project.wiki %><%= check_box_tag 'show_wiki_edits', 1, @show_wiki_edits %><%= hidden_field_tag 'show_wiki_edits', 0, :id => nil %> <%=l(:label_wiki_edit_plural)%><% end %> | |||
</p> | |||
<p><% @event_types.each do |t| %> | |||
<%= check_box_tag "show_#{t}", 1, @scope.include?(t) %> <%= l("label_#{t.singularize}_plural")%><br /> | |||
<% end %></p> | |||
<p class="textcenter"><%= submit_tag l(:button_apply), :class => 'button-small' %></p> | |||
<% end %> | |||
</div> | |||
@@ -20,33 +17,33 @@ | |||
<% @events_by_day.keys.sort {|x,y| y <=> x }.each do |day| %> | |||
<h3><%= day_name(day.cwday) %> <%= day.day %></h3> | |||
<ul> | |||
<% @events_by_day[day].sort {|x,y| y.created_on <=> x.created_on }.each do |e| %> | |||
<% @events_by_day[day].sort {|x,y| y.event_datetime <=> x.event_datetime }.each do |e| %> | |||
<li><p> | |||
<% if e.is_a? Issue %> | |||
<%= e.created_on.strftime("%H:%M") %> <%= link_to_issue e %>: <%=h e.subject %><br /> | |||
<%= e.event_datetime.strftime("%H:%M") %> <%= link_to_issue e %>: <%=h e.subject %><br /> | |||
<i><%= e.author.name %></i> | |||
<% elsif e.is_a? Journal %> | |||
<%= e.created_on.strftime("%H:%M") %> <%= link_to_issue e.journalized %> | |||
(<%=h (status = IssueStatus.find_by_id(e.details.first.value)) ? status.name : '?' %>): <%=h e.journalized.subject %><br /> | |||
<em><%=h e.user.name %><%=h ": #{truncate(e.notes, 500)}" unless e.notes.blank? %></em> | |||
<% elsif e.is_a? News %> | |||
<%= e.created_on.strftime("%H:%M") %> <%=l(:label_news)%>: <%= link_to h(e.title), :controller => 'news', :action => 'show', :id => e %><br /> | |||
<%= e.event_datetime.strftime("%H:%M") %> <%=l(:label_news)%>: <%= link_to h(e.title), :controller => 'news', :action => 'show', :id => e %><br /> | |||
<% unless e.summary.empty? %><%=h e.summary %><br /><% end %> | |||
<i><%= e.author.name %></i> | |||
<% elsif (e.is_a? Attachment) and (e.container.is_a? Version) %> | |||
<%= e.created_on.strftime("%H:%M") %> <%=l(:label_attachment)%> (<%=h e.container.name %>): <%= link_to e.filename, :controller => 'projects', :action => 'list_files', :id => @project %><br /> | |||
<%= e.event_datetime.strftime("%H:%M") %> <%=l(:label_attachment)%> (<%=h e.container.name %>): <%= link_to e.filename, :controller => 'projects', :action => 'list_files', :id => @project %><br /> | |||
<i><%= e.author.name %></i> | |||
<% elsif (e.is_a? Attachment) and (e.container.is_a? Document) %> | |||
<%= e.created_on.strftime("%H:%M") %> <%=l(:label_attachment)%>: <%= e.filename %> (<%= link_to h(e.container.title), :controller => 'documents', :action => 'show', :id => e.container %>)<br /> | |||
<%= e.event_datetime.strftime("%H:%M") %> <%=l(:label_attachment)%>: <%= e.filename %> (<%= link_to h(e.container.title), :controller => 'documents', :action => 'show', :id => e.container %>)<br /> | |||
<i><%= e.author.name %></i> | |||
<% elsif e.is_a? Document %> | |||
<%= e.created_on.strftime("%H:%M") %> <%=l(:label_document)%>: <%= link_to h(e.title), :controller => 'documents', :action => 'show', :id => e %><br /> | |||
<%= e.event_datetime.strftime("%H:%M") %> <%=l(:label_document)%>: <%= link_to h(e.title), :controller => 'documents', :action => 'show', :id => e %><br /> | |||
<% elsif e.is_a? WikiContent.versioned_class %> | |||
<%= e.created_on.strftime("%H:%M") %> <%=l(:label_wiki_edit)%>: <%= link_to h(WikiPage.pretty_title(e.title)), :controller => 'wiki', :page => e.title %> | |||
<%= e.event_datetime.strftime("%H:%M") %> <%=l(:label_wiki_edit)%>: <%= link_to h(WikiPage.pretty_title(e.title)), :controller => 'wiki', :page => e.title %> | |||
(<%= link_to '#' + e.version.to_s, :controller => 'wiki', :page => e.title, :version => e.version %><%= ', ' + link_to('diff', :controller => 'wiki', :action => 'diff', :page => e.title, :version => e.version) if e.version > 1 %>)<br /> | |||
<% unless e.comments.blank? %><em><%=h e.comments %></em><% end %> | |||
<% elsif e.is_a? Changeset %> | |||
<%= e.created_on.strftime("%H:%M") %> <%=l(:label_revision)%> <%= link_to h(e.revision), :controller => 'repositories', :action => 'revision', :id => @project, :rev => e.revision %><br /> | |||
<%= e.event_datetime.strftime("%H:%M") %> <%=l(:label_revision)%> <%= link_to h(e.revision), :controller => 'repositories', :action => 'revision', :id => @project, :rev => e.revision %><br /> | |||
<em><%=h e.committer.blank? ? "anonymous" : e.committer %><%= h(": #{truncate(e.comments, 500)}") unless e.comments.blank? %></em> | |||
<% end %> | |||
</p></li> | |||
@@ -69,3 +66,7 @@ | |||
</div> | |||
<br /> | |||
</div> | |||
<% content_for :header_tags do %> | |||
<%= auto_discovery_link_tag(:atom, params.merge({:format => 'atom', :year => nil, :month => nil, :key => User.current.rss_key})) %> | |||
<% end %> |
@@ -10,7 +10,7 @@ | |||
<% for project in @projects %> | |||
<tr class="<%= cycle("odd", "even") %>"> | |||
<td> | |||
<%= link_to project.name, {:action => 'show', :id => project}, :class => (@logged_in_user && @logged_in_user.role_for_project(project) ? "icon icon-fav" : "") %><br /> | |||
<%= link_to project.name, {:action => 'show', :id => project}, :class => (User.current.member_of?(project) ? "icon icon-fav" : "") %><br /> | |||
<%= textilizable project.description, :project => project %> | |||
</td> | |||
<td><%= link_to(project.parent.name, :action => 'show', :id => project.parent) unless project.parent.nil? %></td> | |||
@@ -20,7 +20,7 @@ | |||
</tbody> | |||
</table> | |||
<% if @logged_in_user %> | |||
<% if User.current.logged? %> | |||
<div class="contextual"> | |||
<span class="icon icon-fav"><%= l(:label_my_projects) %></span> | |||
</div> |
@@ -1,6 +1,7 @@ | |||
<% if @query.new_record? %> | |||
<div class="contextual"> | |||
<%= link_to l(:label_query_plural), :controller => 'queries', :project_id => @project %> | |||
<% if authorize_for('projects', 'add_issues') %>| <%= l(:label_issue_new) %>: <%= new_issue_selector %><% end %> | |||
</div> | |||
<h2><%=l(:label_issue_plural)%></h2> | |||
@@ -19,7 +20,7 @@ | |||
:update => "content", | |||
}, :class => 'icon icon-reload' %> | |||
<% if loggedin? %> | |||
<% if current_role.allowed_to?(:save_queries) %> | |||
<%= link_to_remote l(:button_save), | |||
{ :url => { :controller => 'queries', :action => 'new', :project_id => @project }, | |||
:method => 'get', | |||
@@ -33,6 +34,7 @@ | |||
<div class="contextual"> | |||
<%= link_to l(:label_query_plural), {:controller => 'queries', :project_id => @project} %> | | |||
<%= link_to l(:label_issue_view_all), {:controller => 'projects', :action => 'list_issues', :id => @project, :set_filter => 1} %> | |||
<% if authorize_for('projects', 'add_issues') %>| <%= l(:label_issue_new) %>: <%= new_issue_selector %><% end %> | |||
</div> | |||
<h2><%= @query.name %></h2> | |||
<% end %> | |||
@@ -81,4 +83,4 @@ | |||
</p> | |||
<% end %> | |||
<% end %> | |||
<% end %> | |||
<% end %> |
@@ -7,3 +7,7 @@ | |||
<% if @news.empty? %><p><i><%= l(:label_no_data) %></i></p><% end %> | |||
<%= render :partial => 'news/news', :collection => @news %> | |||
<%= pagination_links_full @news_pages %> | |||
<% content_for :header_tags do %> | |||
<%= auto_discovery_link_tag(:atom, params.merge({:format => 'atom', :page => nil, :key => User.current.rss_key})) %> | |||
<% end %> |
@@ -20,6 +20,7 @@ | |||
</ul> | |||
<div class="box"> | |||
<div class="contextual"><% if authorize_for('projects', 'add_issues') %><%= l(:label_issue_new) %>: <%= new_issue_selector %><% end %></div> | |||
<h3 class="icon22 icon22-tracker"><%=l(:label_issue_tracking)%></h3> | |||
<ul> | |||
<% for tracker in @trackers %> | |||
@@ -49,7 +50,7 @@ | |||
</div> | |||
<% end %> | |||
<% if @news.any? %> | |||
<% if @news.any? && authorize_for('projects', 'list_news') %> | |||
<div class="box"> | |||
<h3><%=l(:label_news_latest)%></h3> | |||
<%= render :partial => 'news/news', :collection => @news %> |
@@ -5,7 +5,7 @@ | |||
<p><label for="query_name"><%=l(:field_name)%></label> | |||
<%= text_field 'query', 'name', :size => 80 %></p> | |||
<% if authorize_for('projects', 'add_query') %> | |||
<% if current_role.allowed_to?(:manage_pulic_queries) %> | |||
<p><label for="query_is_public"><%=l(:field_is_public)%></label> | |||
<%= check_box 'query', 'is_public' %></p> | |||
<% end %> |
@@ -1,7 +1,5 @@ | |||
<div class="contextual"> | |||
<% if loggedin? %> | |||
<%= link_to l(:label_query_new), {:controller => 'queries', :action => 'new', :project_id => @project}, :class => 'icon icon-add' %> | |||
<% end %> | |||
<%= link_to_if_authorized l(:label_query_new), {:controller => 'queries', :action => 'new', :project_id => @project}, :class => 'icon icon-add' %> | |||
</div> | |||
<h2><%= l(:label_query_plural) %></h2> | |||
@@ -17,7 +15,7 @@ | |||
</td> | |||
<td align="right"> | |||
<small> | |||
<% if query.editable_by?(@logged_in_user) %> | |||
<% if query.editable_by?(User.current) %> | |||
<%= link_to l(:button_edit), {:controller => 'queries', :action => 'edit', :id => query}, :class => 'icon icon-edit' %> | |||
<%= link_to l(:button_delete), {:controller => 'queries', :action => 'destroy', :id => query}, :confirm => l(:text_are_you_sure), :method => :post, :class => 'icon icon-del' %> | |||
</small> |
@@ -1,4 +1,4 @@ | |||
<% if @total_hours %> | |||
<% if @total_hours && authorize_for('timelog', 'reports') %> | |||
<div style="float:right;text-align:right;"> | |||
<strong><%= l(:label_spent_time) %></strong>: <span class="icon icon-time"><%= lwr(:label_f_hour, @total_hours) %></span><br /> | |||
<%= link_to(l(:label_details), {:controller => 'timelog', :action => 'details', :project_id => @project}) %> | |
@@ -14,4 +14,5 @@ | |||
<% content_for :header_tags do %> | |||
<%= stylesheet_link_tag "scm" %> | |||
<%= auto_discovery_link_tag(:atom, params.merge({:format => 'atom', :page => nil, :key => User.current.rss_key})) %> | |||
<% end %> |
@@ -4,15 +4,18 @@ | |||
<h2><%= l(:label_repository) %> (<%= @repository.scm_name %>)</h2> | |||
<% unless @entries.nil? %> | |||
<% if !@entries.nil? && authorize_for('repositories', 'browse') %> | |||
<h3><%= l(:label_browse) %></h3> | |||
<%= render :partial => 'dir_list' %> | |||
<% end %> | |||
<% unless @changesets.empty? %> | |||
<% if !@changesets.empty? && authorize_for('repositories', 'revisions') %> | |||
<h3><%= l(:label_latest_revision_plural) %></h3> | |||
<%= render :partial => 'revisions', :locals => {:project => @project, :path => '', :revisions => @changesets, :entry => nil }%> | |||
<p><%= link_to l(:label_view_revisions), :action => 'revisions', :id => @project %></p> | |||
<% content_for :header_tags do %> | |||
<%= auto_discovery_link_tag(:atom, params.merge({:format => 'atom', :action => 'revisions', :id => @project, :page => nil, :key => User.current.rss_key})) %> | |||
<% end %> | |||
<% end %> | |||
<% content_for :header_tags do %> |
@@ -1,23 +1,20 @@ | |||
<%= error_messages_for 'role' %> | |||
<div class="box"> | |||
<!--[form:role]--> | |||
<p><%= f.text_field :name, :required => true %></p> | |||
<p><%= f.text_field :name, :required => true, :disabled => @role.builtin? %></p> | |||
</div> | |||
<p><%= f.check_box :assignable %></p> | |||
<div class="clear"></div> | |||
<h3><%=l(:label_permissions)%></h3> | |||
<% permissions = @permissions.group_by {|p| p.group_id } %> | |||
<% permissions.keys.sort.each do |group_id| %> | |||
<fieldset style="margin-top: 6px;"><legend><strong><%= l(Permission::GROUPS[group_id]) %></strong></legend> | |||
<% permissions[group_id].each do |p| %> | |||
<div style="width:170px;float:left;"><%= check_box_tag "permission_ids[]", p.id, (@role.permissions.include? p) %> | |||
<%= l(p.description.to_sym) %> | |||
</div> | |||
<fieldset class="box"><legend><%=l(:label_permissions)%></legend> | |||
<% @permissions.each do |permission| %> | |||
<div style="width:220px;float:left;"> | |||
<%= check_box_tag 'role[permissions][]', permission.name, (@role.permissions.include? permission.name) %> | |||
<%= permission.name.to_s.humanize %> | |||
</div> | |||
<% end %> | |||
<%= hidden_field_tag 'role[permissions][]', '' %> | |||
<div class="clear"></div> | |||
</fieldset> | |||
<% end %> | |||
<br /> | |||
<%= check_all_links 'role_form' %> | |||
<!--[eoform:role]--> | |||
</div> | |||
</fieldset> |
@@ -13,15 +13,17 @@ | |||
<tbody> | |||
<% for role in @roles %> | |||
<tr class="<%= cycle("odd", "even") %>"> | |||
<td><%= link_to role.name, :action => 'edit', :id => role %></td> | |||
<td><%= content_tag(role.builtin? ? 'em' : 'span', link_to(role.name, :action => 'edit', :id => role)) %></td> | |||
<td align="center" style="width:15%;"> | |||
<% unless role.builtin? %> | |||
<%= link_to image_tag('2uparrow.png', :alt => l(:label_sort_highest)), {:action => 'move', :id => role, :position => 'highest'}, :method => :post, :title => l(:label_sort_highest) %> | |||
<%= link_to image_tag('1uparrow.png', :alt => l(:label_sort_higher)), {:action => 'move', :id => role, :position => 'higher'}, :method => :post, :title => l(:label_sort_higher) %> - | |||
<%= link_to image_tag('1downarrow.png', :alt => l(:label_sort_lower)), {:action => 'move', :id => role, :position => 'lower'}, :method => :post, :title => l(:label_sort_lower) %> | |||
<%= link_to image_tag('2downarrow.png', :alt => l(:label_sort_lowest)), {:action => 'move', :id => role, :position => 'lowest'}, :method => :post, :title => l(:label_sort_lowest) %> | |||
<% end %> | |||
</td> | |||
<td align="center" style="width:10%;"> | |||
<%= button_to l(:button_delete), { :action => 'destroy', :id => role }, :confirm => l(:text_are_you_sure), :class => "button-small" %> | |||
<%= button_to(l(:button_delete), { :action => 'destroy', :id => role }, :confirm => l(:text_are_you_sure), :class => "button-small") unless role.builtin? %> | |||
</tr> | |||
<% end %> | |||
</tbody> |
@@ -1,32 +1,31 @@ | |||
<h2><%=l(:label_permissions_report)%></h2> | |||
<%= start_form_tag({:action => 'report'}, :id => 'permissions_form') %> | |||
<%= hidden_field_tag 'permissions[0]', '' %> | |||
<table class="list"> | |||
<thead><tr> | |||
<th><%=l(:label_permissions)%></th> | |||
<th colspan="<%= @roles.length %>"><%= l(:label_role_plural) %></th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<% permissions = @permissions.group_by {|p| p.group_id } %> | |||
<% permissions.keys.sort.each do |group_id| %> | |||
<thead> | |||
<tr> | |||
<th><%= l(Permission::GROUPS[group_id]) %></th> | |||
<% @roles.each do |role| %><th align="center"><small><%= role.name %></small></th><% end %> | |||
</tr> | |||
<% permissions[group_id].each do |p| %> | |||
<tr class="<%= cycle("odd", "even") %>"> | |||
<td><%= l(p.description.to_sym) %></td> | |||
<th><%=l(:label_permissions)%></th> | |||
<% @roles.each do |role| %> | |||
<td align="center"><%= check_box_tag "permission_ids[#{role.id}][]", p.id, (role.permissions.include? p) %></td> | |||
<th><%= content_tag(role.builtin? ? 'em' : 'span', h(role.name)) %></th> | |||
<% end %> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
<% @permissions.each do |permission| %> | |||
<tr class="<%= cycle('odd', 'even') %>"> | |||
<td><%= permission.name.to_s.humanize %></td> | |||
<% @roles.each do |role| %> | |||
<td align="center"> | |||
<% if role.setable_permissions.include? permission %> | |||
<%= check_box_tag "permissions[#{role.id}][]", permission.name, (role.permissions.include? permission.name) %> | |||
<% end %> | |||
<% reset_cycle | |||
end %> | |||
</td> | |||
<% end %> | |||
</tr> | |||
<% end %> | |||
</tbody> | |||
</table> | |||
<p><%= check_all_links 'permissions_form' %></p> | |||
<p><%= submit_tag l(:button_save) %></p> | |||
<%= end_form_tag %> | |||
<%= end_form_tag %> |
@@ -1,7 +1,7 @@ | |||
<div class="contextual"> | |||
<%= link_to(l(:button_edit), {:action => 'edit', :page => @page.title}, :class => 'icon icon-edit') if @content.version == @page.content.version %> | |||
<%= link_to_if_authorized(l(:button_edit), {:action => 'edit', :page => @page.title}, :class => 'icon icon-edit') if @content.version == @page.content.version %> | |||
<%= link_to_if_authorized(l(:button_delete), {:action => 'destroy', :page => @page.title}, :method => :post, :confirm => l(:text_are_you_sure), :class => 'icon icon-del') %> | |||
<%= link_to(l(:button_rollback), {:action => 'edit', :page => @page.title, :version => @content.version }, :class => 'icon icon-cancel') if @content.version < @page.content.version %> | |||
<%= link_to_if_authorized(l(:button_rollback), {:action => 'edit', :page => @page.title, :version => @content.version }, :class => 'icon icon-cancel') if @content.version < @page.content.version %> | |||
<%= link_to(l(:label_history), {:action => 'history', :page => @page.title}, :class => 'icon icon-history') %> | |||
<%= link_to(l(:label_page_index), {:action => 'special', :page => 'Page_index'}, :class => 'icon icon-index') %> | |||
</div> |
@@ -16,6 +16,10 @@ | |||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |||
class Setup < ActiveRecord::Migration | |||
# model removed | |||
class Permission < ActiveRecord::Base; end | |||
def self.up | |||
create_table "attachments", :force => true do |t| | |||
t.column "container_id", :integer, :default => 0, :null => false |
@@ -1,4 +1,7 @@ | |||
class IssueMove < ActiveRecord::Migration | |||
# model removed | |||
class Permission < ActiveRecord::Base; end | |||
def self.up | |||
Permission.create :controller => "projects", :action => "move_issues", :description => "button_move", :sort => 1061, :mail_option => 0, :mail_enabled => 0 | |||
end |
@@ -1,4 +1,7 @@ | |||
class IssueAddNote < ActiveRecord::Migration | |||
# model removed | |||
class Permission < ActiveRecord::Base; end | |||
def self.up | |||
Permission.create :controller => "issues", :action => "add_note", :description => "label_add_note", :sort => 1057, :mail_option => 1, :mail_enabled => 0 | |||
end |
@@ -1,4 +1,7 @@ | |||
class ExportPdf < ActiveRecord::Migration | |||
# model removed | |||
class Permission < ActiveRecord::Base; end | |||
def self.up | |||
Permission.create :controller => "projects", :action => "export_issues_pdf", :description => "label_export_pdf", :sort => 1002, :is_public => true, :mail_option => 0, :mail_enabled => 0 | |||
Permission.create :controller => "issues", :action => "export_pdf", :description => "label_export_pdf", :sort => 1015, :is_public => true, :mail_option => 0, :mail_enabled => 0 |
@@ -1,4 +1,7 @@ | |||
class CalendarAndActivity < ActiveRecord::Migration | |||
# model removed | |||
class Permission < ActiveRecord::Base; end | |||
def self.up | |||
Permission.create :controller => "projects", :action => "activity", :description => "label_activity", :sort => 160, :is_public => true, :mail_option => 0, :mail_enabled => 0 | |||
Permission.create :controller => "projects", :action => "calendar", :description => "label_calendar", :sort => 165, :is_public => true, :mail_option => 0, :mail_enabled => 0 |
@@ -2,6 +2,8 @@ class CreateJournals < ActiveRecord::Migration | |||
# model removed, but needed for data migration | |||
class IssueHistory < ActiveRecord::Base; belongs_to :issue; end | |||
# model removed | |||
class Permission < ActiveRecord::Base; end | |||
def self.up | |||
create_table :journals, :force => true do |t| |
@@ -1,4 +1,7 @@ | |||
class AddCommentsPermissions < ActiveRecord::Migration | |||
# model removed | |||
class Permission < ActiveRecord::Base; end | |||
def self.up | |||
Permission.create :controller => "news", :action => "add_comment", :description => "label_comment_add", :sort => 1130, :is_public => false, :mail_option => 0, :mail_enabled => 0 | |||
Permission.create :controller => "news", :action => "destroy_comment", :description => "label_comment_delete", :sort => 1133, :is_public => false, :mail_option => 0, :mail_enabled => 0 |
@@ -1,4 +1,7 @@ | |||
class AddQueriesPermissions < ActiveRecord::Migration | |||
# model removed | |||
class Permission < ActiveRecord::Base; end | |||
def self.up | |||
Permission.create :controller => "projects", :action => "add_query", :description => "button_create", :sort => 600, :is_public => false, :mail_option => 0, :mail_enabled => 0 | |||
end |
@@ -1,4 +1,7 @@ | |||
class AddRepositoriesPermissions < ActiveRecord::Migration | |||
# model removed | |||
class Permission < ActiveRecord::Base; end | |||
def self.up | |||
Permission.create :controller => "repositories", :action => "show", :description => "button_view", :sort => 1450, :is_public => true | |||
Permission.create :controller => "repositories", :action => "browse", :description => "label_browse", :sort => 1460, :is_public => true |
@@ -1,4 +1,7 @@ | |||
class SetDocAndFilesNotifications < ActiveRecord::Migration | |||
# model removed | |||
class Permission < ActiveRecord::Base; end | |||
def self.up | |||
Permission.find_by_controller_and_action("projects", "add_file").update_attribute(:mail_option, true) | |||
Permission.find_by_controller_and_action("projects", "add_document").update_attribute(:mail_option, true) |
@@ -1,4 +1,7 @@ | |||
class AddRoadmapPermission < ActiveRecord::Migration | |||
# model removed | |||
class Permission < ActiveRecord::Base; end | |||
def self.up | |||
Permission.create :controller => "projects", :action => "roadmap", :description => "label_roadmap", :sort => 107, :is_public => true, :mail_option => 0, :mail_enabled => 0 | |||
end |
@@ -1,4 +1,7 @@ | |||
class AddSearchPermission < ActiveRecord::Migration | |||
# model removed | |||
class Permission < ActiveRecord::Base; end | |||
def self.up | |||
Permission.create :controller => "projects", :action => "search", :description => "label_search", :sort => 130, :is_public => true, :mail_option => 0, :mail_enabled => 0 | |||
end |
@@ -1,4 +1,7 @@ | |||
class AddProjectsFeedsPermissions < ActiveRecord::Migration | |||
# model removed | |||
class Permission < ActiveRecord::Base; end | |||
def self.up | |||
Permission.create :controller => "projects", :action => "feeds", :description => "label_feed_plural", :sort => 132, :is_public => true, :mail_option => 0, :mail_enabled => 0 | |||
end |
@@ -1,4 +1,7 @@ | |||
class AddTimelogPermissions < ActiveRecord::Migration | |||
# model removed | |||
class Permission < ActiveRecord::Base; end | |||
def self.up | |||
Permission.create :controller => "timelog", :action => "edit", :description => "button_log_time", :sort => 1520, :is_public => false, :mail_option => 0, :mail_enabled => 0 | |||
end |
@@ -1,4 +1,7 @@ | |||
class AddRelationsPermissions < ActiveRecord::Migration | |||
# model removed | |||
class Permission < ActiveRecord::Base; end | |||
def self.up | |||
Permission.create :controller => "issue_relations", :action => "new", :description => "label_relation_new", :sort => 1080, :is_public => false, :mail_option => 0, :mail_enabled => 0 | |||
Permission.create :controller => "issue_relations", :action => "destroy", :description => "label_relation_delete", :sort => 1085, :is_public => false, :mail_option => 0, :mail_enabled => 0 |
@@ -1,4 +1,7 @@ | |||
class AddBoardsPermissions < ActiveRecord::Migration | |||
# model removed | |||
class Permission < ActiveRecord::Base; end | |||
def self.up | |||
Permission.create :controller => "boards", :action => "new", :description => "button_add", :sort => 2000, :is_public => false, :mail_option => 0, :mail_enabled => 0 | |||
Permission.create :controller => "boards", :action => "edit", :description => "button_edit", :sort => 2005, :is_public => false, :mail_option => 0, :mail_enabled => 0 |
@@ -1,4 +1,7 @@ | |||
class AddWikiDestroyPagePermission < ActiveRecord::Migration | |||
# model removed | |||
class Permission < ActiveRecord::Base; end | |||
def self.up | |||
Permission.create :controller => 'wiki', :action => 'destroy', :description => 'button_delete', :sort => 1740, :is_public => false, :mail_option => 0, :mail_enabled => 0 | |||
end |
@@ -1,4 +1,7 @@ | |||
class AddWikiAttachmentsPermissions < ActiveRecord::Migration | |||
# model removed | |||
class Permission < ActiveRecord::Base; end | |||
def self.up | |||
Permission.create :controller => 'wiki', :action => 'add_attachment', :description => 'label_attachment_new', :sort => 1750, :is_public => false, :mail_option => 0, :mail_enabled => 0 | |||
Permission.create :controller => 'wiki', :action => 'destroy_attachment', :description => 'label_attachment_delete', :sort => 1755, :is_public => false, :mail_option => 0, :mail_enabled => 0 |
@@ -1,4 +1,7 @@ | |||
class AddRepositoriesChangesPermission < ActiveRecord::Migration | |||
# model removed | |||
class Permission < ActiveRecord::Base; end | |||
def self.up | |||
Permission.create :controller => 'repositories', :action => 'changes', :description => 'label_change_plural', :sort => 1475, :is_public => true, :mail_option => 0, :mail_enabled => 0 | |||
end |
@@ -0,0 +1,9 @@ | |||
class AddRolesBuiltin < ActiveRecord::Migration | |||
def self.up | |||
add_column :roles, :builtin, :integer, :default => 0, :null => false | |||
end | |||
def self.down | |||
remove_column :roles, :builtin | |||
end | |||
end |
@@ -0,0 +1,15 @@ | |||
class InsertBuiltinRoles < ActiveRecord::Migration | |||
def self.up | |||
nonmember = Role.new(:name => 'Non member', :position => 0) | |||
nonmember.builtin = Role::BUILTIN_NON_MEMBER | |||
nonmember.save | |||
anonymous = Role.new(:name => 'Anonymous', :position => 0) | |||
anonymous.builtin = Role::BUILTIN_ANONYMOUS | |||
anonymous.save | |||
end | |||
def self.down | |||
Role.destroy_all 'builtin <> 0' | |||
end | |||
end |
@@ -0,0 +1,9 @@ | |||
class AddRolesPermissions < ActiveRecord::Migration | |||
def self.up | |||
add_column :roles, :permissions, :text | |||
end | |||
def self.down | |||
remove_column :roles, :permissions | |||
end | |||
end |
@@ -0,0 +1,10 @@ | |||
class DropPermissions < ActiveRecord::Migration | |||
def self.up | |||
drop_table :permissions | |||
drop_table :permissions_roles | |||
end | |||
def self.down | |||
raise IrreversibleMigration | |||
end | |||
end |
@@ -1,6 +1,9 @@ | |||
require 'redmine/version' | |||
require 'redmine/access_control' | |||
require 'redmine/menu_manager' | |||
require 'redmine/mime_type' | |||
require 'redmine/acts_as_watchable/init' | |||
require 'redmine/acts_as_event/init' | |||
begin | |||
require_library_or_gem 'rmagick' unless Object.const_defined?(:Magick) | |||
@@ -9,3 +12,77 @@ rescue LoadError | |||
end | |||
REDMINE_SUPPORTED_SCM = %w( Subversion Darcs Mercurial Cvs ) | |||
# Permissions | |||
Redmine::AccessControl.map do |map| | |||
# Project | |||
map.permission :view_project, {:projects => [:show, :activity, :changelog, :roadmap, :feeds]}, :public => true | |||
map.permission :search_project, {:search => :index}, :public => true | |||
map.permission :edit_project, {:projects => [:settings, :edit]}, :require => :member | |||
map.permission :manage_members, {:projects => [:settings, :add_member], :members => [:edit, :destroy]}, :require => :member | |||
map.permission :manage_versions, {:projects => [:settings, :add_version], :versions => [:edit, :destroy]}, :require => :member | |||
map.permission :manage_categories, {:projects => [:settings, :add_issue_category], :issue_categories => [:edit, :destroy]}, :require => :member | |||
# Issues | |||
map.permission :view_issues, {:projects => [:list_issues, :export_issues_csv, :export_issues_pdf], | |||
:issues => [:show, :export_pdf], | |||
:queries => :index, | |||
:reports => :issue_report}, :public => true | |||
map.permission :add_issues, {:projects => :add_issue}, :require => :loggedin | |||
map.permission :edit_issues, {:issues => [:edit, :destroy_attachment]}, :require => :loggedin | |||
map.permission :manage_issue_relations, {:issue_relations => [:new, :destroy]}, :require => :loggedin | |||
map.permission :add_issue_notes, {:issues => :add_note}, :require => :loggedin | |||
map.permission :change_issue_status, {:issues => :change_status}, :require => :loggedin | |||
map.permission :move_issues, {:projects => :move_issues}, :require => :loggedin | |||
map.permission :delete_issues, {:issues => :destroy}, :require => :member | |||
# Queries | |||
map.permission :manage_pulic_queries, {:queries => [:new, :edit, :destroy]}, :require => :member | |||
map.permission :save_queries, {:queries => [:new, :edit, :destroy]}, :require => :loggedin | |||
# Gantt & calendar | |||
map.permission :view_gantt, :projects => :gantt | |||
map.permission :view_calendar, :projects => :calendar | |||
# Time tracking | |||
map.permission :log_time, {:timelog => :edit}, :require => :loggedin | |||
map.permission :view_time_entries, :timelog => [:details, :report] | |||
# News | |||
map.permission :view_news, {:projects => :list_news, :news => :show}, :public => true | |||
map.permission :manage_news, {:projects => :add_news, :news => [:edit, :destroy, :destroy_comment]}, :require => :member | |||
map.permission :comment_news, {:news => :add_comment}, :require => :loggedin | |||
# Documents | |||
map.permission :view_documents, :projects => :list_documents, :documents => [:show, :download] | |||
map.permission :manage_documents, {:projects => :add_document, :documents => [:edit, :destroy, :add_attachment, :destroy_attachment]}, :require => :loggedin | |||
# Wiki | |||
map.permission :view_wiki_pages, :wiki => [:index, :history, :diff, :special] | |||
map.permission :edit_wiki_pages, :wiki => [:edit, :preview, :add_attachment, :destroy_attachment] | |||
map.permission :delete_wiki_pages, {:wiki => :destroy}, :require => :member | |||
# Message boards | |||
map.permission :view_messages, {:boards => [:index, :show], :messages => [:show]}, :public => true | |||
map.permission :add_messages, {:messages => [:new, :reply]}, :require => :loggedin | |||
map.permission :manage_boards, {:boards => [:new, :edit, :destroy]}, :require => :member | |||
# Files | |||
map.permission :view_files, :projects => :list_files, :versions => :download | |||
map.permission :manage_files, {:projects => :add_file, :versions => :destroy_file}, :require => :loggedin | |||
# Repository | |||
map.permission :browse_repository, :repositories => [:show, :browse, :entry, :changes, :diff, :stats, :graph] | |||
map.permission :view_changesets, :repositories => [:show, :revisions, :revision] | |||
end | |||
# Project menu configuration | |||
Redmine::MenuManager.map :project_menu do |menu| | |||
menu.push :label_overview, :controller => 'projects', :action => 'show' | |||
menu.push :label_calendar, :controller => 'projects', :action => 'calendar' | |||
menu.push :label_gantt, :controller => 'projects', :action => 'gantt' | |||
menu.push :label_issue_plural, :controller => 'projects', :action => 'list_issues' | |||
menu.push :label_report_plural, :controller => 'reports', :action => 'issue_report' | |||
menu.push :label_activity, :controller => 'projects', :action => 'activity' | |||
menu.push :label_news_plural, :controller => 'projects', :action => 'list_news' | |||
menu.push :label_change_log, :controller => 'projects', :action => 'changelog' | |||
menu.push :label_roadmap, :controller => 'projects', :action => 'roadmap' | |||
menu.push :label_document_plural, :controller => 'projects', :action => 'list_documents' | |||
menu.push :label_wiki, { :controller => 'wiki', :action => 'index', :page => nil }, :if => Proc.new { |p| p.wiki && !p.wiki.new_record? } | |||
menu.push :label_board_plural, { :controller => 'boards', :action => 'index', :id => nil }, :param => :project_id, :if => Proc.new { |p| p.boards.any? } | |||
menu.push :label_attachment_plural, :controller => 'projects', :action => 'list_files' | |||
menu.push :label_search, :controller => 'search', :action => 'index' | |||
menu.push :label_repository, { :controller => 'repositories', :action => 'show' }, :if => Proc.new { |p| p.repository && !p.repository.new_record? } | |||
menu.push :label_settings, :controller => 'projects', :action => 'settings' | |||
end |
@@ -0,0 +1,92 @@ | |||
# 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. | |||
module Redmine | |||
module AccessControl | |||
class << self | |||
def map | |||
mapper = Mapper.new | |||
yield mapper | |||
@permissions ||= [] | |||
@permissions += mapper.mapped_permissions | |||
end | |||
def permissions | |||
@permissions | |||
end | |||
def allowed_actions(permission_name) | |||
perm = @permissions.detect {|p| p.name == permission_name} | |||
perm ? perm.actions : [] | |||
end | |||
def public_permissions | |||
@public_permissions ||= @permissions.select {|p| p.public?} | |||
end | |||
def members_only_permissions | |||
@members_only_permissions ||= @permissions.select {|p| p.require_member?} | |||
end | |||
def loggedin_only_permissions | |||
@loggedin_only_permissions ||= @permissions.select {|p| p.require_loggedin?} | |||
end | |||
end | |||
class Mapper | |||
def permission(name, hash, options={}) | |||
@permissions ||= [] | |||
@permissions << Permission.new(name, hash, options) | |||
end | |||
def mapped_permissions | |||
@permissions | |||
end | |||
end | |||
class Permission | |||
attr_reader :name, :actions | |||
def initialize(name, hash, options) | |||
@name = name | |||
@actions = [] | |||
@public = options[:public] || false | |||
@require = options[:require] | |||
hash.each do |controller, actions| | |||
if actions.is_a? Array | |||
@actions << actions.collect {|action| "#{controller}/#{action}"} | |||
else | |||
@actions << "#{controller}/#{actions}" | |||
end | |||
end | |||
end | |||
def public? | |||
@public | |||
end | |||
def require_member? | |||
@require && @require == :member | |||
end | |||
def require_loggedin? | |||
@require && (@require == :member || @require == :loggedin) | |||
end | |||
end | |||
end | |||
end |
@@ -0,0 +1,2 @@ | |||
require File.dirname(__FILE__) + '/lib/acts_as_event' | |||
ActiveRecord::Base.send(:include, Redmine::Acts::Event) |
@@ -0,0 +1,68 @@ | |||
# 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. | |||
module Redmine | |||
module Acts | |||
module Event | |||
def self.included(base) | |||
base.extend ClassMethods | |||
end | |||
module ClassMethods | |||
def acts_as_event(options = {}) | |||
return if self.included_modules.include?(Redmine::Acts::Event::InstanceMethods) | |||
options[:datetime] ||= 'created_on' | |||
options[:title] ||= 'title' | |||
options[:description] ||= 'description' | |||
options[:author] ||= 'author' | |||
options[:url] ||= {:controller => 'welcome'} | |||
cattr_accessor :event_options | |||
self.event_options = options | |||
send :include, Redmine::Acts::Event::InstanceMethods | |||
end | |||
end | |||
module InstanceMethods | |||
def self.included(base) | |||
base.extend ClassMethods | |||
end | |||
%w(datetime title description author).each do |attr| | |||
src = <<-END_SRC | |||
def event_#{attr} | |||
option = event_options[:#{attr}] | |||
option.is_a?(Proc) ? option.call(self) : send(option) | |||
end | |||
END_SRC | |||
class_eval src, __FILE__, __LINE__ | |||
end | |||
def event_date | |||
event_datetime.to_date | |||
end | |||
def event_url(options = {}) | |||
option = event_options[:url] | |||
(option.is_a?(Proc) ? option.call(self) : send(option)).merge(options) | |||
end | |||
module ClassMethods | |||
end | |||
end | |||
end | |||
end | |||
end |
@@ -0,0 +1,61 @@ | |||
# 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. | |||
module Redmine | |||
module MenuManager | |||
class << self | |||
def map(menu_name) | |||
mapper = Mapper.new | |||
yield mapper | |||
@items ||= {} | |||
@items[menu_name.to_sym] ||= [] | |||
@items[menu_name.to_sym] += mapper.items | |||
end | |||
def items(menu_name) | |||
@items[menu_name.to_sym] || [] | |||
end | |||
def allowed_items(menu_name, role) | |||
items(menu_name).select {|item| role && role.allowed_to?(item.url)} | |||
end | |||
end | |||
class Mapper | |||
def push(name, url, options={}) | |||
@items ||= [] | |||
@items << MenuItem.new(name, url, options) | |||
end | |||
def items | |||
@items | |||
end | |||
end | |||
class MenuItem | |||
attr_reader :name, :url, :param, :condition | |||
def initialize(name, url, options) | |||
@name = name | |||
@url = url | |||
@condition = options[:if] | |||
@param = options[:param] || :id | |||
end | |||
end | |||
end | |||
end |
@@ -8,4 +8,11 @@ module Redmine | |||
def self.to_s; STRING end | |||
end | |||
module Info | |||
class << self | |||
def name; 'Redmine' end | |||
def url; 'http://www.redmine.org/' end | |||
end | |||
end | |||
end |
@@ -19,7 +19,7 @@ task :load_default_data => :environment do | |||
begin | |||
# check that no data already exists | |||
if Role.find(:first) | |||
if Role.find(:first, :conditions => {:builtin => 0}) | |||
raise "Some roles are already defined." | |||
end | |||
if Tracker.find(:first) | |||
@@ -35,17 +35,78 @@ begin | |||
puts "Loading default configuration data for language: #{current_language}" | |||
# roles | |||
manager = Role.create :name => l(:default_role_manager), :position => 1 | |||
manager.permissions = Permission.find(:all, :conditions => ["is_public=?", false]) | |||
manager = Role.create :name => l(:default_role_manager), | |||
:position => 1 | |||
manager.permissions = manager.setable_permissions.collect {|p| p.name} | |||
manager.save | |||
developper = Role.create :name => l(:default_role_developper), :position => 2 | |||
perms = [150, 320, 321, 322, 420, 421, 422, 1050, 1060, 1070, 1075, 1130, 1220, 1221, 1222, 1223, 1224, 1320, 1322, 1061, 1057, 1520] | |||
developper.permissions = Permission.find(:all, :conditions => ["sort IN (#{perms.join(',')})"]) | |||
reporter = Role.create :name => l(:default_role_reporter), :position => 3 | |||
perms = [1050, 1060, 1070, 1057, 1130] | |||
reporter.permissions = Permission.find(:all, :conditions => ["sort IN (#{perms.join(',')})"]) | |||
developper = Role.create :name => l(:default_role_developper), | |||
:position => 2, | |||
:permissions => [:manage_versions, | |||
:manage_categories, | |||
:add_issues, | |||
:edit_issues, | |||
:manage_issue_relations, | |||
:add_issue_notes, | |||
:change_issue_status, | |||
:save_queries, | |||
:view_gantt, | |||
:view_calendar, | |||
:log_time, | |||
:view_time_entries, | |||
:comment_news, | |||
:view_documents, | |||
:view_wiki_pages, | |||
:edit_wiki_pages, | |||
:delete_wiki_pages, | |||
:add_messages, | |||
:view_files, | |||
:manage_files, | |||
:browse_repository, | |||
:view_changesets] | |||
reporter = Role.create :name => l(:default_role_reporter), | |||
:position => 3, | |||
:permissions => [:add_issues, | |||
:add_issue_notes, | |||
:change_issue_status, | |||
:save_queries, | |||
:view_gantt, | |||
:view_calendar, | |||
:log_time, | |||
:view_time_entries, | |||
:comment_news, | |||
:view_documents, | |||
:view_wiki_pages, | |||
:add_messages, | |||
:view_files, | |||
:browse_repository, | |||
:view_changesets] | |||
Role.non_member.update_attribute :permissions, [:add_issues, | |||
:add_issue_notes, | |||
:change_issue_status, | |||
:save_queries, | |||
:view_gantt, | |||
:view_calendar, | |||
:view_time_entries, | |||
:comment_news, | |||
:view_documents, | |||
:view_wiki_pages, | |||
:add_messages, | |||
:view_files, | |||
:browse_repository, | |||
:view_changesets] | |||
Role.anonymous.update_attribute :permissions, [:view_gantt, | |||
:view_calendar, | |||
:view_time_entries, | |||
:view_documents, | |||
:view_wiki_pages, | |||
:view_files, | |||
:browse_repository, | |||
:view_changesets] | |||
# trackers | |||
Tracker.create(:name => l(:default_tracker_bug), :is_in_chlog => true, :is_in_roadmap => false, :position => 1) | |||
Tracker.create(:name => l(:default_tracker_feature), :is_in_chlog => true, :is_in_roadmap => true, :position => 2) |
@@ -1,559 +0,0 @@ | |||
--- | |||
permissions_052: | |||
action: destroy_comment | |||
id: 52 | |||
description: label_comment_delete | |||
controller: news | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1133 | |||
is_public: false | |||
permissions_041: | |||
action: add_file | |||
id: 41 | |||
description: button_add | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: true | |||
sort: 1320 | |||
is_public: false | |||
permissions_030: | |||
action: destroy | |||
id: 30 | |||
description: button_delete | |||
controller: news | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1122 | |||
is_public: false | |||
permissions_019: | |||
action: download | |||
id: 19 | |||
description: button_download | |||
controller: issues | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1010 | |||
is_public: true | |||
permissions_008: | |||
action: edit | |||
id: 8 | |||
description: button_edit | |||
controller: members | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 221 | |||
is_public: false | |||
permissions_053: | |||
action: add_query | |||
id: 53 | |||
description: button_create | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 600 | |||
is_public: false | |||
permissions_042: | |||
action: destroy_file | |||
id: 42 | |||
description: button_delete | |||
controller: versions | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1322 | |||
is_public: false | |||
permissions_031: | |||
action: list_documents | |||
id: 31 | |||
description: button_list | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1200 | |||
is_public: true | |||
permissions_020: | |||
action: add_issue | |||
id: 20 | |||
description: button_add | |||
controller: projects | |||
mail_enabled: true | |||
mail_option: true | |||
sort: 1050 | |||
is_public: false | |||
permissions_009: | |||
action: destroy | |||
id: 9 | |||
description: button_delete | |||
controller: members | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 222 | |||
is_public: false | |||
permissions_054: | |||
action: show | |||
id: 54 | |||
description: button_view | |||
controller: repositories | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1450 | |||
is_public: true | |||
permissions_043: | |||
action: move_issues | |||
id: 43 | |||
description: button_move | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1061 | |||
is_public: false | |||
permissions_032: | |||
action: show | |||
id: 32 | |||
description: button_view | |||
controller: documents | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1201 | |||
is_public: true | |||
permissions_021: | |||
action: edit | |||
id: 21 | |||
description: button_edit | |||
controller: issues | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1055 | |||
is_public: false | |||
permissions_010: | |||
action: add_version | |||
id: 10 | |||
description: button_add | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 320 | |||
is_public: false | |||
permissions_055: | |||
action: browse | |||
id: 55 | |||
description: label_browse | |||
controller: repositories | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1460 | |||
is_public: true | |||
permissions_044: | |||
action: add_note | |||
id: 44 | |||
description: label_add_note | |||
controller: issues | |||
mail_enabled: false | |||
mail_option: true | |||
sort: 1057 | |||
is_public: false | |||
permissions_033: | |||
action: download | |||
id: 33 | |||
description: button_download | |||
controller: documents | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1202 | |||
is_public: true | |||
permissions_022: | |||
action: change_status | |||
id: 22 | |||
description: label_change_status | |||
controller: issues | |||
mail_enabled: true | |||
mail_option: true | |||
sort: 1060 | |||
is_public: false | |||
permissions_011: | |||
action: edit | |||
id: 11 | |||
description: button_edit | |||
controller: versions | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 321 | |||
is_public: false | |||
permissions_056: | |||
action: entry | |||
id: 56 | |||
description: entry | |||
controller: repositories | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1462 | |||
is_public: true | |||
permissions_045: | |||
action: export_issues_pdf | |||
id: 45 | |||
description: label_export_pdf | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1002 | |||
is_public: true | |||
permissions_034: | |||
action: add_document | |||
id: 34 | |||
description: button_add | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: true | |||
sort: 1220 | |||
is_public: false | |||
permissions_023: | |||
action: destroy | |||
id: 23 | |||
description: button_delete | |||
controller: issues | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1065 | |||
is_public: false | |||
permissions_012: | |||
action: destroy | |||
id: 12 | |||
description: button_delete | |||
controller: versions | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 322 | |||
is_public: false | |||
permissions_001: | |||
action: show | |||
id: 1 | |||
description: label_overview | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 100 | |||
is_public: true | |||
permissions_057: | |||
action: revisions | |||
id: 57 | |||
description: label_view_revisions | |||
controller: repositories | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1470 | |||
is_public: true | |||
permissions_046: | |||
action: export_pdf | |||
id: 46 | |||
description: label_export_pdf | |||
controller: issues | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1015 | |||
is_public: true | |||
permissions_035: | |||
action: edit | |||
id: 35 | |||
description: button_edit | |||
controller: documents | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1221 | |||
is_public: false | |||
permissions_024: | |||
action: add_attachment | |||
id: 24 | |||
description: label_attachment_new | |||
controller: issues | |||
mail_enabled: false | |||
mail_option: true | |||
sort: 1070 | |||
is_public: false | |||
permissions_013: | |||
action: add_issue_category | |||
id: 13 | |||
description: button_add | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 420 | |||
is_public: false | |||
permissions_002: | |||
action: changelog | |||
id: 2 | |||
description: label_change_log | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 105 | |||
is_public: true | |||
permissions_058: | |||
action: revision | |||
id: 58 | |||
description: label_view_revisions | |||
controller: repositories | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1472 | |||
is_public: true | |||
permissions_047: | |||
action: activity | |||
id: 47 | |||
description: label_activity | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 160 | |||
is_public: true | |||
permissions_036: | |||
action: destroy | |||
id: 36 | |||
description: button_delete | |||
controller: documents | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1222 | |||
is_public: false | |||
permissions_025: | |||
action: destroy_attachment | |||
id: 25 | |||
description: label_attachment_delete | |||
controller: issues | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1075 | |||
is_public: false | |||
permissions_014: | |||
action: edit | |||
id: 14 | |||
description: button_edit | |||
controller: issue_categories | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 421 | |||
is_public: false | |||
permissions_003: | |||
action: issue_report | |||
id: 3 | |||
description: label_report_plural | |||
controller: reports | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 110 | |||
is_public: true | |||
permissions_059: | |||
action: diff | |||
id: 59 | |||
description: diff | |||
controller: repositories | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1480 | |||
is_public: true | |||
permissions_048: | |||
action: calendar | |||
id: 48 | |||
description: label_calendar | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 165 | |||
is_public: true | |||
permissions_037: | |||
action: add_attachment | |||
id: 37 | |||
description: label_attachment_new | |||
controller: documents | |||
mail_enabled: false | |||
mail_option: true | |||
sort: 1223 | |||
is_public: false | |||
permissions_026: | |||
action: list_news | |||
id: 26 | |||
description: button_list | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1100 | |||
is_public: true | |||
permissions_015: | |||
action: destroy | |||
id: 15 | |||
description: button_delete | |||
controller: issue_categories | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 422 | |||
is_public: false | |||
permissions_004: | |||
action: settings | |||
id: 4 | |||
description: label_settings | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 150 | |||
is_public: false | |||
permissions_060: | |||
action: search | |||
id: 61 | |||
description: label_search | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 130 | |||
is_public: true | |||
permissions_049: | |||
action: gantt | |||
id: 49 | |||
description: label_gantt | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 166 | |||
is_public: true | |||
permissions_038: | |||
action: destroy_attachment | |||
id: 38 | |||
description: label_attachment_delete | |||
controller: documents | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1224 | |||
is_public: false | |||
permissions_027: | |||
action: show | |||
id: 27 | |||
description: button_view | |||
controller: news | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1101 | |||
is_public: true | |||
permissions_016: | |||
action: list_issues | |||
id: 16 | |||
description: button_list | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1000 | |||
is_public: true | |||
permissions_005: | |||
action: edit | |||
id: 5 | |||
description: button_edit | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 151 | |||
is_public: false | |||
permissions_061: | |||
action: search | |||
id: 62 | |||
description: label_search | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 130 | |||
is_public: true | |||
permissions_062: | |||
action: roadmap | |||
id: 63 | |||
description: label_roadmap | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 107 | |||
is_public: true | |||
permissions_050: | |||
action: history | |||
id: 50 | |||
description: label_history | |||
controller: issues | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1006 | |||
is_public: true | |||
permissions_039: | |||
action: list_files | |||
id: 39 | |||
description: button_list | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1300 | |||
is_public: true | |||
permissions_028: | |||
action: add_news | |||
id: 28 | |||
description: button_add | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1120 | |||
is_public: false | |||
permissions_017: | |||
action: export_issues_csv | |||
id: 17 | |||
description: label_export_csv | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1001 | |||
is_public: true | |||
permissions_006: | |||
action: list_members | |||
id: 6 | |||
description: button_list | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 200 | |||
is_public: true | |||
permissions_051: | |||
action: add_comment | |||
id: 51 | |||
description: label_comment_add | |||
controller: news | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1130 | |||
is_public: false | |||
permissions_040: | |||
action: download | |||
id: 40 | |||
description: button_download | |||
controller: versions | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1301 | |||
is_public: true | |||
permissions_029: | |||
action: edit | |||
id: 29 | |||
description: button_edit | |||
controller: news | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1121 | |||
is_public: false | |||
permissions_018: | |||
action: show | |||
id: 18 | |||
description: button_view | |||
controller: issues | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 1005 | |||
is_public: true | |||
permissions_007: | |||
action: add_member | |||
id: 7 | |||
description: button_add | |||
controller: projects | |||
mail_enabled: false | |||
mail_option: false | |||
sort: 220 | |||
is_public: false |
@@ -1,163 +0,0 @@ | |||
--- | |||
permissions_roles_054: | |||
role_id: 3 | |||
permission_id: 44 | |||
permissions_roles_043: | |||
role_id: 2 | |||
permission_id: 25 | |||
permissions_roles_032: | |||
role_id: 1 | |||
permission_id: 42 | |||
permissions_roles_021: | |||
role_id: 1 | |||
permission_id: 22 | |||
permissions_roles_010: | |||
role_id: 1 | |||
permission_id: 4 | |||
permissions_roles_044: | |||
role_id: 3 | |||
permission_id: 22 | |||
permissions_roles_033: | |||
role_id: 2 | |||
permission_id: 22 | |||
permissions_roles_022: | |||
role_id: 1 | |||
permission_id: 38 | |||
permissions_roles_011: | |||
role_id: 1 | |||
permission_id: 20 | |||
permissions_roles_045: | |||
role_id: 1 | |||
permission_id: 12 | |||
permissions_roles_034: | |||
role_id: 2 | |||
permission_id: 44 | |||
permissions_roles_023: | |||
role_id: 2 | |||
permission_id: 15 | |||
permissions_roles_012: | |||
role_id: 1 | |||
permission_id: 36 | |||
permissions_roles_001: | |||
role_id: 1 | |||
permission_id: 14 | |||
permissions_roles_046: | |||
role_id: 1 | |||
permission_id: 29 | |||
permissions_roles_035: | |||
role_id: 1 | |||
permission_id: 10 | |||
permissions_roles_024: | |||
role_id: 2 | |||
permission_id: 42 | |||
permissions_roles_013: | |||
role_id: 2 | |||
permission_id: 13 | |||
permissions_roles_002: | |||
role_id: 1 | |||
permission_id: 34 | |||
permissions_roles_047: | |||
role_id: 2 | |||
permission_id: 4 | |||
permissions_roles_036: | |||
role_id: 1 | |||
permission_id: 25 | |||
permissions_roles_025: | |||
role_id: 1 | |||
permission_id: 8 | |||
permissions_roles_014: | |||
role_id: 2 | |||
permission_id: 38 | |||
permissions_roles_003: | |||
role_id: 2 | |||
permission_id: 11 | |||
permissions_roles_048: | |||
role_id: 2 | |||
permission_id: 34 | |||
permissions_roles_037: | |||
role_id: 1 | |||
permission_id: 43 | |||
permissions_roles_026: | |||
role_id: 1 | |||
permission_id: 23 | |||
permissions_roles_015: | |||
role_id: 1 | |||
permission_id: 5 | |||
permissions_roles_004: | |||
role_id: 2 | |||
permission_id: 36 | |||
permissions_roles_049: | |||
role_id: 3 | |||
permission_id: 24 | |||
permissions_roles_038: | |||
role_id: 2 | |||
permission_id: 24 | |||
permissions_roles_027: | |||
role_id: 1 | |||
permission_id: 41 | |||
permissions_roles_016: | |||
role_id: 1 | |||
permission_id: 21 | |||
permissions_roles_005: | |||
role_id: 1 | |||
permission_id: 53 | |||
permissions_roles_050: | |||
role_id: 1 | |||
permission_id: 13 | |||
permissions_roles_039: | |||
role_id: 3 | |||
permission_id: 20 | |||
permissions_roles_028: | |||
role_id: 2 | |||
permission_id: 20 | |||
permissions_roles_017: | |||
role_id: 1 | |||
permission_id: 37 | |||
permissions_roles_006: | |||
role_id: 1 | |||
permission_id: 15 | |||
permissions_roles_051: | |||
role_id: 1 | |||
permission_id: 30 | |||
permissions_roles_040: | |||
role_id: 1 | |||
permission_id: 11 | |||
permissions_roles_029: | |||
role_id: 2 | |||
permission_id: 43 | |||
permissions_roles_018: | |||
role_id: 2 | |||
permission_id: 14 | |||
permissions_roles_007: | |||
role_id: 1 | |||
permission_id: 35 | |||
permissions_roles_052: | |||
role_id: 2 | |||
permission_id: 10 | |||
permissions_roles_041: | |||
role_id: 1 | |||
permission_id: 28 | |||
permissions_roles_030: | |||
role_id: 1 | |||
permission_id: 9 | |||
permissions_roles_019: | |||
role_id: 2 | |||
permission_id: 41 | |||
permissions_roles_008: | |||
role_id: 2 | |||
permission_id: 12 | |||
permissions_roles_053: | |||
role_id: 2 | |||
permission_id: 35 | |||
permissions_roles_042: | |||
role_id: 1 | |||
permission_id: 44 | |||
permissions_roles_031: | |||
role_id: 1 | |||
permission_id: 24 | |||
permissions_roles_020: | |||
role_id: 1 | |||
permission_id: 7 | |||
permissions_roles_009: | |||
role_id: 2 | |||
permission_id: 37 |
@@ -1,10 +1,161 @@ | |||
--- | |||
roles_004: | |||
name: Non member | |||
id: 4 | |||
builtin: 1 | |||
permissions: | | |||
--- | |||
- :add_issues | |||
- :edit_issues | |||
- :manage_issue_relations | |||
- :add_issue_notes | |||
- :change_issue_status | |||
- :move_issues | |||
- :save_queries | |||
- :view_gantt | |||
- :view_calendar | |||
- :log_time | |||
- :view_time_entries | |||
- :comment_news | |||
- :view_documents | |||
- :manage_documents | |||
- :view_wiki_pages | |||
- :edit_wiki_pages | |||
- :add_messages | |||
- :view_files | |||
- :manage_files | |||
- :browse_repository | |||
- :view_changesets | |||
position: 5 | |||
roles_005: | |||
name: Anonymous | |||
id: 5 | |||
builtin: 2 | |||
permissions: | | |||
--- | |||
- :view_gantt | |||
- :view_calendar | |||
- :view_time_entries | |||
- :view_documents | |||
- :view_wiki_pages | |||
- :edit_wiki_pages | |||
- :view_files | |||
- :browse_repository | |||
- :view_changesets | |||
position: 6 | |||
roles_001: | |||
name: Manager | |||
id: 1 | |||
builtin: 0 | |||
permissions: | | |||
--- | |||
- :edit_project | |||
- :manage_members | |||
- :manage_versions | |||
- :manage_categories | |||
- :add_issues | |||
- :edit_issues | |||
- :manage_issue_relations | |||
- :add_issue_notes | |||
- :change_issue_status | |||
- :move_issues | |||
- :delete_issues | |||
- :manage_pulic_queries | |||
- :save_queries | |||
- :view_gantt | |||
- :view_calendar | |||
- :log_time | |||
- :view_time_entries | |||
- :manage_news | |||
- :comment_news | |||
- :view_documents | |||
- :manage_documents | |||
- :view_wiki_pages | |||
- :edit_wiki_pages | |||
- :delete_wiki_pages | |||
- :add_messages | |||
- :manage_boards | |||
- :view_files | |||
- :manage_files | |||
- :browse_repository | |||
- :view_changesets | |||
position: 2 | |||
roles_002: | |||
name: Developer | |||
id: 2 | |||
builtin: 0 | |||
permissions: | | |||
--- | |||
- :edit_project | |||
- :manage_members | |||
- :manage_versions | |||
- :manage_categories | |||
- :add_issues | |||
- :edit_issues | |||
- :manage_issue_relations | |||
- :add_issue_notes | |||
- :change_issue_status | |||
- :move_issues | |||
- :delete_issues | |||
- :manage_pulic_queries | |||
- :save_queries | |||
- :view_gantt | |||
- :view_calendar | |||
- :log_time | |||
- :view_time_entries | |||
- :manage_news | |||
- :comment_news | |||
- :view_documents | |||
- :manage_documents | |||
- :view_wiki_pages | |||
- :edit_wiki_pages | |||
- :delete_wiki_pages | |||
- :add_messages | |||
- :manage_boards | |||
- :view_files | |||
- :manage_files | |||
- :browse_repository | |||
- :view_changesets | |||
position: 3 | |||
roles_003: | |||
name: Reporter | |||
id: 3 | |||
builtin: 0 | |||
permissions: | | |||
--- | |||
- :edit_project | |||
- :manage_members | |||
- :manage_versions | |||
- :manage_categories | |||
- :add_issues | |||
- :edit_issues | |||
- :manage_issue_relations | |||
- :add_issue_notes | |||
- :change_issue_status | |||
- :move_issues | |||
- :delete_issues | |||
- :manage_pulic_queries | |||
- :save_queries | |||
- :view_gantt | |||
- :view_calendar | |||
- :log_time | |||
- :view_time_entries | |||
- :manage_news | |||
- :comment_news | |||
- :view_documents | |||
- :manage_documents | |||
- :view_wiki_pages | |||
- :edit_wiki_pages | |||
- :delete_wiki_pages | |||
- :add_messages | |||
- :manage_boards | |||
- :view_files | |||
- :manage_files | |||
- :browse_repository | |||
- :view_changesets | |||
position: 4 |
@@ -58,7 +58,7 @@ class FeedsControllerTest < Test::Unit::TestCase | |||
def test_rss_key | |||
user = User.find(2) | |||
key = user.get_or_create_rss_key.value | |||
key = user.rss_key | |||
get :news, :project_id => 2, :key => key | |||
assert_response :success |
@@ -22,7 +22,7 @@ require 'projects_controller' | |||
class ProjectsController; def rescue_action(e) raise e end; end | |||
class ProjectsControllerTest < Test::Unit::TestCase | |||
fixtures :projects, :permissions | |||
fixtures :projects, :users, :roles | |||
def setup | |||
@controller = ProjectsController.new | |||
@@ -50,13 +50,6 @@ class ProjectsControllerTest < Test::Unit::TestCase | |||
assert_not_nil assigns(:project) | |||
end | |||
def test_list_members | |||
get :list_members, :id => 1 | |||
assert_response :success | |||
assert_template 'list_members' | |||
assert_not_nil assigns(:members) | |||
end | |||
def test_list_documents | |||
get :list_documents, :id => 1 | |||
assert_response :success |
@@ -11,6 +11,7 @@ class SearchControllerTest < Test::Unit::TestCase | |||
@controller = SearchController.new | |||
@request = ActionController::TestRequest.new | |||
@response = ActionController::TestResponse.new | |||
User.current = nil | |||
end | |||
def test_search_for_projects |
@@ -1,7 +1,7 @@ | |||
require "#{File.dirname(__FILE__)}/../test_helper" | |||
class IssuesTest < ActionController::IntegrationTest | |||
fixtures :projects, :users, :trackers, :issue_statuses, :issues, :permissions, :permissions_roles, :enumerations | |||
fixtures :projects, :users, :trackers, :issue_statuses, :issues, :enumerations | |||
# create an issue | |||
def test_add_issue | |||
@@ -38,7 +38,7 @@ class IssuesTest < ActionController::IntegrationTest | |||
def test_issue_attachements | |||
log_user('jsmith', 'jsmith') | |||
post "issues/add_attachment/1", { 'attachments[]' => ActionController::TestUploadedFile.new(Test::Unit::TestCase.fixture_path + '/files/testfile.txt', 'text/plain') } | |||
post "issues/add_note/1", { :notes => 'Some notes', 'attachments[]' => ActionController::TestUploadedFile.new(Test::Unit::TestCase.fixture_path + '/files/testfile.txt', 'text/plain') } | |||
assert_redirected_to "issues/show/1" | |||
# make sure attachment was saved |
@@ -31,9 +31,9 @@ class ProjectsTest < ActionController::IntegrationTest | |||
assert !Project.find(1).active? | |||
get "projects/show", :id => 1 | |||
assert_response :missing | |||
assert_response 403 | |||
get "projects/show", :id => subproject.id | |||
assert_response :missing | |||
assert_response 403 | |||
post "projects/unarchive", :id => 1 | |||
assert_redirected_to "admin/projects" |
@@ -18,7 +18,7 @@ | |||
require File.dirname(__FILE__) + '/../test_helper' | |||
class MailHandlerTest < Test::Unit::TestCase | |||
fixtures :users, :projects, :roles, :members, :permissions, :issues, :permissions_roles, :trackers, :enumerations | |||
fixtures :users, :projects, :roles, :members, :issues, :trackers, :enumerations | |||
FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures' | |||
CHARSET = "utf-8" |
@@ -88,16 +88,12 @@ class UserTest < Test::Unit::TestCase | |||
end | |||
def test_rss_key | |||
assert_nil @jsmith.rss_key | |||
key = @jsmith.get_or_create_rss_key | |||
assert_kind_of Token, key | |||
assert_equal 40, key.value.length | |||
assert_nil @jsmith.rss_token | |||
key = @jsmith.rss_key | |||
assert_equal 40, key.length | |||
@jsmith.reload | |||
assert_equal key.value, @jsmith.get_or_create_rss_key.value | |||
@jsmith.reload | |||
assert_equal key.value, @jsmith.rss_key.value | |||
assert_equal key, @jsmith.rss_key | |||
end | |||
def test_role_for_project | |||
@@ -107,6 +103,6 @@ class UserTest < Test::Unit::TestCase | |||
assert_equal "Manager", role.name | |||
# user with no role | |||
assert_nil @dlopper.role_for_project(Project.find(2)) | |||
assert !@dlopper.role_for_project(Project.find(2)).member? | |||
end | |||
end |