feat: added capes table and fetch upon registration
Co-authored-by: zaaarf <zaaarf@proton.me>
This commit is contained in:
parent
98446959bc
commit
a090e6f1aa
8 changed files with 212 additions and 5 deletions
|
@ -1,12 +1,16 @@
|
|||
pub use sea_orm_migration::prelude::*;
|
||||
|
||||
mod m20220101_000001_create_table;
|
||||
mod m20230123_000947_skin_table;
|
||||
|
||||
pub struct Migrator;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigratorTrait for Migrator {
|
||||
fn migrations() -> Vec<Box<dyn MigrationTrait>> {
|
||||
vec![Box::new(m20220101_000001_create_table::Migration)]
|
||||
vec![
|
||||
Box::new(m20220101_000001_create_table::Migration),
|
||||
Box::new(m20230123_000947_skin_table::Migration),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
61
migration/src/m20230123_000947_skin_table.rs
Normal file
61
migration/src/m20230123_000947_skin_table.rs
Normal file
|
@ -0,0 +1,61 @@
|
|||
use sea_orm_migration::prelude::*;
|
||||
|
||||
#[derive(DeriveMigrationName)]
|
||||
pub struct Migration;
|
||||
|
||||
#[async_trait::async_trait]
|
||||
impl MigrationTrait for Migration {
|
||||
async fn up(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.create_table(
|
||||
Table::create()
|
||||
.table(Property::Table)
|
||||
.if_not_exists()
|
||||
.col(
|
||||
ColumnDef::new(Property::Id)
|
||||
.integer()
|
||||
.not_null()
|
||||
.auto_increment()
|
||||
.primary_key(),
|
||||
)
|
||||
.col(ColumnDef::new(Property::UserId).integer().not_null()) // TODO
|
||||
.foreign_key(
|
||||
ForeignKey::create()
|
||||
.name("fk-property-user")
|
||||
.from(Property::Table, Property::UserId)
|
||||
.to(User::Table, User::Id)
|
||||
)
|
||||
.col(ColumnDef::new(Property::Name).string().not_null())
|
||||
.col(ColumnDef::new(Property::Value).string().not_null())
|
||||
.col(ColumnDef::new(Property::Signature).string().null())
|
||||
.to_owned(),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn down(&self, manager: &SchemaManager) -> Result<(), DbErr> {
|
||||
manager
|
||||
.drop_table(Table::drop().table(Property::Table).to_owned())
|
||||
.await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
enum User {
|
||||
Table,
|
||||
Id,
|
||||
}
|
||||
|
||||
#[derive(Iden)]
|
||||
enum Property {
|
||||
Table,
|
||||
Id,
|
||||
UserId,
|
||||
Name,
|
||||
Value,
|
||||
Signature,
|
||||
}
|
|
@ -2,5 +2,6 @@
|
|||
|
||||
pub mod prelude;
|
||||
|
||||
pub mod property;
|
||||
pub mod token;
|
||||
pub mod user;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.10.7
|
||||
|
||||
pub use super::property::Entity as Property;
|
||||
pub use super::token::Entity as Token;
|
||||
pub use super::user::Entity as User;
|
||||
|
|
34
src/entities/property.rs
Normal file
34
src/entities/property.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
//! `SeaORM` Entity. Generated by sea-orm-codegen 0.10.7
|
||||
|
||||
use sea_orm::entity::prelude::*;
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, DeriveEntityModel, Eq)]
|
||||
#[sea_orm(table_name = "property")]
|
||||
pub struct Model {
|
||||
#[sea_orm(primary_key)]
|
||||
pub id: i32,
|
||||
pub user_id: i32,
|
||||
pub name: String,
|
||||
pub value: String,
|
||||
pub signature: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(
|
||||
belongs_to = "super::user::Entity",
|
||||
from = "Column::UserId",
|
||||
to = "super::user::Column::Id",
|
||||
on_update = "NoAction",
|
||||
on_delete = "NoAction"
|
||||
)]
|
||||
User,
|
||||
}
|
||||
|
||||
impl Related<super::user::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::User.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
|
@ -17,13 +17,19 @@ pub struct Model {
|
|||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {
|
||||
#[sea_orm(
|
||||
belongs_to = "Entity",
|
||||
belongs_to = "super::user::Entity",
|
||||
from = "Column::UserId",
|
||||
to = "Column::Id",
|
||||
to = "super::user::Column::Id",
|
||||
on_update = "NoAction",
|
||||
on_delete = "NoAction"
|
||||
)]
|
||||
SelfRef,
|
||||
User,
|
||||
}
|
||||
|
||||
impl Related<super::user::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::User.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
|
|
|
@ -13,6 +13,23 @@ pub struct Model {
|
|||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, EnumIter, DeriveRelation)]
|
||||
pub enum Relation {}
|
||||
pub enum Relation {
|
||||
#[sea_orm(has_many = "super::property::Entity")]
|
||||
Property,
|
||||
#[sea_orm(has_many = "super::token::Entity")]
|
||||
Token,
|
||||
}
|
||||
|
||||
impl Related<super::property::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Property.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl Related<super::token::Entity> for Entity {
|
||||
fn to() -> RelationDef {
|
||||
Relation::Token.def()
|
||||
}
|
||||
}
|
||||
|
||||
impl ActiveModelBehavior for ActiveModel {}
|
||||
|
|
83
src/routes/register.rs
Normal file
83
src/routes/register.rs
Normal file
|
@ -0,0 +1,83 @@
|
|||
use axum::{extract::State, Json};
|
||||
use reqwest::StatusCode;
|
||||
use sea_orm::{EntityTrait, QueryFilter, ColumnTrait, Set, ActiveValue::NotSet};
|
||||
use tracing::info;
|
||||
|
||||
use crate::{AppState, proto::{self, Response}, entities};
|
||||
|
||||
//TODO: replace format! with axum's own
|
||||
pub async fn register_unmigrated(State(state): State<AppState>, Json(payload): Json<proto::RegisterRequest>) -> Response<proto::RegisterResponse> {
|
||||
info!(target: "REGISTER", "[UNMIGRATED] called with {:?}", payload);
|
||||
|
||||
let form = proto::RefreshRequest {
|
||||
accessToken: payload.token.accessToken,
|
||||
clientToken: payload.token.clientToken,
|
||||
selectedProfile: None,
|
||||
requestUser: Some(true),
|
||||
};
|
||||
|
||||
let c = reqwest::Client::new();
|
||||
let response = c.post("https://authserver.mojang.com/refresh")
|
||||
.json(&form)
|
||||
.send().await
|
||||
.map_err(|e| (StatusCode::INTERNAL_SERVER_ERROR, Json(proto::Error::simple(format!("mojang error : {:?}", e)))))?
|
||||
.text().await.expect("invalid body on response");
|
||||
|
||||
info!(target:"REGISTER", "Mojang response to refresh request: {}", &response);
|
||||
let doc = serde_json::from_str::<proto::RefreshResponse>(&response)
|
||||
.map_err(|_| (StatusCode::UNAUTHORIZED, Json(proto::Error::simple("invalid token"))))?;
|
||||
|
||||
let user = doc.user.expect("user not found in response, even though we requested it!");
|
||||
|
||||
entities::user::Entity::insert(
|
||||
entities::user::ActiveModel {
|
||||
id: NotSet,
|
||||
name: Set(user.username.clone()),
|
||||
password: Set(payload.password),
|
||||
uuid: Set(user.id),
|
||||
}
|
||||
).exec(&state.db).await
|
||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, Json(proto::Error::simple("db error"))))?;
|
||||
|
||||
let u = entities::user::Entity::find().filter(
|
||||
entities::user::Column::Uuid.eq(user.id)
|
||||
).one(&state.db).await
|
||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, Json(proto::Error::simple("db error"))))?
|
||||
.ok_or((StatusCode::INTERNAL_SERVER_ERROR, Json(proto::Error::simple("failed creating user"))))?;
|
||||
|
||||
let response = c.get(format!("https://sessionserver.mojang.com/session/minecraft/profile/{}", user.id)) //TODO: needs trimmed uuid, is it trimmed by default?
|
||||
.send().await
|
||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, Json(proto::Error::simple("internal server error"))))?
|
||||
.text().await.expect("invalid body on response");
|
||||
|
||||
info!(target:"REGISTER", "Mojang response to texture fetch: {}", &response);
|
||||
let doc = serde_json::from_str::<proto::SessionUser>(&response)
|
||||
.map_err(|_| (StatusCode::UNAUTHORIZED, Json(proto::Error::simple("invalid texture response"))))?;
|
||||
|
||||
let mut skin = proto::Property::default_skin();
|
||||
|
||||
for s in doc.properties.expect("missing properties field") {
|
||||
if s.name == "textures" {
|
||||
skin = s;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
entities::property::Entity::insert(
|
||||
entities::property::ActiveModel {
|
||||
id: NotSet,
|
||||
name: Set("textures".into()),
|
||||
user_id: Set(u.id),
|
||||
value: Set(skin.value),
|
||||
signature: Set(skin.signature),
|
||||
}
|
||||
).exec(&state.db).await
|
||||
.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, Json(proto::Error::simple("db error"))))?;
|
||||
|
||||
Ok(Json(proto::RegisterResponse {
|
||||
user: proto::Profile {
|
||||
name: user.username,
|
||||
id: user.id,
|
||||
}
|
||||
}))
|
||||
}
|
Loading…
Reference in a new issue