1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// Copyright 2019-2024 ChainSafe Systems
// SPDX-License-Identifier: Apache-2.0, MIT

use crate::rpc::{self, auth::AuthNewParams, prelude::*};
use chrono::Duration;
use clap::Subcommand;

use super::print_rpc_res_bytes;

#[derive(Debug, Subcommand)]
pub enum AuthCommands {
    /// Create a new Authentication token with given permission
    CreateToken {
        /// Permission to assign to the token, one of: read, write, sign, admin
        #[arg(short, long)]
        perm: String,
        /// Token is revoked after this duration
        #[arg(long, default_value = "2 months")]
        expire_in: humantime::Duration,
    },
    /// Get RPC API Information
    ApiInfo {
        /// permission to assign the token, one of: read, write, sign, admin
        #[arg(short, long)]
        perm: String,
        /// Token is revoked after this duration
        #[arg(long, default_value = "2 months")]
        expire_in: humantime::Duration,
    },
}

impl AuthCommands {
    pub async fn run(self, client: rpc::Client) -> anyhow::Result<()> {
        match self {
            Self::CreateToken { perm, expire_in } => {
                let perm: String = perm.parse()?;
                let perms = AuthNewParams::process_perms(perm)?;
                let token_exp = Duration::from_std(expire_in.into())?;
                let res = AuthNew::call(&client, AuthNewParams { perms, token_exp }.into()).await?;
                print_rpc_res_bytes(res)
            }
            Self::ApiInfo { perm, expire_in } => {
                let perm: String = perm.parse()?;
                let perms = AuthNewParams::process_perms(perm)?;
                let token_exp = Duration::from_std(expire_in.into())?;
                let token = String::from_utf8(
                    AuthNew::call(&client, AuthNewParams { perms, token_exp }.into()).await?,
                )?;
                let addr = multiaddr::from_url(client.base_url().as_str())?;
                println!("FULLNODE_API_INFO=\"{}:{}\"", token, addr);
                Ok(())
            }
        }
    }
}