feat: some refactoring and /v1/api/provider/nex_token/@me
This commit is contained in:
parent
4c24fce110
commit
9f9393cfe5
7 changed files with 85 additions and 47 deletions
|
|
@ -5,6 +5,7 @@ variables:
|
||||||
IMAGE_TAG: "${CI_COMMIT_REF_SLUG}"
|
IMAGE_TAG: "${CI_COMMIT_REF_SLUG}"
|
||||||
|
|
||||||
before_script:
|
before_script:
|
||||||
|
- git submodule update --init
|
||||||
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" ci.perditum.com
|
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" ci.perditum.com
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
|
|
@ -12,10 +13,6 @@ stages:
|
||||||
- build
|
- build
|
||||||
- push
|
- push
|
||||||
|
|
||||||
initialize-submodules:
|
|
||||||
stage: initialize-submodules
|
|
||||||
script:
|
|
||||||
- git submodule update --init
|
|
||||||
|
|
||||||
build:
|
build:
|
||||||
stage: build
|
stage: build
|
||||||
|
|
@ -25,6 +22,8 @@ build:
|
||||||
|
|
||||||
push:
|
push:
|
||||||
stage: push
|
stage: push
|
||||||
|
needs:
|
||||||
|
- build
|
||||||
script:
|
script:
|
||||||
- docker tag "$IMAGE_NAME:$IMAGE_TAG" "$IMAGE_NAME:latest"
|
- docker tag "$IMAGE_NAME:$IMAGE_TAG" "$IMAGE_NAME:latest"
|
||||||
- docker push "$IMAGE_NAME:$IMAGE_TAG"
|
- docker push "$IMAGE_NAME:$IMAGE_TAG"
|
||||||
|
|
|
||||||
11
Cargo.lock
generated
11
Cargo.lock
generated
|
|
@ -1507,6 +1507,15 @@ version = "2.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
|
checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ipnetwork"
|
||||||
|
version = "0.20.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bf466541e9d546596ee94f9f69590f89473455f88372423e0008fc1a7daf100e"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "is-terminal"
|
name = "is-terminal"
|
||||||
version = "0.4.15"
|
version = "0.4.15"
|
||||||
|
|
@ -2760,6 +2769,7 @@ dependencies = [
|
||||||
"hashbrown 0.15.2",
|
"hashbrown 0.15.2",
|
||||||
"hashlink",
|
"hashlink",
|
||||||
"indexmap 2.7.1",
|
"indexmap 2.7.1",
|
||||||
|
"ipnetwork",
|
||||||
"log",
|
"log",
|
||||||
"memchr",
|
"memchr",
|
||||||
"native-tls",
|
"native-tls",
|
||||||
|
|
@ -2879,6 +2889,7 @@ dependencies = [
|
||||||
"hkdf",
|
"hkdf",
|
||||||
"hmac",
|
"hmac",
|
||||||
"home",
|
"home",
|
||||||
|
"ipnetwork",
|
||||||
"itoa",
|
"itoa",
|
||||||
"log",
|
"log",
|
||||||
"md-5",
|
"md-5",
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ base64 = "0.22.1"
|
||||||
hex = "0.4.3"
|
hex = "0.4.3"
|
||||||
thiserror = "2.0.11"
|
thiserror = "2.0.11"
|
||||||
bcrypt = "0.17.0"
|
bcrypt = "0.17.0"
|
||||||
sqlx = { version = "0.8.3", features = [ "runtime-tokio", "tls-native-tls", "postgres", "chrono" ] }
|
sqlx = { version = "0.8.3", features = [ "runtime-tokio", "tls-native-tls", "postgres", "chrono", "ipnetwork" ] }
|
||||||
aes = "0.8.4"
|
aes = "0.8.4"
|
||||||
hmac = "0.12.1"
|
hmac = "0.12.1"
|
||||||
md-5 = "0.10.6"
|
md-5 = "0.10.6"
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
# syntax=docker/dockerfile:1
|
||||||
|
|
||||||
FROM rust:alpine as builder
|
FROM rust:alpine as builder
|
||||||
|
|
||||||
RUN apk add --no-cache musl-dev openssl-dev openssl-libs-static protobuf-dev lld
|
RUN apk add --no-cache musl-dev openssl-dev openssl-libs-static protobuf-dev lld
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,8 @@ pub struct User {
|
||||||
pub region: i32,
|
pub region: i32,
|
||||||
pub mii_data: String,
|
pub mii_data: String,
|
||||||
pub creation_date: NaiveDateTime,
|
pub creation_date: NaiveDateTime,
|
||||||
pub updated: NaiveDateTime
|
pub updated: NaiveDateTime,
|
||||||
|
pub nex_password: String
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generate_nintendo_hash(pid: i32, text_password: &str) -> String{
|
fn generate_nintendo_hash(pid: i32, text_password: &str) -> String{
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,17 @@ use rocket::form::Form;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use crate::account::account::User;
|
use crate::account::account::User;
|
||||||
use crate::error::{Error, Errors};
|
use crate::error::{Error, Errors};
|
||||||
|
use crate::nnid::oauth::generate_token::token_type::{AUTH_REFRESH_TOKEN, AUTH_TOKEN};
|
||||||
use crate::nnid::oauth::TokenData;
|
use crate::nnid::oauth::TokenData;
|
||||||
use crate::Pool;
|
use crate::Pool;
|
||||||
use crate::xml::Xml;
|
use crate::xml::Xml;
|
||||||
|
|
||||||
|
pub mod token_type{
|
||||||
|
pub const AUTH_REFRESH_TOKEN: i32 = 1;
|
||||||
|
pub const AUTH_TOKEN: i32 = 0;
|
||||||
|
pub const NEX_TOKEN: i32 = 2;
|
||||||
|
}
|
||||||
|
|
||||||
const ACCOUNT_ID_OR_PASSWORD_ERRORS: Errors = Errors{
|
const ACCOUNT_ID_OR_PASSWORD_ERRORS: Errors = Errors{
|
||||||
error: &[
|
error: &[
|
||||||
Error{
|
Error{
|
||||||
|
|
@ -40,51 +47,33 @@ pub struct TokenReturnData {
|
||||||
expires_in: i32
|
expires_in: i32
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TokenReturnData {
|
pub async fn create_token(pool: &Pool, pid: i32, token_type: i32, title_id: Option<&str>) -> String{
|
||||||
async fn create_token(pid: i32, pool: &Pool, is_refresh_token: bool) -> (i64, i32){
|
let data = sqlx::query!(
|
||||||
let token_type = if is_refresh_token{
|
"insert into tokens (token_type, pid, title_id)
|
||||||
0x0
|
values ($1, $2, $3) returning token_id, random",
|
||||||
} else {
|
token_type, pid, title_id
|
||||||
0x1
|
|
||||||
};
|
|
||||||
let data = sqlx::query!(
|
|
||||||
"insert into tokens (token_type, pid)
|
|
||||||
values ($1, $2) returning token_id, random",
|
|
||||||
token_type, pid
|
|
||||||
)
|
)
|
||||||
.fetch_one(pool)
|
.fetch_one(pool)
|
||||||
.await.unwrap();
|
.await.unwrap();
|
||||||
|
|
||||||
(data.token_id, data.random)
|
let token_id = data.token_id;
|
||||||
}
|
let random = data.random;
|
||||||
async fn create_regular_token(pid: i32, pool: &Pool) -> (i64, i32){
|
|
||||||
Self::create_token(pid, pool, false).await
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn create_refresh_token(pid: i32, pool: &Pool) -> (i64, i32){
|
let token = TokenData {
|
||||||
Self::create_token(pid, pool, true).await
|
token_id,
|
||||||
}
|
random,
|
||||||
|
pid
|
||||||
|
};
|
||||||
|
|
||||||
|
token.encode().to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl TokenReturnData {
|
||||||
async fn new(pid: i32, pool: &Pool) -> Self{
|
async fn new(pid: i32, pool: &Pool) -> Self{
|
||||||
let (token_id, random) = Self::create_regular_token(pid, pool).await;
|
let token = create_token(pool, pid, AUTH_TOKEN, None).await;
|
||||||
|
|
||||||
let token = TokenData {
|
let refresh_token = create_token(pool, pid, AUTH_REFRESH_TOKEN, None).await;
|
||||||
token_id,
|
|
||||||
random,
|
|
||||||
pid
|
|
||||||
};
|
|
||||||
|
|
||||||
let token = token.encode().to_string();
|
|
||||||
|
|
||||||
let (token_id, random) = Self::create_refresh_token(pid, pool).await;
|
|
||||||
|
|
||||||
let refresh_token = TokenData {
|
|
||||||
token_id,
|
|
||||||
random,
|
|
||||||
pid
|
|
||||||
};
|
|
||||||
|
|
||||||
let refresh_token = refresh_token.encode().to_string();
|
|
||||||
|
|
||||||
Self{
|
Self{
|
||||||
token,
|
token,
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,12 @@
|
||||||
use std::net::Ipv4Addr;
|
use std::net::Ipv4Addr;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use rocket::get;
|
use rocket::{get, State};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
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::Pool;
|
||||||
use crate::xml::Xml;
|
use crate::xml::Xml;
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
|
|
@ -15,6 +20,37 @@ struct NexToken{
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/v1/api/provider/nex_token/@me?<game_server_id>")]
|
#[get("/v1/api/provider/nex_token/@me?<game_server_id>")]
|
||||||
pub async fn get_nex_token(game_server_id: String) -> Option<Xml<NexToken>>{
|
pub async fn get_nex_token(pool: &State<Pool>, auth: Auth<true>, game_server_id: String) -> Option<Xml<NexToken>>{
|
||||||
None
|
// 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",
|
||||||
|
game_server_id
|
||||||
|
) .fetch_one(pool).await.ok()?;
|
||||||
|
|
||||||
|
let token = create_token(pool, auth.pid, NEX_TOKEN, None).await;
|
||||||
|
|
||||||
|
let V4(host) = server.address else {
|
||||||
|
return None
|
||||||
|
};
|
||||||
|
|
||||||
|
let host = host.ip();
|
||||||
|
|
||||||
|
Some(
|
||||||
|
Xml(
|
||||||
|
NexToken{
|
||||||
|
host,
|
||||||
|
port: server.port as u16,
|
||||||
|
nex_password: auth.nex_password.clone(),
|
||||||
|
pid: auth.pid,
|
||||||
|
token
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue