Skip to content

Commit 08675aa

Browse files
committed
Get user info after verify
1 parent c19ee58 commit 08675aa

File tree

4 files changed

+49
-16
lines changed

4 files changed

+49
-16
lines changed

Cargo.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

aiscript-runtime/src/config/sso.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ fn sso_extra_fields(provider: SsoProvider) -> HashMap<&'static str, serde_json::
3333
"token_url",
3434
"https://graph.facebook.com/v19.0/oauth/access_token".into(),
3535
),
36+
(
37+
"userinfo_url",
38+
"https://graph.facebook.com/v19.0/me?fields=id,name,email,first_name,last_name,picture".into(),
39+
),
3640
]
3741
.into_iter()
3842
.collect(),
@@ -45,12 +49,17 @@ fn sso_extra_fields(provider: SsoProvider) -> HashMap<&'static str, serde_json::
4549
"token_url",
4650
"https://www.googleapis.com/oauth2/v3/token".into(),
4751
),
52+
(
53+
"userinfo_url",
54+
"https://openidconnect.googleapis.com/v1/userinfo".into(),
55+
),
4856
]
4957
.into_iter()
5058
.collect(),
5159
SsoProvider::Discord => [
5260
("auth_url", "https://discord.com/oauth2/authorize".into()),
5361
("token_url", "https://discord.com/api/oauth2/token".into()),
62+
("userinfo_url", "https://discord.com/api/users/@me".into()),
5463
]
5564
.into_iter()
5665
.collect(),
@@ -63,6 +72,7 @@ fn sso_extra_fields(provider: SsoProvider) -> HashMap<&'static str, serde_json::
6372
"token_url",
6473
"https://github.com/login/oauth/access_token".into(),
6574
),
75+
("userinfo_url", "https://api.github.com/user".into()),
6676
]
6777
.into_iter()
6878
.collect(),

aiscript-vm/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ sqlx = { version = "0.8", features = [
3232
redis = "0.27.6"
3333
jsonwebtoken = "9.3"
3434
reqwest = "0.12"
35-
oauth2 = "5.0.0-rc.1"
35+
oauth2 = "5.0"
3636

3737
[features]
3838
# Enable debug features

aiscript-vm/src/builtins/sso.rs

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ struct AuthFields {
4343
client_secret: String,
4444
auth_url: String,
4545
token_url: String,
46+
userinfo_url: String,
4647
redirect_url: String,
4748
scopes: Vec<Scope>,
4849
}
@@ -74,6 +75,12 @@ fn parse_auth_fields(state: &mut State<'_>) -> Result<AuthFields, VmError> {
7475
.as_string()
7576
.unwrap()
7677
.to_string();
78+
let userinfo_url = fields
79+
.get(&state.intern_static("userinfo_url"))
80+
.unwrap()
81+
.as_string()
82+
.unwrap()
83+
.to_string();
7784
let redirect_url = fields
7885
.get(&state.intern_static("redirect_url"))
7986
.unwrap()
@@ -96,6 +103,7 @@ fn parse_auth_fields(state: &mut State<'_>) -> Result<AuthFields, VmError> {
96103
client_secret,
97104
auth_url,
98105
token_url,
106+
userinfo_url,
99107
redirect_url,
100108
scopes,
101109
})
@@ -161,26 +169,41 @@ fn verify<'gc>(state: &mut State<'gc>, args: Vec<Value<'gc>>) -> Result<Value<'g
161169
let code = code
162170
.ok_or_else(|| VmError::RuntimeError("verify() requires 'code' keyword argument".into()))?;
163171

164-
let fields = parse_auth_fields(state)?;
172+
let mut fields = parse_auth_fields(state)?;
173+
let userinfo_url = mem::take(&mut fields.userinfo_url);
165174

166175
let http_client = reqwest::ClientBuilder::new()
167176
// Following redirects opens the client up to SSRF vulnerabilities.
168177
.redirect(reqwest::redirect::Policy::none())
169178
.build()
170179
.expect("Client should build");
171180

172-
let token = match Handle::current().block_on(async {
173-
get_client(fields)
181+
Handle::current().block_on(async {
182+
let token = get_client(fields)
174183
.exchange_code(AuthorizationCode::new(code.to_string()))
175184
.request_async(&http_client)
176185
.await
177-
}) {
178-
Ok(token) => token,
179-
Err(err) => return Err(VmError::RuntimeError(err.to_string())),
180-
};
181-
182-
Ok(Value::IoString(Gc::new(
183-
state,
184-
token.access_token().secret().to_owned(),
185-
)))
186+
.map_err(|err| VmError::RuntimeError(err.to_string()))?;
187+
let access_token = token.access_token().secret().to_owned();
188+
189+
let response = http_client
190+
.get(userinfo_url)
191+
.header("Authorization", format!("Bearer {}", access_token))
192+
.send()
193+
.await
194+
.map_err(|err| VmError::RuntimeError(err.to_string()))?;
195+
196+
if !response.status().is_success() {
197+
return Err(VmError::RuntimeError(format!(
198+
"Failed to fetch user info: {}",
199+
response.status()
200+
)));
201+
}
202+
203+
let info = response
204+
.json::<serde_json::Value>()
205+
.await
206+
.map_err(|err| VmError::RuntimeError(err.to_string()))?;
207+
Ok(Value::from_serde_value(state.get_context(), &info))
208+
})
186209
}

0 commit comments

Comments
 (0)