# Undefined method `time_zone` for PulseUser - No events in the past 24 hours. - In the last 14 days only 3 URL routes report this exception. - /api/v1/media_items/??? (2,100+ events) - /mobile_devices/api/v1/device_locations (638 events) - /assets/nitro_theme/backgrounds/greyzz_@2X.png (9 events) The last one is curious because the `/assets/` directory should [bypass the authentication completely](https://github.com/powerhome/nitro-web/blob/master/lib/middleware/ui_state_middleware.rb#L10). The `media_items`route isn't used internally within Nitro, but within the mobile app. The `api` routes both make use of component method `check_api_token_or_login` for authentication which is in the following components: - accounting - admin - marketing - media - mobile_devices - nitro_component_transition - purchase_orders - spaces ```ruby # If Authorization header present, api-token authentication is used. # If no Authorization header present, uses warden for auth. def check_api_token_or_login @key = request.headers["Authorization"] # token-based auth has a single param; multiple params are used by warden and unit test auth if @key.present? && @key.split.count == 1 load_partner(api_key: @key) else authenticate!(:basic) end end ``` For logging, dumping the entire `env["warden"]` object doesn't seem interesting alone. ```ruby envv["warden"] => Warden::Proxy:200320 @config={:failure_app=>NitroAuth::WardenFailureApp, :default_scope=>:default, :scope_defaults=>{:mdm=>{:store=>false}}, :default_strategies=>{:_all=>[:password, :basic, :training], :customer=>[:pulse_user_auth_token], :mdm=>[:jwt]}, :intercept_401=>true} ``` Out of the full list of methods, I think these are the one's of primary interest when called on `env["warden"]`. - `authenticated?` True if true. - `result` Not sure what responses this may provide. - `errors` but I don't think we're seeing any for this specific issue. - `winning_strategy` tells us which actual strategy won out. - `user` is already being used. - `message` may be interesting but it was `nil` the times I checked it locally. Note that where I placed the logging, most of these don't appear to be set at the point as they are typically blank. ## Once the pulse cookies are set, is `:customer` now a valid Nitro scope? Looking at `Pulse::AuthStrategies::UserAuthToken`, it's considered a valid path if `request.cookies[Pulse::USER_AUTH_TOKEN_COOKIE]` is present. When using normal Nitro, if that cookie is set, does that allow this strategy to _win_ when we're not using Pulse? When testing locally I wasn't seeing anything related to a customer scope in my logs, but when I tried to load a Pulse project, that set the cookies in my browser and even on Nitro pages, the `after_fetch` callback for `warden` started reporting that it was trying to use the `customer` scope and I was seeing `pulse_users` and `pulse_preferences` queries within the context of normal Nitro requests. ``` [request_id=b6a9202d-8b83-434e-bb26-68a67e22f3ee] [IP=::1] [U=1674] [user_agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36] [user_name=Kraig Schwerin] [territory_id=1] [territory=Philadelphia] [department_id=2] [department=Business Technology] NitroAuth::AuthenticatedSession Load (2.5ms) SELECT `nitro_auth_authenticated_sessions`.* FROM `nitro_auth_authenticated_sessions` WHERE `nitro_auth_authenticated_sessions`.`id` = 13340299 LIMIT 1 [request_id=b6a9202d-8b83-434e-bb26-68a67e22f3ee] [IP=::1] [U=1674] [user_agent=Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36] [user_name=Kraig Schwerin] [territory_id=1] [territory=Philadelphia] [department_id=2] [department=Business Technology] Pulse::User Load (2.4ms) SELECT `pulse_users`.* FROM `pulse_users` WHERE `pulse_users`.`id` = 122265 LIMIT 1 ``` Looking in `nitro_auth_authenticated_sessions` just attempting to load Pulse changed the `identify_type` to `Pulse::User`. Loading Pulse appears to have created a NEW session id for me and switched over to that for both Nitro **and** Pulse in my browser. ## Added logging To help find these, I added the following to my local logs and then just searched on `[Warden]` Add these lines to the bottom of `components/nitro_auth/config/initializers/warden.rb` ```ruby Warden::Manager.after_authentication do |user, auth, opts| Rails.logger.info "[WARDEN] after_authentication scope=#{opts[:scope]} #{user.class.to_s} winning_strategy=#{auth.winning_strategy} result=#{auth.result rescue nil} message=#{auth.message rescue nil} errors=#{auth.errors}" end Warden::Manager.after_fetch do |user, auth, opts| Rails.logger.info "[WARDEN] after_fetch scope=#{opts[:scope]} #{user.class.to_s} winning_strategy=#{auth.winning_strategy} result=#{auth.result rescue nil} message=#{auth.message rescue nil} errors=#{auth.errors}" end ``` The `after_fetch` log entry was really where I was seeing the `PulseUser` details. I"m not sure why the `auth` object isn't showing the strategy/message/etc that are always empty, but we can see the behavior without them. How did I find out about using `after_fetch`? RTFD. Change the `call` method in `lib/middleware/ui_state_middleware.rb` to the following which just adds the `Rails.logger.info` line. ```ruby def call(env) request = ActionDispatch::Request.new(env) unless env["PATH_INFO"].starts_with?(Rails.configuration.assets.prefix) Rails.logger.info "[WARDEN] UIStateMiddleware.call #{env["warden"].user.class.to_s} path=#{env["PATH_INFO"]} winning_strategy=#{env["warden"].winning_strategy} result=#{env["warden"].result rescue nil} message=#{env["warden"].message rescue nil} errors=#{env["warden"].errors}" env[:nitro_ui_state] = UIState.new(env["warden"].user, request) end @app.call(env) end ```