maxrossello / redmine_extended_watchers

Grant additional issue and project view permissions to watcher users
GNU General Public License v3.0
44 stars 20 forks source link

500 error,after installed this plugin,see the log #42

Closed perryjun closed 2 years ago

perryjun commented 2 years ago

I, [2022-08-27T10:02:07.051745 #7540] INFO -- : [d8ba1742-1cb8-41dc-b201-047aa5aba2f5] Processing by WelcomeController#index as HTML I, [2022-08-27T10:02:07.058221 #7540] INFO -- : [d8ba1742-1cb8-41dc-b201-047aa5aba2f5] Current user: admin (id=1) I, [2022-08-27T10:02:07.175897 #7540] INFO -- : [d8ba1742-1cb8-41dc-b201-047aa5aba2f5] Rendered welcome/index.html.erb within layouts/base (Duration: 49.7ms | Allocations: 24787) I, [2022-08-27T10:02:07.179882 #7540] INFO -- : [d8ba1742-1cb8-41dc-b201-047aa5aba2f5] Rendered inline template (Duration: 0.2ms | Allocations: 170) I, [2022-08-27T10:02:07.196081 #7540] INFO -- : [d8ba1742-1cb8-41dc-b201-047aa5aba2f5] Rendered layout layouts/base.html.erb (Duration: 69.9ms | Allocations: 38196) I, [2022-08-27T10:02:07.196430 #7540] INFO -- : [d8ba1742-1cb8-41dc-b201-047aa5aba2f5] Completed 500 Internal Server Error in 144ms (ActiveRecord: 19.1ms | Allocations: 61015) F, [2022-08-27T10:02:07.196662 #7540] FATAL -- : [d8ba1742-1cb8-41dc-b201-047aa5aba2f5]
[d8ba1742-1cb8-41dc-b201-047aa5aba2f5] SystemStackError (stack level too deep): [d8ba1742-1cb8-41dc-b201-047aa5aba2f5]
W, [2022-08-27T10:02:48.539464 #5960] WARN -- : Creating scope :sorted. Overwriting existing method User.sorted. W, [2022-08-27T10:02:48.539898 #5960] WARN -- : Creating scope :having_mail. Overwriting existing method User.having_mail. W, [2022-08-27T10:02:48.650127 #5960] WARN -- : Creating scope :system. Overwriting existing method Enumeration.system. I, [2022-08-27T10:02:48.772741 #5960] INFO -- : Starting Extended Watchers plugin for Redmine W, [2022-08-27T10:02:49.691149 #5960] WARN -- : Creating scope :sorted. Overwriting existing method Group.sorted. W, [2022-08-27T10:02:53.188719 #5960] WARN -- : No Xapian search engine interface for Ruby installed => Full-text search won't be available. Install a ruby-xapian package or an alternative Xapian binding (https://xapian.org). W, [2022-08-27T10:02:53.188951 #5960] WARN -- : cannot load such file -- xapian W, [2022-08-27T10:02:53.687919 #5960] WARN -- : Creating scope :visible. Overwriting existing method PeopleQuery.visible. W, [2022-08-27T10:02:55.174714 #5960] WARN -- : DEPRECATION WARNING: Using a dynamic :action segment in a route is deprecated and will be removed in Rails 7.0. (called from instance_eval at C:/Bitnami/redmine-5.0.2-0/apps/redmine/htdocs/config/routes.rb:402) W, [2022-08-27T10:02:55.175458 #5960] WARN -- : DEPRECATION WARNING: Using a dynamic :action segment in a route is deprecated and will be removed in Rails 7.0. (called from instance_eval at C:/Bitnami/redmine-5.0.2-0/apps/redmine/htdocs/config/routes.rb:402) W, [2022-08-27T10:02:55.175803 #5960] WARN -- : DEPRECATION WARNING: Using a dynamic :action segment in a route is deprecated and will be removed in Rails 7.0. (called from instance_eval at C:/Bitnami/redmine-5.0.2-0/apps/redmine/htdocs/config/routes.rb:402) W, [2022-08-27T10:02:55.176159 #5960] WARN -- : DEPRECATION WARNING: Using a dynamic :action segment in a route is deprecated and will be removed in Rails 7.0. (called from instance_eval at C:/Bitnami/redmine-5.0.2-0/apps/redmine/htdocs/config/routes.rb:402) W, [2022-08-27T10:02:55.176517 #5960] WARN -- : DEPRECATION WARNING: Using a dynamic :action segment in a route is deprecated and will be removed in Rails 7.0. (called from instance_eval at C:/Bitnami/redmine-5.0.2-0/apps/redmine/htdocs/config/routes.rb:402) W, [2022-08-27T10:02:55.176869 #5960] WARN -- : DEPRECATION WARNING: Using a dynamic :action segment in a route is deprecated and will be removed in Rails 7.0. (called from instance_eval at C:/Bitnami/redmine-5.0.2-0/apps/redmine/htdocs/config/routes.rb:402) W, [2022-08-27T10:02:55.177220 #5960] WARN -- : DEPRECATION WARNING: Using a dynamic :action segment in a route is deprecated and will be removed in Rails 7.0. (called from instance_eval at C:/Bitnami/redmine-5.0.2-0/apps/redmine/htdocs/config/routes.rb:402) W, [2022-08-27T10:02:55.227144 #5960] WARN -- : DEPRECATION WARNING: Using a dynamic :action segment in a route is deprecated and will be removed in Rails 7.0. (called from instance_eval at C:/Bitnami/redmine-5.0.2-0/apps/redmine/htdocs/config/routes.rb:402)

maxrossello commented 2 years ago

You probably have a conflict with other plugins. Please try this in isolation and see what happens by re-adding other plugins one at a time to identify the conflicting one.

perryjun commented 2 years ago

You probably have a conflict with other plugins. Please try this in isolation and see what happens by re-adding other plugins one at a time to identify the conflicting one.

thanks,i will try it later

perryjun commented 2 years ago

You probably have a conflict with other plugins. Please try this in isolation and see what happens by re-adding other plugins one at a time to identify the conflicting one.

i really works only installed this pllugin, how to find it is conflict with which another plugin,a big headache

perryjun commented 2 years ago

finally, spent lots of time , i found the conflicted plugin is "people", https://www.redmineup.com/pages/plugins/people

maxrossello commented 2 years ago

Hi @perryjun , you are the second user complaining a conflict with redmine_people (after @ashrafalzyoud) , so I went a bit deeper. The problem is that redmine_people light claims compatibility with redmine 5.0 but it wasn't really ported. In fact, it still uses deprecated alias_method to modify base behaviors, and require_dependency which should be removed with the zeitwerk autoloader. redmine_people probably works together with other redmineUP plugins that ALL use alias_method, but will show conflicts with any plugin oveloading some same method (in our case, allowed_to?) using the intended mixin policy with modern Rails, i.e. module prepend.

I attach a replacement for redmine_people's user_patch.rb to solve the conflict over allowed_to? but please note that I can't assure there's no other conflict around, that I am not sure about collateral problems and that I won't provide further support. All other mixins still rely upon alias_method. Ask RedmineUP for full plugin compliance.

In other words, I suggest to use redmineUP plugins on Redmine 4.2 only, or use them in isolation on Redmine 5.0 (if they all use deprecated methods they won't get in conflict), or wait for full porting towards 5.0. The following is just a workaround with no guarantee.

Good luck.

# This file is a part of Redmine People (redmine_people) plugin,
# humanr resources management plugin for Redmine
#
# Copyright (C) 2011-2022 RedmineUP
# http://www.redmineup.com/
#
# redmine_people 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 3 of the License, or
# (at your option) any later version.
#
# redmine_people 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 redmine_people.  If not, see .

require 'project'
require 'principal'
require 'user'

module RedminePeople
  module Patches
    module UserPatch
      module ClassMethods
        def self.included(base)
          if ActiveRecord::VERSION::MAJOR >= 4
            has_one :avatar, lambda { where("#{Attachment.table_name}.description = 'avatar'") }, :class_name => 'Attachment', :as => :container, :dependent => :destroy
          else
            has_one :avatar, :class_name => 'Attachment', :as => :container, :conditions => "#{Attachment.table_name}.description = 'avatar'", :dependent => :destroy
          end
          acts_as_attachable_global

          clear_safe_attributes

          safe_attributes 'firstname', 'lastname', 'mail', 'custom_field_values', 'custom_fields',
          :if => lambda { |user, current_user| current_user.allowed_people_to?(:edit_people, user) || (user.new_record? && current_user.anonymous? && Setting.self_registration?) }
        end

        def self.clear_safe_attributes
          @safe_attributes.collect! do |attrs, options|
            if attrs.collect!(&:to_s).include?('firstname')
              [attrs - ['firstname', 'lastname', 'mail', 'custom_field_values', 'custom_fields'], options]
            else
              [attrs, options]
            end
          end
        end
      end

      module InstanceMethods
        # include ContactsHelper

        def project
          @project ||= Project.new
        end

        def allowed_people_to?(permission, person = nil)
          unless RedminePeople.available_permissions.include?(permission)
            raise "The permission #{permission} does not exist"
          end

          return true if admin?

          if respond_to?(:"check_permission_#{permission.to_s}", true)
            send("check_permission_#{permission}".to_sym, person)
          else
            has_permission?(permission)
          end
        end

        def allowed_to?(action, context, options={}, &block)
          return allowed_people_to?(action) if !action.is_a?(Hash) && RedminePeople.available_permissions.include?(action)

          super(action, context, options, &block)
        end

        def has_permission?(permission)
          (groups + [self]).map { |principal| PeopleAcl.allowed_to?(principal, permission) }.inject { |memo, allowed| memo || allowed }
        end

        protected

        def check_permission_view_people(person)
          if person && person.is_a?(User) && person.id == id
            return true
          elsif is_a?(User) && !anonymous? && Setting.plugin_redmine_people['visibility'].to_i > 0
            return true
          end
          has_permission?(:view_people)
        end

        def check_permission_edit_people(person)
          if person && person.is_a?(User)
            # Check to edit himself
            if person.id == id && Setting.plugin_redmine_people['edit_own_data'].to_i > 0
              return true
            end

            # Check to edit subordinates.
            # Works only for persons.
            if person.respond_to?(:manager_id) && has_permission?(:edit_subordinates) && id == person.manager_id
              return true
            end
          end

          has_permission?(:edit_people)
        end

        def check_permission_view_performance(person)
          (person.is_a?(User) && person.id == self.id) || has_permission?(:view_performance)
        end
      end
    end
  end
end

unless User.included_modules.include?(RedminePeople::Patches::UserPatch::InstanceMethods)
  User.send(:prepend, RedminePeople::Patches::UserPatch::InstanceMethods)
end

unless User.singleton_class.included_modules.include?(RedminePeople::Patches::UserPatch::ClassMethods)
  User.singleton_class.send(:prepend, RedminePeople::Patches::UserPatch::ClassMethods)
end
perryjun commented 2 years ago

thanks a lot.

ashrafalzyoud commented 2 years ago

this user.batch.rb in pro version and last

require_dependency 'project'
require_dependency 'principal'
require_dependency 'user'

module RedminePeople
  module Patches
    module UserPatch
      def self.included(base) # :nodoc:
        base.send(:include, InstanceMethods)

        base.class_eval do
          unloadable

          alias_method :'allowed_to?_without_people', :allowed_to?
          alias_method :allowed_to?, :'allowed_to?_with_people'

          if ActiveRecord::VERSION::MAJOR >= 4
            has_one :avatar, lambda { where("#{Attachment.table_name}.description = 'avatar'") }, :class_name => 'Attachment', :as => :container, :dependent => :destroy
          else
            has_one :avatar, :class_name => 'Attachment', :as => :container, :conditions => "#{Attachment.table_name}.description = 'avatar'", :dependent => :destroy
          end
          acts_as_attachable_global

          # <PRO>
          has_many :dayoffs, foreign_key: :user_id, dependent: :destroy
          # </PRO>

          def self.clear_safe_attributes
            @safe_attributes.collect! do |attrs, options|
              if attrs.collect!(&:to_s).include?('firstname')
                [attrs - ['firstname', 'lastname', 'mail', 'custom_field_values', 'custom_fields'], options]
              else
                [attrs, options]
              end
            end
          end
          self.clear_safe_attributes

          safe_attributes 'firstname', 'lastname', 'mail', 'custom_field_values', 'custom_fields',
          :if => lambda { |user, current_user| current_user.allowed_people_to?(:edit_people, user) || (user.new_record? && current_user.anonymous? && Setting.self_registration?) }
        end
      end

      module InstanceMethods
        # include ContactsHelper

        def project
          @project ||= Project.new
        end

        def allowed_people_to?(permission, person = nil)
          unless RedminePeople.available_permissions.include?(permission)
            raise "The permission #{permission} does not exist"
          end

          return true if admin?

          if respond_to?(:"check_permission_#{permission.to_s}", true)
            send("check_permission_#{permission}".to_sym, person)
          else
            has_permission?(permission)
          end
        end

        define_method 'allowed_to?_with_people' do |action, context, options={}, &block|
          return allowed_people_to?(action) if !action.is_a?(Hash) && RedminePeople.available_permissions.include?(action)

          public_send('allowed_to?_without_people', action, context, options, &block)
        end

        def has_permission?(permission)
          (groups + [self]).map { |principal| PeopleAcl.allowed_to?(principal, permission) }.inject { |memo, allowed| memo || allowed }
        end

        protected

        def check_permission_view_people(person)
          if person && person.is_a?(User) && person.id == id
            return true
          elsif is_a?(User) && !anonymous? && Setting.plugin_redmine_people['visibility'].to_i > 0
            return true
          end
          has_permission?(:view_people)
        end

        def check_permission_edit_people(person)
          if person && person.is_a?(User)
            # Check to edit himself
            if person.id == id && Setting.plugin_redmine_people['edit_own_data'].to_i > 0
              return true
            end

            # Check to edit subordinates.
            # Works only for persons.
            if person.respond_to?(:manager_id) && has_permission?(:edit_subordinates) && id == person.manager_id
              return true
            end
          end

          has_permission?(:edit_people)
        end

        def check_permission_view_performance(person)
          (person.is_a?(User) && person.id == self.id) || has_permission?(:view_performance)
        end
      end
    end
  end
end

unless User.included_modules.include?(RedminePeople::Patches::UserPatch)
  User.send(:include, RedminePeople::Patches::UserPatch)
end
ashrafalzyoud commented 2 years ago

this error when im use your code in user_patch.rb

F, [2022-09-04T01:35:43.578018 #6244] FATAL -- : [8fd8f048-76aa-4803-b8ef-9e57144dd3dc]   
[8fd8f048-76aa-4803-b8ef-9e57144dd3dc] ActionView::Template::Error (Association named 'avatar' was not found on Person; perhaps you misspelled it?
Did you mean?  manager
               auth_source
               votes
               rates):
[8fd8f048-76aa-4803-b8ef-9e57144dd3dc]     109: <!-- </PRO> -->
[8fd8f048-76aa-4803-b8ef-9e57144dd3dc]     110: 
[8fd8f048-76aa-4803-b8ef-9e57144dd3dc]     111: <div id="people_list">
[8fd8f048-76aa-4803-b8ef-9e57144dd3dc]     112: <% if @people.blank? %>
[8fd8f048-76aa-4803-b8ef-9e57144dd3dc]     113:     <p class="nodata"><%= l(:label_no_data) %></p>
[8fd8f048-76aa-4803-b8ef-9e57144dd3dc]     114: <% else %>
[8fd8f048-76aa-4803-b8ef-9e57144dd3dc]     115:     <%= render :partial => people_list_style %>
[8fd8f048-76aa-4803-b8ef-9e57144dd3dc]   
[8fd8f048-76aa-4803-b8ef-9e57144dd3dc] plugins/redmine_people/app/views/people/index.html.erb:112
[8fd8f048-76aa-4803-b8ef-9e57144dd3dc] lib/redmine/sudo_mode.rb:61:in `sudo_mode'
ashrafalzyoud commented 2 years ago

@maxrossello

maxrossello commented 2 years ago

@ashrafalzyoud maybe I wasn't clear enough with my statement:

please note that I can't assure there's no other conflict around, that I am not sure about collateral problems and that I won't provide further support.

Plugins using alias_method are not compatible with plugins using prepend over the same methods. Fullstop.

ashrafalzyoud commented 2 years ago

i will delete the plugin redmine_people and use only your plugin because its so important to me