nabla_cli/cli/
auth.rs

1use crate::cli::{JwtData, NablaCli};
2use anyhow::Result;
3
4#[derive(clap::Args)]
5pub struct AuthArgs {
6    #[command(subcommand)]
7    pub command: Option<AuthCommands>,
8
9    /// Set JWT token for authentication
10    #[arg(long = "set-jwt")]
11    pub set_jwt: Option<String>,
12}
13
14#[derive(clap::Subcommand)]
15pub enum AuthCommands {
16    Upgrade,
17    Status,
18}
19
20impl NablaCli {
21    pub fn handle_auth_args(&mut self, args: AuthArgs) -> Result<()> {
22        // Handle --set-jwt flag first
23        if let Some(jwt_token) = args.set_jwt {
24            return self.handle_set_jwt(jwt_token);
25        }
26
27        // Handle subcommands
28        match args.command {
29            Some(AuthCommands::Upgrade) => self.handle_auth_upgrade(),
30            Some(AuthCommands::Status) => self.handle_auth_status(),
31            None => {
32                // If no subcommand provided, default to status
33                self.handle_auth_status()
34            }
35        }
36    }
37
38    fn handle_set_jwt(&mut self, jwt_token: String) -> Result<()> {
39        // Verify JWT against your signing key before storing
40        match self.jwt_store.verify_and_store_jwt(&jwt_token) {
41            Ok(jwt_data) => {
42                println!("✅ JWT token verified and set successfully!");
43                println!("User ID: {}", jwt_data.sub);
44                println!("Deployment ID: {}", jwt_data.deployment_id);
45
46                // Show available features based on JWT claims
47                println!("🎯 Enabled Features:");
48                if jwt_data.features.chat_enabled {
49                    println!("  • Chat (Premium)");
50                }
51                if jwt_data.features.api_access {
52                    println!("  • API Access");
53                }
54                if jwt_data.features.sbom_generation {
55                    println!("  • SBOM Generation");
56                }
57                if jwt_data.features.vulnerability_scanning {
58                    println!("  • Vulnerability Scanning");
59                }
60                if jwt_data.features.custom_models {
61                    println!("  • Custom Models");
62                }
63
64                self.show_portal_link(&jwt_data)?;
65            }
66            Err(e) => {
67                println!("❌ JWT verification failed: {}", e);
68                println!("💡 Please ensure you have a valid JWT token from your account manager.");
69                println!("🔐 The token must be signed with the authorized key.");
70            }
71        }
72        Ok(())
73    }
74
75    fn handle_auth_upgrade(&mut self) -> Result<()> {
76        // Check if already authenticated
77        if let Some(jwt_data) = self.jwt_store.load_jwt()? {
78            println!("✅ You are already authenticated!");
79            self.show_portal_link(&jwt_data)?;
80            return Ok(());
81        }
82
83        // Show upgrade message and open scheduling link
84        println!("🚀 Ready to upgrade to Nabla Pro?");
85        println!();
86        println!("Our security experts will help you:");
87        println!("  • Choose the right plan for your needs");
88        println!("  • Set up enterprise features like FIPS compliance");
89        println!("  • Configure integrations and deployment options");
90        println!("  • Provide dedicated support and training");
91        println!();
92
93        let scheduling_url = "https://cal.com/team/atelier-logos/platform-intro"; // Replace with your actual Calendly link
94
95        #[cfg(feature = "cloud")]
96        {
97            if let Err(e) = webbrowser::open(scheduling_url) {
98                println!("❌ Could not open browser automatically: {}", e);
99                println!("Please visit: {}", scheduling_url);
100            } else {
101                println!("🌐 Opening scheduling page in your browser...");
102                println!("📅 Schedule your demo at: {}", scheduling_url);
103            }
104        }
105
106        #[cfg(not(feature = "cloud"))]
107        {
108            println!("📅 Schedule your demo at: {}", scheduling_url);
109            println!("💡 Copy and paste this link into your browser to get started.");
110        }
111
112        Ok(())
113    }
114
115    fn handle_auth_status(&self) -> Result<()> {
116        match self.jwt_store.load_jwt()? {
117            Some(jwt_data) => {
118                println!("✅ Authenticated!");
119                println!("User ID: {}", jwt_data.sub);
120                println!("Deployment ID: {}", jwt_data.deployment_id);
121
122                // Show available features based on JWT claims
123                println!("🎯 Enabled Features:");
124                if jwt_data.features.chat_enabled {
125                    println!("  • Chat (Premium)");
126                }
127                if jwt_data.features.api_access {
128                    println!("  • API Access");
129                }
130                if jwt_data.features.sbom_generation {
131                    println!("  • SBOM Generation");
132                }
133                if jwt_data.features.vulnerability_scanning {
134                    println!("  • Vulnerability Scanning");
135                }
136                if jwt_data.features.signed_attestation {
137                    println!("  • Signed Attestation (Premium)");
138                }
139                if jwt_data.features.custom_models {
140                    println!("  • Custom Models");
141                }
142
143                self.show_portal_link(&jwt_data)?;
144            }
145            None => {
146                println!("❌ Not authenticated");
147                println!();
148                println!("To get started with Nabla Pro:");
149                println!("  • Run 'nabla upgrade' to schedule a demo");
150                println!("  • Or visit: https://cal.com/team/atelier-logos/platform-intro");
151                println!();
152                println!("After our call, you'll receive a token:");
153                println!("  nabla auth --set-jwt <YOUR_TOKEN>");
154            }
155        }
156        Ok(())
157    }
158
159    pub fn show_portal_link(&self, jwt_data: &JwtData) -> Result<()> {
160        let base_url = self.config_store.get_base_url()?;
161        self.show_auth_details(jwt_data, &base_url)
162    }
163
164    fn show_auth_details(&self, jwt_data: &JwtData, _base_url: &str) -> Result<()> {
165        println!();
166        println!("🔑 Token: {}", jwt_data.token);
167        println!();
168        println!("💡 You can also use the CLI to analyze binaries:");
169        println!("  nabla analyze /path/to/binary");
170
171        Ok(())
172    }
173}