Add XblTestAccount tool and silent test account authentication - #139
Add XblTestAccount tool and silent test account authentication#139Jon Martin (jonmartinms) wants to merge 6 commits into
Conversation
Reuse a cached XSTS token, then a silently refreshed MSA token, before falling back to interactive sign in, so a test account can be used from a script or an automated build with no UI. Persist the last signed in test account to a lastTestUser cache file and add SignOutTestAccount to clear it. Add forceRefresh overloads of GetTestTokenSilentlyAsync and a new GetTestAccountSilentlyAsync, so callers can mint a new token to observe a privilege or privacy change and to recover from the service rejecting a token issued before such a change. Make the token cache tolerate entries with no "enm" claim, which test account XSTS tokens do not carry, and resolve MSAL accounts with FirstOrDefault so a duplicate cache entry cannot make silent auth throw. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ba5c5086-7199-4fde-be11-88b6942afc7c
XblTestAccount signs in an Xbox Live test account and caches the credential, then reads and changes the privileges and privacy settings of that account. It is the command line equivalent of the Privacy and Privilege tabs in XblTestAccountGui. Verbs: signin, signout, show, privilege, list-privileges, privacy and list-privacy-settings. The privilege action is a positional word (get, block or allow) rather than an option, and both it and the privacy value are parsed by name only, so a numeric argument cannot select a member by ordinal and silently perform the wrong write. Only 185 and 254 can be blocked or allowed directly, so the tool refuses other ids up front rather than surfacing the bare HTTP 400 the service returns. Privileges the service derives from a privacy setting are reported as such, and the error points at the setting that controls them. The parental and privacy services require a user XSTS token, so requests are issued directly rather than through XboxLiveHttpRequest, which attaches a Partner Center eToken. Changing a privilege invalidates the token the call was made with, so a 401 is retried once with a freshly minted token. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ba5c5086-7199-4fde-be11-88b6942afc7c
Document the XblTestAccount verbs in the README, and note that signing test accounts in beforehand lets XblPlayerDataReset run unattended. Cover test account sign in, the silent and cached paths, and sign out in AuthTest. Clear both token caches during test setup: the caches are written to disk and outlive the run, and SignOut only drops tokens whose "enm" claim matches the signed in user name, which the mocked account never does, so a token cached by one test would otherwise be served to the next and make the results depend on the order the tests run in. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: ba5c5086-7199-4fde-be11-88b6942afc7c
Register the new tool for release and match the style used by the other command line tools. - Add XblTestAccount.exe to signConfig.xml so it is Authenticode signed - Copy XblTestAccount.exe into ToolZip and Tools-VPack in postBuildScript - Write errors and warnings to stderr, matching XblConfig, GlobalStorage, XblConnectedStorage and XblPlayerDataReset - Add the UTF-8 BOM carried by every other source file in the repo - Drop an unused using and import Newtonsoft.Json rather than fully qualifying Formatting.None - Remove the unused single argument SignInTestAccountAsync overload - Mention test account support in the README capability list Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: fb12dba7-caf1-4def-9e64-bf611128fbe2
…er-tools into user/jonmartin/xbltestaccount
Use the same Fody and Costura versions and configuration as the other command-line projects to prevent mixed weaver assemblies during parallel solution builds. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 8048a542-e97b-44e1-8843-19912690da4b
| } | ||
| } | ||
|
|
||
| [Verb("list-privacy-settings", HelpText = "List the known Xbox Live privacy settings, their aliases and their values.")] |
There was a problem hiding this comment.
Maybe change to "list-privacy" to match "list-privileges"?
| /// </summary> | ||
| internal static class PrivacyNames | ||
| { | ||
| private static readonly Dictionary<string, string> DescriptionMapping = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase) |
There was a problem hiding this comment.
Why only these 4 are listed? There are many more that show up when using the "privacy" command:
AllowFollowers Everyone
AllowFriendInvites Everyone
AllowProfileViewing Everyone
AllowUserCreatedContentViewing Everyone
CollectVoiceData Blocked
CollectVoiceGameChatData Everyone
CollectVoiceSearchData Everyone
CollectXboxVideoData Everyone
CommunicateDuringCrossNetworkPlay Everyone
CommunicateUsingTextAndVoice Everyone
CommunicateUsingVideo PeopleOnMyList
ShareActivityFeed Everyone
ShareClubMembership Everyone
ShareContentToExternalNetworks Everyone
ShareFriendList Everyone
ShareGameHistory Everyone
ShareMusicHistory Everyone
SharePresence Everyone
ShareProfile PeopleOnMyList
ShareRecordedGameSessions Everyone
ShareVideoHistory Blocked
ShareXboxMusicActivity Everyone
Perhaps this isn't a useful feature?
| @@ -0,0 +1,26 @@ | |||
| // Copyright (c) Microsoft Corporation | |||
There was a problem hiding this comment.
Can we get this into something that isn't a separate file? It's the only enum broken out.
| } | ||
| } | ||
|
|
||
| Console.WriteLine($"Restricted privileges for {testAccount.Gamertag} ({xuid}):"); |
There was a problem hiding this comment.
A few things...
- For privacy, things are broken out to a PrivacyClient.cs, but Privilege is just baked into Program.cs
- In my usage, running
showlists all numeric privileges for a test account. Running withprivilegeonly shows restricted privileges and both are unknown. Runninglist-privilegesgives me a full list of all privileges. This is confusing... - Both
privacyandprivilegeallow setting/getting, but it's not at all obvious they have these features from the base usage of both...seems like they just list. - Instead of separate commands to list, how about just doing this in the
showcommand and changeprivacyandprivilegeto require an action?
Overall, just seems very confusing and the outputs are not what I'd expect...happy to discuss further on changing the way this works. The features are good, but they are not easily discoverable or usable IMO.
There was a problem hiding this comment.
Maybe show does the list of privacy and privilege, with the number and mapping. Then privilege and privacy take a 2nd action of listall, get, set followed by the appropriate args for 2nd action?
Is get useful if we have the modified show?
Summary
Adds XblTestAccount, a new command line tool for signing in Xbox Live test accounts and managing their privileges and privacy settings, plus the auth library work needed to make sign in silent and repeatable.
Previously a test account sign in required interactive UI on every invocation, which makes it awkward to use from scripts or automated test passes. This branch caches the credential so subsequent runs need no UI.
Auth library changes
ToolAuthentication/AuthClientgain silent test account support:SignInTestAccountAsyncnow tries, in order, a cached XSTS token, then a silent MSAL token, and only falls back to interactive sign in when both miss.LoadLastSignedInTestAccount,GetTestAccountSilentlyAsync,SignOutTestAccount,SaveLastSignedInTestAccount, plusforceInteractiveSignIn/forceRefreshoverloads for callers that need to bypass the cache.AuthTokenCacheandMsalTestAuthContextupdated to persist and retrieve the test account entry.New tool
CommandLine/XblTestAccountwith these verbs:signin/signout/showprivilegelist-privilegesprivacylist-privacy-settingsIt follows the conventions of the existing tools: same csproj/App.config/packages.config shape as
XblDevAccount, Costura/Fody single file exe, StyleCop clean, errors on stderr, registered insignConfig.xmlandpostBuildScript.cmdso it is signed and included in ToolZip and Tools-VPack.Dependencies
No new external dependencies. The tool references only Newtonsoft.Json 13.0.1, already used by
Microsoft.Xbox.Service.DevTools,XblConfig,SessionHistoryViewerand the unit tests. No version bumps.Tests
Four new cases in
AuthTest.cscover the silent path:SignInTestAccountSilentlyTest,SignInTestAccountFallsBackToInteractiveTest,SignInTestAccountReusesCachedXTokenTestandLoadLastSignedInTestAccountTest. All pass locally, along with the four pre-existingAuthTestcases.Also verified the built exe end to end against a live sandbox:
signin,show,list-privileges,list-privacy-settingsand a privilege change all behave as expected.Notes for reviewers
Two pre-existing issues surfaced while getting the test suite to run. Both predate this branch and are not addressed here, but are worth knowing about:
RichardSzalay.MockHttppackage binary is not strong named, so it fails to load at runtime. Separately, the library grantsInternalsVisibleTotoDynamicProxyGenAssembly2using the Microsoft shared key, while Castle DynamicProxy signs that generated assembly with its own key, so Moq cannot proxy the internalIAuthContext. I worked around both locally to validate the new tests.DevTools.CI.ymlbuilds, packs and publishes, but has no VSTest task, which is likely why the above went unnoticed.Happy to open a follow up for either if useful.
Also note that building
XblTestAccount.csprojon its own fails Fody weaving because Fody 3.x resolves weavers through$(SolutionDir). BuildXboxLiveTools.slninstead, as CI does.