malwaredb 0.3.2

Service for storing malicious, benign, or unknown files and related metadata and relationships.
// SPDX-License-Identifier: Apache-2.0

use malwaredb_server::State;

use std::process::ExitCode;

use anyhow::{ensure, Result};
use clap::Parser;

/// Add a user to a group
#[derive(Clone, Debug, Parser, PartialEq)]
pub struct AddUser {
    /// User ID
    #[arg(short, long)]
    pub uid: u32,

    /// Group ID
    #[arg(short, long)]
    pub gid: u32,
}

impl AddUser {
    pub async fn execute(&self, state: State) -> Result<ExitCode> {
        let users = state.db_type.list_users().await?;
        ensure!(
            users.iter().any(|u| u.id == self.uid),
            "User ID {} is not valid.",
            self.uid
        );

        let groups = state.db_type.list_groups().await?;
        ensure!(
            groups.iter().any(|g| g.id == self.gid),
            "Group ID {} is not valid.",
            self.gid
        );

        state.db_type.add_user_to_group(self.uid, self.gid).await?;
        Ok(ExitCode::SUCCESS)
    }
}

/// Create a new group
#[derive(Clone, Debug, Parser, PartialEq)]
pub struct Create {
    /// Name
    #[arg(short, long)]
    pub name: String,

    /// Description
    #[arg(short, long)]
    pub description: String,

    /// Parent group
    #[arg(short, long)]
    pub parent: Option<u32>,
}

impl Create {
    pub async fn execute(&self, state: State) -> Result<ExitCode> {
        let gid = state
            .db_type
            .create_group(&self.name, &self.description, self.parent)
            .await?;

        println!("Created group {} with ID: {gid}.", self.name);

        Ok(ExitCode::SUCCESS)
    }
}

/// List groups, optionally showing membership
#[derive(Clone, Debug, Parser, PartialEq)]
pub struct List {
    /// Show members of each group
    #[arg(short, long, default_value = "false")]
    pub members: bool,

    /// Show available sources for each group
    #[arg(short, long, default_value = "false")]
    pub sources: bool,
}

impl List {
    pub async fn execute(&self, state: State) -> Result<ExitCode> {
        for group in state.db_type.list_groups().await? {
            println!("{group}");
        }
        Ok(ExitCode::SUCCESS)
    }
}