mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Server auth handling improvements.
This commit is contained in:
parent
584dcddba9
commit
403deecc6d
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -3878,6 +3878,7 @@ dependencies = [
|
||||
name = "veloren-common"
|
||||
version = "0.5.0"
|
||||
dependencies = [
|
||||
"authc 1.0.0 (git+https://gitlab.com/veloren/auth.git?rev=7c1abde83f0ea7d83b0e7c655fac82eb9bb3d7ad)",
|
||||
"bincode 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"criterion 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"crossbeam 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -552,6 +552,7 @@ impl Client {
|
||||
ServerError::TooManyPlayers => return Err(Error::ServerWentMad),
|
||||
ServerError::InvalidAuth => return Err(Error::InvalidAuth),
|
||||
ServerError::AlreadyLoggedIn => return Err(Error::AlreadyLoggedIn),
|
||||
ServerError::AuthError(_) => unreachable!(),
|
||||
//TODO: ServerError::InvalidAlias => return Err(Error::InvalidAlias),
|
||||
},
|
||||
ServerMsg::Shutdown => return Err(Error::ServerShutdown),
|
||||
|
@ -33,6 +33,7 @@ crossbeam = "=0.7.2"
|
||||
notify = "5.0.0-pre.1"
|
||||
indexmap = "1.3.0"
|
||||
sum_type = "0.2.0"
|
||||
authc = { git = "https://gitlab.com/veloren/auth.git", rev = "7c1abde83f0ea7d83b0e7c655fac82eb9bb3d7ad" }
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = "0.3"
|
||||
|
@ -4,6 +4,7 @@ use crate::{
|
||||
terrain::{Block, TerrainChunk},
|
||||
ChatType,
|
||||
};
|
||||
use authc::AuthClientError;
|
||||
use hashbrown::HashMap;
|
||||
use vek::*;
|
||||
|
||||
@ -88,9 +89,14 @@ pub enum ServerError {
|
||||
TooManyPlayers,
|
||||
InvalidAuth,
|
||||
AlreadyLoggedIn,
|
||||
AuthError(String),
|
||||
//TODO: InvalidAlias,
|
||||
}
|
||||
|
||||
impl From<AuthClientError> for ServerError {
|
||||
fn from(err: AuthClientError) -> Self { Self::AuthError(err.to_string()) }
|
||||
}
|
||||
|
||||
impl ServerMsg {
|
||||
pub fn chat(message: String) -> ServerMsg {
|
||||
ServerMsg::ChatMsg {
|
||||
|
@ -1,8 +1,39 @@
|
||||
use authc::{AuthClient, AuthToken};
|
||||
use authc::{AuthClient, AuthToken, Uuid};
|
||||
use common::msg::ServerError;
|
||||
use hashbrown::HashMap;
|
||||
use std::str::FromStr;
|
||||
|
||||
fn contains_value(map: &HashMap<String, String>, value: &str) -> bool {
|
||||
let mut contains = false;
|
||||
for ev in map.values() {
|
||||
if value == ev {
|
||||
contains = true;
|
||||
}
|
||||
}
|
||||
contains
|
||||
}
|
||||
|
||||
fn derive_uuid(username: &str) -> Uuid {
|
||||
let mut state: [u8; 16] = [
|
||||
52, 17, 19, 239, 52, 17, 19, 239, 52, 17, 19, 239, 52, 17, 19, 239,
|
||||
];
|
||||
for mix_byte_1 in username.as_bytes() {
|
||||
for i in 0..16 {
|
||||
let mix_byte_step: u8 = mix_byte_1
|
||||
.wrapping_pow(239)
|
||||
.wrapping_mul((i as u8).wrapping_pow(43));
|
||||
let mix_byte_2 = state[i + mix_byte_step as usize % 16];
|
||||
let rot_step: u8 = mix_byte_1
|
||||
.wrapping_pow(29)
|
||||
.wrapping_mul((i as u8).wrapping_pow(163));
|
||||
state[i] = (state[i] ^ mix_byte_1)
|
||||
.wrapping_mul(mix_byte_2)
|
||||
.rotate_left(rot_step as u32);
|
||||
}
|
||||
}
|
||||
Uuid::from_slice(&state).unwrap()
|
||||
}
|
||||
|
||||
pub struct AuthProvider {
|
||||
accounts: HashMap<String, String>,
|
||||
auth_server: Option<AuthClient>,
|
||||
@ -27,28 +58,29 @@ impl AuthProvider {
|
||||
match &self.auth_server {
|
||||
// Token from auth server expected
|
||||
Some(srv) => {
|
||||
// TODO: Check if already logged in!
|
||||
log::info!("Validating '{}' token.", &username_or_token);
|
||||
match srv.validate(
|
||||
AuthToken::from_str(&username_or_token).expect("Failed parsing token"), // TODO: POSSIBLE DOS, handle result!
|
||||
) {
|
||||
Ok(id) => {
|
||||
// TODO: Get username!
|
||||
self.accounts.insert("peter".into(), id.to_string());
|
||||
Ok(true)
|
||||
}
|
||||
Err(e) => {
|
||||
log::error!("{}", e);
|
||||
Ok(false)
|
||||
if let Ok(token) = AuthToken::from_str(&username_or_token) {
|
||||
match srv.validate(token) {
|
||||
Ok(id) => {
|
||||
if contains_value(&self.accounts, &id.to_string()) {
|
||||
return Err(ServerError::AlreadyLoggedIn);
|
||||
}
|
||||
let username = srv.uuid_to_username(id.clone())?;
|
||||
self.accounts.insert(username, id.to_string());
|
||||
Ok(true)
|
||||
},
|
||||
Err(e) => Err(ServerError::from(e)),
|
||||
}
|
||||
} else {
|
||||
Ok(false)
|
||||
}
|
||||
},
|
||||
// Username is expected
|
||||
None => {
|
||||
if !self.accounts.contains_key(&username_or_token) {
|
||||
log::info!("New User '{}'", username_or_token);
|
||||
self.accounts
|
||||
.insert(username_or_token, "whateverUUID".into()); // TODO: generate UUID
|
||||
let uuid = derive_uuid(&username_or_token);
|
||||
self.accounts.insert(username_or_token, uuid.to_string());
|
||||
Ok(true)
|
||||
} else {
|
||||
Err(ServerError::AlreadyLoggedIn)
|
||||
|
Loading…
Reference in New Issue
Block a user