mystiq-sso/accounts/management/commands/create_oidc.py

111 lines
4.1 KiB
Python

# Copyright © 2022 Aravinth Manivannan <realaravinth@batsense.net>
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from django.core.management.base import BaseCommand
from django.core.exceptions import ValidationError
from django.conf import settings
from django.contrib.auth import get_user_model
from oauth2_provider.models import get_application_model
from oauth2_provider.generators import generate_client_id, generate_client_secret
from accounts.utils import gen_secret
Application = get_application_model()
class Command(BaseCommand):
help = "Get user ID from username"
app_name_key = "app_name"
username_key = "username"
redirect_uri_key = "redirect_uri"
def add_arguments(self, parser):
parser.add_argument(self.app_name_key, type=str, help="The application name")
parser.add_argument(
self.username_key,
type=str,
help="The username of user who will own this app",
)
parser.add_argument(
self.redirect_uri_key,
type=str,
help="The redirection URI of relying party/client",
)
def handle(self, *args, **options):
if self.username_key not in options:
self.stdout.write(self.style.ERROR("Please provide username"))
return
if self.app_name_key not in options:
self.stdout.write(self.style.ERROR("Please provide application name"))
return
if self.redirect_uri_key not in options:
self.stdout.write(self.style.ERROR("Please provide redirect uri"))
return
username = options[self.username_key]
application_name = options[self.app_name_key]
redirect_uri = options[self.redirect_uri_key]
User = get_user_model()
if not User.objects.filter(username=username).exists():
self.stderr.write(self.style.ERROR(f"user {username} not found"))
return
user = User.objects.get(username=username)
# python manage.py createapplication --name demo-oidc-app --user 1 --client-id 22500acb0bcfcba137d6b8ae96d3f2 --client-secret 296055337620b0e443ad24a32cb675 --algorithm HS256 --skip-authorization --redirect-uri http://example.org/uri1 confidential code -v
client_id = generate_client_id()
client_secret = generate_client_secret()
config = {
"name": application_name,
"user_id": user.id,
"client_id": client_id,
"client_secret": client_secret,
"algorithm": "HS256",
"skip_authorization": True,
"redirect_uris": redirect_uri,
"authorization_grant_type": "authorization-code",
"client_type": "confidential",
}
app = Application(**config)
try:
app.full_clean()
except ValidationError as exc:
errors = "\n ".join(
[
"- " + err_key + ": " + str(err_value)
for err_key, err_value in exc.message_dict.items()
]
)
self.stdout.write(
self.style.ERROR("Please correct the following errors:\n %s" % errors)
)
else:
app.save()
self.stdout.write(
self.style.SUCCESS(
f"New application {application_name} created successfully."
)
)
self.stdout.write(f"client_id: {client_id}")
self.stdout.write(f"client_secret: {client_secret}")