ng_net/actors/admin/
add_user.rs

1/*
2 * Copyright (c) 2022-2025 Niko Bonnieure, Par le Peuple, NextGraph.org developers
3 * All rights reserved.
4 * Licensed under the Apache License, Version 2.0
5 * <LICENSE-APACHE2 or http://www.apache.org/licenses/LICENSE-2.0>
6 * or the MIT license <LICENSE-MIT or http://opensource.org/licenses/MIT>,
7 * at your option. All files in the project carrying such
8 * notice may not be copied, modified, or distributed except
9 * according to those terms.
10*/
11
12use std::sync::Arc;
13
14use async_std::sync::Mutex;
15use serde::{Deserialize, Serialize};
16
17use ng_repo::errors::*;
18use ng_repo::log::*;
19use ng_repo::types::PubKey;
20
21use super::super::StartProtocol;
22
23use crate::broker::{ServerConfig, BROKER};
24use crate::connection::NoiseFSM;
25use crate::types::*;
26use crate::{actor::*, types::ProtocolMessage};
27
28/// Add user account
29#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
30pub struct AddUserV0 {
31    /// User pub key
32    pub user: PubKey,
33    /// should the newly added user be an admin of the server
34    pub is_admin: bool,
35}
36
37/// Add user account
38#[derive(Clone, Copy, Debug, Serialize, Deserialize)]
39pub enum AddUser {
40    V0(AddUserV0),
41}
42
43impl AddUser {
44    pub fn user(&self) -> PubKey {
45        match self {
46            AddUser::V0(o) => o.user,
47        }
48    }
49    pub fn is_admin(&self) -> bool {
50        match self {
51            AddUser::V0(o) => o.is_admin,
52        }
53    }
54    pub fn get_actor(&self) -> Box<dyn EActor> {
55        Actor::<AddUser, AdminResponse>::new_responder(0)
56    }
57}
58
59impl TryFrom<ProtocolMessage> for AddUser {
60    type Error = ProtocolError;
61    fn try_from(msg: ProtocolMessage) -> Result<Self, Self::Error> {
62        if let ProtocolMessage::Start(StartProtocol::Admin(AdminRequest::V0(AdminRequestV0 {
63            content: AdminRequestContentV0::AddUser(a),
64            ..
65        }))) = msg
66        {
67            Ok(a)
68        } else {
69            log_debug!("INVALID {:?}", msg);
70            Err(ProtocolError::InvalidValue)
71        }
72    }
73}
74
75impl From<AddUser> for ProtocolMessage {
76    fn from(_msg: AddUser) -> ProtocolMessage {
77        unimplemented!();
78    }
79}
80
81impl From<AddUser> for AdminRequestContentV0 {
82    fn from(msg: AddUser) -> AdminRequestContentV0 {
83        AdminRequestContentV0::AddUser(msg)
84    }
85}
86
87impl Actor<'_, AddUser, AdminResponse> {}
88
89#[async_trait::async_trait]
90impl EActor for Actor<'_, AddUser, AdminResponse> {
91    async fn respond(
92        &mut self,
93        msg: ProtocolMessage,
94        fsm: Arc<Mutex<NoiseFSM>>,
95    ) -> Result<(), ProtocolError> {
96        let req = AddUser::try_from(msg)?;
97
98        let res = {
99            let mut is_admin = req.is_admin();
100            let sb = {
101                let broker = BROKER.read().await;
102                if let Some(ServerConfig {
103                    admin_user: Some(admin_user),
104                    ..
105                }) = broker.get_config()
106                {
107                    if *admin_user == req.user() {
108                        is_admin = true;
109                    }
110                }
111                broker.get_server_broker()?
112            };
113
114            let lock = sb.read().await;
115            lock.add_user(req.user(), is_admin)
116        };
117        let response: AdminResponseV0 = res.into();
118        fsm.lock().await.send(response.into()).await?;
119        Ok(())
120    }
121}