diff --git a/superset/views.py b/superset/views.py index fec9f50c312..17ef8439e8d 100755 --- a/superset/views.py +++ b/superset/views.py @@ -1134,21 +1134,57 @@ appbuilder.add_view_no_menu(R) class Superset(BaseSupersetView): """The base views for Superset!""" + @api @has_access_api @expose("/update_role/", methods=['POST']) def update_role(self): """Assigns a list of found users to the given role.""" data = request.get_json(force=True) - usernames = data['usernames'] + gamma_role = sm.find_role('Gamma') + + username_set = set() + user_data_dict = {} + for user_data in data['users']: + username = user_data['username'] + if not username: + continue + user_data_dict[username] = user_data + username_set.add(username) + + existing_users = db.session.query(sm.user_model).filter( + sm.user_model.username.in_(username_set)).all() + missing_users = username_set.difference( + set([u.username for u in existing_users])) + logging.info('Missing users: {}'.format(missing_users)) + + created_users = [] + for username in missing_users: + user_data = user_data_dict[username] + user = sm.find_user(email=user_data['email']) + if not user: + logging.info("Adding user: {}.".format(user_data)) + sm.add_user( + username=user_data['username'], + first_name=user_data['first_name'], + last_name=user_data['last_name'], + email=user_data['email'], + role=gamma_role, + ) + sm.get_session.commit() + user = sm.find_user(username=user_data['username']) + existing_users.append(user) + created_users.append(user.username) + role_name = data['role_name'] role = sm.find_role(role_name) - role.user = [] - for username in usernames: - user = sm.find_user(username=username) - if user: - role.user.append(user) - db.session.commit() - return Response(status=201) + role.user = existing_users + sm.get_session.commit() + return Response(json.dumps({ + 'role': role_name, + '# missing users': len(missing_users), + '# granted': len(existing_users), + 'created_users': created_users, + }), status=201) @has_access_api @expose("/override_role_permissions/", methods=['POST']) diff --git a/tests/access_tests.py b/tests/access_tests.py index f57d2669829..376da41dc9c 100644 --- a/tests/access_tests.py +++ b/tests/access_tests.py @@ -354,14 +354,17 @@ class RequestAccessTests(SupersetTestCase): if update_role: db.session.delete(update_role) db.session.commit() - with self.assertRaises(AttributeError): - self.get_resp( - '/superset/update_role/', - data=json.dumps({ - 'usernames': ['gamma'], - 'role_name': update_role_str, - }) - ) + data = json.dumps({ + 'users': [{ + 'username': 'gamma', + 'first_name': 'Gamma', + 'last_name': 'Gamma', + 'email': 'gamma@superset.com', + }], + 'role_name': update_role_str}) + r = self.client.post('/superset/update_role/', data=data, + follow_redirects=True) + self.assertEquals(500, r.status_code) def test_update_role(self): update_role_str = 'update_me' @@ -370,7 +373,12 @@ class RequestAccessTests(SupersetTestCase): resp = self.client.post( '/superset/update_role/', data=json.dumps({ - 'usernames': ['gamma'], + 'users': [{ + 'username': 'gamma', + 'first_name': 'Gamma', + 'last_name': 'Gamma', + 'email': 'gamma@superset.com' + }], 'role_name': update_role_str }), follow_redirects=True @@ -383,7 +391,17 @@ class RequestAccessTests(SupersetTestCase): resp = self.client.post( '/superset/update_role/', data=json.dumps({ - 'usernames': ['alpha', 'unknown'], + 'users': [{ + 'username': 'alpha', + 'first_name': 'Alpha', + 'last_name': 'Alpha', + 'email': 'alpha@superset.com' + }, { + 'username': 'unknown', + 'first_name': 'Unknown1', + 'last_name': 'Unknown2', + 'email': 'unknown@superset.com' + }], 'role_name': update_role_str }), follow_redirects=True @@ -391,9 +409,16 @@ class RequestAccessTests(SupersetTestCase): self.assertEquals(resp.status_code, 201) update_role = sm.find_role(update_role_str) self.assertEquals( - update_role.user, [sm.find_user(username='alpha')]) - + update_role.user, [ + sm.find_user(username='alpha'), + sm.find_user(username='unknown'), + ]) + unknown = sm.find_user(username='unknown') + self.assertEquals('Unknown2', unknown.last_name) + self.assertEquals('Unknown1', unknown.first_name) + self.assertEquals('unknown@superset.com', unknown.email) db.session.delete(update_role) + db.session.delete(unknown) db.session.commit()