@@ -7,7 +7,10 @@ use std::process::{
7
7
use std:: time:: Duration ;
8
8
9
9
use anstream:: println;
10
- use clap:: Subcommand ;
10
+ use clap:: {
11
+ Args ,
12
+ Subcommand ,
13
+ } ;
11
14
use crossterm:: style:: Stylize ;
12
15
use eyre:: {
13
16
Result ,
@@ -46,7 +49,7 @@ use crate::util::{
46
49
#[ derive( Subcommand , Debug , PartialEq , Eq ) ]
47
50
pub enum RootUserSubcommand {
48
51
/// Login
49
- Login ,
52
+ Login ( LoginArgs ) ,
50
53
/// Logout
51
54
Logout ,
52
55
/// Prints details about the current user
@@ -57,6 +60,29 @@ pub enum RootUserSubcommand {
57
60
} ,
58
61
}
59
62
63
+ #[ derive( Args , Debug , PartialEq , Eq , Clone ) ]
64
+ pub struct LoginArgs {
65
+ /// License type (pro for Identity Center, free for Builder ID)
66
+ #[ arg( long, value_enum) ]
67
+ pub license : Option < LicenseType > ,
68
+
69
+ /// Identity provider URL (for Identity Center)
70
+ #[ arg( long) ]
71
+ pub identity_provider : Option < String > ,
72
+
73
+ /// Region (for Identity Center)
74
+ #[ arg( long) ]
75
+ pub region : Option < String > ,
76
+ }
77
+
78
+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , clap:: ValueEnum ) ]
79
+ pub enum LicenseType {
80
+ /// Free license with Builder ID
81
+ Free ,
82
+ /// Pro license with Identity Center
83
+ Pro ,
84
+ }
85
+
60
86
#[ derive( Debug , Clone , Copy , PartialEq , Eq ) ]
61
87
enum AuthMethod {
62
88
/// Builder ID (free)
@@ -77,15 +103,15 @@ impl Display for AuthMethod {
77
103
impl RootUserSubcommand {
78
104
pub async fn execute ( self ) -> Result < ExitCode > {
79
105
match self {
80
- Self :: Login => {
106
+ Self :: Login ( args ) => {
81
107
if fig_auth:: is_logged_in ( ) . await {
82
108
eyre:: bail!(
83
109
"Already logged in, please logout with {} first" ,
84
110
format!( "{CLI_BINARY_NAME} logout" ) . magenta( )
85
111
) ;
86
112
}
87
113
88
- login_interactive ( ) . await ?;
114
+ login_interactive ( args ) . await ?;
89
115
90
116
Ok ( ExitCode :: SUCCESS )
91
117
} ,
@@ -155,23 +181,44 @@ impl UserSubcommand {
155
181
}
156
182
}
157
183
158
- pub async fn login_interactive ( ) -> Result < ( ) > {
159
- let options = [ AuthMethod :: BuilderId , AuthMethod :: IdentityCenter ] ;
160
- let i = match choose ( "Select login method" , & options) ? {
161
- Some ( i) => i,
162
- None => bail ! ( "No login method selected" ) ,
184
+ pub async fn login_interactive ( args : LoginArgs ) -> Result < ( ) > {
185
+ let login_method = match args. license {
186
+ Some ( LicenseType :: Free ) => AuthMethod :: BuilderId ,
187
+ Some ( LicenseType :: Pro ) => AuthMethod :: IdentityCenter ,
188
+ None => {
189
+ // No license specified, prompt the user to choose
190
+ let options = [ AuthMethod :: BuilderId , AuthMethod :: IdentityCenter ] ;
191
+ let i = match choose ( "Select login method" , & options) ? {
192
+ Some ( i) => i,
193
+ None => bail ! ( "No login method selected" ) ,
194
+ } ;
195
+ options[ i]
196
+ } ,
163
197
} ;
164
- let login_method = options [ i ] ;
198
+
165
199
match login_method {
166
200
AuthMethod :: BuilderId | AuthMethod :: IdentityCenter => {
167
201
let ( start_url, region) = match login_method {
168
202
AuthMethod :: BuilderId => ( None , None ) ,
169
203
AuthMethod :: IdentityCenter => {
170
- let default_start_url = fig_settings:: state:: get_string ( "auth.idc.start-url" ) . ok ( ) . flatten ( ) ;
171
- let default_region = fig_settings:: state:: get_string ( "auth.idc.region" ) . ok ( ) . flatten ( ) ;
204
+ let default_start_url = args
205
+ . identity_provider
206
+ . or_else ( || fig_settings:: state:: get_string ( "auth.idc.start-url" ) . ok ( ) . flatten ( ) ) ;
207
+ let default_region = args
208
+ . region
209
+ . or_else ( || fig_settings:: state:: get_string ( "auth.idc.region" ) . ok ( ) . flatten ( ) ) ;
210
+
211
+ let start_url = if let Some ( url) = default_start_url. clone ( ) {
212
+ url
213
+ } else {
214
+ input ( "Enter Start URL" , default_start_url. as_deref ( ) ) ?
215
+ } ;
172
216
173
- let start_url = input ( "Enter Start URL" , default_start_url. as_deref ( ) ) ?;
174
- let region = input ( "Enter Region" , default_region. as_deref ( ) ) ?;
217
+ let region = if let Some ( reg) = default_region. clone ( ) {
218
+ reg
219
+ } else {
220
+ input ( "Enter Region" , default_region. as_deref ( ) ) ?
221
+ } ;
175
222
176
223
let _ = fig_settings:: state:: set_value ( "auth.idc.start-url" , start_url. clone ( ) ) ;
177
224
let _ = fig_settings:: state:: set_value ( "auth.idc.region" , region. clone ( ) ) ;
0 commit comments