From ccab1e750ee77bdd2854375fa5dec42699c7cedc Mon Sep 17 00:00:00 2001 From: Alan Crosswell Date: Sat, 7 May 2022 10:38:21 -0400 Subject: [PATCH 1/4] createapplication command display autogenerated secret before it gets hashed. --- CHANGELOG.md | 3 ++ docs/management_commands.rst | 53 ++++++++++++++----- .../management/commands/createapplication.py | 19 +++++-- tests/test_commands.py | 2 +- 4 files changed, 60 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7819fe616..b032955e4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [unreleased] +### Changed +* `createpplication` management command enhanced to display an auto-generated secret before it gets hashed. + ## [2.0.0] 2022-04-24 This is a major release with **BREAKING** changes. Please make sure to review these changes before upgrading: diff --git a/docs/management_commands.rst b/docs/management_commands.rst index 085b130ec..21ea469e7 100644 --- a/docs/management_commands.rst +++ b/docs/management_commands.rst @@ -34,28 +34,57 @@ The ``createapplication`` management command provides a shortcut to create a new .. code-block:: sh - usage: manage.py createapplication [-h] [--client-id CLIENT_ID] [--user USER] [--redirect-uris REDIRECT_URIS] - [--client-secret CLIENT_SECRET] [--name NAME] [--skip-authorization] [--version] [-v {0,1,2,3}] - [--settings SETTINGS] [--pythonpath PYTHONPATH] [--traceback] [--no-color] [--force-color] - [--skip-checks] - client_type authorization_grant_type + usage: manage.py createapplication [-h] [--client-id CLIENT_ID] [--user USER] + [--redirect-uris REDIRECT_URIS] + [--client-secret CLIENT_SECRET] + [--name NAME] [--skip-authorization] + [--algorithm ALGORITHM] [--version] + [-v {0,1,2,3}] [--settings SETTINGS] + [--pythonpath PYTHONPATH] [--traceback] + [--no-color] [--force-color] + [--skip-checks] + client_type authorization_grant_type Shortcut to create a new application in a programmatic way positional arguments: - client_type The client type, can be confidential or public + client_type The client type, one of: confidential, public authorization_grant_type - The type of authorization grant to be used + The type of authorization grant to be used, one of: + authorization-code, implicit, password, client- + credentials, openid-hybrid optional arguments: -h, --help show this help message and exit --client-id CLIENT_ID - The ID of the new application + The ID of the new application --user USER The user the application belongs to --redirect-uris REDIRECT_URIS - The redirect URIs, this must be a space separated string e.g 'URI1 URI2' + The redirect URIs, this must be a space separated + string e.g 'URI1 URI2' --client-secret CLIENT_SECRET - The secret for this application + The secret for this application --name NAME The name this application - --skip-authorization The ID of the new application - ... + --skip-authorization If set, completely bypass the authorization form, even + on the first use of the application + --algorithm ALGORITHM + The OIDC token signing algorithm for this application, + one of: RS256, HS256 + --version Show program's version number and exit. + -v {0,1,2,3}, --verbosity {0,1,2,3} + Verbosity level; 0=minimal output, 1=normal output, + 2=verbose output, 3=very verbose output + --settings SETTINGS The Python path to a settings module, e.g. + "myproject.settings.main". If this isn't provided, the + DJANGO_SETTINGS_MODULE environment variable will be + used. + --pythonpath PYTHONPATH + A directory to add to the Python path, e.g. + "/home/djangoprojects/myproject". + --traceback Raise on CommandError exceptions. + --no-color Don't colorize the command output. + --force-color Force colorization of the command output. + --skip-checks Skip system checks. + +If you let `createapplication` auto-generate the secret then it displays the value before hashing it. + diff --git a/oauth2_provider/management/commands/createapplication.py b/oauth2_provider/management/commands/createapplication.py index f8575a8b0..7212b0162 100644 --- a/oauth2_provider/management/commands/createapplication.py +++ b/oauth2_provider/management/commands/createapplication.py @@ -14,12 +14,13 @@ def add_arguments(self, parser): parser.add_argument( "client_type", type=str, - help="The client type, can be confidential or public", + help="The client type, one of: %s" % ", ".join([ctype[0] for ctype in Application.CLIENT_TYPES]), ) parser.add_argument( "authorization_grant_type", type=str, - help="The type of authorization grant to be used", + help="The type of authorization grant to be used, one of: %s" + % ", ".join([gtype[0] for gtype in Application.GRANT_TYPES]), ) parser.add_argument( "--client-id", @@ -54,7 +55,8 @@ def add_arguments(self, parser): parser.add_argument( "--algorithm", type=str, - help="The OIDC token signing algorithm for this application (e.g., 'RS256' or 'HS256')", + help="The OIDC token signing algorithm for this application, one of: %s" + % ", ".join([atype[0] for atype in Application.ALGORITHM_TYPES if atype[0]]), ) def handle(self, *args, **options): @@ -82,5 +84,14 @@ def handle(self, *args, **options): ) self.stdout.write(self.style.ERROR("Please correct the following errors:\n %s" % errors)) else: + cleartext_secret = new_application.client_secret new_application.save() - self.stdout.write(self.style.SUCCESS("New application created successfully")) + # Display the newly-created client_name or id. + client_name_or_id = application_data.get("name", new_application.client_id) + self.stdout.write( + self.style.SUCCESS("New application %s created successfully." % client_name_or_id) + ) + # Print out the cleartext client_secret if it was autogenerated. + if "client_secret" not in application_data: + self.stdout.write(self.style.SUCCESS("client_secret: %s" % cleartext_secret)) + self.stdout.write(self.style.WARNING(Application.client_secret.field.help_text)) diff --git a/tests/test_commands.py b/tests/test_commands.py index f9a9f5ade..8861f5698 100644 --- a/tests/test_commands.py +++ b/tests/test_commands.py @@ -27,7 +27,7 @@ def test_command_creates_application(self): stdout=output, ) self.assertEqual(Application.objects.count(), 1) - self.assertIn("New application created successfully", output.getvalue()) + self.assertIn("created successfully", output.getvalue()) def test_missing_required_args(self): self.assertEqual(Application.objects.count(), 0) From b198887a799a43aa72ba17d6acc1ec90f7fbd2e0 Mon Sep 17 00:00:00 2001 From: Alan Crosswell Date: Sat, 7 May 2022 10:44:55 -0400 Subject: [PATCH 2/4] sphinxlint --- docs/management_commands.rst | 52 ++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/docs/management_commands.rst b/docs/management_commands.rst index 21ea469e7..8e6eaaac2 100644 --- a/docs/management_commands.rst +++ b/docs/management_commands.rst @@ -35,52 +35,52 @@ The ``createapplication`` management command provides a shortcut to create a new .. code-block:: sh usage: manage.py createapplication [-h] [--client-id CLIENT_ID] [--user USER] - [--redirect-uris REDIRECT_URIS] - [--client-secret CLIENT_SECRET] - [--name NAME] [--skip-authorization] - [--algorithm ALGORITHM] [--version] - [-v {0,1,2,3}] [--settings SETTINGS] - [--pythonpath PYTHONPATH] [--traceback] - [--no-color] [--force-color] - [--skip-checks] - client_type authorization_grant_type + [--redirect-uris REDIRECT_URIS] + [--client-secret CLIENT_SECRET] + [--name NAME] [--skip-authorization] + [--algorithm ALGORITHM] [--version] + [-v {0,1,2,3}] [--settings SETTINGS] + [--pythonpath PYTHONPATH] [--traceback] + [--no-color] [--force-color] + [--skip-checks] + client_type authorization_grant_type Shortcut to create a new application in a programmatic way positional arguments: client_type The client type, one of: confidential, public authorization_grant_type - The type of authorization grant to be used, one of: - authorization-code, implicit, password, client- - credentials, openid-hybrid + The type of authorization grant to be used, one of: + authorization-code, implicit, password, client- + credentials, openid-hybrid optional arguments: -h, --help show this help message and exit --client-id CLIENT_ID - The ID of the new application + The ID of the new application --user USER The user the application belongs to --redirect-uris REDIRECT_URIS - The redirect URIs, this must be a space separated - string e.g 'URI1 URI2' + The redirect URIs, this must be a space separated + string e.g 'URI1 URI2' --client-secret CLIENT_SECRET - The secret for this application + The secret for this application --name NAME The name this application --skip-authorization If set, completely bypass the authorization form, even - on the first use of the application + on the first use of the application --algorithm ALGORITHM - The OIDC token signing algorithm for this application, - one of: RS256, HS256 + The OIDC token signing algorithm for this application, + one of: RS256, HS256 --version Show program's version number and exit. -v {0,1,2,3}, --verbosity {0,1,2,3} - Verbosity level; 0=minimal output, 1=normal output, - 2=verbose output, 3=very verbose output + Verbosity level; 0=minimal output, 1=normal output, + 2=verbose output, 3=very verbose output --settings SETTINGS The Python path to a settings module, e.g. - "myproject.settings.main". If this isn't provided, the - DJANGO_SETTINGS_MODULE environment variable will be - used. + "myproject.settings.main". If this isn't provided, the + DJANGO_SETTINGS_MODULE environment variable will be + used. --pythonpath PYTHONPATH - A directory to add to the Python path, e.g. - "/home/djangoprojects/myproject". + A directory to add to the Python path, e.g. + "/home/djangoprojects/myproject". --traceback Raise on CommandError exceptions. --no-color Don't colorize the command output. --force-color Force colorization of the command output. From fb523c13a62c1cb4161434d02bb585753c65861c Mon Sep 17 00:00:00 2001 From: Alan Crosswell Date: Sat, 7 May 2022 11:28:12 -0400 Subject: [PATCH 3/4] older version of django don't resolve field.help_text --- oauth2_provider/management/commands/createapplication.py | 1 - 1 file changed, 1 deletion(-) diff --git a/oauth2_provider/management/commands/createapplication.py b/oauth2_provider/management/commands/createapplication.py index 7212b0162..12d7aa280 100644 --- a/oauth2_provider/management/commands/createapplication.py +++ b/oauth2_provider/management/commands/createapplication.py @@ -94,4 +94,3 @@ def handle(self, *args, **options): # Print out the cleartext client_secret if it was autogenerated. if "client_secret" not in application_data: self.stdout.write(self.style.SUCCESS("client_secret: %s" % cleartext_secret)) - self.stdout.write(self.style.WARNING(Application.client_secret.field.help_text)) From 4cd0c61ccf04aa3efc18cc45e094ef7ccd865cab Mon Sep 17 00:00:00 2001 From: Alan Crosswell Date: Sat, 7 May 2022 11:29:01 -0400 Subject: [PATCH 4/4] typo fix per @rcmurphy review --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b032955e4..02d598034 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [unreleased] ### Changed -* `createpplication` management command enhanced to display an auto-generated secret before it gets hashed. +* #1152 `createapplication` management command enhanced to display an auto-generated secret before it gets hashed. ## [2.0.0] 2022-04-24