AtProtoScopes.Repo silently widens RepoAction.None to a full write grant #94
Labels
No labels
breaking-change
bug
documentation
duplicate
enhancement
good first issue
help wanted
performance
question
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Grandiras/ATProto.NET#94
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
AppendRepoActionsinsrc/ATProtoNet/Auth/OAuth/AtProtoScopes.cs:567returns early for bothRepoAction.AllandRepoAction.None:Since an omitted
action=list means the full default set in the scope grammar,AtProtoScopes.Repo("app.bsky.feed.post", RepoAction.None)returnsrepo:app.bsky.feed.post— a grant of create + update + delete, the exact opposite of what the caller asked for. It affects bothRepo(string, RepoAction)(line 202) andRepo(IReadOnlyList<string>, RepoAction)(line 219).This is the same defect that was just fixed for
AtProtoScopes.Space(...)on PR #90, whereSpaceAction.Nonenow throws anArgumentExceptionbecause the grammar has no way to express an empty action list. It was left out of that PR becauseRepois shipped public API and changing it from "returns a string" to "throws" is a binary-compatible but behaviourally breaking change that needs its ownBreaking changesCHANGELOG entry.Suggested fix: throw
ArgumentException(nameof(actions))forRepoAction.Nonein both overloads, add a test, and note the change underBreaking changes.Filed by Claude while working on #90 (run).
🤖 On it — follow along in the action run; the reply will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the task runs.
Fixed and pushed to
claude/issue-94.What changed
AppendRepoActions(src/ATProtoNet/Auth/OAuth/AtProtoScopes.cs) treatedRepoAction.NoneandRepoAction.Allidentically — both emitted noaction=list. Since an omitted list means the full default set in the scope grammar,AtProtoScopes.Repo("app.bsky.feed.post", RepoAction.None)handed backrepo:app.bsky.feed.post: a create + update + delete grant, the opposite of what the caller asked for.RepoAction.Nonenow throwsArgumentException(ParamName=actions), mirroring whatSpace(...)does forSpaceAction.None. The guard sits in the shared helper rather than in each entry point, so it coversRepo(string, RepoAction),Repo(IReadOnlyList<string>, RepoAction), and the one-element list that delegates between them — all three are pinned by tests.RepoAction.Alland every partial combination are untouched.The two
Repooverloads gained<exception>tags and anactionsparameter note, and theRepoAction.Noneenum member now says it is rejected. I also updatedSpaceAction.None's summary:Space(...)has thrown for it since #90, but the member still read "No specific action", which is now the same trap for the next reader.CHANGELOG gets a new
### Breaking changessection under[Unreleased]with the migration note — a caller passingRepoAction.Nonewas silently requesting full write access, so the fix is to drop therepo:scope entirely or name the narrowest action actually needed.Verified
dotnet build src/ATProtoNet/ATProtoNet.csproj— 0 warnings, 0 errors.dotnet test tests/ATProtoNet.Tests/— 1514 passed, 0 failed, 5 skipped (the pre-existing Aspire manifest skips).A full-solution
dotnet buildfails in this container onsamples/ManagedPdsSample.AppHost, which can't resolve theAspire.AppHost.Sdkpackage from nuget.org — a sandbox network limitation unrelated to this change, and not a project my diff touches. The canonical pre-merge check (the unit test project) runs clean.⏱ 2m 55s · 21 turns · tokens: 41.4k in / 9.0k out (+912.6k cache-read)
📜 Full session transcript
→ Opened PR: #95