Skip to content

Fix Graph URL tokenization for parenthesized segments - #2043

Open
waldekmastykarz wants to merge 2 commits into
dotnet:mainfrom
waldekmastykarz:graph-tokenized-urls
Open

waldekmastykarz wants to merge 2 commits into
dotnet:mainfrom
waldekmastykarz:graph-tokenized-urls

Conversation

@waldekmastykarz

@waldekmastykarz waldekmastykarz commented Oct 31, 2026 •

Copy link
Copy Markdown
Collaborator

Closes #2041

GraphUtils.GetTokenizedUrl (via ProxyUtils.SanitizeUrl) threw ArgumentOutOfRangeException for any Graph URL with a parenthesized segment, so the Graph permissions plugins skipped those requests.

Changes

  • Fix the substring bug: the text inside the parentheses was extracted with the wrong length, so every key or function segment threw (users('id'), applications(appId='…'), delta()).

  • Widen the function regex: it now accepts digits, _ and . in the name (getOffice365ActiveUserDetail, microsoft.graph.…). Previously these segments fell through to {reports-id}.

  • Empty parentheses are kept as-is (delta()).

  • Quote-aware parameter parsing: , and = inside OData quoted literals no longer split parameters.

  • Positional segment sanitization: each path segment is now sanitized separately and the segments are rejoined. Previously a global string.Replace let earlier IDs corrupt later segments. For example, …/items/1/getActivitiesByInterval(startDateTime='2017-01-01') became '20{items-id}7-…', and /sites/root/lists/1/items/1 became /lists/{lists-id}/items/{lists-id}.

  • Delegated user-scope correction: GraphUtils.UpdateUserScopesAsync now also treats /users(<value>) endpoints as other-user endpoints, so they get the same scope correction as /users/{users-id}.

Tokenized format

The output keeps the format the existing code was designed for: users(<value>), fn(key=<value>), delta(). I checked it against https://graph-devx-api.microsoft.com/permissions (POST). It resolves /users(<value>), /applications(appId=<value>), /devices(deviceId=<value>) and /me/drive/recent(). The reports/get* functions return "not found" in every format I tried (<value>, {period}, 'D7', and others). That's a gap in the DevX data, not a tokenization problem.

Tests

Added GraphUtilsTests cases for key-in-parentheses, functions with parameters (including quoted commas/equals and escaped quotes), namespaced functions and repeated segment values. Added an UpdateUserScopesAsync test that uses a fake HttpClient and covers both user-key shapes.

…2041

- Fix out-of-range Substring when extracting text within parentheses,
  which made every key/function segment (e.g. users('id')) throw
- Match function names containing digits, underscores and dots
  (e.g. getOffice365ActiveUserDetail, microsoft.graph.delta)
- Keep empty parentheses as-is (delta())
- Split parameters outside OData quoted literals
- Sanitize path segments positionally instead of using a global
  string replace, which corrupted later segments with the same value

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 31, 2026 15:30
@waldekmastykarz
waldekmastykarz requested a review from a team as a code owner October 31, 2026 15:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Parenthesized user-key URLs bypass delegated-scope correction in both minimal-permissions plugins, requiring an expanded endpoint filter and a permission-calculation regression test.

1 open issue
What changed in this PR

Fixes parenthesized Microsoft Graph URL tokenization so permissions plugins can process key and function segments without exceptions.

Changes:

  • Corrects parameter extraction and supports digits, underscores, and namespaces in function names.
  • Preserves empty parentheses and handles separators inside quoted OData values.
  • Sanitizes path segments independently and adds regression tests.
File Description
DevProxy.Integration.Tests/​GraphUtilsTests.cs Adds coverage for parenthesized keys, functions, quoted parameters, and repeated IDs.
DevProxy.Abstractions/​Utils/​ProxyUtils.cs Fixes parenthesized-segment parsing and prevents cross-segment replacements.

Review effort: Balanced

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

There are no active review issues for the Microsoft Graph URL tokenization and delegated-scope changes.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GetTokenizedUrl fails on parenthesized Graph URL segments

2 participants