Example #1
0
def _modify_groups(cloud_node, request):
    action = request.args['action']
    resp = {
        'groups': request.json['groups'],
        'action': action,
        f'{cloud_node.object_type}_id': cloud_node.name
    }
    try:
        Group.exists(request.json['groups'])
        if action == 'add':
            cloud_node.add_groups(request.json['groups'])
        elif action == 'remove':
            cloud_node.remove_groups(request.json['groups'])
    except cd_client.exceptions.BatchWriteException as ex:
        resp['msg'] = ex.response['Error']['Message']
        code = 304
    except FusilladeLimitException as ex:
        raise FusilladeHTTPException(detail=ex.reason,
                                     status=requests.codes.conflict,
                                     title="Conflict")
    else:
        resp[
            'msg'] = f"{cloud_node.object_type}'s groups successfully modified."
        code = 200
    return resp, code
 def test_get_group(self):
     headers = {'Content-Type': "application/json"}
     headers.update(get_auth_header(service_accounts['admin']))
     name = "test_get_group_Groupx"
     resp = self.app.get(f'/v1/group/{name}/', headers=headers)
     self.assertEqual(404, resp.status_code)
     Group.create(name)
     resp = self.app.get(f'/v1/group/{name}/', headers=headers)
     self.assertEqual(name, json.loads(resp.body)['group_id'])
     self.assertTrue(json.loads(resp.body)['policies'])
Example #3
0
    def test_get_groups(self):
        name = "*****@*****.**"
        test_groups = [(f"group_{i}", create_test_IAMPolicy(f"GroupPolicy{i}"))
                       for i in range(5)]
        groups = [Group.create(*i) for i in test_groups]

        user = User.provision_user(name)
        with self.subTest(
                "A user is in the public group when user is first created."):
            self.assertEqual(
                Group(object_ref=user.groups[0]).name, 'user_default')

        user.add_groups([])
        with self.subTest(
                "A user is added to no groups when add_groups is called with no groups"
        ):
            self.assertEqual(len(user.groups), 1)

        with self.subTest(
                "An error is returned when add a user to a group that does not exist."
        ):
            with self.assertRaises(
                    cd_client.exceptions.BatchWriteException) as ex:
                user.add_groups(["ghost_group"])
            self.assertTrue('ResourceNotFoundException' in
                            ex.exception.response['Error']['Message'])
            self.assertEqual(len(user.groups), 1)

        with self.subTest(
                "An error is returned when add a user to a group that they are already apart."
        ):
            with self.assertRaises(
                    cd_client.exceptions.BatchWriteException) as ex:
                user.add_groups(["user_default"])
            self.assertTrue('InvalidAttachmentException' in
                            ex.exception.response['Error']['Message'])
            self.assertEqual(len(user.groups), 1)

        user.add_groups([group.name for group in groups])
        with self.subTest(
                "A user is added to multiple groups when add_groups is called with multiple groups"
        ):
            self.assertEqual(len(user.groups), 6)

        with self.subTest(
                "A user inherits the groups policies when joining a group"):
            policies = set([
                normalize_json(p['policy_document'])
                for p in user.get_authz_params()['IAMPolicy']
            ])
            expected_policies = set(
                [normalize_json(i[1]) for i in test_groups])
            expected_policies.update(self.default_user_policies)
            self.assertSetEqual(policies, expected_policies)
Example #4
0
 def test_ownership(self):
     user = User.provision_user('test_user')
     group = Group.create("group_ownership")
     with self.subTest("A user is not an owner when new group is created"):
         self.assertFalse(user.is_owner(group))
     user.add_ownership(group)
     with self.subTest("A user is owner after assigning ownership."):
         self.assertTrue(user.is_owner(group))
     group2 = Group.create("group_ownership2")
     user.add_ownership(group2)
     with self.subTest("List groups owned, when list_owned is called"):
         resp = user.list_owned(Group)
     user.remove_ownership(group)
     self.assertFalse(user.is_owner(group))
Example #5
0
def backup_groups():
    groups = []
    for name in list_node(Group, 'groups'):
        group = Group(name)
        info = {
            'name': group.name,
            'members': [User(object_ref=u).name for u in group.get_users_iter()],
            'policies': format_policies([(p, group.get_policy(p)) for p in group.allowed_policy_types]),
            'owners': group.list_owners(),
            'roles': [Role(object_ref=r).name for r in group.roles]
        }
        groups.append(info)
    print("GROUPS:", *groups, sep='\n\t')
    return groups
Example #6
0
def get_resource_authz_parameters(user: str, resources: Union[List[str], str]):
    """

    Get all policy ids, and send them to lookup policy, group them by policy type.

    :param user:
    :param resource:
    :return:
    """
    policies = []
    _user = User(user)
    try:
        groups = _user.groups
    except cd_client.exceptions.ResourceNotFoundException:
        _user = User.provision_user(user)
        groups = _user.groups

    # Only support a single resource for now
    resource = resources[0] if isinstance(resources, list) else resources
    r_type, r_id, *_ = resource.split(':')[-1].split('/')
    if r_type in ResourceType.get_types():
        r_id = ResourceId(r_type, r_id)
        resource_policies = r_id.check_access(
            [_user] + [Group(object_ref=g) for g in groups])
        if not resource_policies:
            raise ResourceNotFound("ResourceNotFound")
        policies.extend(resource_policies)
    policies.extend(list(_user.get_policy_ids()))
    authz_params = Config.get_directory().get_policies(policies)
    if authz_params.get('ResourcePolicy'):
        authz_params['ResourcePolicy'] = combine(
            [i['policy_document'] for i in authz_params.get('ResourcePolicy')])
    return authz_params
Example #7
0
    def test_policy(self):
        group = Group.create("new_group")
        with self.subTest(
                "Only one policy is attached when lookup policy is called on a group without any roles"
        ):
            policies = [
                p['policy_document']
                for p in group.get_authz_params()['IAMPolicy']
            ]
            self.assertEqual(len(policies), 1)
            self.assertJSONEqual(policies[0], self.default_group_statement)

        group_name = "NewGroup1234"
        statement = create_test_IAMPolicy(group_name)
        with self.subTest("The group policy changes when satement is set"):
            group.set_policy(statement)
            policies = [
                p['policy_document']
                for p in group.get_authz_params()['IAMPolicy']
            ]
            self.assertJSONEqual(policies[0], statement)

        with self.subTest(
                "error raised when invalid statement assigned to group.get_policy()."
        ):
            with self.assertRaises(FusilladeHTTPException):
                group.set_policy({"Statement": "Something else"})
Example #8
0
 def test_remove_groups(self):
     name = "*****@*****.**"
     test_groups = [(f"group_{i}", create_test_IAMPolicy(f"GroupPolicy{i}"))
                    for i in range(5)]
     groups = [Group.create(*i).name for i in test_groups]
     user = User.provision_user(name)
     with self.subTest(
             "A user is removed from a group when remove_group is called for a group the user belongs "
             "to."):
         user.add_groups(groups)
         self.assertEqual(len(user.groups), 6)
         user.remove_groups(groups)
         self.assertEqual(len(user.groups), 1)
     with self.subTest(
             "Error is raised when removing a user from a group it's not in."
     ):
         self.assertRaises(cd_client.exceptions.BatchWriteException,
                           user.remove_groups, groups)
         self.assertEqual(len(user.groups), 1)
     with self.subTest(
             "An error is raised and the user is not removed from any groups when the user is in some of "
             "the groups to remove."):
         user.add_groups(groups[:2])
         self.assertEqual(len(user.groups), 3)
         self.assertRaises(cd_client.exceptions.BatchWriteException,
                           user.remove_groups, groups)
         self.assertEqual(len(user.groups), 3)
Example #9
0
 def test_put_username_groups(self):
     tests = [
         {
             'name': "*****@*****.**",
             'action': 'add',
             'json_request_body': {
                 "groups": [Group.create("test_put_username_groups_0").name]
             },
             'responses': [
                 {'code': 200},
                 {'code': 304}
             ]
         },
         {
             'name': "*****@*****.**",
             'action': 'remove',
             'json_request_body': {
                 "groups": [Group.create("test_put_username_groups_1").name]
             },
             'responses': [
                 {'code': 200},
                 {'code': 304}
             ]
         }
     ]
     for test in tests:
         with self.subTest(test['json_request_body']):
             data = json.dumps(test['json_request_body'])
             headers = {'Content-Type': "application/json"}
             headers.update(get_auth_header(service_accounts['admin']))
             url = furl(f'/v1/user/{test["name"]}/groups/')
             query_params = {
                 'user_id': test['name'],
                 'action': test['action']
             }
             url.add(query_params=query_params)
             user = User.provision_user(test['name'])
             if test['action'] == 'remove':
                 user.add_groups(test['json_request_body']['groups'])
             resp = self.app.put(url.url, headers=headers, data=data)
             self.assertEqual(test['responses'][0]['code'], resp.status_code)
             resp = self.app.put(url.url, headers=headers, data=data)
             self.assertEqual(test['responses'][1]['code'], resp.status_code)
Example #10
0
 def test_get_username_groups(self):
     headers = {'Content-Type': "application/json"}
     headers.update(get_auth_header(service_accounts['admin']))
     name = "*****@*****.**"
     key = 'groups'
     user = User.provision_user(name)
     resp = self.app.get(f'/v1/user/{name}/groups', headers=headers)
     self.assertEqual(1, len(json.loads(resp.body)[key]))
     groups = [Group.create(f"test_get_username_groups_{i}").name for i in range(8)]
     user.add_groups(groups)
     self._test_paging(f'/v1/user/{name}/groups', headers, 5, key)
 def test_get_group_users(self):
     headers = {'Content-Type': "application/json"}
     headers.update(get_auth_header(service_accounts['admin']))
     name = "test_get_group_users_group"
     key = 'users'
     group = Group.create(name)
     resp = self.app.get(f'/v1/group/{name}/users', headers=headers)
     group_user_names = [User(user).name for user in group.get_users_iter()]
     self.assertEqual(0, len(json.loads(resp.body)[key]))
     users = [User.provision_user(f"test_get_group_user_{i}", groups=[name]).name for i in range(10)]
     self._test_paging(f'/v1/group/{name}/users', headers, 5, key)
 def test_get_group_roles(self):
     headers = {'Content-Type': "application/json"}
     headers.update(get_auth_header(service_accounts['admin']))
     name = "test_get_group_roles_group"
     key = 'roles'
     group = Group.create(name)
     resp = self.app.get(f'/v1/group/{name}/roles', headers=headers)
     group_role_names = [Role(None, role).name for role in group.roles]
     self.assertEqual(0, len(json.loads(resp.body)[key]))
     roles = [Role.create(f"test_get_group_roles_role_{i}").name for i in range(10)]
     group.add_roles(roles)
     self._test_paging(f'/v1/group/{name}/roles', headers, 5, key)
Example #13
0
    def test_users(self):
        emails = ["*****@*****.**", "*****@*****.**", "*****@*****.**"]
        users = [User.provision_user(email).name for email in emails]
        with self.subTest(
                "A user is added to the group when add_users is called"):
            group = Group.create("test")
            user = User.provision_user("*****@*****.**")
            group.add_users([user.name])
            actual_users = [i for i in group.get_users_iter()]
            self.assertEqual(len(actual_users), 1)
            self.assertEqual(User(object_ref=actual_users[0]).name, user.name)

        with self.subTest(
                "Multiple users are added to the group when multiple users are passed to add_users"
        ):
            group = Group.create("test2")
            group.add_users(users)
            actual_users = [i[1] for i in group.get_users_iter()]
            self.assertEqual(len(actual_users), 3)

        with self.subTest(
                "Error returned when a user is added to a group it's already apart of."
        ):
            group = Group.create("test3")
            group.add_users(users)
            try:
                group.add_users(users)
            except cd_client.exceptions.BatchWriteException:
                pass
            actual_users = [i[1] for i in group.get_users_iter()]
            self.assertEqual(len(actual_users), 3)

        with self.subTest(
                "Error returned when adding a user that does not exist"):
            group = Group.create("test4")
            user = User("*****@*****.**")
            try:
                group.add_users([user.name])
            except cd_client.exceptions.ResourceNotFoundException:
                pass
Example #14
0
    def test_group_and_role(self):
        """
        A user inherits policies from groups and roles when the user is apart of a group and assigned a role.
        """
        name = "*****@*****.**"
        user = User.provision_user(name)
        test_groups = [(f"group_{i}", create_test_IAMPolicy(f"GroupPolicy{i}"))
                       for i in range(5)]
        [Group.create(*i) for i in test_groups]
        group_names, _ = zip(*test_groups)
        group_names = sorted(group_names)
        group_statements = [i[1] for i in test_groups]
        test_roles = [(f"role_{i}", create_test_IAMPolicy(f"RolePolicy{i}"))
                      for i in range(5)]
        [Role.create(*i) for i in test_roles]
        role_names, _ = zip(*test_roles)
        role_names = sorted(role_names)
        role_statements = [i[1] for i in test_roles]

        user.add_roles(role_names)
        user.add_groups(group_names)
        user.set_policy(self.default_policy)
        user_role_names = [Role(object_ref=role).name for role in user.roles]
        user_group_names = [
            Group(object_ref=group).name for group in user.groups
        ]

        self.assertListEqual(sorted(user_role_names), role_names)
        self.assertEqual(sorted(user_group_names),
                         group_names + ['user_default'])
        authz_params = user.get_authz_params()
        self.assertListEqual(sorted(authz_params['roles']),
                             sorted(['default_user'] + role_names))
        self.assertListEqual(sorted(authz_params['groups']),
                             sorted(['user_default'] + group_names))
        self.assertJSONListEqual(
            [p['policy_document'] for p in authz_params['IAMPolicy']],
            [user.get_policy(), *self.default_user_policies] +
            group_statements + role_statements)
Example #15
0
    def test_create_group(self):
        with self.subTest(
                "an error is returned when creating a group with an invalid statement."
        ):
            with self.assertRaises(FusilladeHTTPException):
                group = Group.create("new_group1", {"random": "fields"})

        with self.subTest(
                "The group is returned when the group has been created with default valid statement"
        ):
            group = Group.create("new_group2")
            self.assertEqual(group.name, "new_group2")
            self.assertJSONEqual(group.get_policy(),
                                 self.default_group_statement)

        with self.subTest(
                "The group is returned when the group has been created with specified valid statement."
        ):
            group_name = "NewGroup1234"
            statement = create_test_IAMPolicy(group_name)
            group = Group.create("new_group3", statement)
            self.assertEqual(group.name, "new_group3")
            self.assertJSONEqual(group.get_policy(), statement)
Example #16
0
def userinfo(token_info):
    """
    Part of OIDC
    """
    from fusillade.directory import User, Group, Role
    user = User(token_info['email'])
    # TODO save user info in fusillade at the same time.
    token_info[f"https://{os.environ['API_DOMAIN_NAME']}/app_metadata"] = {
        'authorization': {
            'groups': Group.get_names(user.groups),
            'roles': Role.get_names(user.roles),
            'scope': [i for i in user.get_actions()]
        }
    }
    return make_response(json.jsonify(**token_info), requests.codes.ok)
 def test_put_group_roles(self):
     tests = [
         {
             'group_id': "test_put_group_roles_Group1",
             'action': 'add',
             'json_request_body': {
                 "roles": [Role.create("role_0").name]
             },
             'responses': [
                 {'code': 200},
                 {'code': 304}
             ]
         },
         {
             'group_id': "test_put_group_roles_Group2",
             'action': 'remove',
             'json_request_body': {
                 "roles": [Role.create("role_1").name]
             },
             'responses': [
                 {'code': 200},
                 {'code': 304}
             ]
         }
     ]
     for test in tests:
         with self.subTest(test['json_request_body']):
             data = json.dumps(test['json_request_body'])
             headers = {'Content-Type': "application/json"}
             headers.update(get_auth_header(service_accounts['admin']))
             url = furl(f'/v1/group/{test["group_id"]}/roles/')
             query_params = {
                 'group_id': test['group_id'],
                 'action': test['action']
             }
             url.add(query_params=query_params)
             group = Group.create(test['group_id'])
             if test['action'] == 'remove':
                 group.add_roles(test['json_request_body']['roles'])
             resp = self.app.put(url.url, headers=headers, data=data)
             self.assertEqual(test['responses'][0]['code'], resp.status_code)
             resp = self.app.put(url.url, headers=headers, data=data)
             self.assertEqual(test['responses'][1]['code'], resp.status_code)
Example #18
0
    def test_user_group_limit(self):
        groups = [Group.create(f"test_user_group_limit{i}").name for i in range(10)]
        name = "*****@*****.**"
        user = User.provision_user(name)
        tests = [
            {
                'action': 'add',
                'json_request_body': {
                    "groups": groups[:8]
                },
                'response': {
                    'code': 200
                }
            },
            {
                'action': 'add',
                'json_request_body': {
                    "groups": [groups[9]]
                },
                'response': {
                    'code': 409
                }
            }
        ]
        for test in tests:
            with self.subTest(test['json_request_body']):
                data = json.dumps(test['json_request_body'])
                headers = {'Content-Type': "application/json"}
                headers.update(get_auth_header(service_accounts['admin']))
                url = furl(f'/v1/user/{name}/groups/')
                query_params = {
                    'user_id': name,
                    'action': test['action']
                }
                url.add(query_params=query_params)

                if test['action'] == 'remove':
                    user.add_groups(test['json_request_body']['groups'])
                resp = self.app.put(url.url, headers=headers, data=data)
                self.assertEqual(test['response']['code'], resp.status_code)
Example #19
0
 def test_roles(self):
     roles = ['role1', 'role2']
     role_objs = [
         Role.create(name, create_test_IAMPolicy(name)) for name in roles
     ]
     with self.subTest(
             "multiple roles return when multiple roles are attached to group."
     ):
         group = Group.create("test_roles")
         group.add_roles(roles)
         self.assertEqual(len(group.roles), 2)
     with self.subTest(
             "policies inherited from roles are returned when lookup policies is called"
     ):
         group_policies = sorted([
             normalize_json(p['policy_document'])
             for p in group.get_authz_params()['IAMPolicy']
         ])
         role_policies = sorted(
             [normalize_json(role.get_policy())
              for role in role_objs] + [self.default_group_statement])
         self.assertListEqual(group_policies, role_policies)
 def test_put_users(self):
     users = [User.provision_user(f"test_put_user_{i}").name for i in range(11)]
     tests = [
         {
             'action': 'add',
             'json_request_body': {
                 "users": [users[0]]
             },
             'responses': [
                 {'code': 200},
                 {'code': 304}
             ]
         },
         {
             'action': 'remove',
             'json_request_body': {
                 "users": [users[0]]
             },
             'responses': [
                 {'code': 200},
                 {'code': 304}
             ]
         },
         {
             'action': 'add',
             'json_request_body': {
                 "users": users[:-1]
             },
             'responses': [
                 {'code': 200},
                 {'code': 304}
             ]
         },
         {
             'action': 'remove',
             'json_request_body': {
                 "users": users[:-1]
             },
             'responses': [
                 {'code': 200},
                 {'code': 304}
             ]
         },
         {
             'action': 'add',
             'json_request_body': {
                 "users": users
             },
             'responses': [
                 {'code': 400},
                 {'code': 400}
             ]
         },
         {
             'action': 'remove',
             'json_request_body': {
                 "users": users
             },
             'responses': [
                 {'code': 400},
                 {'code': 400}
             ]
         }
     ]
     for i, test in enumerate(tests):
         group_id = Group.create(f"Group{i}").name
         with self.subTest(test['json_request_body']):
             data = json.dumps(test['json_request_body'])
             headers = {'Content-Type': "application/json"}
             headers.update(get_auth_header(service_accounts['admin']))
             if test['action'] == 'remove':
                 url = furl(f'/v1/group/{group_id}/users', query_params={'action': 'add'})
                 resp = self.app.put(url.url, headers=headers, data=data)
             url = furl(f'/v1/group/{group_id}/users', query_params={'action': test['action']})
             resp = self.app.put(url.url, headers=headers, data=data)
             self.assertEqual(test['responses'][0]['code'], resp.status_code)
             resp = self.app.put(url.url, headers=headers, data=data)
             self.assertEqual(test['responses'][1]['code'], resp.status_code)
Example #21
0
    def test_post_new_user(self):
        tests = [
            {
                'name': f'201 returned when creating a user',
                'json_request_body': {
                    "user_id": "*****@*****.**"

                },
                'response': {
                    'code': 201
                }
            },
            {
                'name': f'201 returned when creating a user with group only',
                'json_request_body': {
                    "user_id": "*****@*****.**",
                    "groups": [Group.create("test_post_new_user_group_01").name]
                },
                'response': {
                    'code': 201
                }
            },
            {
                'name': f'201 returned when creating a user with role only',
                'json_request_body': {
                    "user_id": "*****@*****.**",
                    "roles": [Role.create("test_post_new_user_role_02").name]
                },
                'response': {
                    'code': 201
                }
            },
            {
                'name': f'201 returned when creating a user with policy only',
                'json_request_body': {
                    "user_id": "*****@*****.**",
                    "policy": create_test_IAMPolicy("policy_03")
                },
                'response': {
                    'code': 201
                }
            },
            {
                'name': f'201 returned when creating a user with group, role and policy',
                'json_request_body': {
                    "user_id": "*****@*****.**",
                    "groups": [Group.create("test_post_new_user_group_04").name],
                    "roles": [Role.create("test_post_new_user_role_04").name],
                    "policy": create_test_IAMPolicy("policy_04")
                },
                'response': {
                    'code': 201
                }
            },
            {
                'name': f'400 returned when creating a user without username',
                'json_request_body': {
                    "groups": [Group.create("test_post_new_user_group_05").name],
                    "roles": [Role.create("test_post_new_user_role_05").name],
                    "policy": create_test_IAMPolicy("policy_05")
                },
                'response': {
                    'code': 400
                }
            },
            {
                'name': f'409 returned when creating a user that already exists',
                'json_request_body': {
                    "user_id": "*****@*****.**"
                },
                'response': {
                    'code': 409
                }
            }
        ]
        tests.extend([{
            'name': f'201 returned when creating a role when name is {description}',
            'json_request_body': {
                "user_id": name
            },
            'response': {
                'code': 201
            }
        } for name, description in TEST_NAMES_POS
        ])
        tests.extend([{
            'name': f'400 returned when creating a role when name is {description}',
            'json_request_body': {
                "user_id": name
            },
            'response': {
                'code': 400
            }
        } for name, description in TEST_NAMES_NEG
        ])
        for test in tests:
            with self.subTest(test['name']):
                headers = {'Content-Type': "application/json"}
                headers.update(get_auth_header(service_accounts['admin']))
                if test['name'] == "409 returned when creating a user that already exists":
                    self.app.post('/v1/user', headers=headers, data=json.dumps(test['json_request_body']))
                resp = self.app.post('/v1/user', headers=headers, data=json.dumps(test['json_request_body']))
                self.assertEqual(test['response']['code'], resp.status_code)
                if resp.status_code == 201:
                    resp = self.app.get(f'/v1/user/{test["json_request_body"]["user_id"]}/', headers=headers)
                    self.assertEqual(test["json_request_body"]["user_id"], json.loads(resp.body)['user_id'])