collectiveidea / audited

Audited (formerly acts_as_audited) is an ORM extension that logs all changes to your Rails models.
MIT License
3.34k stars 645 forks source link

Infinite loop with devise timeoutable + rememberable when session expires - SystemStackError (stack level too deep) #678

Open ndbroadbent opened 11 months ago

ndbroadbent commented 11 months ago

Hello, I'm not sure if I should post this here, or on the devise/warden repos. But I'm getting an infinite loop when I use the audited gem with devise "timeoutable". Here is the stack trace I'm seeing:

https://gist.github.com/ndbroadbent/4fd5114ab14d1d3593ea5cb9593ecfc2

I have a custom #current_user method in application_controller.rb that is basically the same as the default Devise one, but adds eager loading for User roles (from the rolify gem.)

  def current_user
    return @current_user if @current_user

    @current_user = warden.authenticate(scope: :user)
    ActiveRecord::Associations::Preloader.new.preload(@current_user, :roles)
    @current_user
  end

I'm not sure why, but this is only crashing with a SystemStackError on production, and it's not crashing locally or on CI. It might be because I have set ulimit to "unlimited" locally and on CI containers, and maybe devise or warden has an internal counter somewhere to detect and prevent infinite loops. I noticed that the current_user method is called around 97 times before it stops trying and moves on, so that's why I think there might be some infinite loop detection happening somewhere. But unfortunately it's not enough to prevent a SystemStackError crash on production.

I'm trying to understand the stack trace, and here's what I think is happening:

      def forget_me!
        return unless persisted?
        self.remember_token = nil if respond_to?(:remember_token)
        self.remember_created_at = nil if self.class.expire_all_remember_me_on_sign_out
        save(validate: false)
      end

(I did notice that my Audited db table was taking a ton of space, so this might be related, since I think it's creating audited records in an infinite loop until it crashes. I might have to check this and delete a bunch of rows.)

Solutions:

Please let me know if you have any other suggestions or feedback. Thanks!

bkd commented 10 months ago

Yup i have the same issue also