account/src/nnid/provider.rs

122 lines
3.4 KiB
Rust
Raw Normal View History

use std::net::Ipv4Addr;
use std::str::FromStr;
use rocket::{get, State};
use serde::Serialize;
use sqlx::types::ipnetwork::IpNetwork::V4;
use crate::account::account::Auth;
2025-04-26 20:10:14 +02:00
use crate::error::{Error, Errors};
use crate::nnid::oauth::generate_token::{create_token, TokenRequestReturnData};
use crate::nnid::oauth::generate_token::token_type::NEX_TOKEN;
2025-03-09 23:47:46 +01:00
use crate::nnid::provider::Test::{A, B};
use crate::Pool;
use crate::xml::Xml;
2025-03-09 23:47:46 +01:00
enum Test{
A(String),
B(i32)
}
2025-04-26 20:10:14 +02:00
const NO_IPV4_ERROR: Errors = Errors{
error: &[
Error{
code: "1022",
message: "Server is not a valid IPv4 address"
}
]
};
const NO_SERVER_ERROR: Errors = Errors{
error: &[
Error{
code: "1021",
message: "The requested game server was not found"
}
]
};
2025-03-09 23:47:46 +01:00
#[derive(Serialize)]
#[serde(rename = "nex_token")]
2025-03-09 23:47:46 +01:00
pub struct NexToken{
host: Ipv4Addr,
nex_password: String,
pid: i32,
port: u16,
token: String
}
2025-03-09 23:47:46 +01:00
#[derive(Serialize)]
#[serde(rename = "service_token")]
pub struct ServiceToken{
token: String
}
#[get("/v1/api/provider/service_token/@me")]
2025-04-26 20:10:14 +02:00
pub async fn get_service_token(pool: &State<Pool>, auth: Auth<true>) -> Result<Xml<ServiceToken>, Option<Errors<'static>>>{
2025-03-09 23:47:46 +01:00
// just gonna put this here as a side note for the future:
// we could also be using key derivation to derive the nex token as if it were a key
// that way we could reduce the data the database needs to store and also reduce the transfer
// cost of sending an entire row from the user table (which is required for the auth code unless
// we change the way we read in data to essentially having the user object be a proxy for its
// table row)
let pool = pool.inner();
let token = create_token(pool, auth.pid, NEX_TOKEN, None).await;
2025-04-26 20:10:14 +02:00
Ok(
2025-03-09 23:47:46 +01:00
Xml(
ServiceToken{
token
}
)
)
}
#[get("/v1/api/provider/nex_token/@me?<game_server_id>")]
2025-04-26 20:10:14 +02:00
pub async fn get_nex_token(pool: &State<Pool>, auth: Auth<true>, game_server_id: &str) -> Result<Xml<NexToken>, Option<Errors<'static>>>{
// just gonna put this here as a side note for the future:
// we could also be using key derivation to derive the nex token as if it were a key
// that way we could reduce the data the database needs to store and also reduce the transfer
// cost of sending an entire row from the user table (which is required for the auth code unless
// we change the way we read in data to essentially having the user object be a proxy for its
// table row)
2025-03-09 23:47:46 +01:00
let pool = pool.inner();
let server = sqlx::query!(
2025-04-26 20:10:14 +02:00
"select address, port from nex_servers where game_server_id = $1",
game_server_id
)
.fetch_optional(pool)
.await
.expect("database error"); // only crash on db failure (not missing row)
let server = match server {
Some(server) => server,
None => return Err(Some(NO_SERVER_ERROR)), // or custom error
};
let token = create_token(pool, auth.pid, NEX_TOKEN, None).await;
let V4(host) = server.address else {
2025-04-26 20:10:14 +02:00
return Err(Some(NO_IPV4_ERROR));
};
let host = host.ip();
2025-04-26 20:10:14 +02:00
Ok(
Xml(
NexToken{
host,
port: server.port as u16,
nex_password: auth.nex_password.clone(),
pid: auth.pid,
token
}
)
)
}