rust/hedgewars-server/src/core/anteroom.rs
author alfadur
Sat, 22 Feb 2025 19:39:31 +0300
changeset 16120 5febd2bc5372
parent 16018 fb389df02e3e
permissions -rw-r--r--
Add server reconnection tokens and anteroom local list of used nicks
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
15543
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
     1
use super::{indexslab::IndexSlab, types::ClientId};
16120
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
     2
use crate::core::client::HwClient;
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
     3
use crate::core::digest::Sha1Digest;
15543
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
     4
use chrono::{offset, DateTime};
16120
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
     5
use std::collections::{HashMap, HashSet};
15543
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
     6
use std::{iter::Iterator, num::NonZeroU16};
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
     7
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
     8
pub struct HwAnteroomClient {
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
     9
    pub nick: Option<String>,
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    10
    pub protocol_number: Option<NonZeroU16>,
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    11
    pub server_salt: String,
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    12
    pub is_checker: bool,
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    13
    pub is_local_admin: bool,
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    14
    pub is_registered: bool,
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    15
    pub is_admin: bool,
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    16
    pub is_contributor: bool,
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    17
}
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    18
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    19
struct Ipv4AddrRange {
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    20
    min: [u8; 4],
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    21
    max: [u8; 4],
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    22
}
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    23
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    24
impl Ipv4AddrRange {
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    25
    fn contains(&self, addr: [u8; 4]) -> bool {
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    26
        (0..4).all(|i| self.min[i] <= addr[i] && addr[i] <= self.max[i])
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    27
    }
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    28
}
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    29
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    30
struct BanCollection {
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    31
    ban_ips: Vec<Ipv4AddrRange>,
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    32
    ban_timeouts: Vec<DateTime<offset::Utc>>,
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    33
    ban_reasons: Vec<String>,
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    34
}
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    35
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    36
impl BanCollection {
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    37
    fn new() -> Self {
16018
fb389df02e3e add some more todo!s
alfadur
parents: 15968
diff changeset
    38
        //todo!("add nick bans");
15543
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    39
        Self {
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    40
            ban_ips: vec![],
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    41
            ban_timeouts: vec![],
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    42
            ban_reasons: vec![],
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    43
        }
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    44
    }
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    45
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    46
    fn find(&self, addr: [u8; 4]) -> Option<String> {
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    47
        let time = offset::Utc::now();
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    48
        self.ban_ips
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    49
            .iter()
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    50
            .enumerate()
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    51
            .find(|(i, r)| r.contains(addr) && time < self.ban_timeouts[*i])
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    52
            .map(|(i, _)| self.ban_reasons[i].clone())
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    53
    }
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    54
}
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    55
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    56
pub struct HwAnteroom {
16120
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
    57
    clients: IndexSlab<HwAnteroomClient>,
15543
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    58
    bans: BanCollection,
16120
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
    59
    taken_nicks: HashSet<String>,
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
    60
    reconnection_tokens: HashMap<String, String>,
15543
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    61
}
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    62
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    63
impl HwAnteroom {
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    64
    pub fn new(clients_limit: usize) -> Self {
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    65
        let clients = IndexSlab::with_capacity(clients_limit);
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    66
        HwAnteroom {
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    67
            clients,
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    68
            bans: BanCollection::new(),
16120
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
    69
            taken_nicks: Default::default(),
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
    70
            reconnection_tokens: Default::default(),
15543
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    71
        }
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    72
    }
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    73
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    74
    pub fn find_ip_ban(&self, addr: [u8; 4]) -> Option<String> {
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    75
        self.bans.find(addr)
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    76
    }
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    77
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    78
    pub fn add_client(&mut self, client_id: ClientId, salt: String, is_local_admin: bool) {
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    79
        let client = HwAnteroomClient {
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    80
            nick: None,
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    81
            protocol_number: None,
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    82
            server_salt: salt,
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    83
            is_checker: false,
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    84
            is_local_admin,
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    85
            is_registered: false,
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    86
            is_admin: false,
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    87
            is_contributor: false,
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    88
        };
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    89
        self.clients.insert(client_id, client);
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    90
    }
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
    91
16120
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
    92
    pub fn has_client(&self, id: ClientId) -> bool {
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
    93
        self.clients.contains(id)
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
    94
    }
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
    95
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
    96
    pub fn get_client(&mut self, id: ClientId) -> &HwAnteroomClient {
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
    97
        &self.clients[id]
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
    98
    }
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
    99
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   100
    pub fn get_client_mut(&mut self, id: ClientId) -> &mut HwAnteroomClient {
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   101
        &mut self.clients[id]
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   102
    }
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   103
15543
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
   104
    pub fn remove_client(&mut self, client_id: ClientId) -> Option<HwAnteroomClient> {
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
   105
        let client = self.clients.remove(client_id);
16120
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   106
        if let Some(HwAnteroomClient {
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   107
            nick: Some(nick), ..
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   108
        }) = &client
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   109
        {
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   110
            self.taken_nicks.remove(nick);
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   111
        }
15543
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
   112
        client
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
   113
    }
16120
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   114
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   115
    pub fn nick_taken(&self, nick: &str) -> bool {
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   116
        self.taken_nicks.contains(nick)
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   117
    }
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   118
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   119
    pub fn remember_nick(&mut self, nick: String) {
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   120
        self.taken_nicks.insert(nick);
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   121
    }
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   122
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   123
    pub fn forget_nick(&mut self, nick: &str) {
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   124
        self.taken_nicks.remove(nick);
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   125
    }
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   126
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   127
    #[inline]
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   128
    pub fn get_nick_token(&self, nick: &str) -> Option<&str> {
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   129
        self.reconnection_tokens.get(nick).map(|s| &s[..])
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   130
    }
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   131
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   132
    #[inline]
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   133
    pub fn register_nick_token(&mut self, nick: &str) -> Option<&str> {
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   134
        if self.reconnection_tokens.contains_key(nick) {
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   135
            None
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   136
        } else {
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   137
            let token = format!("{:x}", Sha1Digest::random());
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   138
            self.reconnection_tokens.insert(nick.to_string(), token);
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   139
            Some(&self.reconnection_tokens[nick])
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   140
        }
5febd2bc5372 Add server reconnection tokens and anteroom local list of used nicks
alfadur
parents: 16018
diff changeset
   141
    }
15543
1fcce8feace4 lost the anteroom
alfadur <mail@none>
parents:
diff changeset
   142
}