We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
User-creation should not fail, when the account already exists
I'm creating an Ansible role for installing sentry on our network. The software is installed via `pip` -- version 8.22.0, which seems to be the latest as of today. Not using Docker -- just a dedicated VM.

One of the tasks is to create a Sentry-admin:
```
sentry createuser --superuser --no-input --password=FOO --email=sentry@example.com
```
Unfortunately, the above command only works _the first time_. Trying to run it again fails:
```
django.db.utils.IntegrityError: IntegrityError('duplicate key value violates unique constraint \"auth_user_username_key\"
DETAIL:  Key (username)=(sentry@example.com) already exists
```
I understand, why the same account can not be created again. But it should not be an _error_ -- simply update the existing record if necessary. Or, if it must be an error, there should be a specific exit-code for this case, which would allow systems like Ansible to move on. Currently, `sentry` exits with the same code 1 for all errors...

At the very least, there needs to be a way to check, whether the account exists already... Ansible would then be able to perform the query before attempting to add the user.


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `src/sentry/runner/commands/createuser.py`
Content:
```
1 from __future__ import absolute_import, print_function
2 
3 import click
4 from sentry.runner.decorators import configuration
5 
6 
7 def _get_field(field_name):
8     from sentry.models import User
9 
10     return User._meta.get_field(field_name)
11 
12 
13 def _get_email():
14     from django.core.exceptions import ValidationError
15 
16     rv = click.prompt("Email")
17     field = _get_field("email")
18     try:
19         return field.clean(rv, None)
20     except ValidationError as e:
21         raise click.ClickException("; ".join(e.messages))
22 
23 
24 def _get_password():
25     from django.core.exceptions import ValidationError
26 
27     rv = click.prompt("Password", hide_input=True, confirmation_prompt=True)
28     field = _get_field("password")
29     try:
30         return field.clean(rv, None)
31     except ValidationError as e:
32         raise click.ClickException("; ".join(e.messages))
33 
34 
35 def _get_superuser():
36     return click.confirm("Should this user be a superuser?", default=False)
37 
38 
39 @click.command()
40 @click.option("--email")
41 @click.option("--password")
42 @click.option("--superuser/--no-superuser", default=None, is_flag=True)
43 @click.option("--no-password", default=False, is_flag=True)
44 @click.option("--no-input", default=False, is_flag=True)
45 @configuration
46 def createuser(email, password, superuser, no_password, no_input):
47     "Create a new user."
48     if not no_input:
49         if not email:
50             email = _get_email()
51 
52         if not (password or no_password):
53             password = _get_password()
54 
55         if superuser is None:
56             superuser = _get_superuser()
57 
58     if superuser is None:
59         superuser = False
60 
61     if not email:
62         raise click.ClickException("Invalid or missing email address.")
63 
64     # TODO(mattrobenolt): Accept password over stdin?
65     if not no_password and not password:
66         raise click.ClickException("No password set and --no-password not passed.")
67 
68     from sentry import roles
69     from sentry.models import User
70     from django.conf import settings
71 
72     user = User(
73         email=email, username=email, is_superuser=superuser, is_staff=superuser, is_active=True
74     )
75 
76     if password:
77         user.set_password(password)
78 
79     user.save()
80 
81     click.echo("User created: %s" % (email,))
82 
83     # TODO(dcramer): kill this when we improve flows
84     if settings.SENTRY_SINGLE_ORGANIZATION:
85         from sentry.models import Organization, OrganizationMember, OrganizationMemberTeam, Team
86 
87         org = Organization.get_default()
88         if superuser:
89             role = roles.get_top_dog().id
90         else:
91             role = org.default_role
92         member = OrganizationMember.objects.create(organization=org, user=user, role=role)
93 
94         # if we've only got a single team let's go ahead and give
95         # access to that team as its likely the desired outcome
96         teams = list(Team.objects.filter(organization=org)[0:2])
97         if len(teams) == 1:
98             OrganizationMemberTeam.objects.create(team=teams[0], organizationmember=member)
99         click.echo("Added to organization: %s" % (org.slug,))
100
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/src/sentry/runner/commands/createuser.py b/src/sentry/runner/commands/createuser.py
--- a/src/sentry/runner/commands/createuser.py
+++ b/src/sentry/runner/commands/createuser.py
@@ -1,6 +1,7 @@
 from __future__ import absolute_import, print_function
 
 import click
+import sys
 from sentry.runner.decorators import configuration
 
 
@@ -42,8 +43,9 @@
 @click.option("--superuser/--no-superuser", default=None, is_flag=True)
 @click.option("--no-password", default=False, is_flag=True)
 @click.option("--no-input", default=False, is_flag=True)
+@click.option("--force-update", default=False, is_flag=True)
 @configuration
-def createuser(email, password, superuser, no_password, no_input):
+def createuser(email, password, superuser, no_password, no_input, force_update):
     "Create a new user."
     if not no_input:
         if not email:
@@ -76,24 +78,31 @@
     if password:
         user.set_password(password)
 
-    user.save()
-
-    click.echo("User created: %s" % (email,))
-
-    # TODO(dcramer): kill this when we improve flows
-    if settings.SENTRY_SINGLE_ORGANIZATION:
-        from sentry.models import Organization, OrganizationMember, OrganizationMemberTeam, Team
-
-        org = Organization.get_default()
-        if superuser:
-            role = roles.get_top_dog().id
+    if User.objects.filter(username=email).exists():
+        if force_update:
+            user.save(force_update=force_update)
+            click.echo("User updated: %s" % (email,))
         else:
-            role = org.default_role
-        member = OrganizationMember.objects.create(organization=org, user=user, role=role)
-
-        # if we've only got a single team let's go ahead and give
-        # access to that team as its likely the desired outcome
-        teams = list(Team.objects.filter(organization=org)[0:2])
-        if len(teams) == 1:
-            OrganizationMemberTeam.objects.create(team=teams[0], organizationmember=member)
-        click.echo("Added to organization: %s" % (org.slug,))
+            click.echo("User: %s exists, use --force-update to force" % (email,))
+            sys.exit(3)
+    else:
+        user.save()
+        click.echo("User created: %s" % (email,))
+
+        # TODO(dcramer): kill this when we improve flows
+        if settings.SENTRY_SINGLE_ORGANIZATION:
+            from sentry.models import Organization, OrganizationMember, OrganizationMemberTeam, Team
+
+            org = Organization.get_default()
+            if superuser:
+                role = roles.get_top_dog().id
+            else:
+                role = org.default_role
+            member = OrganizationMember.objects.create(organization=org, user=user, role=role)
+
+            # if we've only got a single team let's go ahead and give
+            # access to that team as its likely the desired outcome
+            teams = list(Team.objects.filter(organization=org)[0:2])
+            if len(teams) == 1:
+                OrganizationMemberTeam.objects.create(team=teams[0], organizationmember=member)
+            click.echo("Added to organization: %s" % (org.slug,))

{"golden_diff": "diff --git a/src/sentry/runner/commands/createuser.py b/src/sentry/runner/commands/createuser.py\n--- a/src/sentry/runner/commands/createuser.py\n+++ b/src/sentry/runner/commands/createuser.py\n@@ -1,6 +1,7 @@\n from __future__ import absolute_import, print_function\n \n import click\n+import sys\n from sentry.runner.decorators import configuration\n \n \n@@ -42,8 +43,9 @@\n @click.option(\"--superuser/--no-superuser\", default=None, is_flag=True)\n @click.option(\"--no-password\", default=False, is_flag=True)\n @click.option(\"--no-input\", default=False, is_flag=True)\n+@click.option(\"--force-update\", default=False, is_flag=True)\n @configuration\n-def createuser(email, password, superuser, no_password, no_input):\n+def createuser(email, password, superuser, no_password, no_input, force_update):\n     \"Create a new user.\"\n     if not no_input:\n         if not email:\n@@ -76,24 +78,31 @@\n     if password:\n         user.set_password(password)\n \n-    user.save()\n-\n-    click.echo(\"User created: %s\" % (email,))\n-\n-    # TODO(dcramer): kill this when we improve flows\n-    if settings.SENTRY_SINGLE_ORGANIZATION:\n-        from sentry.models import Organization, OrganizationMember, OrganizationMemberTeam, Team\n-\n-        org = Organization.get_default()\n-        if superuser:\n-            role = roles.get_top_dog().id\n+    if User.objects.filter(username=email).exists():\n+        if force_update:\n+            user.save(force_update=force_update)\n+            click.echo(\"User updated: %s\" % (email,))\n         else:\n-            role = org.default_role\n-        member = OrganizationMember.objects.create(organization=org, user=user, role=role)\n-\n-        # if we've only got a single team let's go ahead and give\n-        # access to that team as its likely the desired outcome\n-        teams = list(Team.objects.filter(organization=org)[0:2])\n-        if len(teams) == 1:\n-            OrganizationMemberTeam.objects.create(team=teams[0], organizationmember=member)\n-        click.echo(\"Added to organization: %s\" % (org.slug,))\n+            click.echo(\"User: %s exists, use --force-update to force\" % (email,))\n+            sys.exit(3)\n+    else:\n+        user.save()\n+        click.echo(\"User created: %s\" % (email,))\n+\n+        # TODO(dcramer): kill this when we improve flows\n+        if settings.SENTRY_SINGLE_ORGANIZATION:\n+            from sentry.models import Organization, OrganizationMember, OrganizationMemberTeam, Team\n+\n+            org = Organization.get_default()\n+            if superuser:\n+                role = roles.get_top_dog().id\n+            else:\n+                role = org.default_role\n+            member = OrganizationMember.objects.create(organization=org, user=user, role=role)\n+\n+            # if we've only got a single team let's go ahead and give\n+            # access to that team as its likely the desired outcome\n+            teams = list(Team.objects.filter(organization=org)[0:2])\n+            if len(teams) == 1:\n+                OrganizationMemberTeam.objects.create(team=teams[0], organizationmember=member)\n+            click.echo(\"Added to organization: %s\" % (org.slug,))\n", "issue": "User-creation should not fail, when the account already exists\nI'm creating an Ansible role for installing sentry on our network. The software is installed via `pip` -- version 8.22.0, which seems to be the latest as of today. Not using Docker -- just a dedicated VM.\r\n\r\nOne of the tasks is to create a Sentry-admin:\r\n```\r\nsentry createuser --superuser --no-input --password=FOO --email=sentry@example.com\r\n```\r\nUnfortunately, the above command only works _the first time_. Trying to run it again fails:\r\n```\r\ndjango.db.utils.IntegrityError: IntegrityError('duplicate key value violates unique constraint \\\"auth_user_username_key\\\"\r\nDETAIL:  Key (username)=(sentry@example.com) already exists\r\n```\r\nI understand, why the same account can not be created again. But it should not be an _error_ -- simply update the existing record if necessary. Or, if it must be an error, there should be a specific exit-code for this case, which would allow systems like Ansible to move on. Currently, `sentry` exits with the same code 1 for all errors...\r\n\r\nAt the very least, there needs to be a way to check, whether the account exists already... Ansible would then be able to perform the query before attempting to add the user.\r\n\n", "before_files": [{"content": "from __future__ import absolute_import, print_function\n\nimport click\nfrom sentry.runner.decorators import configuration\n\n\ndef _get_field(field_name):\n    from sentry.models import User\n\n    return User._meta.get_field(field_name)\n\n\ndef _get_email():\n    from django.core.exceptions import ValidationError\n\n    rv = click.prompt(\"Email\")\n    field = _get_field(\"email\")\n    try:\n        return field.clean(rv, None)\n    except ValidationError as e:\n        raise click.ClickException(\"; \".join(e.messages))\n\n\ndef _get_password():\n    from django.core.exceptions import ValidationError\n\n    rv = click.prompt(\"Password\", hide_input=True, confirmation_prompt=True)\n    field = _get_field(\"password\")\n    try:\n        return field.clean(rv, None)\n    except ValidationError as e:\n        raise click.ClickException(\"; \".join(e.messages))\n\n\ndef _get_superuser():\n    return click.confirm(\"Should this user be a superuser?\", default=False)\n\n\n@click.command()\n@click.option(\"--email\")\n@click.option(\"--password\")\n@click.option(\"--superuser/--no-superuser\", default=None, is_flag=True)\n@click.option(\"--no-password\", default=False, is_flag=True)\n@click.option(\"--no-input\", default=False, is_flag=True)\n@configuration\ndef createuser(email, password, superuser, no_password, no_input):\n    \"Create a new user.\"\n    if not no_input:\n        if not email:\n            email = _get_email()\n\n        if not (password or no_password):\n            password = _get_password()\n\n        if superuser is None:\n            superuser = _get_superuser()\n\n    if superuser is None:\n        superuser = False\n\n    if not email:\n        raise click.ClickException(\"Invalid or missing email address.\")\n\n    # TODO(mattrobenolt): Accept password over stdin?\n    if not no_password and not password:\n        raise click.ClickException(\"No password set and --no-password not passed.\")\n\n    from sentry import roles\n    from sentry.models import User\n    from django.conf import settings\n\n    user = User(\n        email=email, username=email, is_superuser=superuser, is_staff=superuser, is_active=True\n    )\n\n    if password:\n        user.set_password(password)\n\n    user.save()\n\n    click.echo(\"User created: %s\" % (email,))\n\n    # TODO(dcramer): kill this when we improve flows\n    if settings.SENTRY_SINGLE_ORGANIZATION:\n        from sentry.models import Organization, OrganizationMember, OrganizationMemberTeam, Team\n\n        org = Organization.get_default()\n        if superuser:\n            role = roles.get_top_dog().id\n        else:\n            role = org.default_role\n        member = OrganizationMember.objects.create(organization=org, user=user, role=role)\n\n        # if we've only got a single team let's go ahead and give\n        # access to that team as its likely the desired outcome\n        teams = list(Team.objects.filter(organization=org)[0:2])\n        if len(teams) == 1:\n            OrganizationMemberTeam.objects.create(team=teams[0], organizationmember=member)\n        click.echo(\"Added to organization: %s\" % (org.slug,))\n", "path": "src/sentry/runner/commands/createuser.py"}], "after_files": [{"content": "from __future__ import absolute_import, print_function\n\nimport click\nimport sys\nfrom sentry.runner.decorators import configuration\n\n\ndef _get_field(field_name):\n    from sentry.models import User\n\n    return User._meta.get_field(field_name)\n\n\ndef _get_email():\n    from django.core.exceptions import ValidationError\n\n    rv = click.prompt(\"Email\")\n    field = _get_field(\"email\")\n    try:\n        return field.clean(rv, None)\n    except ValidationError as e:\n        raise click.ClickException(\"; \".join(e.messages))\n\n\ndef _get_password():\n    from django.core.exceptions import ValidationError\n\n    rv = click.prompt(\"Password\", hide_input=True, confirmation_prompt=True)\n    field = _get_field(\"password\")\n    try:\n        return field.clean(rv, None)\n    except ValidationError as e:\n        raise click.ClickException(\"; \".join(e.messages))\n\n\ndef _get_superuser():\n    return click.confirm(\"Should this user be a superuser?\", default=False)\n\n\n@click.command()\n@click.option(\"--email\")\n@click.option(\"--password\")\n@click.option(\"--superuser/--no-superuser\", default=None, is_flag=True)\n@click.option(\"--no-password\", default=False, is_flag=True)\n@click.option(\"--no-input\", default=False, is_flag=True)\n@click.option(\"--force-update\", default=False, is_flag=True)\n@configuration\ndef createuser(email, password, superuser, no_password, no_input, force_update):\n    \"Create a new user.\"\n    if not no_input:\n        if not email:\n            email = _get_email()\n\n        if not (password or no_password):\n            password = _get_password()\n\n        if superuser is None:\n            superuser = _get_superuser()\n\n    if superuser is None:\n        superuser = False\n\n    if not email:\n        raise click.ClickException(\"Invalid or missing email address.\")\n\n    # TODO(mattrobenolt): Accept password over stdin?\n    if not no_password and not password:\n        raise click.ClickException(\"No password set and --no-password not passed.\")\n\n    from sentry import roles\n    from sentry.models import User\n    from django.conf import settings\n\n    user = User(\n        email=email, username=email, is_superuser=superuser, is_staff=superuser, is_active=True\n    )\n\n    if password:\n        user.set_password(password)\n\n    if User.objects.filter(username=email).exists():\n        if force_update:\n            user.save(force_update=force_update)\n            click.echo(\"User updated: %s\" % (email,))\n        else:\n            click.echo(\"User: %s exists, use --force-update to force\" % (email,))\n            sys.exit(3)\n    else:\n        user.save()\n        click.echo(\"User created: %s\" % (email,))\n\n        # TODO(dcramer): kill this when we improve flows\n        if settings.SENTRY_SINGLE_ORGANIZATION:\n            from sentry.models import Organization, OrganizationMember, OrganizationMemberTeam, Team\n\n            org = Organization.get_default()\n            if superuser:\n                role = roles.get_top_dog().id\n            else:\n                role = org.default_role\n            member = OrganizationMember.objects.create(organization=org, user=user, role=role)\n\n            # if we've only got a single team let's go ahead and give\n            # access to that team as its likely the desired outcome\n            teams = list(Team.objects.filter(organization=org)[0:2])\n            if len(teams) == 1:\n                OrganizationMemberTeam.objects.create(team=teams[0], organizationmember=member)\n            click.echo(\"Added to organization: %s\" % (org.slug,))\n", "path": "src/sentry/runner/commands/createuser.py"}]}