We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Users who are already disabled still appear on CLI
<!--
#####################################################################
#
# Need support? USE THE FORUM! https://discuss.redash.io/c/support.
#
# Don't have steps to reproduce and actually not sure it's a bug?
# Use the forum! https://discuss.redash.io/c/support.
#
#####################################################################

**Got an idea for a new feature?** Check if it isn't on the roadmap already: http://bit.ly/redash-roadmap and start a new discussion in the features category: https://discuss.redash.io/c/feature-requests 🌟.

Found a bug? Please fill out the sections below... thank you 👍

Found a security vulnerability? Please email security@redash.io to report any security vulnerabilities. We will acknowledge receipt of your vulnerability and strive to send you regular updates about our progress. If you're curious about the status of your disclosure please feel free to email us again. If you want to encrypt your disclosure email, you can use this PGP key.

-->

### Issue Summary

When I refer to user list on redash cli.
Even I made some user disabled, the user is still existed on the list.

### Steps to Reproduce

``` docker exec -it redash_server_1 ./manage.py users list ```

```
Id: 2
Name: sumito
Email: sute@sumito.jp
Organization: sumito
--------------------
```
Any other info e.g. Why do you consider this to be a bug? What did you expect to happen instead?

### Technical details:

* Redash Version: 5.0.1+b4850
* Browser/OS: Chrome
* How did you install Redash: docker
Users who are already disabled still appear on CLI
<!--
#####################################################################
#
# Need support? USE THE FORUM! https://discuss.redash.io/c/support.
#
# Don't have steps to reproduce and actually not sure it's a bug?
# Use the forum! https://discuss.redash.io/c/support.
#
#####################################################################

**Got an idea for a new feature?** Check if it isn't on the roadmap already: http://bit.ly/redash-roadmap and start a new discussion in the features category: https://discuss.redash.io/c/feature-requests 🌟.

Found a bug? Please fill out the sections below... thank you 👍

Found a security vulnerability? Please email security@redash.io to report any security vulnerabilities. We will acknowledge receipt of your vulnerability and strive to send you regular updates about our progress. If you're curious about the status of your disclosure please feel free to email us again. If you want to encrypt your disclosure email, you can use this PGP key.

-->

### Issue Summary

When I refer to user list on redash cli.
Even I made some user disabled, the user is still existed on the list.

### Steps to Reproduce

``` docker exec -it redash_server_1 ./manage.py users list ```

```
Id: 2
Name: sumito
Email: sute@sumito.jp
Organization: sumito
--------------------
```
Any other info e.g. Why do you consider this to be a bug? What did you expect to happen instead?

### Technical details:

* Redash Version: 5.0.1+b4850
* Browser/OS: Chrome
* How did you install Redash: docker

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `redash/cli/users.py`
Content:
```
1 from __future__ import print_function
2 from sys import exit
3 
4 from click import BOOL, argument, option, prompt
5 from flask.cli import AppGroup
6 from six import string_types
7 from sqlalchemy.orm.exc import NoResultFound
8 from sqlalchemy.exc import IntegrityError
9 
10 from redash import models
11 from redash.handlers.users import invite_user
12 
13 manager = AppGroup(help="Users management commands.")
14 
15 
16 def build_groups(org, groups, is_admin):
17     if isinstance(groups, string_types):
18         groups = groups.split(',')
19         groups.remove('')  # in case it was empty string
20         groups = [int(g) for g in groups]
21 
22     if groups is None:
23         groups = [org.default_group.id]
24 
25     if is_admin:
26         groups += [org.admin_group.id]
27 
28     return groups
29 
30 
31 @manager.command()
32 @argument('email')
33 @option('--org', 'organization', default='default',
34         help="the organization the user belongs to, (leave blank for "
35         "'default').")
36 def grant_admin(email, organization='default'):
37     """
38     Grant admin access to user EMAIL.
39     """
40     try:
41         org = models.Organization.get_by_slug(organization)
42         admin_group = org.admin_group
43         user = models.User.get_by_email_and_org(email, org)
44 
45         if admin_group.id in user.group_ids:
46             print("User is already an admin.")
47         else:
48             user.group_ids = user.group_ids + [org.admin_group.id]
49             models.db.session.add(user)
50             models.db.session.commit()
51             print("User updated.")
52     except NoResultFound:
53         print("User [%s] not found." % email)
54 
55 
56 @manager.command()
57 @argument('email')
58 @argument('name')
59 @option('--org', 'organization', default='default',
60         help="The organization the user belongs to (leave blank for "
61         "'default').")
62 @option('--admin', 'is_admin', is_flag=True, default=False,
63         help="set user as admin")
64 @option('--google', 'google_auth', is_flag=True,
65         default=False, help="user uses Google Auth to login")
66 @option('--password', 'password', default=None,
67         help="Password for users who don't use Google Auth "
68         "(leave blank for prompt).")
69 @option('--groups', 'groups', default=None,
70         help="Comma separated list of groups (leave blank for "
71         "default).")
72 def create(email, name, groups, is_admin=False, google_auth=False,
73            password=None, organization='default'):
74     """
75     Create user EMAIL with display name NAME.
76     """
77     print("Creating user (%s, %s) in organization %s..." % (email, name,
78                                                             organization))
79     print("Admin: %r" % is_admin)
80     print("Login with Google Auth: %r\n" % google_auth)
81 
82     org = models.Organization.get_by_slug(organization)
83     groups = build_groups(org, groups, is_admin)
84 
85     user = models.User(org=org, email=email, name=name, group_ids=groups)
86     if not password and not google_auth:
87         password = prompt("Password", hide_input=True,
88                           confirmation_prompt=True)
89     if not google_auth:
90         user.hash_password(password)
91 
92     try:
93         models.db.session.add(user)
94         models.db.session.commit()
95     except Exception as e:
96         print("Failed creating user: %s" % e.message)
97         exit(1)
98 
99 
100 @manager.command()
101 @argument('email')
102 @argument('name')
103 @option('--org', 'organization', default='default',
104         help="The organization the root user belongs to (leave blank for 'default').")
105 @option('--google', 'google_auth', is_flag=True,
106         default=False, help="user uses Google Auth to login")
107 @option('--password', 'password', default=None,
108         help="Password for root user who don't use Google Auth "
109         "(leave blank for prompt).")
110 def create_root(email, name, google_auth=False, password=None, organization='default'):
111     """
112     Create root user.
113     """
114     print("Creating root user (%s, %s) in organization %s..." % (email, name, organization))
115     print("Login with Google Auth: %r\n" % google_auth)
116 
117     user = models.User.query.filter(models.User.email == email).first()
118     if user is not None:
119         print("User [%s] is already exists." % email)
120         exit(1)
121 
122     slug = 'default'
123     default_org = models.Organization.query.filter(models.Organization.slug == slug).first()
124     if default_org is None:
125         default_org = models.Organization(name=organization, slug=slug, settings={})
126 
127     admin_group = models.Group(name='admin', permissions=['admin', 'super_admin'],
128                                org=default_org, type=models.Group.BUILTIN_GROUP)
129     default_group = models.Group(name='default', permissions=models.Group.DEFAULT_PERMISSIONS,
130                                  org=default_org, type=models.Group.BUILTIN_GROUP)
131 
132     models.db.session.add_all([default_org, admin_group, default_group])
133     models.db.session.commit()
134 
135     user = models.User(org=default_org, email=email, name=name,
136                        group_ids=[admin_group.id, default_group.id])
137     if not google_auth:
138         user.hash_password(password)
139 
140     try:
141         models.db.session.add(user)
142         models.db.session.commit()
143     except Exception as e:
144         print("Failed creating root user: %s" % e.message)
145         exit(1)
146 
147 
148 @manager.command()
149 @argument('email')
150 @option('--org', 'organization', default=None,
151         help="The organization the user belongs to (leave blank for all"
152         " organizations).")
153 def delete(email, organization=None):
154     """
155     Delete user EMAIL.
156     """
157     if organization:
158         org = models.Organization.get_by_slug(organization)
159         deleted_count = models.User.query.filter(
160             models.User.email == email,
161             models.User.org == org.id,
162         ).delete()
163     else:
164         deleted_count = models.User.query.filter(models.User.email == email).delete(
165             synchronize_session=False)
166     models.db.session.commit()
167     print("Deleted %d users." % deleted_count)
168 
169 
170 @manager.command()
171 @argument('email')
172 @argument('password')
173 @option('--org', 'organization', default=None,
174         help="The organization the user belongs to (leave blank for all "
175         "organizations).")
176 def password(email, password, organization=None):
177     """
178     Resets password for EMAIL to PASSWORD.
179     """
180     if organization:
181         org = models.Organization.get_by_slug(organization)
182         user = models.User.query.filter(
183             models.User.email == email,
184             models.User.org == org,
185         ).first()
186     else:
187         user = models.User.query.filter(models.User.email == email).first()
188 
189     if user is not None:
190         user.hash_password(password)
191         models.db.session.add(user)
192         models.db.session.commit()
193         print("User updated.")
194     else:
195         print("User [%s] not found." % email)
196         exit(1)
197 
198 
199 @manager.command()
200 @argument('email')
201 @argument('name')
202 @argument('inviter_email')
203 @option('--org', 'organization', default='default',
204         help="The organization the user belongs to (leave blank for 'default')")
205 @option('--admin', 'is_admin', type=BOOL, default=False,
206         help="set user as admin")
207 @option('--groups', 'groups', default=None,
208         help="Comma seperated list of groups (leave blank for default).")
209 def invite(email, name, inviter_email, groups, is_admin=False,
210            organization='default'):
211     """
212     Sends an invitation to the given NAME and EMAIL from INVITER_EMAIL.
213     """
214     org = models.Organization.get_by_slug(organization)
215     groups = build_groups(org, groups, is_admin)
216     try:
217         user_from = models.User.get_by_email_and_org(inviter_email, org)
218         user = models.User(org=org, name=name, email=email, group_ids=groups)
219         models.db.session.add(user)
220         try:
221             models.db.session.commit()
222             invite_user(org, user_from, user)
223             print("An invitation was sent to [%s] at [%s]." % (name, email))
224         except IntegrityError as e:
225             if "email" in e.message:
226                 print("Cannot invite. User already exists [%s]" % email)
227             else:
228                 print(e)
229     except NoResultFound:
230         print("The inviter [%s] was not found." % inviter_email)
231 
232 
233 @manager.command()
234 @option('--org', 'organization', default=None,
235         help="The organization the user belongs to (leave blank for all"
236         " organizations)")
237 def list(organization=None):
238     """List all users"""
239     if organization:
240         org = models.Organization.get_by_slug(organization)
241         users = models.User.query.filter(models.User.org == org)
242     else:
243         users = models.User.query
244     for i, user in enumerate(users):
245         if i > 0:
246             print("-" * 20)
247 
248         print("Id: {}\nName: {}\nEmail: {}\nOrganization: {}".format(
249             user.id, user.name.encode('utf-8'), user.email, user.org.name))
250
```
--- 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/redash/cli/users.py b/redash/cli/users.py
--- a/redash/cli/users.py
+++ b/redash/cli/users.py
@@ -245,5 +245,5 @@
         if i > 0:
             print("-" * 20)
 
-        print("Id: {}\nName: {}\nEmail: {}\nOrganization: {}".format(
-            user.id, user.name.encode('utf-8'), user.email, user.org.name))
+        print("Id: {}\nName: {}\nEmail: {}\nOrganization: {}\nActive: {}".format(
+            user.id, user.name.encode('utf-8'), user.email, user.org.name, not(user.is_disabled)))

{"golden_diff": "diff --git a/redash/cli/users.py b/redash/cli/users.py\n--- a/redash/cli/users.py\n+++ b/redash/cli/users.py\n@@ -245,5 +245,5 @@\n         if i > 0:\n             print(\"-\" * 20)\n \n-        print(\"Id: {}\\nName: {}\\nEmail: {}\\nOrganization: {}\".format(\n-            user.id, user.name.encode('utf-8'), user.email, user.org.name))\n+        print(\"Id: {}\\nName: {}\\nEmail: {}\\nOrganization: {}\\nActive: {}\".format(\n+            user.id, user.name.encode('utf-8'), user.email, user.org.name, not(user.is_disabled)))\n", "issue": "Users who are already disabled still appear on CLI\n<!--\r\n#####################################################################\r\n#\r\n# Need support? USE THE FORUM! https://discuss.redash.io/c/support.\r\n#\r\n# Don't have steps to reproduce and actually not sure it's a bug?\r\n# Use the forum! https://discuss.redash.io/c/support.\r\n#\r\n#####################################################################\r\n\r\n**Got an idea for a new feature?** Check if it isn't on the roadmap already: http://bit.ly/redash-roadmap and start a new discussion in the features category: https://discuss.redash.io/c/feature-requests \ud83c\udf1f.\r\n\r\nFound a bug? Please fill out the sections below... thank you \ud83d\udc4d\r\n\r\nFound a security vulnerability? Please email security@redash.io to report any security vulnerabilities. We will acknowledge receipt of your vulnerability and strive to send you regular updates about our progress. If you're curious about the status of your disclosure please feel free to email us again. If you want to encrypt your disclosure email, you can use this PGP key.\r\n\r\n-->\r\n\r\n### Issue Summary\r\n\r\nWhen I refer to user list on redash cli.\r\nEven I made some user disabled, the user is still existed on the list.\r\n\r\n### Steps to Reproduce\r\n\r\n``` docker exec -it redash_server_1 ./manage.py users list ```\r\n\r\n```\r\nId: 2\r\nName: sumito\r\nEmail: sute@sumito.jp\r\nOrganization: sumito\r\n--------------------\r\n```\r\nAny other info e.g. Why do you consider this to be a bug? What did you expect to happen instead?\r\n\r\n### Technical details:\r\n\r\n* Redash Version: 5.0.1+b4850\r\n* Browser/OS: Chrome\r\n* How did you install Redash: docker\nUsers who are already disabled still appear on CLI\n<!--\r\n#####################################################################\r\n#\r\n# Need support? USE THE FORUM! https://discuss.redash.io/c/support.\r\n#\r\n# Don't have steps to reproduce and actually not sure it's a bug?\r\n# Use the forum! https://discuss.redash.io/c/support.\r\n#\r\n#####################################################################\r\n\r\n**Got an idea for a new feature?** Check if it isn't on the roadmap already: http://bit.ly/redash-roadmap and start a new discussion in the features category: https://discuss.redash.io/c/feature-requests \ud83c\udf1f.\r\n\r\nFound a bug? Please fill out the sections below... thank you \ud83d\udc4d\r\n\r\nFound a security vulnerability? Please email security@redash.io to report any security vulnerabilities. We will acknowledge receipt of your vulnerability and strive to send you regular updates about our progress. If you're curious about the status of your disclosure please feel free to email us again. If you want to encrypt your disclosure email, you can use this PGP key.\r\n\r\n-->\r\n\r\n### Issue Summary\r\n\r\nWhen I refer to user list on redash cli.\r\nEven I made some user disabled, the user is still existed on the list.\r\n\r\n### Steps to Reproduce\r\n\r\n``` docker exec -it redash_server_1 ./manage.py users list ```\r\n\r\n```\r\nId: 2\r\nName: sumito\r\nEmail: sute@sumito.jp\r\nOrganization: sumito\r\n--------------------\r\n```\r\nAny other info e.g. Why do you consider this to be a bug? What did you expect to happen instead?\r\n\r\n### Technical details:\r\n\r\n* Redash Version: 5.0.1+b4850\r\n* Browser/OS: Chrome\r\n* How did you install Redash: docker\n", "before_files": [{"content": "from __future__ import print_function\nfrom sys import exit\n\nfrom click import BOOL, argument, option, prompt\nfrom flask.cli import AppGroup\nfrom six import string_types\nfrom sqlalchemy.orm.exc import NoResultFound\nfrom sqlalchemy.exc import IntegrityError\n\nfrom redash import models\nfrom redash.handlers.users import invite_user\n\nmanager = AppGroup(help=\"Users management commands.\")\n\n\ndef build_groups(org, groups, is_admin):\n    if isinstance(groups, string_types):\n        groups = groups.split(',')\n        groups.remove('')  # in case it was empty string\n        groups = [int(g) for g in groups]\n\n    if groups is None:\n        groups = [org.default_group.id]\n\n    if is_admin:\n        groups += [org.admin_group.id]\n\n    return groups\n\n\n@manager.command()\n@argument('email')\n@option('--org', 'organization', default='default',\n        help=\"the organization the user belongs to, (leave blank for \"\n        \"'default').\")\ndef grant_admin(email, organization='default'):\n    \"\"\"\n    Grant admin access to user EMAIL.\n    \"\"\"\n    try:\n        org = models.Organization.get_by_slug(organization)\n        admin_group = org.admin_group\n        user = models.User.get_by_email_and_org(email, org)\n\n        if admin_group.id in user.group_ids:\n            print(\"User is already an admin.\")\n        else:\n            user.group_ids = user.group_ids + [org.admin_group.id]\n            models.db.session.add(user)\n            models.db.session.commit()\n            print(\"User updated.\")\n    except NoResultFound:\n        print(\"User [%s] not found.\" % email)\n\n\n@manager.command()\n@argument('email')\n@argument('name')\n@option('--org', 'organization', default='default',\n        help=\"The organization the user belongs to (leave blank for \"\n        \"'default').\")\n@option('--admin', 'is_admin', is_flag=True, default=False,\n        help=\"set user as admin\")\n@option('--google', 'google_auth', is_flag=True,\n        default=False, help=\"user uses Google Auth to login\")\n@option('--password', 'password', default=None,\n        help=\"Password for users who don't use Google Auth \"\n        \"(leave blank for prompt).\")\n@option('--groups', 'groups', default=None,\n        help=\"Comma separated list of groups (leave blank for \"\n        \"default).\")\ndef create(email, name, groups, is_admin=False, google_auth=False,\n           password=None, organization='default'):\n    \"\"\"\n    Create user EMAIL with display name NAME.\n    \"\"\"\n    print(\"Creating user (%s, %s) in organization %s...\" % (email, name,\n                                                            organization))\n    print(\"Admin: %r\" % is_admin)\n    print(\"Login with Google Auth: %r\\n\" % google_auth)\n\n    org = models.Organization.get_by_slug(organization)\n    groups = build_groups(org, groups, is_admin)\n\n    user = models.User(org=org, email=email, name=name, group_ids=groups)\n    if not password and not google_auth:\n        password = prompt(\"Password\", hide_input=True,\n                          confirmation_prompt=True)\n    if not google_auth:\n        user.hash_password(password)\n\n    try:\n        models.db.session.add(user)\n        models.db.session.commit()\n    except Exception as e:\n        print(\"Failed creating user: %s\" % e.message)\n        exit(1)\n\n\n@manager.command()\n@argument('email')\n@argument('name')\n@option('--org', 'organization', default='default',\n        help=\"The organization the root user belongs to (leave blank for 'default').\")\n@option('--google', 'google_auth', is_flag=True,\n        default=False, help=\"user uses Google Auth to login\")\n@option('--password', 'password', default=None,\n        help=\"Password for root user who don't use Google Auth \"\n        \"(leave blank for prompt).\")\ndef create_root(email, name, google_auth=False, password=None, organization='default'):\n    \"\"\"\n    Create root user.\n    \"\"\"\n    print(\"Creating root user (%s, %s) in organization %s...\" % (email, name, organization))\n    print(\"Login with Google Auth: %r\\n\" % google_auth)\n\n    user = models.User.query.filter(models.User.email == email).first()\n    if user is not None:\n        print(\"User [%s] is already exists.\" % email)\n        exit(1)\n\n    slug = 'default'\n    default_org = models.Organization.query.filter(models.Organization.slug == slug).first()\n    if default_org is None:\n        default_org = models.Organization(name=organization, slug=slug, settings={})\n\n    admin_group = models.Group(name='admin', permissions=['admin', 'super_admin'],\n                               org=default_org, type=models.Group.BUILTIN_GROUP)\n    default_group = models.Group(name='default', permissions=models.Group.DEFAULT_PERMISSIONS,\n                                 org=default_org, type=models.Group.BUILTIN_GROUP)\n\n    models.db.session.add_all([default_org, admin_group, default_group])\n    models.db.session.commit()\n\n    user = models.User(org=default_org, email=email, name=name,\n                       group_ids=[admin_group.id, default_group.id])\n    if not google_auth:\n        user.hash_password(password)\n\n    try:\n        models.db.session.add(user)\n        models.db.session.commit()\n    except Exception as e:\n        print(\"Failed creating root user: %s\" % e.message)\n        exit(1)\n\n\n@manager.command()\n@argument('email')\n@option('--org', 'organization', default=None,\n        help=\"The organization the user belongs to (leave blank for all\"\n        \" organizations).\")\ndef delete(email, organization=None):\n    \"\"\"\n    Delete user EMAIL.\n    \"\"\"\n    if organization:\n        org = models.Organization.get_by_slug(organization)\n        deleted_count = models.User.query.filter(\n            models.User.email == email,\n            models.User.org == org.id,\n        ).delete()\n    else:\n        deleted_count = models.User.query.filter(models.User.email == email).delete(\n            synchronize_session=False)\n    models.db.session.commit()\n    print(\"Deleted %d users.\" % deleted_count)\n\n\n@manager.command()\n@argument('email')\n@argument('password')\n@option('--org', 'organization', default=None,\n        help=\"The organization the user belongs to (leave blank for all \"\n        \"organizations).\")\ndef password(email, password, organization=None):\n    \"\"\"\n    Resets password for EMAIL to PASSWORD.\n    \"\"\"\n    if organization:\n        org = models.Organization.get_by_slug(organization)\n        user = models.User.query.filter(\n            models.User.email == email,\n            models.User.org == org,\n        ).first()\n    else:\n        user = models.User.query.filter(models.User.email == email).first()\n\n    if user is not None:\n        user.hash_password(password)\n        models.db.session.add(user)\n        models.db.session.commit()\n        print(\"User updated.\")\n    else:\n        print(\"User [%s] not found.\" % email)\n        exit(1)\n\n\n@manager.command()\n@argument('email')\n@argument('name')\n@argument('inviter_email')\n@option('--org', 'organization', default='default',\n        help=\"The organization the user belongs to (leave blank for 'default')\")\n@option('--admin', 'is_admin', type=BOOL, default=False,\n        help=\"set user as admin\")\n@option('--groups', 'groups', default=None,\n        help=\"Comma seperated list of groups (leave blank for default).\")\ndef invite(email, name, inviter_email, groups, is_admin=False,\n           organization='default'):\n    \"\"\"\n    Sends an invitation to the given NAME and EMAIL from INVITER_EMAIL.\n    \"\"\"\n    org = models.Organization.get_by_slug(organization)\n    groups = build_groups(org, groups, is_admin)\n    try:\n        user_from = models.User.get_by_email_and_org(inviter_email, org)\n        user = models.User(org=org, name=name, email=email, group_ids=groups)\n        models.db.session.add(user)\n        try:\n            models.db.session.commit()\n            invite_user(org, user_from, user)\n            print(\"An invitation was sent to [%s] at [%s].\" % (name, email))\n        except IntegrityError as e:\n            if \"email\" in e.message:\n                print(\"Cannot invite. User already exists [%s]\" % email)\n            else:\n                print(e)\n    except NoResultFound:\n        print(\"The inviter [%s] was not found.\" % inviter_email)\n\n\n@manager.command()\n@option('--org', 'organization', default=None,\n        help=\"The organization the user belongs to (leave blank for all\"\n        \" organizations)\")\ndef list(organization=None):\n    \"\"\"List all users\"\"\"\n    if organization:\n        org = models.Organization.get_by_slug(organization)\n        users = models.User.query.filter(models.User.org == org)\n    else:\n        users = models.User.query\n    for i, user in enumerate(users):\n        if i > 0:\n            print(\"-\" * 20)\n\n        print(\"Id: {}\\nName: {}\\nEmail: {}\\nOrganization: {}\".format(\n            user.id, user.name.encode('utf-8'), user.email, user.org.name))\n", "path": "redash/cli/users.py"}], "after_files": [{"content": "from __future__ import print_function\nfrom sys import exit\n\nfrom click import BOOL, argument, option, prompt\nfrom flask.cli import AppGroup\nfrom six import string_types\nfrom sqlalchemy.orm.exc import NoResultFound\nfrom sqlalchemy.exc import IntegrityError\n\nfrom redash import models\nfrom redash.handlers.users import invite_user\n\nmanager = AppGroup(help=\"Users management commands.\")\n\n\ndef build_groups(org, groups, is_admin):\n    if isinstance(groups, string_types):\n        groups = groups.split(',')\n        groups.remove('')  # in case it was empty string\n        groups = [int(g) for g in groups]\n\n    if groups is None:\n        groups = [org.default_group.id]\n\n    if is_admin:\n        groups += [org.admin_group.id]\n\n    return groups\n\n\n@manager.command()\n@argument('email')\n@option('--org', 'organization', default='default',\n        help=\"the organization the user belongs to, (leave blank for \"\n        \"'default').\")\ndef grant_admin(email, organization='default'):\n    \"\"\"\n    Grant admin access to user EMAIL.\n    \"\"\"\n    try:\n        org = models.Organization.get_by_slug(organization)\n        admin_group = org.admin_group\n        user = models.User.get_by_email_and_org(email, org)\n\n        if admin_group.id in user.group_ids:\n            print(\"User is already an admin.\")\n        else:\n            user.group_ids = user.group_ids + [org.admin_group.id]\n            models.db.session.add(user)\n            models.db.session.commit()\n            print(\"User updated.\")\n    except NoResultFound:\n        print(\"User [%s] not found.\" % email)\n\n\n@manager.command()\n@argument('email')\n@argument('name')\n@option('--org', 'organization', default='default',\n        help=\"The organization the user belongs to (leave blank for \"\n        \"'default').\")\n@option('--admin', 'is_admin', is_flag=True, default=False,\n        help=\"set user as admin\")\n@option('--google', 'google_auth', is_flag=True,\n        default=False, help=\"user uses Google Auth to login\")\n@option('--password', 'password', default=None,\n        help=\"Password for users who don't use Google Auth \"\n        \"(leave blank for prompt).\")\n@option('--groups', 'groups', default=None,\n        help=\"Comma separated list of groups (leave blank for \"\n        \"default).\")\ndef create(email, name, groups, is_admin=False, google_auth=False,\n           password=None, organization='default'):\n    \"\"\"\n    Create user EMAIL with display name NAME.\n    \"\"\"\n    print(\"Creating user (%s, %s) in organization %s...\" % (email, name,\n                                                            organization))\n    print(\"Admin: %r\" % is_admin)\n    print(\"Login with Google Auth: %r\\n\" % google_auth)\n\n    org = models.Organization.get_by_slug(organization)\n    groups = build_groups(org, groups, is_admin)\n\n    user = models.User(org=org, email=email, name=name, group_ids=groups)\n    if not password and not google_auth:\n        password = prompt(\"Password\", hide_input=True,\n                          confirmation_prompt=True)\n    if not google_auth:\n        user.hash_password(password)\n\n    try:\n        models.db.session.add(user)\n        models.db.session.commit()\n    except Exception as e:\n        print(\"Failed creating user: %s\" % e.message)\n        exit(1)\n\n\n@manager.command()\n@argument('email')\n@argument('name')\n@option('--org', 'organization', default='default',\n        help=\"The organization the root user belongs to (leave blank for 'default').\")\n@option('--google', 'google_auth', is_flag=True,\n        default=False, help=\"user uses Google Auth to login\")\n@option('--password', 'password', default=None,\n        help=\"Password for root user who don't use Google Auth \"\n        \"(leave blank for prompt).\")\ndef create_root(email, name, google_auth=False, password=None, organization='default'):\n    \"\"\"\n    Create root user.\n    \"\"\"\n    print(\"Creating root user (%s, %s) in organization %s...\" % (email, name, organization))\n    print(\"Login with Google Auth: %r\\n\" % google_auth)\n\n    user = models.User.query.filter(models.User.email == email).first()\n    if user is not None:\n        print(\"User [%s] is already exists.\" % email)\n        exit(1)\n\n    slug = 'default'\n    default_org = models.Organization.query.filter(models.Organization.slug == slug).first()\n    if default_org is None:\n        default_org = models.Organization(name=organization, slug=slug, settings={})\n\n    admin_group = models.Group(name='admin', permissions=['admin', 'super_admin'],\n                               org=default_org, type=models.Group.BUILTIN_GROUP)\n    default_group = models.Group(name='default', permissions=models.Group.DEFAULT_PERMISSIONS,\n                                 org=default_org, type=models.Group.BUILTIN_GROUP)\n\n    models.db.session.add_all([default_org, admin_group, default_group])\n    models.db.session.commit()\n\n    user = models.User(org=default_org, email=email, name=name,\n                       group_ids=[admin_group.id, default_group.id])\n    if not google_auth:\n        user.hash_password(password)\n\n    try:\n        models.db.session.add(user)\n        models.db.session.commit()\n    except Exception as e:\n        print(\"Failed creating root user: %s\" % e.message)\n        exit(1)\n\n\n@manager.command()\n@argument('email')\n@option('--org', 'organization', default=None,\n        help=\"The organization the user belongs to (leave blank for all\"\n        \" organizations).\")\ndef delete(email, organization=None):\n    \"\"\"\n    Delete user EMAIL.\n    \"\"\"\n    if organization:\n        org = models.Organization.get_by_slug(organization)\n        deleted_count = models.User.query.filter(\n            models.User.email == email,\n            models.User.org == org.id,\n        ).delete()\n    else:\n        deleted_count = models.User.query.filter(models.User.email == email).delete(\n            synchronize_session=False)\n    models.db.session.commit()\n    print(\"Deleted %d users.\" % deleted_count)\n\n\n@manager.command()\n@argument('email')\n@argument('password')\n@option('--org', 'organization', default=None,\n        help=\"The organization the user belongs to (leave blank for all \"\n        \"organizations).\")\ndef password(email, password, organization=None):\n    \"\"\"\n    Resets password for EMAIL to PASSWORD.\n    \"\"\"\n    if organization:\n        org = models.Organization.get_by_slug(organization)\n        user = models.User.query.filter(\n            models.User.email == email,\n            models.User.org == org,\n        ).first()\n    else:\n        user = models.User.query.filter(models.User.email == email).first()\n\n    if user is not None:\n        user.hash_password(password)\n        models.db.session.add(user)\n        models.db.session.commit()\n        print(\"User updated.\")\n    else:\n        print(\"User [%s] not found.\" % email)\n        exit(1)\n\n\n@manager.command()\n@argument('email')\n@argument('name')\n@argument('inviter_email')\n@option('--org', 'organization', default='default',\n        help=\"The organization the user belongs to (leave blank for 'default')\")\n@option('--admin', 'is_admin', type=BOOL, default=False,\n        help=\"set user as admin\")\n@option('--groups', 'groups', default=None,\n        help=\"Comma seperated list of groups (leave blank for default).\")\ndef invite(email, name, inviter_email, groups, is_admin=False,\n           organization='default'):\n    \"\"\"\n    Sends an invitation to the given NAME and EMAIL from INVITER_EMAIL.\n    \"\"\"\n    org = models.Organization.get_by_slug(organization)\n    groups = build_groups(org, groups, is_admin)\n    try:\n        user_from = models.User.get_by_email_and_org(inviter_email, org)\n        user = models.User(org=org, name=name, email=email, group_ids=groups)\n        models.db.session.add(user)\n        try:\n            models.db.session.commit()\n            invite_user(org, user_from, user)\n            print(\"An invitation was sent to [%s] at [%s].\" % (name, email))\n        except IntegrityError as e:\n            if \"email\" in e.message:\n                print(\"Cannot invite. User already exists [%s]\" % email)\n            else:\n                print(e)\n    except NoResultFound:\n        print(\"The inviter [%s] was not found.\" % inviter_email)\n\n\n@manager.command()\n@option('--org', 'organization', default=None,\n        help=\"The organization the user belongs to (leave blank for all\"\n        \" organizations)\")\ndef list(organization=None):\n    \"\"\"List all users\"\"\"\n    if organization:\n        org = models.Organization.get_by_slug(organization)\n        users = models.User.query.filter(models.User.org == org)\n    else:\n        users = models.User.query\n    for i, user in enumerate(users):\n        if i > 0:\n            print(\"-\" * 20)\n\n        print(\"Id: {}\\nName: {}\\nEmail: {}\\nOrganization: {}\\nActive: {}\".format(\n            user.id, user.name.encode('utf-8'), user.email, user.org.name, not(user.is_disabled)))\n", "path": "redash/cli/users.py"}]}