tangled
alpha
login
or
join now
tsunagite.dev
/
tsunagite
1
fork
atom
A rhythm game net ranking service built on ATproto.
1
fork
atom
overview
issues
pulls
pipelines
ok it's now at least *half* working
LemmaEOF
2 months ago
33c18f2f
43d2e896
+30
-6
1 changed file
expand all
collapse all
unified
split
game-example
OAuth.cs
+30
-6
game-example/OAuth.cs
···
18
18
public TcpServer RedirectServer = new();
19
19
public string RedirectUri = $"http://{Binding}:{Port}";
20
20
21
21
-
public string ClientId = "client_XTcqz8gXODW6yDv-lf9KJg";
21
21
+
public const string ClientId = "client_lvRAJmPuwePq5oEqoFR_Ww";
22
22
+
//I have completely given up on using DPoP for this demo.
23
23
+
// THIS IS FOR DEMONSTRATION PURPOSES ONLY! DO NOT USE A CLIENT SECRET IN AN APP PLAYERS WILL DOWNLOAD!
24
24
+
//(this is bound to my localhost docker container so you can't use this secret in prod anyway)
25
25
+
private const string clientSecret = "8f03wNGkVL8oOqd1IUAZaYFUrZBQTIXoC2o8Wo6wXl8";
26
26
+
27
27
+
public bool Authorized = false;
22
28
23
29
public string Token;
24
30
private string refreshToken;
···
34
40
// Called when the node enters the scene tree for the first time.
35
41
public override void _Ready() {
36
42
SetProcess(false);
43
43
+
//InitialAuth();
37
44
}
38
45
39
46
// Called every frame. 'delta' is the elapsed time since the previous frame.
···
44
51
if (!String.IsNullOrEmpty(request)) {
45
52
SetProcess(false);
46
53
//TODO: this seems sus, will need to check for quickslice
47
47
-
string authCode = request.Split("&scope")[0].Split("=")[1];
54
54
+
GD.Print($"Request result: `{request}`");
55
55
+
string authCode = request.Split(" HTTP/1.1")[0].Split("=")[1];
56
56
+
GD.Print($"Parsed auth code: `{authCode}`");
48
57
GetTokenFromAuth(authCode);
49
58
50
59
connection.PutData("HTTP/1.1 200\r\n".ToAsciiBuffer());
51
60
//TODO: response page here
52
52
-
connection.PutData("".ToAsciiBuffer());
61
61
+
connection.PutData("Authentication complete!".ToAsciiBuffer());
53
62
RedirectServer.Stop();
54
63
}
55
64
}
56
65
}
57
66
67
67
+
public async void InitialAuth() {
68
68
+
LoadTokens();
69
69
+
70
70
+
if (!await IsTokenValid()) {
71
71
+
if (!await RefreshTokens()) {
72
72
+
Authorized = false;
73
73
+
return;
74
74
+
}
75
75
+
}
76
76
+
Authorized = true;
77
77
+
}
78
78
+
58
79
public async Task Authorize(string handle) {
59
80
LoadTokens();
60
81
···
67
88
68
89
private void GetAuthCode(string handle) {
69
90
SetProcess(true);
70
70
-
RedirectServer.Listen(Port, Binding);
71
91
Error err = RedirectServer.Listen(Port, Binding);
72
92
73
93
string[] bodyParts = [
74
94
$"client_id={ClientId}",
95
95
+
$"client_secret={clientSecret}",
75
96
$"redirect_uri={RedirectUri}",
76
97
$"response_type=code",
77
98
//TODO: code challenge?
78
99
$"login_hint={handle}",
79
79
-
$"scope=atproto transition:generic"
100
100
+
"scope=atproto transition:generic"
80
101
];
81
102
string url = $"{AuthUrl}?{bodyParts.Join("&")}";
82
103
···
92
113
string[] bodyParts = [
93
114
$"code={authCode}",
94
115
$"client_id={ClientId}",
116
116
+
$"client_secret={clientSecret}",
95
117
$"redirect_uri={RedirectUri}",
96
118
"grant_type=authorization_code"
97
119
];
···
121
143
];
122
144
string[] bodyParts = [
123
145
$"client_id={ClientId}",
146
146
+
$"client_secret={clientSecret}",
124
147
$"refresh_token={refreshToken}",
125
148
"grant_type=refresh_token"
126
149
];
···
145
168
return false;
146
169
}
147
170
171
171
+
//TODO: Quickslice doesn't have a way to get token info! Need to refactor to check expiry + stored issue time directly
148
172
private async Task<bool> IsTokenValid() {
149
173
GD.Print("Checking if tokens are valid");
150
174
if (string.IsNullOrEmpty(Token)) {
···
160
184
161
185
string body = $"access_token={Token}";
162
186
163
163
-
Error err = Request.Request(TokenUrl+"info", headers, HttpClient.Method.Post, body);
187
187
+
Error err = Request.Request(TokenUrl, headers, HttpClient.Method.Post, body);
164
188
165
189
if (err != Error.Ok) {
166
190
GD.PushError($"HTTP error {err} occured while trying to check auth token validity");