Skip to content

Instantly share code, notes, and snippets.

@arockwell
Created July 18, 2025 18:13
Show Gist options
  • Select an option

  • Save arockwell/b61498b25414598e052ea21afa472d8d to your computer and use it in GitHub Desktop.

Select an option

Save arockwell/b61498b25414598e052ea21afa472d8d to your computer and use it in GitHub Desktop.
Punchout Admin Session Issues - Existing Solutions Analysis

Punchout Admin Session Issues - Existing Solutions Analysis

Current Problem

Admins assuming identity in punchout organizations face the issue where requires_punchout_url? returns true because current_user.cart.punchout_form_url.blank? is true, blocking their ability to work with the cart.

Existing Solutions and Patterns Found

1. Impersonation Detection Pattern (Most Relevant)

Location: app/helpers/auth_helper.rb

def impersonating_user?
  true_user.present? && current_user != true_user
end

Also found in: app/services/off_catalog/permissions_service.rb

def impersonating?
  true_user.present? && true_user != current_user
end

2. Off-Catalog Admin Bypass Pattern (Direct Precedent)

Location: app/services/off_catalog/permissions_service.rb

# Lines 37-44: Allows internal users to access off-catalog by simply impersonating
def enabled?
  standard_permit = organization.off_catalog_enabled? &&
    permissions.enable_off_catalog_orders[role]

  # Allows internal Order users to access off-catalog by simply impersonating.
  # This is temporary and will be removed soon once we allow public view access
  # for off-catalog.
  prototype_permit = organization.off_catalog_enabled? &&
    impersonating?

  standard_permit || prototype_permit
end

3. Internal Employee Detection

Location: app/models/user.rb

def internal_employee?
  !user_group?
end

Used in: app/controllers/application_controller.rb

def internal_employee?
  current_user.internal_employee?
end

4. Current Punchout Logic

Location: app/helpers/carts_helper.rb

def requires_punchout_url?
  current_org.is_punchout? && current_user.cart.punchout_form_url.blank?
end

Key Insights

1. Impersonation is Already Handled

The app already has a robust impersonation system using the pretender gem with true_user and current_user distinction.

2. Direct Precedent Exists

Off-catalog already implements the exact pattern needed:

  • Check if user is impersonating (true_user != current_user)
  • Allow bypass for admin users when impersonating

3. Pattern Used Throughout App

Multiple services use impersonation checks:

  • OffCatalog::PermissionsService - bypasses restrictions
  • OffCatalog::OrderSearchService - shows all orders when impersonating
  • Various permission checks use impersonating? pattern

4. Consistent Helper Pattern

The auth_helper.rb already provides the impersonating_user? method that could be reused.

Recommended Solution Pattern

Based on the existing patterns, the solution should be:

def requires_punchout_url?
  current_org.is_punchout? && 
    current_user.cart.punchout_form_url.blank? &&
    !impersonating_user?
end

This follows the exact same pattern as off-catalog and leverages existing infrastructure.

Files to Modify

  1. Primary: app/helpers/carts_helper.rb - Update requires_punchout_url? method
  2. Include: app/helpers/auth_helper.rb in CartsHelper if not already included
  3. Test: Update specs in spec/helpers/carts_helper_spec.rb

Alternative Approaches Found

1. Check for Internal Employee

Could also check true_user&.internal_employee? but impersonation check is more specific.

2. Check Admin Role

Could check current_user.admin? but this might not cover all admin scenarios.

3. Combined Approach

Could combine impersonation check with internal employee check for extra safety.

Existing Test Patterns

The carts_helper_spec.rb already has comprehensive tests for requires_punchout_url? including:

  • Punchout org with blank form URL
  • Punchout org with non-blank form URL
  • Non-punchout org scenarios

No Existing Workarounds Found

  • No TODO/FIXME comments about this specific issue
  • No existing scripts for mocking punchout data
  • No conditional logic currently skipping punchout checks for admins
  • This appears to be an unaddressed issue that needs the solution

Conclusion

The existing off-catalog impersonation bypass pattern provides the perfect template for solving this punchout admin issue. The solution is straightforward and follows established patterns in the codebase.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment