1
0
mirror of https://git.ngram.ca/OpenJam/rc-servers synced 2026-08-23 23:08:52 +00:00

Create society service with basic functionality and auth #118

This commit is contained in:
NG (Graham)
2026-05-02 11:03:49 -04:00
parent e09aeceed3
commit e3183eb238
51 changed files with 1424 additions and 77 deletions

View File

@@ -81,16 +81,12 @@ impl AccountProvider {
db: self.db.clone(),
})
}*/
}
#[async_trait::async_trait]
impl <C: Clone + Send> super::UserProvider<C> for AccountProvider {
async fn authenticate(&self, token: super::UserToken) -> Result<Box<dyn super::User<C> + Send + Sync>, super::AuthError> {
//let new_root = self.root.join(&token.uuid);
async fn auth_internal(&self, token: &str) -> Result<UserData, super::AuthError> {
let secret = jsonwebtoken::DecodingKey::from_secret(&self.secret);
let mut validation = jsonwebtoken::Validation::new(jsonwebtoken::Algorithm::HS256);
validation.set_required_spec_claims::<&str>(&[]);
let token_data = jsonwebtoken::decode::<crate::auth::Token>(&token.token, &secret, &validation).map_err(|e| super::AuthError {
let token_data = jsonwebtoken::decode::<crate::auth::Token>(&token, &secret, &validation).map_err(|e| super::AuthError {
message: e.to_string(),
code: crate::data::error_codes::AuthErrorCode::BadCredentials,
})?;
@@ -119,8 +115,7 @@ impl <C: Clone + Send> super::UserProvider<C> for AccountProvider {
};
#[cfg(debug_assertions)]
log::info!("Authenticated user {} with flags {:?}", display_name, token_data.claims.client_details.flags.as_slice());
//let account_info = AccountInfo::load(&new_root).map_err(|e| e.to_string())?;
Ok(Box::new(UserData {
Ok(UserData {
account: user_info,
perms: user_perms,
cubes: self.cubes.clone(),
@@ -133,7 +128,14 @@ impl <C: Clone + Send> super::UserProvider<C> for AccountProvider {
http_client: std::sync::Arc::new(reqwest::Client::new()),
db: self.db.clone(),
secret: self.secret.clone(),
}))
})
}
}
#[async_trait::async_trait]
impl <C: Clone + Send> super::UserProvider<C> for AccountProvider {
async fn authenticate(&self, token: super::UserToken) -> Result<Box<dyn super::User<C> + Send + Sync>, super::AuthError> {
Ok(Box::new(self.auth_internal(&token.token).await?))
}
async fn multiplayer_authenticate(&self, user: String) -> Result<Box<dyn super::User<C> + Send + Sync>, super::AuthError> {
@@ -174,6 +176,10 @@ impl <C: Clone + Send> super::UserProvider<C> for AccountProvider {
secret: self.secret.clone(),
}))
}
async fn web_authenticate(&self, token: String) -> Result<Box<dyn super::WebUser>, super::AuthError> {
Ok(Box::new(self.auth_internal(&token).await?))
}
}
#[async_trait::async_trait]
@@ -349,6 +355,18 @@ impl super::UserAuthenticator for AccountProvider {
async fn register(&self, info: super::RegistrationInfo) -> Result<i32, String> {
super::register_new_user(&info, &self.db).await.map_err(|e| e.to_string())
}
async fn verify(&self, token: String) -> Result<crate::auth::Token, super::AuthError> {
let secret = jsonwebtoken::DecodingKey::from_secret(&self.secret);
let mut validation = jsonwebtoken::Validation::new(jsonwebtoken::Algorithm::HS256);
validation.set_required_spec_claims::<&str>(&[]);
jsonwebtoken::decode::<crate::auth::Token>(&token, &secret, &validation)
.map_err(|e| super::AuthError {
message: e.to_string(),
code: crate::data::error_codes::AuthErrorCode::BadCredentials,
})
.map(|decoded| decoded.claims)
}
}
pub(super) struct UserData {

View File

@@ -14,6 +14,14 @@ impl super::CommonUser for UserData {
&self.account.public_id
}
fn display_name(&self) -> &'_ str {
&self.account.display_name
}
fn creation(&self) -> i64 {
self.account.creation_time
}
fn is_mod(&self) -> bool {
self.perms.moderator
}

View File

@@ -11,7 +11,7 @@ mod inventory;
pub use inventory::{UnlockedParts, UnlockOverride};
mod traits;
pub use traits::{UserProvider, User, UserToken, UserSlots, UserSlotData, VehicleData, UserAuthInfo, UserLoginInfo, UserAuthenticator, NewSlotData, UserId, RegistrationInfo, VehicleUploadData, ChatUser, AvatarInfo, GetAvatarInfo, ControlData, ControlType, CustomisationData, GetCustomisationData, SetSanction, SanctionType, LobbyUser, GameDescriptor, PlayerLobbyDescriptor, MultiplayerUser, PlayerScore, MultiplayerError, MultiplayerErrorCode, PlayerDescriptor, GameEventSetter, CurrentGameEvent, AuthError, IntercomUser, FakePlayers, ResolvedVehicle, CommonUser, IntercomListener, UserRole, SocialUser, SocialUserC, CurrencyType, CurrencyOp, MatchRewards, SingleplayerUser, PurchaseResult, FactoryUser, FriendInviteReturn, FriendData, FriendInviteStatus, SocialInfo, ClanData, ClanMember, ClanMemberRank, ClanType, ClanSearchQuery, ClanInviteData, Userless, GameOverrides};
pub use traits::{UserProvider, User, UserToken, UserSlots, UserSlotData, VehicleData, UserAuthInfo, UserLoginInfo, UserAuthenticator, NewSlotData, UserId, RegistrationInfo, VehicleUploadData, ChatUser, AvatarInfo, GetAvatarInfo, ControlData, ControlType, CustomisationData, GetCustomisationData, SetSanction, SanctionType, LobbyUser, GameDescriptor, PlayerLobbyDescriptor, MultiplayerUser, PlayerScore, MultiplayerError, MultiplayerErrorCode, PlayerDescriptor, GameEventSetter, CurrentGameEvent, AuthError, IntercomUser, FakePlayers, ResolvedVehicle, CommonUser, IntercomListener, UserRole, SocialUser, SocialUserC, CurrencyType, CurrencyOp, MatchRewards, SingleplayerUser, PurchaseResult, FactoryUser, FriendInviteReturn, FriendData, FriendInviteStatus, SocialInfo, ClanData, ClanMember, ClanMemberRank, ClanType, ClanSearchQuery, ClanInviteData, Userless, GameOverrides, WebUser};
pub mod intercom;
pub use intercom::generate_token as generate_intercom_token;
@@ -26,6 +26,7 @@ mod factory;
mod userless;
mod team;
pub use team::{TeamChooser, StandardTeamChooser};
mod web;
pub const TOKEN_SECRET_FILENAME: &str = "token_secret.key";

View File

@@ -106,18 +106,6 @@ impl UserData {
#[async_trait::async_trait]
impl super::MultiplayerUser for UserData {
fn user_id(&self) -> i32 {
self.account.id
}
fn user_name(&self) -> &'_ str {
&self.account.public_id
}
fn display_name(&self) -> &'_ str {
&self.account.display_name
}
async fn current_game(&self) -> Result<Option<super::GameDescriptor>, super::MultiplayerError> {
Ok(self.db.game_by_user_id_and_completion(self.account.id, false).await
.map_err(|e| {

View File

@@ -63,6 +63,8 @@ pub trait UserProvider<C> {
async fn authenticate(&self, user: UserToken) -> Result<Box<dyn User<C> + Send + Sync>, AuthError>;
async fn multiplayer_authenticate(&self, user: String) -> Result<Box<dyn User<C> + Send + Sync>, AuthError>;
async fn web_authenticate(&self, token: String) -> Result<Box<dyn WebUser>, AuthError>;
}
#[async_trait::async_trait]
@@ -70,6 +72,7 @@ pub trait UserAuthenticator {
async fn login(&self, info: UserAuthInfo) -> Result<UserLoginInfo, AuthError>;
async fn user_exists(&self, user: UserId) -> Result<bool, String>;
async fn register(&self, info: RegistrationInfo) -> Result<i32, String>;
async fn verify(&self, token: String) -> Result<crate::auth::Token, AuthError>;
}
#[async_trait::async_trait]
@@ -385,9 +388,6 @@ pub enum MultiplayerErrorCode {
#[async_trait::async_trait]
pub trait MultiplayerUser: IntercomUser + CommonUser {
fn user_id(&self) -> i32;
fn user_name(&self) -> &'_ str;
fn display_name(&self) -> &'_ str;
async fn current_game(&self) -> Result<Option<GameDescriptor>, MultiplayerError>;
async fn game_players(&self, guid: &str) -> Result<Vec<PlayerDescriptor>, MultiplayerError>;
async fn complete_game(&self, guid: &str) -> Result<(), MultiplayerError>;
@@ -455,6 +455,9 @@ pub trait CommonUser: Send + Sync {
fn account_id(&self) -> i32;
async fn resolve_config_vehicle(&self, vehicle: &crate::persist::config::VehicleInfo, factory: &dyn oj_rc_factory::VehicleFactoryAdapter, weapon_order: &crate::cubes::WeaponListParser, cpu_counter: &crate::cubes::CpuListParser) -> Result<ResolvedVehicle, polariton_server::operations::SimpleOpError>;
fn public_id(&self) -> &'_ str;
fn display_name(&self) -> &'_ str;
/// Seconds since Unix epoch
fn creation(&self) -> i64;
fn is_mod(&self) -> bool;
fn is_admin(&self) -> bool;
fn is_dev(&self) -> bool;
@@ -671,6 +674,11 @@ pub trait FactoryUser {
async fn rate_vehicle(&self, slot: i32, combat: i32, cosmetic: i32) -> Result<Option<i32>, polariton_server::operations::SimpleOpError>;
}
#[async_trait::async_trait]
pub trait WebUser: CommonUser {
}
#[async_trait::async_trait]
pub trait Userless: Send + Sync {
async fn lobby_state_listener(&self) -> Result<super::IntercomListener<super::intercom::IntercomLobbyStateMessage>, reqwest_websocket::Error>;

View File

@@ -0,0 +1,4 @@
#[async_trait::async_trait]
impl super::WebUser for super::account_json::UserData {
// TODO
}