chore: remove debugging files

This commit is contained in:
Shivam Mishra
2025-08-28 16:02:46 +05:30
parent b999fe6439
commit 04cc25d55e
7 changed files with 0 additions and 858 deletions
-153
View File
@@ -1,153 +0,0 @@
# SAML Testing Guide with MockSAML.com
## Prerequisites
- Chatwoot running locally on `http://localhost:3000`
- MockSAML.com account (free tier works)
- A user account in Chatwoot that you'll use for testing
## Step 1: Set Up MockSAML
1. Go to https://mocksaml.com and sign in
2. Click "Create New Configuration"
3. Fill in the configuration:
- **Configuration Name**: Chatwoot Test
- **Service Provider Entity ID**: `http://localhost:3000/saml/1` (or use your custom entity ID from SAML settings)
- **Assertion Consumer Service URL**: `http://localhost:3000/auth/saml/1/callback`
- **Authentication Method**: Email/Password
- **Default RelayState**: `/app/dashboard` (optional)
4. In the "Attributes" section, add:
- **Email Address**:
- Name: `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress`
- Value: Use the email of an existing user in your Chatwoot database
- **Name**:
- Name: `http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name`
- Value: The user's full name
5. Save the configuration and note down:
- The SSO URL (will be like `https://mocksaml.com/api/saml/sso/{config-id}`)
- Download the certificate from the "Metadata" section
## Step 2: Update Chatwoot SAML Settings
### Using Rails Console:
```ruby
rails console
# Find your account
account = Account.find(1)
# Get or create SAML settings
saml_settings = account.account_saml_settings || account.create_account_saml_settings
# Update with MockSAML values
saml_settings.update!(
enabled: true,
sso_url: 'https://mocksaml.com/api/saml/sso/YOUR_CONFIG_ID', # Replace with your MockSAML SSO URL
certificate: %{-----BEGIN CERTIFICATE-----
PASTE_THE_CERTIFICATE_FROM_MOCKSAML_HERE
-----END CERTIFICATE-----},
sp_entity_id: 'http://localhost:3000/saml/1', # Must match what you set in MockSAML
enforced_sso: false
)
# Verify settings
puts saml_settings.certificate_fingerprint
```
### Using API:
```bash
# Update SAML settings via API
curl -X PUT http://localhost:3000/api/v1/accounts/1/saml_settings \
-H "Content-Type: application/json" \
-H "api_access_token: YOUR_API_TOKEN" \
-d '{
"enabled": true,
"sso_url": "https://mocksaml.com/api/saml/sso/YOUR_CONFIG_ID",
"certificate": "-----BEGIN CERTIFICATE-----\n...\n-----END CERTIFICATE-----",
"sp_entity_id": "http://localhost:3000/saml/1"
}'
```
## Step 3: Test the SAML Flow
### Method 1: Direct Browser Test
1. Open your browser
2. Navigate to: `http://localhost:3000/auth/saml/1`
3. You should be redirected to MockSAML login page
4. Enter the test credentials you configured in MockSAML
5. After successful authentication, you should be redirected to:
- `http://localhost:3000/app/login?email=USER_EMAIL&sso_auth_token=TOKEN`
6. The frontend should automatically complete the login using the SSO token
### Method 2: API Test
```bash
# 1. Get SAML configuration
curl http://localhost:3000/api/v1/accounts/1/saml/sso
# 2. Initiate SAML flow (in browser)
# Visit: http://localhost:3000/auth/saml/1
```
## Step 4: Verify the Login
1. Check browser developer tools:
- Network tab should show the SAML flow
- After redirect, check for `/auth/sign_in` API call with SSO token
2. Check Rails logs:
```bash
tail -f log/development.log | grep -E "OmniauthController|SAML|SSO"
```
3. Verify in Rails console:
```ruby
# Check if SSO token was created
Redis::Alfred.keys("chatwoot:user:*:sso_auth_token:*")
# Check user's last sign in
User.find_by(email: 'your-test-email@example.com').current_sign_in_at
```
## Troubleshooting
### Common Issues:
1. **"SAML not enabled for this account"**
- Ensure `enabled: true` in SAML settings
- Verify account ID matches
2. **Redirect to /auth/sign_in without SSO token**
- Check if SAML response validation failed
- Verify certificate and fingerprint match
- Check Rails logs for OmniAuth errors
3. **"User not found" error**
- Ensure the email in MockSAML matches an existing Chatwoot user
- Check if `User.find_by(email: 'test@example.com')` returns a user
4. **Certificate validation errors**
- Make sure you copied the entire certificate including BEGIN/END lines
- Certificate should not have any extra whitespace
### Debug Commands:
```bash
# Check current SAML settings
rails runner "pp AccountSamlSettings.find_by(account_id: 1)"
# Test metadata endpoint
curl http://localhost:3000/auth/saml/1/metadata
# Check OmniAuth configuration
rails runner "pp Rails.application.config.omniauth"
```
## Next Steps
Once basic login works:
1. Test with multiple users
2. Test logout flow (if implementing SLO)
3. Test with enforced SSO enabled
4. Implement user provisioning for new users
5. Add role mapping from SAML attributes
-5
View File
@@ -1,5 +0,0 @@
#!/bin/bash
echo "Starting Rails server with debug logging..."
echo "Watch for [SAML Setup] and [OmniAuth Callback] messages in the logs"
echo ""
bundle exec rails server
-270
View File
@@ -1,270 +0,0 @@
#!/usr/bin/env ruby
# Run with: rails runner test_saml_devise_flow.rb
require 'net/http'
require 'uri'
require 'json'
require 'base64'
require 'time'
# Enable OmniAuth debug logging
OmniAuth.config.logger = Rails.logger
OmniAuth.config.logger.level = Logger::DEBUG
puts "=== SAML Authentication Flow Test ==="
puts ""
# 1. Find SAML settings
account_id = 1
saml_settings = AccountSamlSettings.find_by(account_id: account_id, enabled: true)
unless saml_settings
puts "❌ No SAML settings found for account #{account_id}"
exit 1
end
puts "✅ Found SAML settings for account #{account_id}"
puts " SSO URL: #{saml_settings.sso_url}"
puts " SP Entity ID: #{saml_settings.sp_entity_id_or_default}"
puts ""
# 2. Find a test user
user = User.first
unless user
puts "❌ No user found to test with"
exit 1
end
puts "✅ Testing with user: #{user.email}"
puts ""
# 3. Test the initial SAML request endpoint
puts "=== Testing SAML Initiation ==="
saml_init_url = "http://localhost:3000/auth/saml?account_id=#{account_id}"
puts "GET #{saml_init_url}"
uri = URI(saml_init_url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = false
http.set_debug_output($stdout) if ENV['DEBUG']
# Enable cookie handling
http.start do |http_session|
request = Net::HTTP::Get.new(uri)
request['Accept'] = 'text/html'
response = http_session.request(request)
puts "Response Status: #{response.code}"
# Store cookies
cookies = response.get_fields('set-cookie')
cookie_hash = {}
if cookies
cookies.each do |cookie|
cookie_hash[cookie.split(';')[0].split('=')[0]] = cookie.split(';')[0]
end
end
if response.code == '307'
puts "✅ Got temporary redirect to: #{response['location']}"
# Follow the redirect
redirect_uri = URI(response['location'])
redirect_request = Net::HTTP::Get.new(redirect_uri)
redirect_request['Cookie'] = cookie_hash.values.join('; ') if cookie_hash.any?
redirect_response = http_session.request(redirect_request)
puts "Redirect Response Status: #{redirect_response.code}"
if redirect_response.code == '302' || redirect_response.code == '303'
puts "✅ Redirected to IdP: #{redirect_response['location']}"
# Check if it's redirecting to the IdP
if redirect_response['location']&.include?(saml_settings.sso_url)
puts "✅ Correctly redirecting to IdP"
else
puts "❌ Not redirecting to expected IdP URL"
end
end
elsif response.code == '302' || response.code == '303'
puts "✅ Redirected to: #{response['location']}"
# Check if it's redirecting to the IdP
if response['location']&.include?(saml_settings.sso_url)
puts "✅ Correctly redirecting to IdP"
else
puts "❌ Not redirecting to expected IdP URL"
end
else
puts "❌ Expected redirect but got #{response.code}"
puts "Response body: #{response.body[0..500]}"
end
end
puts ""
# 4. Simulate SAML callback
puts "=== Simulating SAML Callback ==="
# Generate a mock SAML response
def generate_saml_response(saml_settings, user)
issue_instant = Time.now.utc.iso8601
response_id = "_#{SecureRandom.hex(21)}"
assertion_id = "_#{SecureRandom.hex(21)}"
# Create a simple unsigned SAML response for testing
saml_response = <<-XML
<?xml version="1.0" encoding="UTF-8"?>
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="#{response_id}"
Version="2.0"
IssueInstant="#{issue_instant}"
Destination="http://localhost:3000/omniauth/saml/callback">
<saml:Issuer>#{saml_settings.sso_url}</saml:Issuer>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</samlp:Status>
<saml:Assertion ID="#{assertion_id}" Version="2.0" IssueInstant="#{issue_instant}">
<saml:Issuer>#{saml_settings.sso_url}</saml:Issuer>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">#{user.email}</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData NotOnOrAfter="#{(Time.now.utc + 300).iso8601}"
Recipient="http://localhost:3000/omniauth/saml/callback"/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:AuthnStatement AuthnInstant="#{issue_instant}">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
<saml:AttributeStatement>
<saml:Attribute Name="email">
<saml:AttributeValue>#{user.email}</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="name">
<saml:AttributeValue>#{user.name}</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
</samlp:Response>
XML
Base64.strict_encode64(saml_response)
end
callback_url = "http://localhost:3000/omniauth/saml/callback"
puts "POST #{callback_url}"
saml_response = generate_saml_response(saml_settings, user)
uri = URI(callback_url)
http = Net::HTTP.new(uri.host, uri.port)
# We need to maintain session cookies
cookie_jar = {}
# First, get a session by visiting the auth endpoint
session_uri = URI(saml_init_url)
session_http = Net::HTTP.new(session_uri.host, session_uri.port)
session_request = Net::HTTP::Get.new(session_uri)
session_response = session_http.request(session_request)
if session_response['set-cookie']
cookie_jar['Cookie'] = session_response['set-cookie'].split(';')[0]
puts "✅ Got session cookie"
end
# Now send the callback with the session
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/x-www-form-urlencoded'
request['Cookie'] = cookie_jar['Cookie'] if cookie_jar['Cookie']
callback_params = {
'SAMLResponse' => saml_response,
'RelayState' => ''
}
request.body = URI.encode_www_form(callback_params)
puts "Sending SAML response for user: #{user.email}"
response = http.request(request)
puts "Response Status: #{response.code}"
if response.code == '302' || response.code == '303'
redirect_location = response['location']
puts "✅ Redirected to: #{redirect_location}"
# Parse redirect URL to check for SSO token
if redirect_location
redirect_uri = URI(redirect_location)
if redirect_uri.path == '/app/login'
params = URI.decode_www_form(redirect_uri.query || '')
params_hash = params.to_h
puts ""
puts "=== Login Redirect Parameters ==="
puts "Email: #{params_hash['email']}"
puts "SSO Token: #{params_hash['sso_auth_token']}"
if params_hash['sso_auth_token']
puts ""
puts "✅ Successfully generated SSO auth token!"
# Optional: Test the SSO token login
puts ""
puts "=== Testing SSO Token Login ==="
login_url = "http://localhost:3000/auth/sign_in"
login_params = {
email: params_hash['email'],
sso_auth_token: params_hash['sso_auth_token']
}
uri = URI(login_url)
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/json'
request.body = login_params.to_json
login_response = http.request(request)
puts "Login Response Status: #{login_response.code}"
if login_response.code == '200'
puts "✅ SSO token login successful!"
# Check for auth headers
if login_response['access-token']
puts ""
puts "Authentication Headers:"
puts " access-token: #{login_response['access-token']}"
puts " client: #{login_response['client']}"
puts " uid: #{login_response['uid']}"
end
else
puts "❌ SSO token login failed"
puts "Response: #{login_response.body}"
end
elsif params_hash['error']
puts "❌ Error: #{params_hash['error']}"
end
else
puts "❌ Unexpected redirect path: #{redirect_uri.path}"
end
end
else
puts "❌ Expected redirect but got #{response.code}"
puts "Response body: #{response.body[0..1000]}"
# Check if it's an error page
if response.body.include?('error') || response.body.include?('Error')
puts ""
puts "Possible error in response. Check Rails logs for details."
end
end
puts ""
puts "=== Test Complete ==="
puts "Check your Rails server logs for detailed OmniAuth debug information"
-195
View File
@@ -1,195 +0,0 @@
#!/usr/bin/env ruby
# Run with: rails runner test_saml_login.rb
require 'net/http'
require 'uri'
require 'json'
require 'openssl'
require 'base64'
require 'time'
# Find SAML settings for account 1
saml_settings = AccountSamlSettings.find_by(id: 1)
unless saml_settings
puts "No SAML settings found with ID 1"
exit 1
end
puts "Found SAML settings for account #{saml_settings.account_id}:"
puts " SSO URL: #{saml_settings.sso_url}"
puts " SP Entity ID: #{saml_settings.sp_entity_id_or_default}"
puts " Certificate Fingerprint: #{saml_settings.certificate_fingerprint}"
puts ""
# Find a user to login as
user = User.first
unless user
puts "No user found to test with"
exit 1
end
puts "Testing with user: #{user.email}"
puts ""
# Generate a proper SAML response
def generate_saml_response(saml_settings, user)
# Create a basic SAML response XML
issue_instant = Time.now.utc.iso8601
response_id = "_#{SecureRandom.hex(21)}"
assertion_id = "_#{SecureRandom.hex(21)}"
saml_response = <<-XML
<samlp:Response xmlns:samlp="urn:oasis:names:tc:SAML:2.0:protocol"
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
ID="#{response_id}"
Version="2.0"
IssueInstant="#{issue_instant}"
Destination="http://localhost:3000/saml/#{saml_settings.account_id}/callback">
<saml:Issuer>#{saml_settings.sso_url}</saml:Issuer>
<samlp:Status>
<samlp:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/>
</samlp:Status>
<saml:Assertion ID="#{assertion_id}" Version="2.0" IssueInstant="#{issue_instant}">
<saml:Issuer>#{saml_settings.sso_url}</saml:Issuer>
<saml:Subject>
<saml:NameID Format="urn:oasis:names:tc:SAML:1.1:nameid-format:emailAddress">#{user.email}</saml:NameID>
<saml:SubjectConfirmation Method="urn:oasis:names:tc:SAML:2.0:cm:bearer">
<saml:SubjectConfirmationData NotOnOrAfter="#{(Time.now.utc + 300).iso8601}"
Recipient="http://localhost:3000/saml/#{saml_settings.account_id}/callback"/>
</saml:SubjectConfirmation>
</saml:Subject>
<saml:AuthnStatement AuthnInstant="#{issue_instant}">
<saml:AuthnContext>
<saml:AuthnContextClassRef>urn:oasis:names:tc:SAML:2.0:ac:classes:Password</saml:AuthnContextClassRef>
</saml:AuthnContext>
</saml:AuthnStatement>
<saml:AttributeStatement>
<saml:Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/emailaddress">
<saml:AttributeValue>#{user.email}</saml:AttributeValue>
</saml:Attribute>
<saml:Attribute Name="http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name">
<saml:AttributeValue>#{user.name}</saml:AttributeValue>
</saml:Attribute>
</saml:AttributeStatement>
</saml:Assertion>
</samlp:Response>
XML
Base64.encode64(saml_response)
end
# First, test the SSO endpoint
sso_url = "http://localhost:3000/api/v1/accounts/#{saml_settings.account_id}/saml/sso"
puts "Testing SSO endpoint: #{sso_url}"
uri = URI(sso_url)
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri)
request['Content-Type'] = 'application/json'
response = http.request(request)
puts "SSO Response Status: #{response.code}"
puts "SSO Response Body: #{response.body}"
puts ""
# Now test the callback with a proper SAML response
callback_url = "http://localhost:3000/saml/#{saml_settings.account_id}/callback"
puts "Testing callback endpoint: #{callback_url}"
# Generate SAML response
saml_response = generate_saml_response(saml_settings, user)
# Create a form-encoded body (SAML callbacks are typically POST with form data)
callback_params = {
'SAMLResponse' => saml_response,
'RelayState' => '/app/dashboard'
}
uri = URI(callback_url)
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/x-www-form-urlencoded'
request.body = URI.encode_www_form(callback_params)
puts "Sending POST to callback with SAML response for user: #{user.email}"
response = http.request(request)
puts "Callback Response Status: #{response.code}"
puts "Callback Response Headers:"
response.each_header do |key, value|
puts " #{key}: #{value}" if key.downcase.include?('location') || key.downcase.include?('content-type')
end
if response.code == '302'
puts "\nRedirect location: #{response['location']}"
# Parse the redirect URL to extract SSO token
if response['location']
redirect_uri = URI(response['location'])
params = URI.decode_www_form(redirect_uri.query || '')
params_hash = params.to_h
puts "\nRedirect parameters:"
puts " Email: #{params_hash['email']}"
puts " SSO Auth Token: #{params_hash['sso_auth_token']}"
# Test if we can use this SSO token to login
if params_hash['sso_auth_token']
puts "\n\nTesting SSO token login:"
login_url = "http://localhost:3000/auth/sign_in"
login_params = {
email: params_hash['email'],
sso_auth_token: params_hash['sso_auth_token']
}
uri = URI(login_url)
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/json'
request.body = login_params.to_json
login_response = http.request(request)
puts "Login Response Status: #{login_response.code}"
if login_response.body && !login_response.body.empty?
begin
json = JSON.parse(login_response.body)
puts "Login Response:"
puts JSON.pretty_generate(json)
# Check for auth headers
puts "\nAuthentication Headers:"
puts " access-token: #{login_response['access-token']}" if login_response['access-token']
puts " client: #{login_response['client']}" if login_response['client']
puts " uid: #{login_response['uid']}" if login_response['uid']
rescue
puts "Login Response Body: #{login_response.body}"
end
end
end
end
elsif response.body && !response.body.empty?
puts "\nCallback Response Body:"
begin
json = JSON.parse(response.body)
puts JSON.pretty_generate(json)
rescue
puts response.body
end
end
# Test direct OmniAuth request
puts "\n\nTesting OmniAuth request endpoint:"
omniauth_url = "http://localhost:3000/saml/#{saml_settings.account_id}"
puts "GET #{omniauth_url}"
uri = URI(omniauth_url)
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri)
response = http.request(request)
puts "Response Status: #{response.code}"
if response.code == '302'
puts "Redirected to: #{response['location']}"
end
-71
View File
@@ -1,71 +0,0 @@
# Testing SAML Authentication Flow
## 1. Start the SAML Authentication Flow
Visit this URL in your browser to initiate SAML authentication:
```
http://localhost:3000/auth/saml?account_id=1
```
This should:
1. Trigger the OmniAuth SAML provider
2. Run the setup phase to load account-specific SAML settings
3. Redirect you to MockSAML.com with the correct parameters
## 2. Complete Authentication at MockSAML
At MockSAML.com:
1. Enter any email address (use an existing Chatwoot user's email)
2. Complete the authentication
3. MockSAML will POST back to: `http://localhost:3000/omniauth/saml/callback`
## 3. Expected Flow
After successful SAML authentication:
1. The `devise_overrides/omniauth_callbacks#omniauth_success` method will be called
2. It will find the user by email
3. Generate an SSO auth token
4. Redirect to the frontend login page with the token: `http://localhost:3000/app/login?email=user@example.com&sso_auth_token=xxx`
## 4. Check Server Logs
Monitor the Rails server logs for:
- "Processing by DeviseOverrides::OmniauthCallbacksController#omniauth_success"
- Any SAML-related errors or warnings
## 5. Debugging
If you encounter issues:
1. **Check if SAML settings are loaded:**
```ruby
rails console
AccountSamlSettings.find_by(account_id: 1, enabled: true)
```
2. **Test the setup phase manually:**
```ruby
# In rails console
settings = AccountSamlSettings.find_by(account_id: 1)
puts "SSO URL: #{settings.sso_url}"
puts "SP Entity ID: #{settings.sp_entity_id_or_default}"
puts "Certificate present: #{settings.certificate.present?}"
```
3. **Enable OmniAuth debug logging:**
Add this to an initializer:
```ruby
OmniAuth.config.logger = Rails.logger
OmniAuth.config.logger.level = Logger::DEBUG
```
## 6. Alternative Testing with cURL
You can also test the initial redirect:
```bash
curl -v "http://localhost:3000/auth/saml?account_id=1"
```
This should return a 302 redirect to MockSAML.com.
-122
View File
@@ -1,122 +0,0 @@
# Testing SAML with MockSAML.com
## 1. Verify Your SAML Settings
First, check your current SAML configuration:
```bash
rails console
```
```ruby
settings = AccountSamlSettings.find_by(account_id: 1)
puts "SSO URL: #{settings.sso_url}"
puts "SP Entity ID: #{settings.sp_entity_id_or_default}"
puts "ACS URL: #{ENV.fetch('FRONTEND_URL', 'http://localhost:3000')}/omniauth/saml/callback?account_id=1"
```
## 2. Update MockSAML Configuration
Go to MockSAML.com and ensure these settings match:
- **SP Entity ID**: Should match `settings.sp_entity_id_or_default`
- **ACS URL**: `http://localhost:3000/omniauth/saml/callback?account_id=1`
- **Name ID Format**: Email Address
## 3. Start the Authentication Flow
### Option A: Browser Test
1. Open your browser
2. Navigate to: `http://localhost:3000/auth/saml?account_id=1`
3. You should be redirected to MockSAML.com
4. Enter any email (use an existing Chatwoot user's email like `john@acme.inc`)
5. Complete authentication at MockSAML
6. You should be redirected back to Chatwoot login page with SSO token
### Option B: Direct Link Test
1. Get the SAML initiation URL:
```
http://localhost:3000/auth/saml?account_id=1
```
2. Click or paste this in your browser
## 4. What to Expect
### Success Flow:
1. Browser redirects to MockSAML.com
2. You authenticate at MockSAML
3. MockSAML POST backs to `/omniauth/saml/callback?account_id=1`
4. Chatwoot processes the SAML response
5. You're redirected to: `http://localhost:3000/app/login?email=USER_EMAIL&sso_auth_token=TOKEN`
### If Using ngrok or Public URL:
If you're testing with a public URL (ngrok), update the FRONTEND_URL:
```bash
export FRONTEND_URL=https://your-ngrok-url.ngrok.io
```
## 5. Debugging Tips
### Watch Server Logs:
Look for these log messages:
- `[SAML Setup] Request path:`
- `[SAML Setup] Account ID:`
- `[SAML Setup] Found settings for account`
- `[OmniAuth Callback] Provider: saml`
### Common Issues:
1. **"No fingerprint or certificate on settings"**
- The account_id isn't being passed properly
- Check logs for `[SAML Setup] Account ID:`
2. **Redirect to /auth/sign_in instead of /app/login**
- The SAML response wasn't processed correctly
- Check if the user exists with that email
3. **404 on callback**
- The route isn't configured properly
- Run `rails routes | grep saml` to verify
### Manual SAML Response Test:
If you want to test just the callback with a SAML response from MockSAML:
1. Use browser developer tools to intercept the POST to `/omniauth/saml/callback`
2. Copy the SAMLResponse parameter
3. Use the test script to send it:
```ruby
# save_as: test_saml_callback.rb
require 'net/http'
require 'uri'
saml_response = "PASTE_YOUR_SAML_RESPONSE_HERE"
callback_url = "http://localhost:3000/omniauth/saml/callback?account_id=1"
uri = URI(callback_url)
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Post.new(uri)
request['Content-Type'] = 'application/x-www-form-urlencoded'
request.body = URI.encode_www_form({
'SAMLResponse' => saml_response,
'RelayState' => ''
})
response = http.request(request)
puts "Status: #{response.code}"
puts "Location: #{response['location']}" if response['location']
```
## 6. Test Different Scenarios
### Existing User Login:
- Use email of existing user (e.g., `john@acme.inc`)
- Should redirect with SSO token
### New User (if enabled):
- Use new email address
- Should redirect to password setup page (if account signup is enabled)
### SAML Disabled:
- Disable SAML in settings and try again
- Should show error message
-42
View File
@@ -1,42 +0,0 @@
#!/usr/bin/env ruby
# Run with: rails runner update_mocksaml_certificate.rb
# The certificate from the MockSAML response
mocksaml_certificate = <<~CERT
-----BEGIN CERTIFICATE-----
MIIC4jCCAcoCCQC33wnybT5QZDANBgkqhkiG9w0BAQsFADAyMQswCQYDVQQGEwJV
SzEPMA0GA1UECgwGQm94eUhRMRIwEAYDVQQDDAlNb2NrIFNBTUwwIBcNMjIwMjI4
MjE0NjM4WhgPMzAyMTA3MDEyMTQ2MzhaMDIxCzAJBgNVBAYTAlVLMQ8wDQYDVQQK
DAZCb3h5SFExEjAQBgNVBAMMCU1vY2sgU0FNTDCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBALGfYettMsct1T6tVUwTudNJH5Pnb9GGnkXi9Zw/e6x45DD0
RuRONbFlJ2T4RjAE/uG+AjXxXQ8o2SZfb9+GgmCHuTJFNgHoZ1nFVXCmb/Hg8Hpd
4vOAGXndixaReOiq3EH5XvpMjMkJ3+8+9VYMzMZOjkgQtAqO36eAFFfNKX7dTj3V
pwLkvz6/KFCq8OAwY+AUi4eZm5J57D31GzjHwfjH9WTeX0MyndmnNB1qV75qQR3b
2/W5sGHRv+9AarggJkF+ptUkXoLtVA51wcfYm6hILptpde5FQC8RWY1YrswBWAEZ
NfyrR4JeSweElNHg4NVOs4TwGjOPwWGqzTfgTlECAwEAATANBgkqhkiG9w0BAQsF
AAOCAQEAAYRlYflSXAWoZpFfwNiCQVE5d9zZ0DPzNdWhAybXcTyMf0z5mDf6FWBW
5Gyoi9u3EMEDnzLcJNkwJAAc39Apa4I2/tml+Jy29dk8bTyX6m93ngmCgdLh5Za4
khuU3AM3L63g7VexCuO7kwkjh/+LqdcIXsVGO6XDfu2QOs1Xpe9zIzLpwm/RNYeX
UjbSj5ce/jekpAw7qyVVL4xOyh8AtUW1ek3wIw1MJvEgEPt0d16oshWJpoS1OT8L
r/22SvYEo3EmSGdTVGgk3x3s+A0qWAqTcyjr7Q4s/GKYRFfomGwz0TZ4Iw1ZN99M
m0eo2USlSRTVl7QHRTuiuSThHpLKQQ==
-----END CERTIFICATE-----
CERT
# Find SAML settings for account 1
saml_settings = AccountSamlSettings.find_by(account_id: 1)
if saml_settings
puts "Current fingerprint: #{saml_settings.certificate_fingerprint}"
# Update with MockSAML certificate
saml_settings.certificate = mocksaml_certificate
saml_settings.save!
puts "Updated fingerprint: #{saml_settings.reload.certificate_fingerprint}"
puts ""
puts "SAML settings updated successfully!"
puts "The certificate has been updated to match MockSAML."
else
puts "No SAML settings found for account 1"
end