Changeset View
Changeset View
Standalone View
Standalone View
swh/deposit/cli/admin.py
| # Copyright (C) 2017-2020 The Software Heritage developers | # Copyright (C) 2017-2020 The Software Heritage developers | ||||
| # See the AUTHORS file at the top-level directory of this distribution | # See the AUTHORS file at the top-level directory of this distribution | ||||
| # License: GNU General Public License version 3, or any later version | # License: GNU General Public License version 3, or any later version | ||||
| # See top-level LICENSE file for more information | # See top-level LICENSE file for more information | ||||
| # WARNING: do not import unnecessary things here to keep cli startup time under | # WARNING: do not import unnecessary things here to keep cli startup time under | ||||
| # control | # control | ||||
| from __future__ import annotations | |||||
| from typing import TYPE_CHECKING | |||||
| import click | import click | ||||
| from swh.deposit.cli import deposit | from swh.deposit.cli import deposit | ||||
| if TYPE_CHECKING: | |||||
| from swh.deposit.models import DepositCollection | |||||
| @deposit.group("admin") | @deposit.group("admin") | ||||
| @click.option( | @click.option( | ||||
| "--config-file", | "--config-file", | ||||
| "-C", | "-C", | ||||
| default=None, | default=None, | ||||
| type=click.Path(exists=True, dir_okay=False,), | type=click.Path(exists=True, dir_okay=False,), | ||||
| help="Optional extra configuration file.", | help="Optional extra configuration file.", | ||||
| ) | ) | ||||
| @click.option( | @click.option( | ||||
| "--platform", | "--platform", | ||||
| default="development", | default="development", | ||||
| type=click.Choice(["development", "production"]), | type=click.Choice(["development", "production"]), | ||||
| help="development or production platform", | help="development or production platform", | ||||
| ) | ) | ||||
| @click.pass_context | @click.pass_context | ||||
| def admin(ctx, config_file, platform): | def admin(ctx, config_file: str, platform: str): | ||||
| """Server administration tasks (manipulate user or collections)""" | """Server administration tasks (manipulate user or collections)""" | ||||
| from swh.deposit.config import setup_django_for | from swh.deposit.config import setup_django_for | ||||
| # configuration happens here | # configuration happens here | ||||
| setup_django_for(platform, config_file=config_file) | setup_django_for(platform, config_file=config_file) | ||||
| @admin.group("user") | @admin.group("user") | ||||
| @click.pass_context | @click.pass_context | ||||
| def user(ctx): | def user(ctx): | ||||
| """Manipulate user.""" | """Manipulate user.""" | ||||
| # configuration happens here | # configuration happens here | ||||
| pass | pass | ||||
| def _create_collection(name): | def _create_collection(name: str) -> DepositCollection: | ||||
| """Create the collection with name if it does not exist. | """Create the collection with name if it does not exist. | ||||
| Args: | Args: | ||||
| name (str): collection's name | name: collection name | ||||
| Returns: | Returns: | ||||
| collection (DepositCollection): the existing collection object | collection: the existing collection object | ||||
| (created or not) | |||||
| """ | """ | ||||
| # to avoid loading too early django namespaces | # to avoid loading too early django namespaces | ||||
| from swh.deposit.models import DepositCollection | from swh.deposit.models import DepositCollection | ||||
| try: | try: | ||||
| collection = DepositCollection.objects.get(name=name) | collection = DepositCollection.objects.get(name=name) | ||||
| click.echo("Collection %s exists, nothing to do." % name) | click.echo(f"Collection '{name}' exists, skipping.") | ||||
| except DepositCollection.DoesNotExist: | except DepositCollection.DoesNotExist: | ||||
| click.echo("Create new collection %s" % name) | click.echo(f"Create collection '{name}'.") | ||||
| collection = DepositCollection.objects.create(name=name) | collection = DepositCollection.objects.create(name=name) | ||||
| click.echo("Collection %s created" % name) | click.echo(f"Collection '{name}' created.") | ||||
| return collection | return collection | ||||
| @user.command("create") | @user.command("create") | ||||
| @click.option("--username", required=True, help="User's name") | @click.option("--username", required=True, help="User's name") | ||||
| @click.option("--password", required=True, help="Desired user's password (plain).") | @click.option("--password", required=True, help="Desired user's password (plain).") | ||||
| @click.option("--firstname", default="", help="User's first name") | @click.option("--firstname", default="", help="User's first name") | ||||
| @click.option("--lastname", default="", help="User's last name") | @click.option("--lastname", default="", help="User's last name") | ||||
| @click.option("--email", default="", help="User's email") | @click.option("--email", default="", help="User's email") | ||||
| @click.option("--collection", help="User's collection") | @click.option("--collection", help="User's collection") | ||||
| @click.option("--provider-url", default="", help="Provider URL") | @click.option("--provider-url", default="", help="Provider URL") | ||||
| @click.option("--domain", default="", help="The domain") | @click.option("--domain", default="", help="The domain") | ||||
| @click.pass_context | @click.pass_context | ||||
| def user_create( | def user_create( | ||||
| ctx, | ctx, | ||||
| username, | username: str, | ||||
| password, | password: str, | ||||
| firstname, | firstname: str, | ||||
| lastname, | lastname: str, | ||||
| email, | email: str, | ||||
| collection, | collection: str, | ||||
| provider_url, | provider_url: str, | ||||
| domain, | domain: str, | ||||
| ): | ): | ||||
| """Create a user with some needed information (password, collection) | """Create a user with some needed information (password, collection) | ||||
| If the collection does not exist, the collection is then created | If the collection does not exist, the collection is then created | ||||
| alongside. | alongside. | ||||
| The password is stored encrypted using django's utilities. | The password is stored encrypted using django's utilities. | ||||
| """ | """ | ||||
| # to avoid loading too early django namespaces | # to avoid loading too early django namespaces | ||||
| from swh.deposit.models import DepositClient | from swh.deposit.models import DepositClient | ||||
| # If collection is not provided, fallback to username | # If collection is not provided, fallback to username | ||||
| if not collection: | if not collection: | ||||
| collection = username | collection = username | ||||
| click.echo("collection: %s" % collection) | |||||
| # create the collection if it does not exist | # create the collection if it does not exist | ||||
| collection = _create_collection(collection) | collection_ = _create_collection(collection) | ||||
| # user create/update | # user create/update | ||||
| try: | try: | ||||
| user = DepositClient.objects.get(username=username) | user = DepositClient.objects.get(username=username) # type: ignore | ||||
| click.echo("User %s exists, updating information." % user) | click.echo(f"Update user '{username}'.") | ||||
| user.set_password(password) | user.set_password(password) | ||||
| action_done = "updated" | |||||
| except DepositClient.DoesNotExist: | except DepositClient.DoesNotExist: | ||||
| click.echo("Create new user %s" % username) | click.echo(f"Create user '{username}'.") | ||||
| user = DepositClient.objects.create_user(username=username, password=password) | user = DepositClient.objects.create_user( # type: ignore | ||||
| username=username, password=password | |||||
| ) | |||||
| action_done = "created" | |||||
| user.collections = [collection.id] | user.collections = [collection_.id] | ||||
| user.first_name = firstname | user.first_name = firstname | ||||
| user.last_name = lastname | user.last_name = lastname | ||||
| user.email = email | user.email = email | ||||
| user.is_active = True | user.is_active = True | ||||
| user.provider_url = provider_url | user.provider_url = provider_url | ||||
| user.domain = domain | user.domain = domain | ||||
| user.save() | user.save() | ||||
| click.echo("Information registered for user %s" % user) | click.echo(f"User '{username}' {action_done}.") | ||||
| @user.command("list") | @user.command("list") | ||||
| @click.pass_context | @click.pass_context | ||||
| def user_list(ctx): | def user_list(ctx): | ||||
| """List existing users. | """List existing users. | ||||
| This entrypoint is not paginated yet as there is not a lot of | This entrypoint is not paginated yet as there is not a lot of | ||||
| Show All 9 Lines | def user_list(ctx): | ||||
| else: | else: | ||||
| output = "\n".join((user.username for user in users)) | output = "\n".join((user.username for user in users)) | ||||
| click.echo(output) | click.echo(output) | ||||
| @user.command("exists") | @user.command("exists") | ||||
| @click.argument("username", required=True) | @click.argument("username", required=True) | ||||
| @click.pass_context | @click.pass_context | ||||
| def user_exists(ctx, username): | def user_exists(ctx, username: str): | ||||
| """Check if user exists. | """Check if user exists. | ||||
| """ | """ | ||||
| # to avoid loading too early django namespaces | # to avoid loading too early django namespaces | ||||
| from swh.deposit.models import DepositClient | from swh.deposit.models import DepositClient | ||||
| try: | try: | ||||
| DepositClient.objects.get(username=username) | DepositClient.objects.get(username=username) # type: ignore | ||||
| click.echo("User %s exists." % username) | click.echo(f"User {username} exists.") | ||||
| ctx.exit(0) | ctx.exit(0) | ||||
| except DepositClient.DoesNotExist: | except DepositClient.DoesNotExist: | ||||
| click.echo("User %s does not exist." % username) | click.echo(f"User {username} does not exist.") | ||||
| ctx.exit(1) | ctx.exit(1) | ||||
| @admin.group("collection") | @admin.group("collection") | ||||
| @click.pass_context | @click.pass_context | ||||
| def collection(ctx): | def collection(ctx): | ||||
| """Manipulate collections.""" | """Manipulate collections.""" | ||||
| pass | pass | ||||
| ▲ Show 20 Lines • Show All 105 Lines • Show Last 20 Lines | |||||