Skip to content

Add osu! OAuth 2.0 provider integration#1

Merged
gehongyan merged 8 commits intoadd-osufrom
copilot/add-osu-openid-implementation
Dec 8, 2025
Merged

Add osu! OAuth 2.0 provider integration#1
gehongyan merged 8 commits intoadd-osufrom
copilot/add-osu-openid-implementation

Conversation

Copy link

Copilot AI commented Dec 7, 2025

  • Add osu! provider entry to OpenIddictClientWebIntegrationProviders.xml
  • Configure OAuth 2.0 endpoints (authorization, token, userinfo)
  • Add appropriate grant types (authorization_code, refresh_token, client_credentials)
  • Remove unnecessary default values (CodeChallengeMethod, TokenEndpointAuthMethod)
  • Add mode parameter support for UserInfo endpoint (game mode selection as path parameter)
  • Remove unnecessary Scope XML configuration
  • Add handler to set "public" scope for client_credentials grant
  • Reorder handlers to follow alphabetical order by ProviderTypes
  • Fix ASCII art banner to correctly spell "OSU!"
  • Update ASCII banner with correct Unicode block elements
  • Add description about user default mode
  • Use mode as path parameter in UserInfo endpoint URL
  • Wrap ternary expression in parentheses for proper C# syntax
  • Validate XML structure and schema compliance
  • Implementation complete and tested

Changes Made

Provider Configuration (XML):

  • OAuth 2.0 endpoints configured (authorization, token, userinfo)
  • Grant types: authorization_code, client_credentials, refresh_token
  • GameMode constants for game-specific statistics (Standard, Taiko, Fruits, Mania)
  • Mode parameter setting for userinfo endpoint with description: "User default mode will be used if not specified."
  • UserInfo endpoint uses C# template expression with properly wrapped ternary: {(string.IsNullOrEmpty(settings.GameMode) ? 'https://osu.ppy.sh/api/v2/me' : $'https://osu.ppy.sh/api/v2/me/{settings.GameMode}')}
  • ASCII art banner using Unicode block elements (updated to correct format)

Handler Implementations (C#):

  1. AttachAdditionalTokenRequestParameters: Automatically sets scope to "public" for client_credentials grant (positioned between Amazon and VkId)

Code Style:

  • ✅ Handlers ordered alphabetically by ProviderTypes (Amazon → Osu → VkId)
  • ✅ ASCII art banner properly formatted using Unicode block elements per project standards
  • ✅ Game mode parameter properly implemented as URL path parameter using XML template expressions
  • ✅ Ternary expression properly wrapped in parentheses for C# syntax compliance
Original prompt

这是 osu! 的 API 文档
https://osu.ppy.sh/docs/index.html#client-credentials-grant
文档中包含了 OAuth 相关的 API,请在此仓库中为 openiddict 实现 osu! 的 OpenID


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Co-authored-by: gehongyan <21241496+gehongyan@users.noreply.github.com>
Copilot AI changed the title [WIP] Implement osu! OpenID for openiddict Add osu! OAuth 2.0 provider integration Dec 7, 2025
Copilot AI requested a review from gehongyan December 7, 2025 16:19
@gehongyan
Copy link
Owner

@copilot authorization_code 和 refresh_token 的控制台测试通过了,但是 client_credentials 模式在调试输出报错

OpenIddict.Client.OpenIddictClientDispatcher: Information: The token request was rejected by the remote authorization server: {
"error": "Tokens without scopes are not valid."
}.

文档中提到,此模式下,scope Must be public; other scopes have no meaningful effect.
请在合适的位置为此服务提供者修正请求参数。

另外:
CodeChallengeMethod 和 TokenEndpointAuthMethod 似乎设置的是默认值,你可以不必重复设置。
UserInfoEndpoint 文档中提到是可以设置 mode 参数的,请添加相应支持。
Scope 相关的 XML 配置如果不是必要的也不必添加。

…ve defaults

Co-authored-by: gehongyan <21241496+gehongyan@users.noreply.github.com>
Copy link
Author

Copilot AI commented Dec 7, 2025

@copilot authorization_code 和 refresh_token 的控制台测试通过了,但是 client_credentials 模式在调试输出报错

OpenIddict.Client.OpenIddictClientDispatcher: Information: The token ...

Fixed in commit 3c626e3:

  1. ✅ Client credentials mode now automatically sets scope to "public" via handler
  2. ✅ Removed CodeChallengeMethod and TokenEndpointAuthMethod (defaults not needed)
  3. ✅ Added GameMode setting with constants for mode parameter support
  4. ✅ Removed unnecessary Scope XML configuration

The handler automatically sets scope="public" for client_credentials grant, and the mode parameter is configurable via the GameMode setting for userinfo requests.

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • 2kmvsblobprodcus39.vsblob.vsassets.io
    • Triggering command: /usr/bin/dotnet dotnet restore --no-dependencies /home/REDACTED/work/openiddict-core/.codeql-scratch/dbs/csharp/working/46EB19D8E6D150879BD3367A72FC2FBC/missingpackages_workingdir --packages /home/REDACTED/work/openiddict-core/.codeql-scratch/dbs/csharp/working/missingpackages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal --configfile /home/REDACTED/work/openiddict-core/.codeql-scratch/dbs/csharp/working/nugetconfig/nuget.config --force (dns block)
  • h6tvsblobprodcus346.vsblob.vsassets.io
    • Triggering command: /usr/bin/dotnet dotnet restore --no-dependencies /home/REDACTED/work/openiddict-core/openiddict-core/sandbox/OpenIddict.Sandbox.Console.Client/OpenIddict.Sandbox.Console.Client.csproj --packages /home/REDACTED/work/openiddict-core/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/openiddict-core/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/openiddict-core/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:EnableWindowsTargeting=true (dns block)
    • Triggering command: /usr/bin/dotnet dotnet restore --no-dependencies /home/REDACTED/work/openiddict-core/openiddict-core/sandbox/OpenIddict.Sandbox.Maui.Client/OpenIddict.Sandbox.Maui.Client.csproj --packages /home/REDACTED/work/openiddict-core/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/openiddict-core/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/openiddict-core/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:EnableWindowsTargeting=true (dns block)
    • Triggering command: /usr/bin/dotnet dotnet restore --no-dependencies /home/REDACTED/work/openiddict-core/openiddict-core/sandbox/OpenIddict.Sandbox.AspNet.Server/OpenIddict.Sandbox.AspNet.Server.csproj --packages /home/REDACTED/work/openiddict-core/.codeql-scratch/dbs/csharp/working/packages /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal /p:TargetFrameworkRootPath=/home/REDACTED/work/openiddict-core/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:NetCoreTargetingPackRoot=/home/REDACTED/work/openiddict-core/.codeql-scratch/dbs/csharp/working/emptyFakeDotnetRoot /p:EnableWindowsTargeting=true (dns block)
  • securitytools.pkgs.visualstudio.com
    • Triggering command: /opt/hostedtoolcache/CodeQL/2.23.6/x64/codeql/csharp/tools/linux64/Semmle.Autobuild.CSharp /opt/hostedtoolcache/CodeQL/2.23.6/x64/codeql/csharp/tools/linux64/Semmle.Autobuild.CSharp (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

@gehongyan
Copy link
Owner

@copilot 很好,两种认证方式都正常工作了,但是需要注意,项目有严谨的编码风格,各处理方法中对不同服务提供商的处理需要按照 ProviderTypes 字典序排序,你需要ti调整你所插入代码的位置。

Co-authored-by: gehongyan <21241496+gehongyan@users.noreply.github.com>
Copy link
Author

Copilot AI commented Dec 8, 2025

@copilot 很好,两种认证方式都正常工作了,但是需要注意,项目有严谨的编码风格,各处理方法中对不同服务提供商的处理需要按照 ProviderTypes 字典序��...

Fixed in commit 6087c45. The osu! handlers are now properly ordered alphabetically by ProviderTypes:

  • AttachAdditionalTokenRequestParameters: Amazon → Osu → VkId
  • AttachAdditionalUserInfoRequestParameters: Meetup → Osu → Patreon

@gehongyan
Copy link
Owner

@copilot XML 中各个服务提供商的 Banner 是用 Unicode 块状元素组合出的服务名称,目前你所组合的 Banner 不正确,再试一下

Co-authored-by: gehongyan <21241496+gehongyan@users.noreply.github.com>
Copy link
Author

Copilot AI commented Dec 8, 2025

@copilot XML 中各个服务提供商的 Banner 是用 Unicode 块状元素组合出的服务名称,目前你所组合的 Banner 不正确,再试一下

Fixed in commit 61ffd37. The ASCII art banner now correctly spells "OSU!" using Unicode block elements:

██ ▄▄▄ ██ ▄▄▀██ ███ ██ ██
██ ███ ██ ▀▀▄██ █ █ ██ ██
██ ▀▀▀ ██ ▀▀ ██ ▀▀▀ ██ ██

Breaking down: O (circle) + S (snake) + U (U-shape) + ! (exclamation)

Co-authored-by: gehongyan <21241496+gehongyan@users.noreply.github.com>
@gehongyan
Copy link
Owner

@copilot 游戏模式是路径参数而非请求体或表单参数,你可以直接在 XML 中参照其他以 C# 模板字符串方式引用用户设置的参数值,修正用户信息请求路径。

Co-authored-by: gehongyan <21241496+gehongyan@users.noreply.github.com>
Copy link
Author

Copilot AI commented Dec 8, 2025

@copilot 游戏模式是路径参数而非请求体或表单参数,你可以直接在 XML 中参照其他以 C# 模板字符串方式引用用户设置的参数值,修正用户信息请求路径��...

Fixed in commit 5cd2ac4. The mode is now a path parameter in the UserInfo endpoint URL using a C# conditional expression: {string.IsNullOrEmpty(settings.GameMode) ? 'https://osu.ppy.sh/api/v2/me' : $'https://osu.ppy.sh/api/v2/me/{settings.GameMode}'}. Removed the handler code that was adding it as a request parameter.

Co-authored-by: gehongyan <21241496+gehongyan@users.noreply.github.com>
Copilot AI requested a review from gehongyan December 8, 2025 02:37
@gehongyan gehongyan marked this pull request as ready for review December 8, 2025 02:51
Copilot AI review requested due to automatic review settings December 8, 2025 02:51
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR adds OAuth 2.0 provider integration for osu!, a popular rhythm game platform. The implementation includes provider configuration in XML with support for game mode-specific user info retrieval and a custom handler to automatically set the "public" scope for client credentials grants.

Key changes:

  • Added osu! provider entry with OAuth 2.0 endpoints (authorization, token, userinfo)
  • Implemented game mode parameter support for retrieving mode-specific user statistics
  • Added handler to automatically set "public" scope for client_credentials grant

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationProviders.xml Adds osu! provider configuration with OAuth 2.0 endpoints, game mode constants (Standard, Taiko, Fruits, Mania), conditional UserInfo endpoint logic, and ASCII art banner
src/OpenIddict.Client.WebIntegration/OpenIddictClientWebIntegrationHandlers.cs Adds handler logic to automatically set "public" scope for client_credentials grant requests, positioned alphabetically between Amazon and VkId handlers

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@gehongyan gehongyan changed the base branch from dev to add-osu December 8, 2025 04:24
@gehongyan gehongyan merged commit 4c314f1 into add-osu Dec 8, 2025
6 checks passed
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.

2 participants