diff --git a/swift/common/middleware/swauth.py b/swift/common/middleware/swauth.py index ce6492959d..d4df1aa7ab 100644 --- a/swift/common/middleware/swauth.py +++ b/swift/common/middleware/swauth.py @@ -849,9 +849,11 @@ class Swauth(object): raise Exception('Could not retrieve user object: %s %s' % (path, resp.status)) body = resp.body - if '.reseller_admin' in \ - (g['name'] for g in json.loads(body)['groups']) and \ - not self.is_reseller_admin(req): + display_groups = [g['name'] for g in json.loads(body)['groups']] + if ('.admin' in display_groups and + not self.is_reseller_admin(req)) or \ + ('.reseller_admin' in display_groups and + not self.is_super_admin(req)): return HTTPForbidden(request=req) return Response(body=body) diff --git a/test/unit/common/middleware/test_swauth.py b/test/unit/common/middleware/test_swauth.py index 61af54ce0a..19d07fc8fa 100644 --- a/test/unit/common/middleware/test_swauth.py +++ b/test/unit/common/middleware/test_swauth.py @@ -2354,8 +2354,7 @@ class TestAuth(unittest.TestCase): "auth": "plaintext:key"})), # GET of requested user object ('200 Ok', {}, json.dumps( - {"groups": [{"name": "act:usr"}, {"name": "act"}, - {"name": ".admin"}], + {"groups": [{"name": "act:usr"}, {"name": "act"}], "auth": "plaintext:key"}))])) resp = Request.blank('/auth/v2/act/usr', headers={'X-Auth-Admin-User': 'act:adm', @@ -2363,21 +2362,20 @@ class TestAuth(unittest.TestCase): ).get_response(self.test_auth) self.assertEquals(resp.status_int, 200) self.assertEquals(resp.body, json.dumps( - {"groups": [{"name": "act:usr"}, {"name": "act"}, - {"name": ".admin"}], + {"groups": [{"name": "act:usr"}, {"name": "act"}], "auth": "plaintext:key"})) self.assertEquals(self.test_auth.app.calls, 2) - def test_get_user_account_admin_fail_getting_reseller_admin(self): + def test_get_user_account_admin_fail_getting_account_admin(self): self.test_auth.app = FakeApp(iter([ # GET of user object (account admin check) ('200 Ok', {}, json.dumps({"groups": [{"name": "act:adm"}, {"name": "test"}, {"name": ".admin"}], "auth": "plaintext:key"})), - # GET of requested user object + # GET of requested user object [who is an .admin as well] ('200 Ok', {}, json.dumps( {"groups": [{"name": "act:usr"}, {"name": "act"}, - {"name": ".reseller_admin"}], + {"name": ".admin"}], "auth": "plaintext:key"})), # GET of user object (reseller admin check [and fail here]) ('200 Ok', {}, json.dumps({"groups": [{"name": "act:adm"}, @@ -2390,31 +2388,59 @@ class TestAuth(unittest.TestCase): self.assertEquals(resp.status_int, 403) self.assertEquals(self.test_auth.app.calls, 3) - def test_get_user_reseller_admin_succeed_getting_reseller_admin(self): + def test_get_user_account_admin_fail_getting_reseller_admin(self): + self.test_auth.app = FakeApp(iter([ + # GET of user object (account admin check) + ('200 Ok', {}, json.dumps({"groups": [{"name": "act:adm"}, + {"name": "test"}, {"name": ".admin"}], + "auth": "plaintext:key"})), + # GET of requested user object [who is a .reseller_admin] + ('200 Ok', {}, json.dumps( + {"groups": [{"name": "act:usr"}, {"name": "act"}, + {"name": ".reseller_admin"}], + "auth": "plaintext:key"}))])) + resp = Request.blank('/auth/v2/act/usr', + headers={'X-Auth-Admin-User': 'act:adm', + 'X-Auth-Admin-Key': 'key'} + ).get_response(self.test_auth) + self.assertEquals(resp.status_int, 403) + self.assertEquals(self.test_auth.app.calls, 2) + + def test_get_user_reseller_admin_fail_getting_reseller_admin(self): self.test_auth.app = FakeApp(iter([ # GET of user object (account admin check) ('200 Ok', {}, json.dumps({"groups": [{"name": "act:adm"}, {"name": "test"}, {"name": ".reseller_admin"}], "auth": "plaintext:key"})), + # GET of requested user object [who also is a .reseller_admin] + ('200 Ok', {}, json.dumps( + {"groups": [{"name": "act:usr"}, {"name": "act"}, + {"name": ".reseller_admin"}], + "auth": "plaintext:key"}))])) + resp = Request.blank('/auth/v2/act/usr', + headers={'X-Auth-Admin-User': 'act:adm', + 'X-Auth-Admin-Key': 'key'} + ).get_response(self.test_auth) + self.assertEquals(resp.status_int, 403) + self.assertEquals(self.test_auth.app.calls, 2) + + def test_get_user_super_admin_succeed_getting_reseller_admin(self): + self.test_auth.app = FakeApp(iter([ # GET of requested user object ('200 Ok', {}, json.dumps( {"groups": [{"name": "act:usr"}, {"name": "act"}, {"name": ".reseller_admin"}], - "auth": "plaintext:key"})), - # GET of user object (reseller admin check) - ('200 Ok', {}, json.dumps({"groups": [{"name": "act:adm"}, - {"name": "test"}, {"name": ".reseller_admin"}], - "auth": "plaintext:key"}))])) + "auth": "plaintext:key"}))])) resp = Request.blank('/auth/v2/act/usr', - headers={'X-Auth-Admin-User': 'act:adm', - 'X-Auth-Admin-Key': 'key'} + headers={'X-Auth-Admin-User': '.super_admin', + 'X-Auth-Admin-Key': 'supertest'} ).get_response(self.test_auth) self.assertEquals(resp.status_int, 200) self.assertEquals(resp.body, json.dumps( {"groups": [{"name": "act:usr"}, {"name": "act"}, {"name": ".reseller_admin"}], "auth": "plaintext:key"})) - self.assertEquals(self.test_auth.app.calls, 3) + self.assertEquals(self.test_auth.app.calls, 1) def test_get_user_groups_not_found(self): self.test_auth.app = FakeApp(iter([