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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
mod publish_db;
mod publish_sc;

use crate::types::{ Audit };

use publish_db::publish_audit_db;

use publish_sc::publish_audit_sc;

use crate::{
    cmd::utils::{ upload_ipfs, generate_pdf_from_url },
    utils::{ apply_dotenv, parse_json, validate_pdf, validate_links },
};

use std::path::PathBuf;

use clap::{ Parser, ValueHint };

#[allow(clippy::module_name_repetitions)]
#[derive(Debug, Clone, Parser)]
pub struct PublishAuditArgs {
    #[clap(
        short,
        long = "audit-data",
        help = "File path to JSON file with Audit data",
        value_name = "AUDIT_DATA_JSON_FILE",
        value_hint = ValueHint::FilePath,
        required(true)
    )]
    audit_file_path: PathBuf,

    #[clap(
        short,
        long = "report-pdf",
        help = "File path to audit report PDF file",
        value_name = "AUDIT_REPORT_PDF_FILE",
        value_hint = ValueHint::FilePath,
        value_parser = validate_pdf,
        required(true)
    )]
    report_pdf_file_path: Option<PathBuf>,

    #[clap(
        short = 'u',
        long = "report-url",
        help = "Url to audit report",
        value_name = "AUDIT_REPORT_URL",
        value_hint = ValueHint::Url,
        value_parser = validate_links,
        conflicts_with = "report_pdf_file_path",
        required(true)
    )]
    report_url: Option<String>,

    #[clap(short = 'k', long)]
    api_key: Option<String>,

    #[clap(short = 'p', long)]
    private_key: Option<String>,

    #[clap(short = 's', long, help = "Publish an audit to SC", default_value = "false")]
    publish_sc: bool,
}

impl PublishAuditArgs {
    #[allow(clippy::future_not_send)]
    pub async fn run(self) -> eyre::Result<()> {
        apply_dotenv()?;

        let audit_data = parse_json::<Audit>(&self.audit_file_path)?;

        let api_key = match self.api_key {
            Some(token) => token,
            None => std::env::var("API_KEY")?,
        };

        let project_id = audit_data.project.clone().fetch_project_id().await?;

        let report_pdf_file_path = match self.report_pdf_file_path {
            Some(path) => path,
            None => {
                generate_pdf_from_url(self.report_url.expect("should not fail"), &api_key).await?
            }
        };

        let (report_hash, report_file_url) = upload_ipfs(report_pdf_file_path, &api_key).await?;

        let audit_data = publish_audit_db(
            audit_data,
            project_id,
            report_hash.clone(),
            report_file_url,
            &api_key
        ).await?;

        if self.publish_sc {
            publish_audit_sc(
                &audit_data,
                &audit_data.project.name,
                report_hash,
                self.private_key,
                &api_key
            ).await?;
        }

        println!("Audit published successfully");

        Ok(())
    }
}