|
1 | 1 | import os |
| 2 | +import json |
| 3 | +import random |
| 4 | +import string |
| 5 | +import pathlib |
2 | 6 | from django.contrib.auth import get_user_model |
3 | 7 | from django.core.management.base import BaseCommand |
4 | 8 | from oauth2_provider.models import Application |
5 | 9 |
|
| 10 | + |
6 | 11 | User = get_user_model() |
| 12 | +secrets_path = "/var/run/secrets/drycc/passport" |
7 | 13 |
|
8 | 14 |
|
9 | 15 | class Command(BaseCommand): |
10 | 16 | """Management command for create Oauth2 application""" |
11 | 17 |
|
| 18 | + def add_arguments(self, parser): |
| 19 | + super(Command, self).add_arguments(parser) |
| 20 | + parser.add_argument( |
| 21 | + '--path', dest='path', default=None, |
| 22 | + help='Specifies the path for the secret.', |
| 23 | + ) |
| 24 | + |
12 | 25 | def handle(self, *args, **options): |
13 | | - app_list = [] |
14 | | - if os.environ.get('DRYCC_GRAFANA_DOMAIN'): |
15 | | - app_list.append({ |
16 | | - "name": "GRAFANA", |
17 | | - "redirect_uri": f"{os.environ.get('DRYCC_GRAFANA_DOMAIN')}/login/generic_oauth" # noqa |
18 | | - }) |
19 | | - if os.environ.get('DRYCC_MANAGER_DOMAIN'): |
20 | | - app_list.append({ |
21 | | - "name": "MANAGER", |
22 | | - "redirect_uri": f"{os.environ.get('DRYCC_MANAGER_DOMAIN')}/v1/complete/drycc/" # noqa |
23 | | - }) |
24 | | - if os.environ.get('DRYCC_CONTROLLER_DOMAIN'): |
25 | | - app_list.append({ |
26 | | - "name": "CONTROLLER", |
27 | | - "redirect_uri": f"{os.environ.get('DRYCC_CONTROLLER_DOMAIN')}/v2/complete/drycc/" # noqa |
28 | | - }) |
29 | | - for app in app_list: |
30 | | - client_id = os.environ.get( |
31 | | - f'DRYCC_PASSPORT_{app["name"]}_KEY') if os.environ.get( |
32 | | - f'DRYCC_PASSPORT_{app["name"]}_KEY') else None |
33 | | - client_secret = os.environ.get( |
34 | | - f'DRYCC_PASSPORT_{app["name"]}_SECRET') if os.environ.get( |
35 | | - f'DRYCC_PASSPORT_{app["name"]}_SECRET') else None |
36 | | - if not all([client_id, client_secret]): |
37 | | - self.stdout.write('client_id or client_secret non-existent') |
38 | | - return |
39 | | - user = User.objects.filter(is_superuser=True).first() |
40 | | - if not user: |
41 | | - self.stdout.write("Cannot create because there is no superuser") |
| 26 | + base_path = options.get('path', '') |
| 27 | + user = User.objects.filter(is_superuser=True).first() |
| 28 | + for item in json.loads(pathlib.Path(base_path).read_text()): |
| 29 | + name = item["name"] |
| 30 | + key = self._get_creds(item, "key", 40) |
| 31 | + secret = self._get_creds(item, "secret", 60) |
| 32 | + redirect_uri = self._get_redirect_uri(item) |
42 | 33 | _, updated = Application.objects.update_or_create( |
43 | | - name='Drycc ' + app["name"].title(), |
| 34 | + name=name.lower(), |
44 | 35 | defaults={ |
45 | | - 'client_id': client_id, |
46 | | - 'client_secret': client_secret, |
| 36 | + 'client_id': key, |
| 37 | + 'client_secret': secret, |
47 | 38 | 'user': user, |
48 | | - 'redirect_uris': app["redirect_uri"], |
| 39 | + 'redirect_uris': redirect_uri, |
49 | 40 | 'authorization_grant_type': 'authorization-code', |
50 | | - 'client_type': 'Public', |
| 41 | + 'client_type': 'public', |
51 | 42 | 'algorithm': 'RS256' |
52 | 43 | } |
53 | 44 | ) |
54 | 45 | if updated: |
55 | | - self.stdout.write(f'Drycc {app["name"]} app created') |
| 46 | + self.stdout.write('Drycc % app created' % name) |
| 47 | + else: |
| 48 | + self.stdout.write('Drycc % app updated' % name) |
| 49 | + |
| 50 | + def _get_creds(self, item, suffix, size): |
| 51 | + name, secret, prefix = item["name"], item[suffix], item["prefix"] |
| 52 | + if not secret: |
| 53 | + default_secret_path = os.path.join( |
| 54 | + secrets_path, "drycc-passport-%s-%s" % (name, suffix)) |
| 55 | + if prefix and os.path.exists(default_secret_path): |
| 56 | + secret = pathlib.Path(default_secret_path).read_text() |
| 57 | + else: |
| 58 | + secret = ''.join([random.choice(string.ascii_letters) for _ in range(size)]) |
| 59 | + return secret |
| 60 | + |
| 61 | + def _get_redirect_uri(self, item): |
| 62 | + prefix = item["prefix"] |
| 63 | + domain = os.environ.get("PLATFORM_DOMAIN") |
| 64 | + redirect_uri = item["redirect_uri"] |
| 65 | + if prefix: |
| 66 | + if os.environ.get("CERT_MANAGER_ENABLED") == "true": |
| 67 | + redirect_uri = f"https://{prefix}.{domain}{redirect_uri}" |
56 | 68 | else: |
57 | | - self.stdout.write(f'Drycc {app["name"]} app updated') |
| 69 | + redirect_uri = f"http://{prefix}.{domain}{redirect_uri}" |
| 70 | + return redirect_uri |
0 commit comments