1616import sys
1717
1818from planet_auth import (
19+ Auth ,
1920 AuthException ,
2021 FileBackedOidcCredential ,
2122 OidcAuthClient ,
2223 ExpiredTokenException ,
2324 ClientCredentialsAuthClientBase ,
2425)
26+ from planet_auth_utils .plauth_factory import PlanetAuthFactory
2527
2628from .options import (
2729 opt_audience ,
3234 opt_open_browser ,
3335 opt_organization ,
3436 opt_password ,
37+ opt_profile ,
3538 opt_project ,
3639 opt_refresh ,
3740 opt_scope ,
4447from .jwt_cmd import json_dumps_for_jwt_dict , hazmat_print_jwt
4548
4649
47- def _check_client_type ( ctx ):
48- if not isinstance (ctx . obj [ "AUTH" ] .auth_client (), OidcAuthClient ):
50+ def _check_auth_client_type ( plauth_context : Auth ):
51+ if not isinstance (plauth_context .auth_client (), OidcAuthClient ):
4952 raise click .ClickException (
5053 f'"oauth" auth commands can only be used with OAuth type auth profiles.'
51- f' The current profile "{ ctx . obj [ "AUTH" ]. profile_name ()} " is of type "{ ctx . obj [ "AUTH" ] .auth_client ()._auth_client_config .meta ()["client_type" ]} ".'
54+ f' The current profile "{ plauth_context . profile_name ()} " is of type "{ plauth_context .auth_client ()._auth_client_config .meta ()["client_type" ]} ".'
5255 )
5356
5457
58+ def _check_auth_client_type_for_click_ctx (click_ctx ):
59+ _check_auth_client_type (click_ctx .obj ["AUTH" ])
60+
61+
5562@click .group ("oauth" , invoke_without_command = True )
5663@click .pass_context
5764def cmd_oauth (ctx ):
@@ -62,27 +69,27 @@ def cmd_oauth(ctx):
6269 click .echo (ctx .get_help ())
6370 sys .exit (0 )
6471
65- _check_client_type (ctx )
66-
6772
6873@cmd_oauth .command ("login" )
6974@opt_open_browser ()
7075@opt_qr_code ()
71- @opt_scope ()
72- @opt_audience ()
73- @opt_organization ()
74- @opt_project ()
75- @opt_username ()
76- @opt_password ()
77- @opt_client_id ()
78- @opt_client_secret ()
76+ @opt_profile (envvar = None )
77+ @opt_scope (envvar = None )
78+ @opt_audience (envvar = None )
79+ @opt_organization (envvar = None )
80+ @opt_project (envvar = None )
81+ @opt_username (envvar = None )
82+ @opt_password (envvar = None )
83+ @opt_client_id (envvar = None )
84+ @opt_client_secret (envvar = None )
7985@opt_sops ()
8086@opt_yes_no ()
81- @opt_extra ()
87+ @opt_extra (envvar = None )
8288@click .pass_context
83- @recast_exceptions_to_click (AuthException , ValueError )
89+ @recast_exceptions_to_click (AuthException , ValueError , FileNotFoundError )
8490def cmd_oauth_login (
8591 ctx ,
92+ auth_profile ,
8693 scope ,
8794 audience ,
8895 open_browser ,
@@ -113,9 +120,24 @@ def cmd_oauth_login(
113120 # a particular organization at login when the user belongs to more than one.
114121 login_extra ["organization" ] = organization
115122
116- current_auth_context = ctx .obj ["AUTH" ]
117- print (f"Logging in with authentication profile { current_auth_context .profile_name ()} ..." )
118- current_auth_context .login (
123+ # Like the root login command, the expected behavior of the oauth "login" command is
124+ # to do what it is told, not fall back to defaults and user prefs in unexpected ways.
125+ # We ignore env vars and the config file.
126+ # root_cmd_auth_context = ctx.obj["AUTH"]
127+ override_auth_context = PlanetAuthFactory .initialize_auth_client_context (
128+ auth_profile_opt = auth_profile ,
129+ auth_client_id_opt = auth_client_id ,
130+ auth_client_secret_opt = auth_client_secret ,
131+ # auth_username_opt=auth_username,
132+ # auth_password_opt=auth_password,
133+ use_env = False ,
134+ use_configfile = False ,
135+ # TODO: Save extras/project/organization/scopes in context / created auth client config.
136+ )
137+ _check_auth_client_type (override_auth_context )
138+
139+ print (f"Logging in with authentication profile { override_auth_context .profile_name ()} ..." )
140+ override_auth_context .login (
119141 requested_scopes = scope ,
120142 requested_audiences = audience ,
121143 allow_open_browser = open_browser ,
@@ -128,7 +150,7 @@ def cmd_oauth_login(
128150 extra = login_extra ,
129151 )
130152 print ("Login succeeded." ) # Errors should throw.
131- post_login_cmd_helper (override_auth_context = current_auth_context , use_sops = sops , prompt_pre_selection = yes )
153+ post_login_cmd_helper (override_auth_context = override_auth_context , use_sops = sops , prompt_pre_selection = yes )
132154
133155
134156@cmd_oauth .command ("refresh" )
@@ -143,6 +165,7 @@ def cmd_oauth_refresh(ctx, scope):
143165 from what is currently possessed, but you will never be granted
144166 more scopes than what the user has authorized.
145167 """
168+ _check_auth_client_type_for_click_ctx (ctx )
146169 saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
147170 auth_client = ctx .obj ["AUTH" ].auth_client ()
148171 saved_token .load ()
@@ -162,6 +185,7 @@ def cmd_oauth_list_scopes(ctx):
162185
163186 This command will query the auth server for available scopes that may be requested.
164187 """
188+ _check_auth_client_type_for_click_ctx (ctx )
165189 auth_client = ctx .obj ["AUTH" ].auth_client ()
166190 available_scopes = auth_client .get_scopes ()
167191 available_scopes .sort ()
@@ -178,6 +202,7 @@ def cmd_oauth_discovery(ctx):
178202 """
179203 Look up OAuth server discovery information.
180204 """
205+ _check_auth_client_type_for_click_ctx (ctx )
181206 auth_client = ctx .obj ["AUTH" ].auth_client ()
182207 discovery_json = auth_client .oidc_discovery ()
183208 print_obj (discovery_json )
@@ -192,6 +217,7 @@ def cmd_oauth_validate_access_token_remote(ctx, human_readable):
192217 Validate the access token. Validation is performed by calling
193218 out to the auth provider's token introspection network service.
194219 """
220+ _check_auth_client_type_for_click_ctx (ctx )
195221 saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
196222 auth_client = ctx .obj ["AUTH" ].auth_client ()
197223 saved_token .load ()
@@ -226,6 +252,7 @@ def cmd_oauth_validate_access_token_local(ctx, audience, scope, human_readable):
226252 Access tokens are intended for consumption by resource servers,
227253 and may be opaque to the client.
228254 """
255+ _check_auth_client_type_for_click_ctx (ctx )
229256 saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
230257 auth_client = ctx .obj ["AUTH" ].auth_client ()
231258 saved_token .load ()
@@ -246,6 +273,7 @@ def cmd_oauth_validate_id_token_remote(ctx, human_readable):
246273 Validate the ID token. Validation is performed by calling
247274 out to the auth provider's token introspection network service.
248275 """
276+ _check_auth_client_type_for_click_ctx (ctx )
249277 saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
250278 auth_client = ctx .obj ["AUTH" ].auth_client ()
251279 saved_token .load ()
@@ -269,6 +297,7 @@ def cmd_oauth_validate_id_token_local(ctx, human_readable):
269297 While validation is performed locally, network access is still
270298 required to obtain the signing keys from the auth provider.
271299 """
300+ _check_auth_client_type_for_click_ctx (ctx )
272301 saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
273302 auth_client = ctx .obj ["AUTH" ].auth_client ()
274303 saved_token .load ()
@@ -287,6 +316,7 @@ def cmd_oauth_validate_refresh_token_remote(ctx, human_readable):
287316 Validate the refresh token. Validation is performed by calling
288317 out to the auth provider's token introspection network service.
289318 """
319+ _check_auth_client_type_for_click_ctx (ctx )
290320 saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
291321 auth_client = ctx .obj ["AUTH" ].auth_client ()
292322 saved_token .load ()
@@ -315,6 +345,7 @@ def cmd_oauth_revoke_access_token(ctx):
315345 access tokens are accepted as bearer tokens, or double verified against
316346 the auth services.
317347 """
348+ _check_auth_client_type_for_click_ctx (ctx )
318349 saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
319350 auth_client = ctx .obj ["AUTH" ].auth_client ()
320351 saved_token .load ()
@@ -333,6 +364,7 @@ def cmd_oauth_revoke_refresh_token(ctx):
333364 revoke the current access token, which may remain potent until its
334365 natural expiration time if not also revoked.
335366 """
367+ _check_auth_client_type_for_click_ctx (ctx )
336368 saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
337369 auth_client = ctx .obj ["AUTH" ].auth_client ()
338370 saved_token .load ()
@@ -346,6 +378,7 @@ def cmd_oauth_userinfo(ctx):
346378 """
347379 Look up user information from the auth server using the access token.
348380 """
381+ _check_auth_client_type_for_click_ctx (ctx )
349382 saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
350383 auth_client = ctx .obj ["AUTH" ].auth_client ()
351384 saved_token .load ()
@@ -363,6 +396,7 @@ def cmd_oauth_print_access_token(ctx, refresh):
363396 """
364397 Show the current OAuth access token. Stale tokens will be automatically refreshed.
365398 """
399+ _check_auth_client_type_for_click_ctx (ctx )
366400 saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
367401 saved_token .load ()
368402
@@ -400,6 +434,7 @@ def cmd_oauth_decode_jwt_access_token(ctx, human_readable):
400434 This function will not work for authorization servers that issue
401435 access tokens in other formats.
402436 """
437+ _check_auth_client_type_for_click_ctx (ctx )
403438 saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
404439 hazmat_print_jwt (saved_token .access_token (), human_readable = human_readable )
405440
@@ -414,6 +449,7 @@ def cmd_oauth_decode_jwt_id_token(ctx, human_readable):
414449 VALIDATION IS PERFORMED. This function is intended for local
415450 debugging purposes.
416451 """
452+ _check_auth_client_type_for_click_ctx (ctx )
417453 saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
418454 hazmat_print_jwt (saved_token .id_token (), human_readable = human_readable )
419455
@@ -430,5 +466,6 @@ def cmd_oauth_decode_jwt_refresh_token(ctx, human_readable):
430466 This function will not work for authorization servers that issue
431467 refresh tokens in other formats.
432468 """
469+ _check_auth_client_type_for_click_ctx (ctx )
433470 saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
434471 hazmat_print_jwt (saved_token .refresh_token (), human_readable = human_readable )
0 commit comments