mirror of
https://github.com/zulip/zulip.git
synced 2025-11-05 22:43:42 +00:00
create_user: Extract get_create_user_params.
We set nocoverage for the new function. Ideally it'd eventually get an automated test, but we don't want to block this helpful refactoring on doing so.
This commit is contained in:
@@ -1,11 +1,15 @@
|
|||||||
# Library code for use in management commands
|
# Library code for use in management commands
|
||||||
|
import logging
|
||||||
from argparse import SUPPRESS, ArgumentParser, RawTextHelpFormatter
|
from argparse import SUPPRESS, ArgumentParser, RawTextHelpFormatter
|
||||||
|
from dataclasses import dataclass
|
||||||
from typing import Any, Dict, List, Optional
|
from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.core.exceptions import MultipleObjectsReturned
|
from django.core import validators
|
||||||
|
from django.core.exceptions import MultipleObjectsReturned, ValidationError
|
||||||
from django.core.management.base import BaseCommand, CommandError, CommandParser
|
from django.core.management.base import BaseCommand, CommandError, CommandParser
|
||||||
|
|
||||||
|
from zerver.lib.initial_password import initial_password
|
||||||
from zerver.models import Client, Realm, UserProfile, get_client
|
from zerver.models import Client, Realm, UserProfile, get_client
|
||||||
|
|
||||||
|
|
||||||
@@ -30,6 +34,13 @@ def check_config() -> None:
|
|||||||
raise CommandError(f"Error: You must set {setting_name} in /etc/zulip/settings.py.")
|
raise CommandError(f"Error: You must set {setting_name} in /etc/zulip/settings.py.")
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class CreateUserParameters:
|
||||||
|
email: str
|
||||||
|
full_name: str
|
||||||
|
password: Optional[str]
|
||||||
|
|
||||||
|
|
||||||
class ZulipBaseCommand(BaseCommand):
|
class ZulipBaseCommand(BaseCommand):
|
||||||
|
|
||||||
# Fix support for multi-line usage
|
# Fix support for multi-line usage
|
||||||
@@ -167,3 +178,49 @@ server via `ps -ef` or reading bash history. Prefer
|
|||||||
def get_client(self) -> Client:
|
def get_client(self) -> Client:
|
||||||
"""Returns a Zulip Client object to be used for things done in management commands"""
|
"""Returns a Zulip Client object to be used for things done in management commands"""
|
||||||
return get_client("ZulipServer")
|
return get_client("ZulipServer")
|
||||||
|
|
||||||
|
def get_create_user_params(self, options: Dict[str, Any]) -> CreateUserParameters: # nocoverage
|
||||||
|
"""
|
||||||
|
Parses parameters for user creation defined in add_create_user_args.
|
||||||
|
"""
|
||||||
|
if "email" not in options:
|
||||||
|
email = input("Email: ")
|
||||||
|
else:
|
||||||
|
email = options["email"]
|
||||||
|
|
||||||
|
try:
|
||||||
|
validators.validate_email(email)
|
||||||
|
except ValidationError:
|
||||||
|
raise CommandError("Invalid email address.")
|
||||||
|
|
||||||
|
if "full_name" not in options:
|
||||||
|
full_name = input("Full name: ")
|
||||||
|
else:
|
||||||
|
full_name = options["full_name"]
|
||||||
|
|
||||||
|
if options["password_file"] is not None:
|
||||||
|
with open(options["password_file"]) as f:
|
||||||
|
password: Optional[str] = f.read().strip()
|
||||||
|
elif options["password"] is not None:
|
||||||
|
logging.warning(
|
||||||
|
"Passing password on the command line is insecure; prefer --password-file."
|
||||||
|
)
|
||||||
|
password = options["password"]
|
||||||
|
else:
|
||||||
|
# initial_password will return a random password that
|
||||||
|
# is a salted hash of the email address in a
|
||||||
|
# development environment, and None in a production
|
||||||
|
# environment.
|
||||||
|
user_initial_password = initial_password(email)
|
||||||
|
if user_initial_password is None:
|
||||||
|
logging.info("User will be created with a disabled password.")
|
||||||
|
else:
|
||||||
|
assert settings.DEVELOPMENT
|
||||||
|
logging.info("Password will be available via `./manage.py print_initial_password`.")
|
||||||
|
password = user_initial_password
|
||||||
|
|
||||||
|
return CreateUserParameters(
|
||||||
|
email=email,
|
||||||
|
full_name=full_name,
|
||||||
|
password=password,
|
||||||
|
)
|
||||||
|
|||||||
@@ -1,15 +1,10 @@
|
|||||||
import argparse
|
import argparse
|
||||||
import logging
|
from typing import Any
|
||||||
from typing import Any, Optional
|
|
||||||
|
|
||||||
from django.conf import settings
|
|
||||||
from django.core import validators
|
|
||||||
from django.core.exceptions import ValidationError
|
|
||||||
from django.core.management.base import CommandError
|
from django.core.management.base import CommandError
|
||||||
from django.db.utils import IntegrityError
|
from django.db.utils import IntegrityError
|
||||||
|
|
||||||
from zerver.lib.actions import do_create_user
|
from zerver.lib.actions import do_create_user
|
||||||
from zerver.lib.initial_password import initial_password
|
|
||||||
from zerver.lib.management import ZulipBaseCommand
|
from zerver.lib.management import ZulipBaseCommand
|
||||||
|
|
||||||
|
|
||||||
@@ -31,48 +26,14 @@ Omit both <email> and <full name> for interactive user creation.
|
|||||||
realm = self.get_realm(options)
|
realm = self.get_realm(options)
|
||||||
assert realm is not None # Should be ensured by parser
|
assert realm is not None # Should be ensured by parser
|
||||||
|
|
||||||
if "email" not in options:
|
create_user_params = self.get_create_user_params(options)
|
||||||
email = input("Email: ")
|
|
||||||
else:
|
|
||||||
email = options["email"]
|
|
||||||
|
|
||||||
try:
|
|
||||||
validators.validate_email(email)
|
|
||||||
except ValidationError:
|
|
||||||
raise CommandError("Invalid email address.")
|
|
||||||
|
|
||||||
if "full_name" not in options:
|
|
||||||
full_name = input("Full name: ")
|
|
||||||
else:
|
|
||||||
full_name = options["full_name"]
|
|
||||||
|
|
||||||
if options["password_file"] is not None:
|
|
||||||
with open(options["password_file"]) as f:
|
|
||||||
password: Optional[str] = f.read().strip()
|
|
||||||
elif options["password"] is not None:
|
|
||||||
logging.warning(
|
|
||||||
"Passing password on the command line is insecure; prefer --password-file."
|
|
||||||
)
|
|
||||||
password = options["password"]
|
|
||||||
else:
|
|
||||||
# initial_password will return a random password that
|
|
||||||
# is a salted hash of the email address in a
|
|
||||||
# development environment, and None in a production
|
|
||||||
# environment.
|
|
||||||
user_initial_password = initial_password(email)
|
|
||||||
if user_initial_password is None:
|
|
||||||
logging.info("User will be created with a disabled password.")
|
|
||||||
else:
|
|
||||||
assert settings.DEVELOPMENT
|
|
||||||
logging.info("Password will be available via `./manage.py print_initial_password`.")
|
|
||||||
password = user_initial_password
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
do_create_user(
|
do_create_user(
|
||||||
email,
|
create_user_params.email,
|
||||||
password,
|
create_user_params.password,
|
||||||
realm,
|
realm,
|
||||||
full_name,
|
create_user_params.full_name,
|
||||||
# Explicitly set tos_version=None. For servers that
|
# Explicitly set tos_version=None. For servers that
|
||||||
# have configured Terms of Service, this means that
|
# have configured Terms of Service, this means that
|
||||||
# users created via this mechanism will be prompted to
|
# users created via this mechanism will be prompted to
|
||||||
|
|||||||
Reference in New Issue
Block a user