-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds a
promote_user
command to make it easier to promote/demote a u…
…ser. (#167)
- Loading branch information
Showing
5 changed files
with
206 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
"""Promote/demote a user.""" | ||
|
||
from django.contrib.auth import get_user_model | ||
from django.core.management import BaseCommand, CommandError | ||
|
||
|
||
class Command(BaseCommand): | ||
"""Promote/demote a user.""" | ||
|
||
help = "Promote/demote a user." | ||
|
||
def add_arguments(self, parser): | ||
"""Add arguments to the command.""" | ||
|
||
parser.add_argument( | ||
"email", | ||
type=str, | ||
help="The email of the user to promote/demote.", | ||
) | ||
|
||
parser.add_argument( | ||
"--promote", | ||
action="store_true", | ||
help="Promote the user to staff.", | ||
) | ||
|
||
parser.add_argument( | ||
"--demote", | ||
action="store_true", | ||
help="Demote the user from staff.", | ||
) | ||
|
||
parser.add_argument( | ||
"--superuser", | ||
action="store_true", | ||
help="Promote the user to superuser.", | ||
) | ||
|
||
def handle(self, **options) -> None: | ||
"""Handle the command.""" | ||
|
||
email = options["email"] | ||
promote = options["promote"] | ||
demote = options["demote"] | ||
superuser = options["superuser"] | ||
verb = "" | ||
|
||
User = get_user_model() | ||
|
||
try: | ||
user = User.objects.get(email=email) | ||
except User.DoesNotExist as exc: | ||
errmsg = f"User with email {email} does not exist." | ||
raise CommandError(errmsg) from exc | ||
|
||
if promote and demote: | ||
errmsg = "You cannot provide both --promote and --demote." | ||
raise CommandError(errmsg) | ||
|
||
if promote: | ||
verb = "promoted" | ||
user.is_staff = True | ||
|
||
if superuser: | ||
verb = f"{verb} to superuser" | ||
user.is_superuser = True | ||
|
||
user.save() | ||
elif demote: | ||
verb = "demoted" | ||
# Demoting a superuser just makes them staff. | ||
if superuser: | ||
verb = f"{verb} from superuser to staff" | ||
user.is_staff = True | ||
user.is_superuser = False | ||
else: | ||
user.is_staff = False | ||
user.is_superuser = False | ||
|
||
user.save() | ||
else: | ||
errmsg = "You must provide either --promote or --demote." | ||
raise CommandError(errmsg) | ||
|
||
self.stdout.write(self.style.SUCCESS(f"Successfully {verb} user {user.email}.")) |
Empty file.
121 changes: 121 additions & 0 deletions
121
unified_ecommerce/management/tests/promote_user_test.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
"""Tests for the promote_user command""" | ||
|
||
from io import StringIO | ||
|
||
import faker | ||
import pytest | ||
from django.core.management import CommandError, call_command | ||
|
||
pytestmark = pytest.mark.django_db | ||
FAKE = faker.Faker() | ||
|
||
|
||
def test_promote_user_bad_args(user): | ||
"""Test that the command raises an error with bad arguments.""" | ||
out = StringIO() | ||
|
||
with pytest.raises(CommandError) as exc: | ||
call_command( | ||
"promote_user", | ||
"--promote", | ||
"--demote", | ||
user.email, | ||
stdout=out, | ||
) | ||
|
||
assert "You cannot provide both --promote and --demote." in str(exc.value) | ||
|
||
with pytest.raises(CommandError) as exc: | ||
call_command( | ||
"promote_user", | ||
"--promote", | ||
FAKE.email(), | ||
stdout=out, | ||
) | ||
|
||
assert "User with email" in str(exc.value) | ||
|
||
with pytest.raises(CommandError) as exc: | ||
call_command( | ||
"promote_user", | ||
"--superuser", | ||
user.email, | ||
stdout=out, | ||
) | ||
|
||
assert "You must provide either --promote or --demote" in str(exc.value) | ||
|
||
|
||
@pytest.mark.parametrize("to_superuser", [True, False]) | ||
def test_promote_user(user, to_superuser): | ||
"""Test that promote_user promotes the user correctly.""" | ||
out = StringIO() | ||
|
||
if to_superuser: | ||
call_command( | ||
"promote_user", | ||
"--promote", | ||
"--superuser", | ||
user.email, | ||
stdout=out, | ||
) | ||
else: | ||
call_command( | ||
"promote_user", | ||
"--promote", | ||
user.email, | ||
stdout=out, | ||
) | ||
|
||
user.refresh_from_db() | ||
|
||
assert "promoted" in out.getvalue() | ||
|
||
if to_superuser: | ||
assert "to superuser" in out.getvalue() | ||
else: | ||
assert "to superuser" not in out.getvalue() | ||
|
||
assert user.is_superuser == to_superuser | ||
assert user.is_staff | ||
|
||
|
||
@pytest.mark.parametrize("from_superuser", [True, False]) | ||
def test_demote_user(user, from_superuser): | ||
"""Test that promote_user demotes the user correctly.""" | ||
out = StringIO() | ||
|
||
if from_superuser: | ||
user.is_superuser = True | ||
user.is_staff = True | ||
user.save() | ||
|
||
call_command( | ||
"promote_user", | ||
"--demote", | ||
"--superuser", | ||
user.email, | ||
stdout=out, | ||
) | ||
else: | ||
user.is_staff = True | ||
user.save() | ||
|
||
call_command( | ||
"promote_user", | ||
"--demote", | ||
user.email, | ||
stdout=out, | ||
) | ||
|
||
user.refresh_from_db() | ||
|
||
assert "demoted" in out.getvalue() | ||
|
||
if from_superuser: | ||
assert "to staff" in out.getvalue() | ||
assert not user.is_superuser | ||
assert user.is_staff | ||
else: | ||
assert not user.is_superuser | ||
assert not user.is_staff |