Skip to content
This repository was archived by the owner on Apr 13, 2025. It is now read-only.

Commit 371767f

Browse files
authored
Merge pull request #2 from molecul/main
Implement correct iteraction with Steam OAuth and Steam OpenId
2 parents f1920cc + 23b1805 commit 371767f

File tree

6 files changed

+198
-19
lines changed

6 files changed

+198
-19
lines changed

ASFOAuth/ASFOAuth.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -153,12 +153,20 @@ public Task OnLoaded()
153153
{
154154
//Core
155155
"OAUTH" or
156-
"O" when argLength == 3 && access >= EAccess.Master =>
156+
"OA" when argLength == 3 && access >= EAccess.Master =>
157157
Core.Command.OAuth(args[1], args[2]),
158158

159159
"OAUTH" or
160-
"O" when argLength == 2 && access >= EAccess.Master =>
160+
"OA" when argLength == 2 && access >= EAccess.Master =>
161161
Core.Command.OAuth(bot, args[1]),
162+
163+
"OPENID" or
164+
"OP" when argLength == 3 && access >= EAccess.Master =>
165+
Core.Command.OpenId(args[1], args[2]),
166+
167+
"OPENID" or
168+
"OP" when argLength == 2 && access >= EAccess.Master =>
169+
Core.Command.OpenId(bot, args[1]),
162170

163171
_ => null,
164172
},

ASFOAuth/Core/Command.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,24 @@ internal static class Command
2424
}
2525
return await OAuth(bot, url).ConfigureAwait(false);
2626
}
27+
28+
internal static async Task<string?> OpenId(Bot bot, string url)
29+
{
30+
if (!bot.IsConnectedAndLoggedOn)
31+
{
32+
return bot.FormatBotResponse(Strings.BotNotConnected);
33+
}
34+
var response = await WebRequest.LoginViaSteamOpenId(bot, url).ConfigureAwait(false);
35+
return bot.FormatBotResponse(response);
36+
}
37+
38+
internal static async Task<string?> OpenId(string botName, string url)
39+
{
40+
var bot = Bot.GetBot(botName);
41+
if (bot == null)
42+
{
43+
return Utils.FormatStaticResponse(string.Format(Strings.BotNotFound, botName));
44+
}
45+
return await OpenId(bot, url).ConfigureAwait(false);
46+
}
2747
}

ASFOAuth/Core/WebRequest.cs

Lines changed: 63 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,21 @@ namespace ASFOAuth.Core;
77
internal static partial class WebRequest
88
{
99
[GeneratedRegex(@"(?:(openid\.[a-z_.]+)=([^&]+))")]
10-
private static partial Regex MatchQueries();
10+
private static partial Regex OpenIdMatchQueries();
11+
12+
[GeneratedRegex(@"(?:([a-z_.]+)=([^&]+))")]
13+
private static partial Regex OAuthMatchQueries();
1114

1215
/// <summary>
13-
/// Steam OAuth登录
16+
/// Steam OpenId登录
1417
/// </summary>
1518
/// <param name="bot"></param>
1619
/// <param name="url"></param>
1720
/// <returns></returns>
18-
internal static async Task<string> LoginViaSteamOAuth(Bot bot, string url)
21+
internal static async Task<string> LoginViaSteamOpenId(Bot bot, string url)
1922
{
20-
var regex = MatchQueries();
23+
24+
var regex = OpenIdMatchQueries();
2125
var matches = regex.Matches(url);
2226

2327
var queries = new List<string>();
@@ -28,7 +32,7 @@ internal static async Task<string> LoginViaSteamOAuth(Bot bot, string url)
2832

2933
if (queries.Count == 0)
3034
{
31-
return "OAuth链接无效";
35+
return "OpenId链接无效";
3236
}
3337

3438
var request = new Uri(SteamCommunityURL, "/openid/login?" + string.Join('&', queries));
@@ -37,7 +41,7 @@ internal static async Task<string> LoginViaSteamOAuth(Bot bot, string url)
3741
var eles = response?.Content?.QuerySelectorAll("#openidForm>input[name][value]");
3842
if (eles == null)
3943
{
40-
return "网络错误或OAuth链接无效";
44+
return "网络错误或OpenId链接无效";
4145
}
4246

4347
var formData = new Dictionary<string, string>();
@@ -54,6 +58,59 @@ internal static async Task<string> LoginViaSteamOAuth(Bot bot, string url)
5458
request = new Uri(SteamCommunityURL, "/openid/login");
5559
var response2 = await bot.ArchiWebHandler.UrlPostToHtmlDocumentWithSession(request, data: formData, requestOptions: WebBrowser.ERequestOptions.ReturnRedirections).ConfigureAwait(false);
5660

61+
return response2?.FinalUri.ToString() ?? "登录失败";
62+
}
63+
64+
/// <summary>
65+
/// Steam OAuth登录
66+
/// </summary>
67+
/// <param name="bot"></param>
68+
/// <param name="url"></param>
69+
/// <returns></returns>
70+
internal static async Task<string> LoginViaSteamOAuth(Bot bot, string url)
71+
{
72+
73+
var regex = OAuthMatchQueries();
74+
var matches = regex.Matches(url);
75+
76+
var queries = new List<string>();
77+
foreach (var match in matches.ToList())
78+
{
79+
queries.Add(match.Value);
80+
}
81+
82+
if (queries.Count == 0)
83+
{
84+
return "OAuth链接无效";
85+
}
86+
87+
var request = new Uri(SteamCommunityURL, "/oauth/login?" + string.Join('&', queries));
88+
var response = await bot.ArchiWebHandler.UrlGetToHtmlDocumentWithSession(request).ConfigureAwait(false);
89+
var eles = response?.Content?.QuerySelectorAll("#openidForm>input[name][value]");
90+
if (eles == null)
91+
{
92+
return "网络错误或OAuth链接无效";
93+
}
94+
95+
var formData = new Dictionary<string, string>();
96+
foreach (var ele in eles)
97+
{
98+
var name = ele.GetAttribute("name");
99+
var value = ele.GetAttribute("value");
100+
if (!string.IsNullOrEmpty(name) && !string.IsNullOrEmpty(value))
101+
{
102+
formData.Add(name, value);
103+
}
104+
}
105+
106+
if (!formData.GetValueOrDefault("action", "").Equals("steam_openid_login"))
107+
{
108+
return "网络错误或OAuth链接无效";
109+
}
110+
111+
request = new Uri(SteamCommunityURL, "/oauth/auth");
112+
var response2 = await bot.ArchiWebHandler.UrlPostToHtmlDocumentWithSession(request, data: formData, requestOptions: WebBrowser.ERequestOptions.ReturnRedirections).ConfigureAwait(false);
113+
57114
return response2?.FinalUri.ToString() ?? "登录失败";
58115
}
59116
}

ASFOAuth/IPC/ASFOAuthController.cs

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,22 @@ public sealed record OAuthResponse
2626
public string? LoginUrl { get; set; }
2727
}
2828

29+
public sealed record OpenIdRequest
30+
{
31+
[JsonInclude]
32+
[JsonRequired]
33+
public string? BotName { get; set; }
34+
[JsonInclude]
35+
[JsonRequired]
36+
public string? OpenIdUrl { get; set; }
37+
}
38+
39+
public sealed record OpenIdResponse
40+
{
41+
public bool Success { get; set; }
42+
public string? LoginUrl { get; set; }
43+
}
44+
2945
/// <summary>
3046
/// 基础控制器
3147
/// </summary>
@@ -106,4 +122,80 @@ public async Task<ActionResult<GenericResponse>> Oauth([FromRoute] string botNam
106122

107123
return Ok(new GenericResponse<OAuthResponse>(response));
108124
}
125+
126+
/// <summary>
127+
/// Steam登录
128+
/// </summary>
129+
/// <param name="request"></param>
130+
/// <returns></returns>
131+
/// <exception cref="ArgumentNullException"></exception>
132+
[HttpPost("OpenId")]
133+
[SwaggerOperation(Summary = "Steam登录", Description = "通过SteamOpenId登录第三方网站")]
134+
[SwaggerResponse((int)HttpStatusCode.BadRequest, $"The request has failed, check {nameof(GenericResponse.Message)} from response body for actual reason. Most of the time this is ASF, understanding the request, but refusing to execute it due to provided reason.", typeof(GenericResponse))]
135+
[ProducesResponseType(typeof(GenericResponse<OpenIdResponse>), (int)HttpStatusCode.OK)]
136+
[ProducesResponseType(typeof(GenericResponse), (int)HttpStatusCode.BadRequest)]
137+
public async Task<ActionResult<GenericResponse>> OpenId([FromBody] OpenIdRequest request)
138+
{
139+
if (request == null)
140+
{
141+
throw new ArgumentNullException(nameof(request));
142+
}
143+
144+
if (string.IsNullOrEmpty(request.BotName) || string.IsNullOrEmpty(request.OpenIdUrl))
145+
{
146+
return BadRequest(new GenericResponse(false, "BotName or OpenIdUrl can not be null"));
147+
}
148+
149+
var bot = Bot.GetBot(request.BotName);
150+
if (bot == null)
151+
{
152+
return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.BotNotFound, request.BotName)));
153+
}
154+
155+
var result = await Core.WebRequest.LoginViaSteamOpenId(bot, request.OpenIdUrl).ConfigureAwait(false);
156+
157+
var response = new OpenIdResponse
158+
{
159+
Success = result.StartsWith("https"),
160+
LoginUrl = result,
161+
};
162+
163+
return Ok(new GenericResponse<OpenIdResponse>(response));
164+
}
165+
166+
[HttpGet("OpenId/{botName:required}/{OpenIdUrl:required}")]
167+
[HttpPost("OpenId/{botName:required}/{OpenIdUrl:required}")]
168+
[SwaggerOperation(Summary = "Steam登录", Description = "通过SteamOpenId登录第三方网站")]
169+
[SwaggerResponse((int)HttpStatusCode.BadRequest, $"The request has failed, check {nameof(GenericResponse.Message)} from response body for actual reason. Most of the time this is ASF, understanding the request, but refusing to execute it due to provided reason.", typeof(GenericResponse))]
170+
[ProducesResponseType(typeof(GenericResponse<OpenIdResponse>), (int)HttpStatusCode.OK)]
171+
[ProducesResponseType(typeof(GenericResponse), (int)HttpStatusCode.BadRequest)]
172+
public async Task<ActionResult<GenericResponse>> OpenId([FromRoute] string botName, [FromRoute] string OpenIdUrl)
173+
{
174+
if (string.IsNullOrEmpty(botName))
175+
{
176+
throw new ArgumentNullException(nameof(botName));
177+
}
178+
179+
var bot = Bot.GetBot(botName);
180+
if (bot == null)
181+
{
182+
return BadRequest(new GenericResponse(false, string.Format(CultureInfo.CurrentCulture, Strings.BotNotFound, botName)));
183+
}
184+
185+
if (string.IsNullOrEmpty(OpenIdUrl))
186+
{
187+
return BadRequest(new GenericResponse(false, "OpenIdUrl can not be null"));
188+
}
189+
190+
var result = await Core.WebRequest.LoginViaSteamOpenId(bot, OpenIdUrl).ConfigureAwait(false);
191+
192+
var response = new OpenIdResponse
193+
{
194+
Success = result.StartsWith("https"),
195+
LoginUrl = result,
196+
};
197+
198+
return Ok(new GenericResponse<OpenIdResponse>(response));
199+
}
200+
109201
}

Directory.Build.props

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<Project>
22
<PropertyGroup>
3-
<Version>1.3.0.0</Version>
3+
<Version>1.3.0.1</Version>
44
</PropertyGroup>
55

66
<PropertyGroup>

README.md

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,14 @@
3737
3838
### 更新日志
3939

40-
| ASFOAuth 版本 | 适配 ASF 版本 | 更新说明 |
41-
| ------------------------------------------------------------------ | :-----------: | -------------------------------- |
42-
| [1.3.0.0](https://github.com/chr233/ASFOAuth/releases/tag/1.3.0.0) | 6.0.0.3 | ASF -> 6.0.0.3 |
43-
| [1.2.0.0](https://github.com/chr233/ASFOAuth/releases/tag/1.2.0.0) | 5.5.0.11 | ASF -> 5.5.0.11 |
44-
| [1.1.0.0](https://github.com/chr233/ASFOAuth/releases/tag/1.1.0.0) | 5.4.12.5 | ASF -> 5.4.12.5, 接入 ASFEnhance |
45-
| [1.0.1.0](https://github.com/chr233/ASFOAuth/releases/tag/1.0.1.0) | 5.4.8.3 | ASF -> 5.4.8.3 |
46-
| [1.0.0.2](https://github.com/chr233/ASFOAuth/releases/tag/1.0.0.2) | 5.4.5.2 | 第一个版本 |
40+
| ASFOAuth 版本 | 适配 ASF 版本 | 更新说明 |
41+
|--------------------------------------------------------------------| :-----------: | --------------------------------------------- |
42+
| [1.3.0.1](https://github.com/chr233/ASFOAuth/releases/tag/1.3.0.0) | 6.0.0.3 | 与 Steam OAuth 和 Steam OpenId 实现正确的交互 |
43+
| [1.3.0.0](https://github.com/chr233/ASFOAuth/releases/tag/1.3.0.0) | 6.0.0.3 | ASF -> 6.0.0.3 |
44+
| [1.2.0.0](https://github.com/chr233/ASFOAuth/releases/tag/1.2.0.0) | 5.5.0.11 | ASF -> 5.5.0.11 |
45+
| [1.1.0.0](https://github.com/chr233/ASFOAuth/releases/tag/1.1.0.0) | 5.4.12.5 | ASF -> 5.4.12.5, 接入 ASFEnhance |
46+
| [1.0.1.0](https://github.com/chr233/ASFOAuth/releases/tag/1.0.1.0) | 5.4.8.3 | ASF -> 5.4.8.3 |
47+
| [1.0.0.2](https://github.com/chr233/ASFOAuth/releases/tag/1.0.0.2) | 5.4.5.2 | 第一个版本 |
4748

4849
## 插件配置说明
4950

@@ -82,6 +83,7 @@ ASF.json
8283

8384
### 功能指令
8485

85-
| 命令 | 缩写 | 权限 | 说明 |
86-
| ----------------- | ---- | -------- | ------------------------------------------------------------------------- |
87-
| `OAUTH [Bot] Uri` | `O` | `Master` | 自动使用机器人身份通过 SteamOpenId 登录第三方网站, 返回跳转回第三方的网址 |
86+
| 命令 | 缩写 | 权限 | 说明 |
87+
|--------------------|------|----------|------------------------------------------------------------------------------|
88+
| `OAUTH [Bot] Uri` | `OA` | `Master` | 自动使用机器人身份通过 SteamOAuth 登录第三方网站 , 返回跳转回第三方的网址 |
89+
| `OPENID [Bot] Uri` | `OP` | `Master` | 自动使用机器人身份通过 SteamOpenId 登录第三方网站 , 返回跳转回第三方的网址 |

0 commit comments

Comments
 (0)