16
16
import sys
17
17
18
18
from planet_auth import (
19
+ Auth ,
19
20
AuthException ,
20
21
FileBackedOidcCredential ,
21
22
OidcAuthClient ,
22
23
ExpiredTokenException ,
23
24
ClientCredentialsAuthClientBase ,
24
25
)
26
+ from planet_auth_utils .plauth_factory import PlanetAuthFactory
25
27
26
28
from .options import (
27
29
opt_audience ,
32
34
opt_open_browser ,
33
35
opt_organization ,
34
36
opt_password ,
37
+ opt_profile ,
35
38
opt_project ,
36
39
opt_refresh ,
37
40
opt_scope ,
44
47
from .jwt_cmd import json_dumps_for_jwt_dict , hazmat_print_jwt
45
48
46
49
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 ):
49
52
raise click .ClickException (
50
53
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" ]} ".'
52
55
)
53
56
54
57
58
+ def _check_auth_client_type_for_click_ctx (click_ctx ):
59
+ _check_auth_client_type (click_ctx .obj ["AUTH" ])
60
+
61
+
55
62
@click .group ("oauth" , invoke_without_command = True )
56
63
@click .pass_context
57
64
def cmd_oauth (ctx ):
@@ -62,27 +69,27 @@ def cmd_oauth(ctx):
62
69
click .echo (ctx .get_help ())
63
70
sys .exit (0 )
64
71
65
- _check_client_type (ctx )
66
-
67
72
68
73
@cmd_oauth .command ("login" )
69
74
@opt_open_browser ()
70
75
@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 )
79
85
@opt_sops ()
80
86
@opt_yes_no ()
81
- @opt_extra ()
87
+ @opt_extra (envvar = None )
82
88
@click .pass_context
83
- @recast_exceptions_to_click (AuthException , ValueError )
89
+ @recast_exceptions_to_click (AuthException , ValueError , FileNotFoundError )
84
90
def cmd_oauth_login (
85
91
ctx ,
92
+ auth_profile ,
86
93
scope ,
87
94
audience ,
88
95
open_browser ,
@@ -113,9 +120,24 @@ def cmd_oauth_login(
113
120
# a particular organization at login when the user belongs to more than one.
114
121
login_extra ["organization" ] = organization
115
122
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 (
119
141
requested_scopes = scope ,
120
142
requested_audiences = audience ,
121
143
allow_open_browser = open_browser ,
@@ -128,7 +150,7 @@ def cmd_oauth_login(
128
150
extra = login_extra ,
129
151
)
130
152
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 )
132
154
133
155
134
156
@cmd_oauth .command ("refresh" )
@@ -143,6 +165,7 @@ def cmd_oauth_refresh(ctx, scope):
143
165
from what is currently possessed, but you will never be granted
144
166
more scopes than what the user has authorized.
145
167
"""
168
+ _check_auth_client_type_for_click_ctx (ctx )
146
169
saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
147
170
auth_client = ctx .obj ["AUTH" ].auth_client ()
148
171
saved_token .load ()
@@ -162,6 +185,7 @@ def cmd_oauth_list_scopes(ctx):
162
185
163
186
This command will query the auth server for available scopes that may be requested.
164
187
"""
188
+ _check_auth_client_type_for_click_ctx (ctx )
165
189
auth_client = ctx .obj ["AUTH" ].auth_client ()
166
190
available_scopes = auth_client .get_scopes ()
167
191
available_scopes .sort ()
@@ -178,6 +202,7 @@ def cmd_oauth_discovery(ctx):
178
202
"""
179
203
Look up OAuth server discovery information.
180
204
"""
205
+ _check_auth_client_type_for_click_ctx (ctx )
181
206
auth_client = ctx .obj ["AUTH" ].auth_client ()
182
207
discovery_json = auth_client .oidc_discovery ()
183
208
print_obj (discovery_json )
@@ -192,6 +217,7 @@ def cmd_oauth_validate_access_token_remote(ctx, human_readable):
192
217
Validate the access token. Validation is performed by calling
193
218
out to the auth provider's token introspection network service.
194
219
"""
220
+ _check_auth_client_type_for_click_ctx (ctx )
195
221
saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
196
222
auth_client = ctx .obj ["AUTH" ].auth_client ()
197
223
saved_token .load ()
@@ -226,6 +252,7 @@ def cmd_oauth_validate_access_token_local(ctx, audience, scope, human_readable):
226
252
Access tokens are intended for consumption by resource servers,
227
253
and may be opaque to the client.
228
254
"""
255
+ _check_auth_client_type_for_click_ctx (ctx )
229
256
saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
230
257
auth_client = ctx .obj ["AUTH" ].auth_client ()
231
258
saved_token .load ()
@@ -246,6 +273,7 @@ def cmd_oauth_validate_id_token_remote(ctx, human_readable):
246
273
Validate the ID token. Validation is performed by calling
247
274
out to the auth provider's token introspection network service.
248
275
"""
276
+ _check_auth_client_type_for_click_ctx (ctx )
249
277
saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
250
278
auth_client = ctx .obj ["AUTH" ].auth_client ()
251
279
saved_token .load ()
@@ -269,6 +297,7 @@ def cmd_oauth_validate_id_token_local(ctx, human_readable):
269
297
While validation is performed locally, network access is still
270
298
required to obtain the signing keys from the auth provider.
271
299
"""
300
+ _check_auth_client_type_for_click_ctx (ctx )
272
301
saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
273
302
auth_client = ctx .obj ["AUTH" ].auth_client ()
274
303
saved_token .load ()
@@ -287,6 +316,7 @@ def cmd_oauth_validate_refresh_token_remote(ctx, human_readable):
287
316
Validate the refresh token. Validation is performed by calling
288
317
out to the auth provider's token introspection network service.
289
318
"""
319
+ _check_auth_client_type_for_click_ctx (ctx )
290
320
saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
291
321
auth_client = ctx .obj ["AUTH" ].auth_client ()
292
322
saved_token .load ()
@@ -315,6 +345,7 @@ def cmd_oauth_revoke_access_token(ctx):
315
345
access tokens are accepted as bearer tokens, or double verified against
316
346
the auth services.
317
347
"""
348
+ _check_auth_client_type_for_click_ctx (ctx )
318
349
saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
319
350
auth_client = ctx .obj ["AUTH" ].auth_client ()
320
351
saved_token .load ()
@@ -333,6 +364,7 @@ def cmd_oauth_revoke_refresh_token(ctx):
333
364
revoke the current access token, which may remain potent until its
334
365
natural expiration time if not also revoked.
335
366
"""
367
+ _check_auth_client_type_for_click_ctx (ctx )
336
368
saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
337
369
auth_client = ctx .obj ["AUTH" ].auth_client ()
338
370
saved_token .load ()
@@ -346,6 +378,7 @@ def cmd_oauth_userinfo(ctx):
346
378
"""
347
379
Look up user information from the auth server using the access token.
348
380
"""
381
+ _check_auth_client_type_for_click_ctx (ctx )
349
382
saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
350
383
auth_client = ctx .obj ["AUTH" ].auth_client ()
351
384
saved_token .load ()
@@ -363,6 +396,7 @@ def cmd_oauth_print_access_token(ctx, refresh):
363
396
"""
364
397
Show the current OAuth access token. Stale tokens will be automatically refreshed.
365
398
"""
399
+ _check_auth_client_type_for_click_ctx (ctx )
366
400
saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
367
401
saved_token .load ()
368
402
@@ -400,6 +434,7 @@ def cmd_oauth_decode_jwt_access_token(ctx, human_readable):
400
434
This function will not work for authorization servers that issue
401
435
access tokens in other formats.
402
436
"""
437
+ _check_auth_client_type_for_click_ctx (ctx )
403
438
saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
404
439
hazmat_print_jwt (saved_token .access_token (), human_readable = human_readable )
405
440
@@ -414,6 +449,7 @@ def cmd_oauth_decode_jwt_id_token(ctx, human_readable):
414
449
VALIDATION IS PERFORMED. This function is intended for local
415
450
debugging purposes.
416
451
"""
452
+ _check_auth_client_type_for_click_ctx (ctx )
417
453
saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
418
454
hazmat_print_jwt (saved_token .id_token (), human_readable = human_readable )
419
455
@@ -430,5 +466,6 @@ def cmd_oauth_decode_jwt_refresh_token(ctx, human_readable):
430
466
This function will not work for authorization servers that issue
431
467
refresh tokens in other formats.
432
468
"""
469
+ _check_auth_client_type_for_click_ctx (ctx )
433
470
saved_token = FileBackedOidcCredential (None , ctx .obj ["AUTH" ].token_file_path ())
434
471
hazmat_print_jwt (saved_token .refresh_token (), human_readable = human_readable )
0 commit comments