#27801 closed New feature (fixed)
Make createsuperuser inspect environment variables for username and password
Reported by: | Markus Holtermann | Owned by: | Hasan Ramezani |
---|---|---|---|
Component: | contrib.auth | Version: | dev |
Severity: | Normal | Keywords: | |
Cc: | James Pic | Triage Stage: | Accepted |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
The createsuperuser
management command is not quite suitable for scripting, even with the --no-input
flag, as it doesn't set a password. The management command should inspect some environment variables (e.g. DJANGO_SUPERUSER_{USERNAME_FIELD.upper()}
and DJANGO_SUPERUSER_PASSWORD
) to pick up the username, password and possibly all other required fields.
Change History (16)
comment:1 by , 8 years ago
Owner: | changed from | to
---|---|
Status: | new → assigned |
follow-up: 3 comment:2 by , 8 years ago
comment:3 by , 8 years ago
Replying to Tim Graham:
I'm not certain if using
createsuperuser
in non-interactive mode with environment variables is simpler than writing a standalone script to handle this use case. Did you give any thought to this?
Yes, I gave it some thought. The logic in createsuperuser
for ensuring all required fields are present, selecting the right database, etc is already there. With more and more automated deployments for Django projects I think having this feature built-in is essential.
I think I'd have createsuperuser
fallback to the environment variables if they are present unless fields are overridden by command line arguments:
user_data = {} for field in required_fields: if field in options: user_data[field] = options[field] elif 'DJANGO_SUPERUSER_' + field.upper() in os.environ: user_data[field] = os.environ['DJANGO_SUPERUSER_' + field.upper()] elif options['interactive']: user_data[field] = ask_for_field_value(field) else: raise CommandError('Missing value for %s' % field)
That's a rough draft!
comment:4 by , 8 years ago
I guess it could help to define the scope of the use case. Would this be meant for creating one initial superuser. Should it ease creating many superusers?
That might help clarify the need to have all fields pulled from environment variables rather than just the password. This seems to add some complication and I'd like to keep things as simple as possible.
I think the minimal script for anything more complicated is straightforward. If you're running in non-interactive mode, error handling doesn't seem like a priority.
import django django.setup() from django.contrib.auth import get_user_model UserModel = get_user_model() UserModel._default_manager.db_manager('default').create_superuser()
comment:5 by , 8 years ago
It's for the initial superuser when you can't run the management command in interactive mode. The only field as for AbstractBaseUser
is password
that needs to be passed via environment variables. However, if you have another required field that contains sensitive parameters (e.g. API key) and that is a required field you want to have that handled through environment variables as well.
Hence my though, let's use the command arguments in the first place (e.g. for username), fallback to environment variables (that allows for sensitive values) and fail if that's not defined. I'm not sure if we _need_ support for env vars in the interactive mode, i believe it wouldn't hurt, though. Not sure how complex that change might get if that's added.
comment:6 by , 8 years ago
Triage Stage: | Unreviewed → Accepted |
---|
comment:7 by , 7 years ago
Another potential script friendly solution would be to read the password from a file. Other non-Django commands implement such a feature. For example, ldapsearch -y passwdfile and the PostgreSQL password file.
comment:8 by , 6 years ago
Cc: | added |
---|---|
Easy pickings: | set |
Has patch: | set |
Owner: | changed from | to
For our use case, SUPERUSER_PASSWORD works to drop the dependency to expect in automation code.
comment:9 by , 6 years ago
Easy pickings: | unset |
---|---|
Needs documentation: | set |
Needs tests: | set |
Not sure if that would completely address the ticket, but the patch is incomplete without tests and documentation.
comment:10 by , 6 years ago
FTR there is an external solution for this that you can install with PyPi package djcli. As such this is a wontfix for me.
comment:11 by , 6 years ago
Owner: | changed from | to
---|
@Tim Graham, do we still need this? do you prefer to read the password from the file or environment variable?
comment:12 by , 5 years ago
Needs documentation: | unset |
---|---|
Needs tests: | unset |
I made a PR to read the password from environment variables in the non-interactive mode.
Based on the use case proposed on ticket, this feature could be used in scripting. and the only thing that we can not provide it in non-interactive mode is password
.
comment:13 by , 5 years ago
Patch needs improvement: | set |
---|
comment:14 by , 5 years ago
Patch needs improvement: | unset |
---|
comment:16 by , 5 years ago
FTR, I fixed my issue among others in an external package: https://pypi.org/project/djcli/
I'm not certain if using
createsuperuser
in non-interactive mode with environment variables is simpler than writing a standalone script to handle this use case. Did you give any thought to this?