diff options
93 files changed, 1116 insertions, 1231 deletions
diff --git a/app/controllers/account_controller.rb b/app/controllers/account_controller.rb index 8ee046a0c..44e4cc221 100644 --- a/app/controllers/account_controller.rb +++ b/app/controllers/account_controller.rb @@ -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 diff --git a/app/controllers/admin_controller.rb b/app/controllers/admin_controller.rb index 95d3505c7..78fd1aa15 100644 --- a/app/controllers/admin_controller.rb +++ b/app/controllers/admin_controller.rb @@ -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 diff --git a/app/controllers/application.rb b/app/controllers/application.rb index 3f5a2c76f..cac2d6464 100644 --- a/app/controllers/application.rb +++ b/app/controllers/application.rb @@ -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
\ No newline at end of file +end diff --git a/app/controllers/boards_controller.rb b/app/controllers/boards_controller.rb index 0ad2645f8..2a90e9857 100644 --- a/app/controllers/boards_controller.rb +++ b/app/controllers/boards_controller.rb @@ -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 diff --git a/app/controllers/documents_controller.rb b/app/controllers/documents_controller.rb index 3c7e56b43..5659e9ced 100644 --- a/app/controllers/documents_controller.rb +++ b/app/controllers/documents_controller.rb @@ -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 diff --git a/app/controllers/issues_controller.rb b/app/controllers/issues_controller.rb index 31cc6ae7d..56a9b11ca 100644 --- a/app/controllers/issues_controller.rb +++ b/app/controllers/issues_controller.rb @@ -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 diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index 1b0d2a680..74a957d6c 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -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 } diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb index 0613f9e40..2f5e24e28 100644 --- a/app/controllers/projects_controller.rb +++ b/app/controllers/projects_controller.rb @@ -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 diff --git a/app/controllers/queries_controller.rb b/app/controllers/queries_controller.rb index 631895284..bcc233699 100644 --- a/app/controllers/queries_controller.rb +++ b/app/controllers/queries_controller.rb @@ -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) diff --git a/app/controllers/repositories_controller.rb b/app/controllers/repositories_controller.rb index 5bcba8e3a..f99ea0b35 100644 --- a/app/controllers/repositories_controller.rb +++ b/app/controllers/repositories_controller.rb @@ -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 diff --git a/app/controllers/roles_controller.rb b/app/controllers/roles_controller.rb index 6f1657675..24c7a3ffe 100644 --- a/app/controllers/roles_controller.rb +++ b/app/controllers/roles_controller.rb @@ -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 diff --git a/app/controllers/timelog_controller.rb b/app/controllers/timelog_controller.rb index 01c4ddca9..1c15fa564 100644 --- a/app/controllers/timelog_controller.rb +++ b/app/controllers/timelog_controller.rb @@ -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 diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 3e107287b..7e3abc75c 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -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 diff --git a/app/controllers/watchers_controller.rb b/app/controllers/watchers_controller.rb index f617a5b5a..206dc0843 100644 --- a/app/controllers/watchers_controller.rb +++ b/app/controllers/watchers_controller.rb @@ -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 } diff --git a/app/controllers/welcome_controller.rb b/app/controllers/welcome_controller.rb index 7b1c398d1..2eac2268f 100644 --- a/app/controllers/welcome_controller.rb +++ b/app/controllers/welcome_controller.rb @@ -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 diff --git a/app/controllers/wiki_controller.rb b/app/controllers/wiki_controller.rb index 748821d72..e9212a1c7 100644 --- a/app/controllers/wiki_controller.rb +++ b/app/controllers/wiki_controller.rb @@ -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 } diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 41becd0f2..550ce3c59 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -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 diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index abf2bcf86..da674985b 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -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 diff --git a/app/helpers/watchers_helper.rb b/app/helpers/watchers_helper.rb index 87b381055..c83c785fc 100644 --- a/app/helpers/watchers_helper.rb +++ b/app/helpers/watchers_helper.rb @@ -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'), diff --git a/app/models/attachment.rb b/app/models/attachment.rb index 443a75bab..f57038b96 100644 --- a/app/models/attachment.rb +++ b/app/models/attachment.rb @@ -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" diff --git a/app/models/changeset.rb b/app/models/changeset.rb index 57e2d74a4..9400df869 100644 --- a/app/models/changeset.rb +++ b/app/models/changeset.rb @@ -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 diff --git a/app/models/document.rb b/app/models/document.rb index 8b5d68e87..6989191ce 100644 --- a/app/models/document.rb +++ b/app/models/document.rb @@ -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 diff --git a/app/models/issue.rb b/app/models/issue.rb index 65b34cb92..b6eda1767 100644 --- a/app/models/issue.rb +++ b/app/models/issue.rb @@ -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 diff --git a/app/models/mail_handler.rb b/app/models/mail_handler.rb index 39b088bf4..7a1d73244 100644 --- a/app/models/mail_handler.rb +++ b/app/models/mail_handler.rb @@ -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) diff --git a/app/models/member.rb b/app/models/member.rb index 2aa26d42f..39703147d 100644 --- a/app/models/member.rb +++ b/app/models/member.rb @@ -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 diff --git a/app/models/news.rb b/app/models/news.rb index e9a48846a..4352363d9 100644 --- a/app/models/news.rb +++ b/app/models/news.rb @@ -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") diff --git a/app/models/permission.rb b/app/models/permission.rb deleted file mode 100644 index bea670c4c..000000000 --- a/app/models/permission.rb +++ /dev/null @@ -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 diff --git a/app/models/query.rb b/app/models/query.rb index 28f65ddf6..ff519d71c 100644 --- a/app/models/query.rb +++ b/app/models/query.rb @@ -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 diff --git a/app/models/role.rb b/app/models/role.rb index 98d735e8e..015146dc4 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -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 diff --git a/app/models/user.rb b/app/models/user.rb index a017b4289..4cb8da1f9 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -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 diff --git a/app/models/wiki_content.rb b/app/models/wiki_content.rb index 2d0be8225..4b60a4373 100644 --- a/app/models/wiki_content.rb +++ b/app/models/wiki_content.rb @@ -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' diff --git a/app/views/admin/mail_options.rhtml b/app/views/admin/mail_options.rhtml index c70965776..cab94294f 100644 --- a/app/views/admin/mail_options.rhtml +++ b/app/views/admin/mail_options.rhtml @@ -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' %> diff --git a/app/views/boards/show.rhtml b/app/views/boards/show.rhtml index cb38cdb53..c31ec67e9 100644 --- a/app/views/boards/show.rhtml +++ b/app/views/boards/show.rhtml @@ -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> diff --git a/app/views/common/feed.atom.rxml b/app/views/common/feed.atom.rxml new file mode 100644 index 000000000..fa00d754a --- /dev/null +++ b/app/views/common/feed.atom.rxml @@ -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 diff --git a/app/views/issues/show.rhtml b/app/views/issues/show.rhtml index 078ecd1f5..70b19d1fc 100644 --- a/app/views/issues/show.rhtml +++ b/app/views/issues/show.rhtml @@ -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> diff --git a/app/views/layouts/base.rhtml b/app/views/layouts/base.rhtml index 38a2dbeb6..9c81a313b 100644 --- a/app/views/layouts/base.rhtml +++ b/app/views/layouts/base.rhtml @@ -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> diff --git a/app/views/messages/show.rhtml b/app/views/messages/show.rhtml index c18eb524e..3e546ceea 100644 --- a/app/views/messages/show.rhtml +++ b/app/views/messages/show.rhtml @@ -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' %> diff --git a/app/views/projects/_form.rhtml b/app/views/projects/_form.rhtml index 585217e16..55527e080 100644 --- a/app/views/projects/_form.rhtml +++ b/app/views/projects/_form.rhtml @@ -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 %> diff --git a/app/views/projects/_members.rhtml b/app/views/projects/_members.rhtml index 1924e430a..affaf7854 100644 --- a/app/views/projects/_members.rhtml +++ b/app/views/projects/_members.rhtml @@ -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"> diff --git a/app/views/projects/activity.rhtml b/app/views/projects/activity.rhtml index d510ce08b..fd731cd8f 100644 --- a/app/views/projects/activity.rhtml +++ b/app/views/projects/activity.rhtml @@ -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 %> diff --git a/app/views/projects/list.rhtml b/app/views/projects/list.rhtml index 24448be48..1fc3aab56 100644 --- a/app/views/projects/list.rhtml +++ b/app/views/projects/list.rhtml @@ -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> diff --git a/app/views/projects/list_issues.rhtml b/app/views/projects/list_issues.rhtml index 1cacf0055..5ebc4107e 100644 --- a/app/views/projects/list_issues.rhtml +++ b/app/views/projects/list_issues.rhtml @@ -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 %>
\ No newline at end of file +<% end %> diff --git a/app/views/projects/list_news.rhtml b/app/views/projects/list_news.rhtml index 17a786260..4ab086d55 100644 --- a/app/views/projects/list_news.rhtml +++ b/app/views/projects/list_news.rhtml @@ -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 %> diff --git a/app/views/projects/show.rhtml b/app/views/projects/show.rhtml index 9419fb2a1..5f641f6a4 100644 --- a/app/views/projects/show.rhtml +++ b/app/views/projects/show.rhtml @@ -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 %> diff --git a/app/views/queries/_form.rhtml b/app/views/queries/_form.rhtml index 9482bd33a..d641fa0b5 100644 --- a/app/views/queries/_form.rhtml +++ b/app/views/queries/_form.rhtml @@ -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 %> diff --git a/app/views/queries/index.rhtml b/app/views/queries/index.rhtml index 69cfb8f98..71aa37497 100644 --- a/app/views/queries/index.rhtml +++ b/app/views/queries/index.rhtml @@ -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> diff --git a/app/views/reports/issue_report.rhtml b/app/views/reports/issue_report.rhtml index bf40e79ae..1d865acbc 100644 --- a/app/views/reports/issue_report.rhtml +++ b/app/views/reports/issue_report.rhtml @@ -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}) %> | diff --git a/app/views/repositories/revisions.rhtml b/app/views/repositories/revisions.rhtml index 0c2655d5f..882d5ea4f 100644 --- a/app/views/repositories/revisions.rhtml +++ b/app/views/repositories/revisions.rhtml @@ -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 %> diff --git a/app/views/repositories/show.rhtml b/app/views/repositories/show.rhtml index fcf954473..c9f44d575 100644 --- a/app/views/repositories/show.rhtml +++ b/app/views/repositories/show.rhtml @@ -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 %> diff --git a/app/views/roles/_form.rhtml b/app/views/roles/_form.rhtml index d69fff132..62e25e337 100644 --- a/app/views/roles/_form.rhtml +++ b/app/views/roles/_form.rhtml @@ -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> diff --git a/app/views/roles/list.rhtml b/app/views/roles/list.rhtml index e3e576ed1..14ae260aa 100644 --- a/app/views/roles/list.rhtml +++ b/app/views/roles/list.rhtml @@ -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> diff --git a/app/views/roles/report.rhtml b/app/views/roles/report.rhtml index 61e1e18e4..676e25f39 100644 --- a/app/views/roles/report.rhtml +++ b/app/views/roles/report.rhtml @@ -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 %>
\ No newline at end of file +<%= end_form_tag %> diff --git a/app/views/wiki/show.rhtml b/app/views/wiki/show.rhtml index c7a2985be..06eca76ee 100644 --- a/app/views/wiki/show.rhtml +++ b/app/views/wiki/show.rhtml @@ -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> diff --git a/db/migrate/001_setup.rb b/db/migrate/001_setup.rb index c61b2c37f..8b299eb1e 100644 --- a/db/migrate/001_setup.rb +++ b/db/migrate/001_setup.rb @@ -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
diff --git a/db/migrate/002_issue_move.rb b/db/migrate/002_issue_move.rb index d1acf7ee2..085593e08 100644 --- a/db/migrate/002_issue_move.rb +++ b/db/migrate/002_issue_move.rb @@ -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 diff --git a/db/migrate/003_issue_add_note.rb b/db/migrate/003_issue_add_note.rb index 9f20039b0..a2ab756ee 100644 --- a/db/migrate/003_issue_add_note.rb +++ b/db/migrate/003_issue_add_note.rb @@ -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 diff --git a/db/migrate/004_export_pdf.rb b/db/migrate/004_export_pdf.rb index 66045553f..6ccd67eae 100644 --- a/db/migrate/004_export_pdf.rb +++ b/db/migrate/004_export_pdf.rb @@ -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 diff --git a/db/migrate/006_calendar_and_activity.rb b/db/migrate/006_calendar_and_activity.rb index 5d8474fc2..1cdc91d8e 100644 --- a/db/migrate/006_calendar_and_activity.rb +++ b/db/migrate/006_calendar_and_activity.rb @@ -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 diff --git a/db/migrate/007_create_journals.rb b/db/migrate/007_create_journals.rb index 6170b5bd3..b00347839 100644 --- a/db/migrate/007_create_journals.rb +++ b/db/migrate/007_create_journals.rb @@ -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| diff --git a/db/migrate/012_add_comments_permissions.rb b/db/migrate/012_add_comments_permissions.rb index 37f075082..2bbf87b02 100644 --- a/db/migrate/012_add_comments_permissions.rb +++ b/db/migrate/012_add_comments_permissions.rb @@ -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 diff --git a/db/migrate/014_add_queries_permissions.rb b/db/migrate/014_add_queries_permissions.rb index 27d674650..34eba1e26 100644 --- a/db/migrate/014_add_queries_permissions.rb +++ b/db/migrate/014_add_queries_permissions.rb @@ -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 diff --git a/db/migrate/016_add_repositories_permissions.rb b/db/migrate/016_add_repositories_permissions.rb index 992f8dccd..341707639 100644 --- a/db/migrate/016_add_repositories_permissions.rb +++ b/db/migrate/016_add_repositories_permissions.rb @@ -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 diff --git a/db/migrate/018_set_doc_and_files_notifications.rb b/db/migrate/018_set_doc_and_files_notifications.rb index adbdd3b88..8c1d054c1 100644 --- a/db/migrate/018_set_doc_and_files_notifications.rb +++ b/db/migrate/018_set_doc_and_files_notifications.rb @@ -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) diff --git a/db/migrate/024_add_roadmap_permission.rb b/db/migrate/024_add_roadmap_permission.rb index 5b9f3a562..5c37beac1 100644 --- a/db/migrate/024_add_roadmap_permission.rb +++ b/db/migrate/024_add_roadmap_permission.rb @@ -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 diff --git a/db/migrate/025_add_search_permission.rb b/db/migrate/025_add_search_permission.rb index 408716eb6..a942b01b3 100644 --- a/db/migrate/025_add_search_permission.rb +++ b/db/migrate/025_add_search_permission.rb @@ -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 diff --git a/db/migrate/030_add_projects_feeds_permissions.rb b/db/migrate/030_add_projects_feeds_permissions.rb index 63131001e..7f97035bf 100644 --- a/db/migrate/030_add_projects_feeds_permissions.rb +++ b/db/migrate/030_add_projects_feeds_permissions.rb @@ -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 diff --git a/db/migrate/033_add_timelog_permissions.rb b/db/migrate/033_add_timelog_permissions.rb index 3b5b81ed6..ab9c809e6 100644 --- a/db/migrate/033_add_timelog_permissions.rb +++ b/db/migrate/033_add_timelog_permissions.rb @@ -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 diff --git a/db/migrate/043_add_relations_permissions.rb b/db/migrate/043_add_relations_permissions.rb index 3f1da8f27..32d464a58 100644 --- a/db/migrate/043_add_relations_permissions.rb +++ b/db/migrate/043_add_relations_permissions.rb @@ -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 diff --git a/db/migrate/047_add_boards_permissions.rb b/db/migrate/047_add_boards_permissions.rb index cafdc1eac..5b1f6f779 100644 --- a/db/migrate/047_add_boards_permissions.rb +++ b/db/migrate/047_add_boards_permissions.rb @@ -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 diff --git a/db/migrate/049_add_wiki_destroy_page_permission.rb b/db/migrate/049_add_wiki_destroy_page_permission.rb index c68370f22..c82152388 100644 --- a/db/migrate/049_add_wiki_destroy_page_permission.rb +++ b/db/migrate/049_add_wiki_destroy_page_permission.rb @@ -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 diff --git a/db/migrate/050_add_wiki_attachments_permissions.rb b/db/migrate/050_add_wiki_attachments_permissions.rb index 6c81273a1..c0697be9c 100644 --- a/db/migrate/050_add_wiki_attachments_permissions.rb +++ b/db/migrate/050_add_wiki_attachments_permissions.rb @@ -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 diff --git a/db/migrate/056_add_repositories_changes_permission.rb b/db/migrate/056_add_repositories_changes_permission.rb index e93514900..0d9b13b59 100644 --- a/db/migrate/056_add_repositories_changes_permission.rb +++ b/db/migrate/056_add_repositories_changes_permission.rb @@ -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 diff --git a/db/migrate/061_add_roles_builtin.rb b/db/migrate/061_add_roles_builtin.rb new file mode 100644 index 000000000..a8d6fe9e6 --- /dev/null +++ b/db/migrate/061_add_roles_builtin.rb @@ -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 diff --git a/db/migrate/062_insert_builtin_roles.rb b/db/migrate/062_insert_builtin_roles.rb new file mode 100644 index 000000000..27c7475c3 --- /dev/null +++ b/db/migrate/062_insert_builtin_roles.rb @@ -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 diff --git a/db/migrate/063_add_roles_permissions.rb b/db/migrate/063_add_roles_permissions.rb new file mode 100644 index 000000000..107a3af0a --- /dev/null +++ b/db/migrate/063_add_roles_permissions.rb @@ -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 diff --git a/db/migrate/064_drop_permissions.rb b/db/migrate/064_drop_permissions.rb new file mode 100644 index 000000000..f4ca470bf --- /dev/null +++ b/db/migrate/064_drop_permissions.rb @@ -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 diff --git a/lib/redmine.rb b/lib/redmine.rb index 9fc2a103b..df4d0a8cf 100644 --- a/lib/redmine.rb +++ b/lib/redmine.rb @@ -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 diff --git a/lib/redmine/access_control.rb b/lib/redmine/access_control.rb new file mode 100644 index 000000000..54b344b7e --- /dev/null +++ b/lib/redmine/access_control.rb @@ -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 diff --git a/lib/redmine/acts_as_event/init.rb b/lib/redmine/acts_as_event/init.rb new file mode 100644 index 000000000..91051510a --- /dev/null +++ b/lib/redmine/acts_as_event/init.rb @@ -0,0 +1,2 @@ +require File.dirname(__FILE__) + '/lib/acts_as_event' +ActiveRecord::Base.send(:include, Redmine::Acts::Event) diff --git a/lib/redmine/acts_as_event/lib/acts_as_event.rb b/lib/redmine/acts_as_event/lib/acts_as_event.rb new file mode 100644 index 000000000..a0d1822ad --- /dev/null +++ b/lib/redmine/acts_as_event/lib/acts_as_event.rb @@ -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 diff --git a/lib/redmine/menu_manager.rb b/lib/redmine/menu_manager.rb new file mode 100644 index 000000000..afb7699b0 --- /dev/null +++ b/lib/redmine/menu_manager.rb @@ -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 diff --git a/lib/redmine/version.rb b/lib/redmine/version.rb index 5934af03e..494bb2de2 100644 --- a/lib/redmine/version.rb +++ b/lib/redmine/version.rb @@ -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 diff --git a/lib/tasks/load_default_data.rake b/lib/tasks/load_default_data.rake index 488cd2a64..e59c3c5fe 100644 --- a/lib/tasks/load_default_data.rake +++ b/lib/tasks/load_default_data.rake @@ -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)
diff --git a/test/fixtures/permissions.yml b/test/fixtures/permissions.yml deleted file mode 100644 index c8e460001..000000000 --- a/test/fixtures/permissions.yml +++ /dev/null @@ -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
diff --git a/test/fixtures/permissions_roles.yml b/test/fixtures/permissions_roles.yml deleted file mode 100644 index a47d0af11..000000000 --- a/test/fixtures/permissions_roles.yml +++ /dev/null @@ -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
diff --git a/test/fixtures/roles.yml b/test/fixtures/roles.yml index 4fc9881b4..29eaba3b9 100644 --- a/test/fixtures/roles.yml +++ b/test/fixtures/roles.yml @@ -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
diff --git a/test/functional/feeds_controller_test.rb b/test/functional/feeds_controller_test.rb index 279b2c1a7..c41fa2c60 100644 --- a/test/functional/feeds_controller_test.rb +++ b/test/functional/feeds_controller_test.rb @@ -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 diff --git a/test/functional/projects_controller_test.rb b/test/functional/projects_controller_test.rb index 0e1ff121b..def7b7579 100644 --- a/test/functional/projects_controller_test.rb +++ b/test/functional/projects_controller_test.rb @@ -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 diff --git a/test/functional/search_controller_test.rb b/test/functional/search_controller_test.rb index 8fa2e0890..69e78ac62 100644 --- a/test/functional/search_controller_test.rb +++ b/test/functional/search_controller_test.rb @@ -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 diff --git a/test/integration/issues_test.rb b/test/integration/issues_test.rb index 0583b98a8..668bcbd18 100644 --- a/test/integration/issues_test.rb +++ b/test/integration/issues_test.rb @@ -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 diff --git a/test/integration/projects_test.rb b/test/integration/projects_test.rb index 69b16cf85..e56bee484 100644 --- a/test/integration/projects_test.rb +++ b/test/integration/projects_test.rb @@ -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" diff --git a/test/unit/mail_handler_test.rb b/test/unit/mail_handler_test.rb index 8cac2d8b9..833506a16 100644 --- a/test/unit/mail_handler_test.rb +++ b/test/unit/mail_handler_test.rb @@ -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" diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb index 66cd72472..52776c62f 100644 --- a/test/unit/user_test.rb +++ b/test/unit/user_test.rb @@ -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 |