Skip to content

Commit 6f3ebcf

Browse files
authored
Enhance createapplication command to display autogenerated secret (#1152)
* createapplication command display autogenerated secret before it gets hashed.
1 parent 025cd1b commit 6f3ebcf

File tree

4 files changed

+55
-13
lines changed

4 files changed

+55
-13
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1616

1717
## [unreleased]
1818

19+
### Changed
20+
* #1152 `createapplication` management command enhanced to display an auto-generated secret before it gets hashed.
21+
1922
## [2.0.0] 2022-04-24
2023

2124
This is a major release with **BREAKING** changes. Please make sure to review these changes before upgrading:

docs/management_commands.rst

Lines changed: 37 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -34,28 +34,57 @@ The ``createapplication`` management command provides a shortcut to create a new
3434

3535
.. code-block:: sh
3636
37-
usage: manage.py createapplication [-h] [--client-id CLIENT_ID] [--user USER] [--redirect-uris REDIRECT_URIS]
38-
[--client-secret CLIENT_SECRET] [--name NAME] [--skip-authorization] [--version] [-v {0,1,2,3}]
39-
[--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color]
37+
usage: manage.py createapplication [-h] [--client-id CLIENT_ID] [--user USER]
38+
[--redirect-uris REDIRECT_URIS]
39+
[--client-secret CLIENT_SECRET]
40+
[--name NAME] [--skip-authorization]
41+
[--algorithm ALGORITHM] [--version]
42+
[-v {0,1,2,3}] [--settings SETTINGS]
43+
[--pythonpath PYTHONPATH] [--traceback]
44+
[--no-color] [--force-color]
4045
[--skip-checks]
4146
client_type authorization_grant_type
4247
4348
Shortcut to create a new application in a programmatic way
4449
4550
positional arguments:
46-
client_type The client type, can be confidential or public
51+
client_type The client type, one of: confidential, public
4752
authorization_grant_type
48-
The type of authorization grant to be used
53+
The type of authorization grant to be used, one of:
54+
authorization-code, implicit, password, client-
55+
credentials, openid-hybrid
4956
5057
optional arguments:
5158
-h, --help show this help message and exit
5259
--client-id CLIENT_ID
5360
The ID of the new application
5461
--user USER The user the application belongs to
5562
--redirect-uris REDIRECT_URIS
56-
The redirect URIs, this must be a space separated string e.g 'URI1 URI2'
63+
The redirect URIs, this must be a space separated
64+
string e.g 'URI1 URI2'
5765
--client-secret CLIENT_SECRET
5866
The secret for this application
5967
--name NAME The name this application
60-
--skip-authorization The ID of the new application
61-
...
68+
--skip-authorization If set, completely bypass the authorization form, even
69+
on the first use of the application
70+
--algorithm ALGORITHM
71+
The OIDC token signing algorithm for this application,
72+
one of: RS256, HS256
73+
--version Show program's version number and exit.
74+
-v {0,1,2,3}, --verbosity {0,1,2,3}
75+
Verbosity level; 0=minimal output, 1=normal output,
76+
2=verbose output, 3=very verbose output
77+
--settings SETTINGS The Python path to a settings module, e.g.
78+
"myproject.settings.main". If this isn't provided, the
79+
DJANGO_SETTINGS_MODULE environment variable will be
80+
used.
81+
--pythonpath PYTHONPATH
82+
A directory to add to the Python path, e.g.
83+
"/home/djangoprojects/myproject".
84+
--traceback Raise on CommandError exceptions.
85+
--no-color Don't colorize the command output.
86+
--force-color Force colorization of the command output.
87+
--skip-checks Skip system checks.
88+
89+
If you let `createapplication` auto-generate the secret then it displays the value before hashing it.
90+

oauth2_provider/management/commands/createapplication.py

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,13 @@ def add_arguments(self, parser):
1414
parser.add_argument(
1515
"client_type",
1616
type=str,
17-
help="The client type, can be confidential or public",
17+
help="The client type, one of: %s" % ", ".join([ctype[0] for ctype in Application.CLIENT_TYPES]),
1818
)
1919
parser.add_argument(
2020
"authorization_grant_type",
2121
type=str,
22-
help="The type of authorization grant to be used",
22+
help="The type of authorization grant to be used, one of: %s"
23+
% ", ".join([gtype[0] for gtype in Application.GRANT_TYPES]),
2324
)
2425
parser.add_argument(
2526
"--client-id",
@@ -54,7 +55,8 @@ def add_arguments(self, parser):
5455
parser.add_argument(
5556
"--algorithm",
5657
type=str,
57-
help="The OIDC token signing algorithm for this application (e.g., 'RS256' or 'HS256')",
58+
help="The OIDC token signing algorithm for this application, one of: %s"
59+
% ", ".join([atype[0] for atype in Application.ALGORITHM_TYPES if atype[0]]),
5860
)
5961

6062
def handle(self, *args, **options):
@@ -82,5 +84,13 @@ def handle(self, *args, **options):
8284
)
8385
self.stdout.write(self.style.ERROR("Please correct the following errors:\n %s" % errors))
8486
else:
87+
cleartext_secret = new_application.client_secret
8588
new_application.save()
86-
self.stdout.write(self.style.SUCCESS("New application created successfully"))
89+
# Display the newly-created client_name or id.
90+
client_name_or_id = application_data.get("name", new_application.client_id)
91+
self.stdout.write(
92+
self.style.SUCCESS("New application %s created successfully." % client_name_or_id)
93+
)
94+
# Print out the cleartext client_secret if it was autogenerated.
95+
if "client_secret" not in application_data:
96+
self.stdout.write(self.style.SUCCESS("client_secret: %s" % cleartext_secret))

tests/test_commands.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def test_command_creates_application(self):
2727
stdout=output,
2828
)
2929
self.assertEqual(Application.objects.count(), 1)
30-
self.assertIn("New application created successfully", output.getvalue())
30+
self.assertIn("created successfully", output.getvalue())
3131

3232
def test_missing_required_args(self):
3333
self.assertEqual(Application.objects.count(), 0)

0 commit comments

Comments
 (0)