feat: get in the friends server
This commit is contained in:
parent
9f9393cfe5
commit
2417c109e4
9 changed files with 473 additions and 21 deletions
89
Cargo.lock
generated
89
Cargo.lock
generated
|
|
@ -18,6 +18,8 @@ dependencies = [
|
|||
"gxhash",
|
||||
"hex",
|
||||
"hmac",
|
||||
"juniper",
|
||||
"juniper_rocket",
|
||||
"log",
|
||||
"md-5",
|
||||
"mii",
|
||||
|
|
@ -234,6 +236,18 @@ version = "1.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
|
||||
|
||||
[[package]]
|
||||
name = "auto_enums"
|
||||
version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c170965892137a3a9aeb000b4524aa3cc022a310e709d848b6e1cdce4ab4781"
|
||||
dependencies = [
|
||||
"derive_utils",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.98",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.4.0"
|
||||
|
|
@ -617,6 +631,17 @@ dependencies = [
|
|||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derive_utils"
|
||||
version = "0.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ccfae181bab5ab6c5478b2ccb69e4c68a02f8c3ec72f6616bfec9dbc599d2ee0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.98",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "devise"
|
||||
version = "0.4.2"
|
||||
|
|
@ -839,6 +864,7 @@ checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
|
|||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
|
|
@ -1558,6 +1584,52 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "juniper"
|
||||
version = "0.16.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "943306315b1a7a03d27af9dfb0c288d9f4da8830c17df4bceb7d50a47da0982c"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"auto_enums",
|
||||
"chrono",
|
||||
"fnv",
|
||||
"futures",
|
||||
"indexmap 2.7.1",
|
||||
"juniper_codegen",
|
||||
"serde",
|
||||
"smartstring",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "juniper_codegen"
|
||||
version = "0.16.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "760dbe46660494d469023d661e8d268f413b2cb68c999975dcc237407096a693"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.98",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "juniper_rocket"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce74561b72a9aab16a16df022d7b6551fa8018b0cedfe2187417eeb602b65b3e"
|
||||
dependencies = [
|
||||
"either",
|
||||
"futures",
|
||||
"inlinable_string",
|
||||
"juniper",
|
||||
"pear",
|
||||
"rocket",
|
||||
"serde_json",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
version = "1.5.0"
|
||||
|
|
@ -2708,6 +2780,17 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smartstring"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fb72c633efbaa2dd666986505016c32c3044395ceaf881518399d2f4127ee29"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"static_assertions",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.5.8"
|
||||
|
|
@ -2955,6 +3038,12 @@ dependencies = [
|
|||
"loom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "stringprep"
|
||||
version = "0.1.5"
|
||||
|
|
|
|||
|
|
@ -39,9 +39,13 @@ minio = { git = "https://github.com/minio/minio-rs.git" }
|
|||
crc32fast = "1.4.2"
|
||||
gxhash = "3.4.1"
|
||||
|
||||
juniper = { version = "0.16.1", features = ["chrono"] }
|
||||
juniper_rocket = "0.9.0"
|
||||
|
||||
tonic = "0.12.3"
|
||||
prost = "0.13.4"
|
||||
|
||||
|
||||
|
||||
[build-dependencies]
|
||||
tonic-build = "0.12.3"
|
||||
|
|
@ -124,7 +124,7 @@ pub async fn read_basic_auth_token(connection: &Pool, token: &str) -> Option<Use
|
|||
}
|
||||
}
|
||||
|
||||
async fn read_bearer_auth_token(connection: &Pool, token: &str) -> Option<User> {
|
||||
pub async fn read_bearer_auth_token(connection: &Pool, token: &str) -> Option<User> {
|
||||
let data = TokenData::decode(token)?;
|
||||
|
||||
let token_info =
|
||||
|
|
|
|||
107
src/graphql/mod.rs
Normal file
107
src/graphql/mod.rs
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
use std::fmt::Display;
|
||||
use chrono::NaiveDateTime;
|
||||
use juniper::{graphql_object, EmptyMutation, EmptySubscription, GraphQLObject, RootNode, ScalarValue};
|
||||
use rocket::response::content::RawHtml;
|
||||
use rocket::State;
|
||||
use crate::account::account::{read_basic_auth_token, read_bearer_auth_token};
|
||||
use crate::nnid::oauth::TokenData;
|
||||
use crate::Pool;
|
||||
|
||||
|
||||
|
||||
pub type Schema = RootNode<
|
||||
'static,
|
||||
Query,
|
||||
EmptyMutation<Context>,
|
||||
EmptySubscription<Context>
|
||||
>;
|
||||
|
||||
|
||||
pub struct Context(pub Pool);
|
||||
impl juniper::Context for Context{}
|
||||
|
||||
#[derive(GraphQLObject)]
|
||||
#[graphql(description = "Data inside of a token")]
|
||||
struct TokenInfo {
|
||||
pid: i32,
|
||||
expire_date: NaiveDateTime,
|
||||
title_id: Option<String>
|
||||
}
|
||||
|
||||
pub struct Query;
|
||||
|
||||
#[graphql_object]
|
||||
#[graphql(context = Context)]
|
||||
impl Query {
|
||||
fn api_version() -> &'static str {
|
||||
"1.0"
|
||||
}
|
||||
|
||||
async fn token(
|
||||
token_data: String,
|
||||
context: &Context,
|
||||
) -> Option<TokenInfo>{
|
||||
let data = TokenData::decode(&token_data)?;
|
||||
|
||||
let token_info =
|
||||
sqlx::query!(
|
||||
"select * from tokens where pid = $1 and token_id = $2 and random = $3",
|
||||
data.pid, data.token_id, data.random
|
||||
).
|
||||
fetch_one(&context.0).await.ok()?;
|
||||
|
||||
Some(TokenInfo{
|
||||
pid: data.pid,
|
||||
expire_date: token_info.expires,
|
||||
title_id: token_info.title_id,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
struct Mutation;
|
||||
|
||||
|
||||
#[graphql_object]
|
||||
#[graphql(
|
||||
context = Context,
|
||||
// If we need to use `ScalarValue` parametrization explicitly somewhere
|
||||
// in the object definition (like here in `FieldResult`), we could
|
||||
// declare an explicit type parameter for that, and specify it.
|
||||
scalar = S: ScalarValue + Display,
|
||||
)]
|
||||
impl Mutation {
|
||||
}
|
||||
*/
|
||||
|
||||
#[rocket::get("/graphiql")]
|
||||
pub fn graphiql() -> RawHtml<String> {
|
||||
juniper_rocket::graphiql_source("/graphql", None)
|
||||
}
|
||||
|
||||
|
||||
#[rocket::get("/playground")]
|
||||
pub fn playground() -> RawHtml<String> {
|
||||
juniper_rocket::playground_source("/graphql", None)
|
||||
}
|
||||
|
||||
#[rocket::get("/graphql?<request..>")]
|
||||
pub async fn get_graphql(
|
||||
db: &State<Context>,
|
||||
request: juniper_rocket::GraphQLRequest,
|
||||
schema: &State<Schema>,
|
||||
) -> juniper_rocket::GraphQLResponse {
|
||||
request.execute(schema, db).await
|
||||
}
|
||||
|
||||
#[rocket::post("/graphql", data = "<request>")]
|
||||
pub async fn post_graphql(
|
||||
db: &State<Context>,
|
||||
request: juniper_rocket::GraphQLRequest,
|
||||
schema: &State<Schema>,
|
||||
) -> juniper_rocket::GraphQLResponse {
|
||||
request.execute(schema, db).await
|
||||
}
|
||||
|
|
@ -1,30 +1,103 @@
|
|||
use tonic::{async_trait, Request, Response, Status};
|
||||
use crate::grpc::grpc::{ExchangeTokenForUserDataRequest, GetNexDataRequest, GetNexDataResponse, GetNexPasswordRequest, GetNexPasswordResponse, GetUserDataRequest, GetUserDataResponse, UpdatePnidPermissionsRequest};
|
||||
use crate::Pool;
|
||||
use crate::grpc::grpc::{
|
||||
ExchangeTokenForUserDataRequest, GetNexDataRequest, GetNexDataResponse, GetNexPasswordRequest,
|
||||
GetNexPasswordResponse, GetUserDataRequest, GetUserDataResponse, UpdatePnidPermissionsRequest,
|
||||
};
|
||||
use once_cell::sync::Lazy;
|
||||
use std::env;
|
||||
use tonic::metadata::MetadataMap;
|
||||
use tonic::{Request, Response, Status, async_trait};
|
||||
|
||||
mod grpc {
|
||||
/// This module is a legacy module meant for interacting with existing pretendo
|
||||
/// servers. This will inevitably be removed completely as this is only meant as
|
||||
/// a stopgap until RNEX is in a fully functional state.
|
||||
|
||||
pub mod grpc {
|
||||
tonic::include_proto!("account");
|
||||
}
|
||||
|
||||
static GRPC_PASSWORD: Lazy<Box<str>> = Lazy::new(|| {
|
||||
env::var("GRPC_PASSWORD")
|
||||
.expect("GRPC_PASSWORD not specified")
|
||||
.into_boxed_str()
|
||||
});
|
||||
|
||||
fn verify_grpc_key(meta: &MetadataMap) -> Result<(), Status> {
|
||||
// req.metadata_mut().insert("x-api-key", API_KEY.clone());
|
||||
|
||||
let key = meta
|
||||
.get("x-api-key")
|
||||
.ok_or(Status::permission_denied("api key missing"))?;
|
||||
|
||||
if key.as_bytes() != GRPC_PASSWORD.as_bytes() {
|
||||
return Err(Status::permission_denied("GO AWAY"));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub struct AccountService(pub Pool);
|
||||
|
||||
#[async_trait]
|
||||
impl grpc::account_server::Account for AccountService {
|
||||
async fn exchange_token_for_user_data(&self, request: Request<ExchangeTokenForUserDataRequest>) -> Result<Response<GetUserDataResponse>, Status> {
|
||||
todo!()
|
||||
async fn exchange_token_for_user_data(
|
||||
&self,
|
||||
request: Request<ExchangeTokenForUserDataRequest>,
|
||||
) -> Result<Response<GetUserDataResponse>, Status> {
|
||||
verify_grpc_key(request.metadata())?;
|
||||
|
||||
Err(Status::unimplemented(
|
||||
"grpc tecnically isnt supported by account-rs as such no full support is guaranteed(you called a stubbed function)",
|
||||
))
|
||||
}
|
||||
async fn get_nex_data(&self, request: Request<GetNexDataRequest>) -> Result<Response<GetNexDataResponse>, Status> {
|
||||
todo!()
|
||||
async fn get_nex_data(
|
||||
&self,
|
||||
request: Request<GetNexDataRequest>,
|
||||
) -> Result<Response<GetNexDataResponse>, Status> {
|
||||
verify_grpc_key(request.metadata())?;
|
||||
|
||||
Err(Status::unimplemented(
|
||||
"grpc tecnically isnt supported by account-rs as such no full support is guaranteed(you called a stubbed function)",
|
||||
))
|
||||
}
|
||||
async fn get_nex_password(&self, request: Request<GetNexPasswordRequest>) -> Result<Response<GetNexPasswordResponse>, Status> {
|
||||
todo!()
|
||||
async fn get_nex_password(
|
||||
&self,
|
||||
request: Request<GetNexPasswordRequest>,
|
||||
) -> Result<Response<GetNexPasswordResponse>, Status> {
|
||||
verify_grpc_key(request.metadata())?;
|
||||
|
||||
let data = request.get_ref();
|
||||
|
||||
let password = sqlx::query!(
|
||||
"select nex_password from users where pid = $1",
|
||||
data.pid as i32
|
||||
)
|
||||
.fetch_one(&self.0)
|
||||
.await
|
||||
.map_err(|_| Status::invalid_argument("No NEX account found"))?
|
||||
.nex_password;
|
||||
|
||||
Ok(Response::new(GetNexPasswordResponse { password }))
|
||||
}
|
||||
async fn update_pnid_permissions(&self, request: Request<UpdatePnidPermissionsRequest>) -> Result<Response<()>, Status> {
|
||||
todo!()
|
||||
async fn update_pnid_permissions(
|
||||
&self,
|
||||
request: Request<UpdatePnidPermissionsRequest>,
|
||||
) -> Result<Response<()>, Status> {
|
||||
verify_grpc_key(request.metadata())?;
|
||||
|
||||
Err(Status::unimplemented(
|
||||
"grpc tecnically isnt supported by account-rs as such no full support is guaranteed(you called a stubbed function)",
|
||||
))
|
||||
}
|
||||
|
||||
async fn get_user_data(&self, request: Request<GetUserDataRequest>) -> Result<Response<GetUserDataResponse>, Status> {
|
||||
todo!()
|
||||
async fn get_user_data(
|
||||
&self,
|
||||
request: Request<GetUserDataRequest>,
|
||||
) -> Result<Response<GetUserDataResponse>, Status> {
|
||||
verify_grpc_key(request.metadata())?;
|
||||
|
||||
Err(Status::unimplemented(
|
||||
"grpc tecnically isnt supported by account-rs as such no full support is guaranteed(you called a stubbed function)",
|
||||
))
|
||||
}
|
||||
}
|
||||
59
src/main.rs
59
src/main.rs
|
|
@ -1,15 +1,20 @@
|
|||
|
||||
|
||||
use std::env;
|
||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr, SocketAddrV4};
|
||||
use std::sync::Arc;
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use dotenvy::dotenv;
|
||||
use juniper::{EmptyMutation, EmptySubscription};
|
||||
use log::info;
|
||||
use rocket::fairing::AdHoc;
|
||||
use rocket::futures::FutureExt;
|
||||
use rocket::http::Header;
|
||||
use rocket::routes;
|
||||
use sqlx::Postgres;
|
||||
use sqlx::postgres::PgPoolOptions;
|
||||
use tonic::transport::Server;
|
||||
use crate::graphql::{Query, Schema};
|
||||
|
||||
mod xml;
|
||||
mod conntest;
|
||||
|
|
@ -18,15 +23,49 @@ mod account;
|
|||
mod error;
|
||||
mod dsresponse;
|
||||
mod data_wrapper;
|
||||
#[deprecated]
|
||||
mod grpc;
|
||||
mod graphql;
|
||||
|
||||
type Pool = sqlx::Pool<Postgres>;
|
||||
|
||||
async fn start_grpc(){
|
||||
let act_database_url = env::var("DATABASE_URL").expect("account database url is not set");
|
||||
|
||||
let pool = PgPoolOptions::new()
|
||||
.max_connections(5)
|
||||
.connect(&act_database_url)
|
||||
.await
|
||||
.expect("unable to create pool");
|
||||
|
||||
let grpc_instance = grpc::AccountService(pool);
|
||||
|
||||
let addr: SocketAddr =
|
||||
SocketAddr::from((
|
||||
env::var("ROCKET_ADDRESS").ok()
|
||||
.map(|v| v.parse().expect("unable to read address"))
|
||||
.unwrap_or(IpAddr::V4(Ipv4Addr::LOCALHOST)),
|
||||
7071
|
||||
)
|
||||
);
|
||||
|
||||
|
||||
|
||||
tokio::spawn(async move{
|
||||
Server::builder()
|
||||
.add_service(grpc::grpc::account_server::AccountServer::new(grpc_instance))
|
||||
.serve(addr)
|
||||
.await
|
||||
.expect("unable to start grpc server");
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
#[rocket::launch]
|
||||
async fn launch() -> _ {
|
||||
dotenv().ok();
|
||||
|
||||
|
||||
start_grpc().await;
|
||||
|
||||
let act_database_url = env::var("DATABASE_URL").expect("account database url is not set");
|
||||
|
||||
|
|
@ -35,8 +74,19 @@ async fn launch() -> _ {
|
|||
.connect(&act_database_url).await
|
||||
.expect("unable to create pool");
|
||||
|
||||
let graph_pool = PgPoolOptions::new()
|
||||
.max_connections(5)
|
||||
.connect(&act_database_url).await
|
||||
.expect("unable to create pool");
|
||||
|
||||
rocket::build()
|
||||
.manage(pool)
|
||||
.manage(graphql::Context(graph_pool))
|
||||
.manage(Schema::new(
|
||||
Query,
|
||||
EmptyMutation::new(),
|
||||
EmptySubscription::new())
|
||||
)
|
||||
.attach(AdHoc::on_response("org", |_, response| Box::pin(async move {
|
||||
//response.adjoin_header(Header::new("x-organization", "Nintendo"));
|
||||
response.adjoin_header(Header::new("x-nintendo-date", SystemTime::now()
|
||||
|
|
@ -64,5 +114,12 @@ async fn launch() -> _ {
|
|||
nnid::people::get_own_profile,
|
||||
nnid::oauth::generate_token::generate_token,
|
||||
nnid::provider::get_nex_token,
|
||||
nnid::provider::get_service_token,
|
||||
nnid::mapped_ids::mapped_ids,
|
||||
//graphql
|
||||
graphql::graphiql,
|
||||
graphql::playground,
|
||||
graphql::get_graphql,
|
||||
graphql::post_graphql,
|
||||
])
|
||||
}
|
||||
|
|
|
|||
83
src/nnid/mapped_ids.rs
Normal file
83
src/nnid/mapped_ids.rs
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
use rocket::{get, State};
|
||||
use serde::Serialize;
|
||||
use crate::Pool;
|
||||
use crate::xml::Xml;
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(rename = "mapped_id")]
|
||||
struct MappedId {
|
||||
in_id: String,
|
||||
out_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(rename = "mapped_ids")]
|
||||
struct MappedIds {
|
||||
mapped_id: Vec<MappedId>,
|
||||
}
|
||||
|
||||
struct UserIdAndName {
|
||||
pid: i32,
|
||||
username: String,
|
||||
}
|
||||
|
||||
#[get("/v1/api/admin/mapped_ids?<input_type>&<output_type>&<input>")]
|
||||
pub async fn mapped_ids(pool: &State<Pool>, input_type: String, output_type: String, input: String) -> Option<Xml<MappedIds>> {
|
||||
let pool = pool.inner();
|
||||
|
||||
let is_input_pid = input_type == "pid";
|
||||
let is_output_pid = output_type == "pid";
|
||||
|
||||
let mut outputs = Vec::new();
|
||||
|
||||
for input in input.split(',') {
|
||||
if input == ""{
|
||||
continue;
|
||||
}
|
||||
let Some(user) =
|
||||
(if is_input_pid {
|
||||
let id: i32 = input.parse().ok()?;
|
||||
|
||||
sqlx::query_as!(
|
||||
UserIdAndName,
|
||||
"select pid, username from users where pid = $1",
|
||||
id
|
||||
).fetch_one(pool)
|
||||
.await.ok()
|
||||
} else {
|
||||
sqlx::query_as!(
|
||||
UserIdAndName,
|
||||
"select pid, username from users where username = $1",
|
||||
input
|
||||
).fetch_one(pool)
|
||||
.await.ok()
|
||||
}) else {
|
||||
outputs.push(MappedId{
|
||||
in_id: input.to_string(),
|
||||
out_id: None,
|
||||
});
|
||||
|
||||
continue
|
||||
};
|
||||
|
||||
|
||||
if is_output_pid{
|
||||
outputs.push(MappedId{
|
||||
in_id: input.to_string(),
|
||||
out_id: Some(user.pid.to_string()),
|
||||
})
|
||||
} else {
|
||||
outputs.push(MappedId{
|
||||
in_id: input.to_string(),
|
||||
out_id: Some(user.username),
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some(Xml(
|
||||
MappedIds{
|
||||
mapped_id: outputs
|
||||
}
|
||||
))
|
||||
}
|
||||
|
|
@ -7,3 +7,4 @@ pub mod oauth;
|
|||
mod pid_distribution;
|
||||
pub mod people;
|
||||
pub mod provider;
|
||||
pub mod mapped_ids;
|
||||
|
|
|
|||
|
|
@ -6,12 +6,19 @@ use sqlx::types::ipnetwork::IpNetwork::V4;
|
|||
use crate::account::account::Auth;
|
||||
use crate::nnid::oauth::generate_token::create_token;
|
||||
use crate::nnid::oauth::generate_token::token_type::NEX_TOKEN;
|
||||
use crate::nnid::provider::Test::{A, B};
|
||||
use crate::Pool;
|
||||
use crate::xml::Xml;
|
||||
|
||||
enum Test{
|
||||
A(String),
|
||||
B(i32)
|
||||
}
|
||||
|
||||
|
||||
#[derive(Serialize)]
|
||||
#[serde(rename = "nex_token")]
|
||||
struct NexToken{
|
||||
pub struct NexToken{
|
||||
host: Ipv4Addr,
|
||||
nex_password: String,
|
||||
pid: i32,
|
||||
|
|
@ -19,20 +26,51 @@ struct NexToken{
|
|||
token: String
|
||||
}
|
||||
|
||||
#[get("/v1/api/provider/nex_token/@me?<game_server_id>")]
|
||||
pub async fn get_nex_token(pool: &State<Pool>, auth: Auth<true>, game_server_id: String) -> Option<Xml<NexToken>>{
|
||||
#[derive(Serialize)]
|
||||
#[serde(rename = "service_token")]
|
||||
pub struct ServiceToken{
|
||||
token: String
|
||||
}
|
||||
|
||||
#[get("/v1/api/provider/service_token/@me")]
|
||||
pub async fn get_service_token(pool: &State<Pool>, auth: Auth<true>) -> Option<Xml<ServiceToken>>{
|
||||
// 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;
|
||||
|
||||
|
||||
|
||||
Some(
|
||||
Xml(
|
||||
ServiceToken{
|
||||
token
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
#[get("/v1/api/provider/nex_token/@me?<game_server_id>")]
|
||||
pub async fn get_nex_token(pool: &State<Pool>, auth: Auth<true>, game_server_id: &str) -> Option<Xml<NexToken>>{
|
||||
// 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 server = sqlx::query!(
|
||||
"select * from nex_servers where game_server_id = $1",
|
||||
"select address, port from nex_servers where game_server_id = $1",
|
||||
game_server_id
|
||||
) .fetch_one(pool).await.ok()?;
|
||||
) .fetch_one(pool).await.unwrap();
|
||||
|
||||
let token = create_token(pool, auth.pid, NEX_TOKEN, None).await;
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue