fix(microsoft-shared): drop CGI.escape on UPN; add scope+status logging on Graph access check
Two changes to debug the 'You don't have access' rejection in the
OAuth callback flow:
- Use literal '@' in the /users/{upn} path. Microsoft Graph accepts both
forms in most cases but the URL-encoded %40 form has been seen to fail
with 404 on some endpoints. Literal @ is more reliable.
- Log the actual HTTP status, response body (first 500 chars), and the
granted scopes from the access token's 'scp' claim. Makes future
debugging of permission/scope issues immediate from production.log
instead of a binary 'access denied' message.
Token decoding uses JWT.decode with verify=false — this is our own
token so verifying signature isn't useful here, we just inspect the scp
claim to confirm what scopes Microsoft actually granted.
This commit is contained in:
@@ -35,13 +35,31 @@ class MicrosoftShared::CallbacksController < ApplicationController
|
||||
end
|
||||
|
||||
def mailbox_accessible?
|
||||
response = Faraday.new(url: GRAPH_BASE_URL).get("/users/#{CGI.escape(@upn)}/mailFolders/inbox") do |req|
|
||||
response = Faraday.new(url: GRAPH_BASE_URL).get("/users/#{@upn}/mailFolders/inbox") do |req|
|
||||
req.headers['Authorization'] = "Bearer #{access_token}"
|
||||
end
|
||||
response.status == 200
|
||||
rescue StandardError => e
|
||||
Rails.logger.warn("Microsoft Shared mailbox access check failed: #{e.message}")
|
||||
|
||||
if response.status == 200
|
||||
Rails.logger.info("Microsoft Shared mailbox access verified: upn=#{@upn} granted_scopes=#{token_scopes.inspect}")
|
||||
return true
|
||||
end
|
||||
|
||||
Rails.logger.warn(
|
||||
"Microsoft Shared mailbox access denied: upn=#{@upn} status=#{response.status} " \
|
||||
"granted_scopes=#{token_scopes.inspect} body=#{response.body.to_s[0, 500]}"
|
||||
)
|
||||
false
|
||||
rescue StandardError => e
|
||||
Rails.logger.warn("Microsoft Shared mailbox access check raised: upn=#{@upn} #{e.class}: #{e.message}")
|
||||
false
|
||||
end
|
||||
|
||||
# Decode the JWT payload (without verifying signature — just inspecting our own token's scopes
|
||||
# for debugging purposes). Microsoft Graph access tokens are JWTs with scope info in `scp`.
|
||||
def token_scopes
|
||||
JWT.decode(access_token, nil, false).first['scp']
|
||||
rescue StandardError
|
||||
'unparseable'
|
||||
end
|
||||
|
||||
def create_channel_and_inbox
|
||||
|
||||
Reference in New Issue
Block a user