+4
-4
src/main.rs
+4
-4
src/main.rs
···
1
+
#![warn(clippy::unwrap_used)]
1
2
use crate::xrpc::com_atproto_server::{create_session, get_session, update_email};
2
-
use axum::middleware as ax_middleware;
3
-
mod middleware;
4
3
use axum::body::Body;
5
4
use axum::handler::Handler;
6
5
use axum::http::{Method, header};
6
+
use axum::middleware as ax_middleware;
7
7
use axum::routing::post;
8
8
use axum::{Router, routing::get};
9
9
use axum_template::engine::Engine;
···
24
24
use tracing::{error, log};
25
25
use tracing_subscriber::{EnvFilter, fmt, prelude::*};
26
26
27
+
mod middleware;
27
28
mod xrpc;
28
29
29
30
type HyperUtilClient = hyper_util::client::legacy::Client<HttpConnector, Body>;
···
87
88
//TODO prod
88
89
dotenvy::from_path(Path::new("./pds.env"))?;
89
90
let pds_root = env::var("PDS_DATA_DIRECTORY")?;
90
-
// let pds_root = "/home/baileytownsend/Documents/code/docker_compose/pds/pds_data";
91
91
let account_db_url = format!("{}/account.sqlite", pds_root);
92
92
log::info!("accounts_db_url: {}", account_db_url);
93
93
···
110
110
.connect_with(options)
111
111
.await?;
112
112
113
-
// Run migrations for the bells_and_whistles database
113
+
// Run migrations for the extra database
114
114
// Note: the migrations are embedded at compile time from the given directory
115
115
// sqlx
116
116
sqlx::migrate!("./migrations")
+11
-28
src/middleware.rs
+11
-28
src/middleware.rs
···
7
7
use jwt_compact::{AlgorithmExt, Claims, Token, UntrustedToken, ValidationError};
8
8
use serde::{Deserialize, Serialize};
9
9
use std::env;
10
+
use tracing::log;
10
11
11
12
#[derive(Clone, Debug)]
12
13
pub struct Did(pub Option<String>);
···
22
23
match token {
23
24
Ok(token) => {
24
25
match token {
25
-
None => {
26
-
return json_error_response(
27
-
StatusCode::BAD_REQUEST,
28
-
"TokenRequired",
29
-
"",
30
-
).unwrap();
31
-
}
26
+
None => json_error_response(StatusCode::BAD_REQUEST, "TokenRequired", "").unwrap(),
32
27
Some(token) => {
33
28
let token = UntrustedToken::new(&token);
34
29
//Doing weird unwraps cause I can't do Result for middleware?
35
30
if token.is_err() {
36
-
return json_error_response(
37
-
StatusCode::BAD_REQUEST,
38
-
"TokenRequired",
39
-
"",
40
-
).unwrap();
31
+
return json_error_response(StatusCode::BAD_REQUEST, "TokenRequired", "")
32
+
.unwrap();
41
33
}
42
34
let parsed_token = token.unwrap();
43
35
let claims: Result<Claims<TokenClaims>, ValidationError> =
44
36
parsed_token.deserialize_claims_unchecked();
45
37
if claims.is_err() {
46
-
return json_error_response(
47
-
StatusCode::BAD_REQUEST,
48
-
"TokenRequired",
49
-
"",
50
-
).unwrap();
38
+
return json_error_response(StatusCode::BAD_REQUEST, "TokenRequired", "")
39
+
.unwrap();
51
40
}
52
41
53
42
let key = Hs256Key::new(env::var("PDS_JWT_SECRET").unwrap());
54
43
let token: Result<Token<TokenClaims>, ValidationError> =
55
44
Hs256.validator(&key).validate(&parsed_token);
56
45
if token.is_err() {
57
-
return json_error_response(
58
-
StatusCode::BAD_REQUEST,
59
-
"InvalidToken",
60
-
"",
61
-
).unwrap();
46
+
return json_error_response(StatusCode::BAD_REQUEST, "InvalidToken", "")
47
+
.unwrap();
62
48
}
63
49
let token = token.unwrap();
64
50
//Not going to worry about expiration since it still goes to the PDS
···
69
55
}
70
56
}
71
57
}
72
-
Err(_) => {
73
-
return json_error_response(
74
-
StatusCode::BAD_REQUEST,
75
-
"InvalidToken",
76
-
"",
77
-
).unwrap();
58
+
Err(err) => {
59
+
log::error!("Error extracting token: {}", err);
60
+
json_error_response(StatusCode::BAD_REQUEST, "InvalidToken", "").unwrap()
78
61
}
79
62
}
80
63
}
+23
-25
src/xrpc/helpers.rs
+23
-25
src/xrpc/helpers.rs
···
121
121
122
122
pub enum IdentifierType {
123
123
Email,
124
-
DID,
124
+
Did,
125
125
Handle,
126
126
}
127
127
···
130
130
if identifier.contains("@") {
131
131
IdentifierType::Email
132
132
} else if identifier.contains("did:") {
133
-
IdentifierType::DID
133
+
IdentifierType::Did
134
134
} else {
135
135
IdentifierType::Handle
136
136
}
···
207
207
.fetch_optional(&state.account_pool)
208
208
.await
209
209
.map_err(|_| StatusCode::BAD_REQUEST)?,
210
-
IdentifierType::DID => sqlx::query_as::<_, (String, String, String, String)>(
210
+
IdentifierType::Did => sqlx::query_as::<_, (String, String, String, String)>(
211
211
"SELECT account.did, account.passwordScrypt, account.email, actor.handle
212
212
FROM actor
213
213
LEFT JOIN account ON actor.did = account.did
···
224
224
let required_opt = sqlx::query_as::<_, (u8,)>(
225
225
"SELECT required FROM two_factor_accounts WHERE did = ? LIMIT 1",
226
226
)
227
-
.bind(&did.clone())
227
+
.bind(did.clone())
228
228
.fetch_optional(&state.pds_gatekeeper_pool)
229
229
.await
230
230
.map_err(|_| StatusCode::BAD_REQUEST)?;
···
239
239
let verified = verify_password(password, &password_scrypt).await?;
240
240
if !verified {
241
241
//Theres a chance it could be an app password so check that as well
242
-
return match verify_app_password(&state.account_pool, &did, &password).await {
242
+
return match verify_app_password(&state.account_pool, &did, password).await {
243
243
Ok(valid) => {
244
244
if valid {
245
245
//Was a valid app password up to the PDS now
···
257
257
//Two factor is required and a taken was provided
258
258
if let Some(two_factor_code) = two_factor_code {
259
259
//It seems it sends over a empty on login without it set? As in no input is shown on the ui for the first login try
260
-
if two_factor_code != "" {
260
+
if !two_factor_code.is_empty() {
261
261
return match assert_valid_token(
262
262
&state.account_pool,
263
263
did.clone(),
···
332
332
) -> anyhow::Result<String> {
333
333
let purpose = "2fa_code";
334
334
335
-
loop {
336
-
let token = get_random_token();
337
-
let right_now = Utc::now();
335
+
let token = get_random_token();
336
+
let right_now = Utc::now();
338
337
339
-
let res = sqlx::query(
340
-
"INSERT INTO email_token (purpose, did, token, requestedAt)
338
+
let res = sqlx::query(
339
+
"INSERT INTO email_token (purpose, did, token, requestedAt)
341
340
VALUES (?, ?, ?, ?)
342
341
ON CONFLICT(purpose, did) DO UPDATE SET
343
342
token=excluded.token,
344
343
requestedAt=excluded.requestedAt",
345
-
)
346
-
.bind(purpose)
347
-
.bind(&did)
348
-
.bind(&token)
349
-
.bind(right_now)
350
-
.execute(account_db)
351
-
.await;
344
+
)
345
+
.bind(purpose)
346
+
.bind(&did)
347
+
.bind(&token)
348
+
.bind(right_now)
349
+
.execute(account_db)
350
+
.await;
352
351
353
-
return match res {
354
-
Ok(_) => Ok(token),
355
-
Err(e) => {
356
-
log::error!("Error creating a two factor token: {}", e);
357
-
Err(anyhow::anyhow!(e))
358
-
}
359
-
};
352
+
match res {
353
+
Ok(_) => Ok(token),
354
+
Err(e) => {
355
+
log::error!("Error creating a two factor token: {}", e);
356
+
Err(anyhow::anyhow!(e))
357
+
}
360
358
}
361
359
}
362
360