Beispiel #1
0
 def test_get_role_id(self):
     role_id = 'test_get_role_id'
     admin_auth_header = get_auth_header(service_accounts['admin'])
     tests = [{
         'name': '401 return when no auth headers.',
         'headers': {},
         'role_id': role_id,
         'expected_resp': 401
     }, {
         'name': '403 return when unauthorized user.',
         'headers': get_auth_header(service_accounts['user']),
         'role_id': role_id,
         'expected_resp': 403
     }, {
         'name': '200 returned when user is authorized.',
         'headers': admin_auth_header,
         'role_id': role_id,
         'expected_resp': 200
     }, {
         'name': 'error returned when role does not exist.',
         'headers': admin_auth_header,
         'role_id': 'ghost_role',
         'expected_resp': 404
     }]
     tests.extend([{
         'name':
         f'200 returned when getting a role when name is {description}',
         'role_id': role_id,
         'headers': admin_auth_header,
         'expected_resp': 200
     } for name, description in TEST_NAMES_POS])
     tests.extend([{
         'name':
         f'400 returned when getting a role when name is {description}',
         'role_id': role_id,
         'headers': admin_auth_header,
         'expected_resp': 400
     } for role_id, description in TEST_NAMES_NEG if role_id is not ''])
     policy = create_test_IAMPolicy("test_role")
     role = Role.create(role_id, policy)
     expected_policy = policy
     [Role.create(role_id, policy) for role_id, _ in TEST_NAMES_POS]
     for test in tests:
         with self.subTest(test['name']):
             url = furl('/v1/role/{}'.format(test['role_id']))
             headers = {'Content-Type': "application/json"}
             headers.update(test['headers'])
             resp = self.app.get(url.url, headers=headers)
             self.assertEqual(test['expected_resp'], resp.status_code)
             if test['expected_resp'] == 200:
                 expected_body = {
                     'role_id': test['role_id'],
                     'policies': {
                         'IAMPolicy': expected_policy
                     }
                 }
                 self.assertEqual(expected_body, json.loads(resp.body))
Beispiel #2
0
 def test_put_role_id_policy(self):
     role_id = 'test_put_role_id_policy'
     policy_1 = create_test_IAMPolicy(role_id)
     policy_2 = create_test_IAMPolicy('ABCD')
     policy_invalid = "invalid policy"
     Role.create(role_id, policy_1)
     admin_auth_header = get_auth_header(service_accounts['admin'])
     tests = [{
         'name': '401 return when no auth headers.',
         'headers': {},
         'role_id': role_id,
         'data': {
             'policy': policy_2
         },
         'expected_resp': 401
     }, {
         'name': '403 return when unauthorized user.',
         'headers': get_auth_header(service_accounts['user']),
         'role_id': role_id,
         'data': {
             'policy': policy_2
         },
         'expected_resp': 403
     }, {
         'name': '200 returned when user is authorized.',
         'headers': admin_auth_header,
         'role_id': role_id,
         'data': {
             'policy': policy_2
         },
         'expected_resp': 200
     }, {
         'name': '400 returned when an invalid policy is used.',
         'headers': admin_auth_header,
         'role_id': role_id,
         'data': {
             'policy': policy_invalid
         },
         'expected_resp': 400
     }, {
         'name': '404 returned when role does not exist.',
         'headers': admin_auth_header,
         'role_id': 'ghost_role',
         'data': {
             'policy': policy_2
         },
         'expected_resp': 404
     }]
     for test in tests:
         with self.subTest(test['name']):
             headers = {'Content-Type': "application/json"}
             headers.update(test['headers'])
             url = furl(f"/v1/role/{test['role_id']}/policy")
             data = json.dumps(test['data'])
             resp = self.app.put(url.url, data=data, headers=headers)
             self.assertEqual(test['expected_resp'], resp.status_code)
Beispiel #3
0
def backup_roles():
    roles = []
    for name in list_node(Role, 'roles'):
        role = Role(name)
        info = {
            'name': role.name,
            'policies': format_policies([(p, role.get_policy(p)) for p in role.allowed_policy_types]),
            'owners': role.list_owners()
        }
        roles.append(info)
    print("ROLES:", *roles, sep='\n\t')
    return roles
 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)
Beispiel #5
0
 def test_get_username_roles(self):
     headers = {'Content-Type': "application/json"}
     headers.update(get_auth_header(service_accounts['admin']))
     name = "*****@*****.**"
     key = 'roles'
     user = User.provision_user(name)
     resp = self.app.get(f'/v1/user/{name}/roles', headers=headers)
     user_role_names = [Role(None, role).name for role in user.roles]
     self.assertEqual(0, len(json.loads(resp.body)[key]))
     roles = [Role.create(f"test_get_username_role_{i}").name for i in range(11)]
     user.add_roles(roles)
     self._test_paging(f'/v1/user/{name}/roles', headers, 6, key)
Beispiel #6
0
 def test_user_owned(self):
     headers = {'Content-Type': "application/json"}
     headers.update(get_auth_header(service_accounts['admin']))
     name = "*****@*****.**"
     key = 'roles'
     user = User.provision_user(name)
     url = furl(f"/v1/user/{name}/owns", query_params={'resource_type': 'role'}).url
     resp = self.app.request(url, headers=headers)
     self.assertEqual('False', resp.headers['X-OpenAPI-Pagination'])
     user_role_names = [Role(object_ref=role).name for role in user.roles]
     roles = [Role.create(f"test_user_owned_role_{i}") for i in range(11)]
     user.add_roles([role.name for role in roles])
     [user.add_ownership(role) for role in roles]
     self._test_paging(url, headers, 6, key)
    def test_delete_group(self):
        headers = {'Content-Type': "application/json"}
        headers.update(get_auth_header(service_accounts['admin']))

        role = Role.create("test_delete_group_role").name
        user = User.provision_user("test_delete_group_user").name
        policy = create_test_IAMPolicy("test_delete_group_policy")
        group_id = "test_delete_group_group"

        with self.subTest("Group delete with users and roles."):

            resp = self.app.post(f'/v1/group',
                     headers=headers,
                     data=json.dumps({
                         "group_id": group_id,
                         "roles": [role],
                         "policy": policy
                     }))
            resp.raise_for_status()
            resp = self.app.put(f'/v1/user/{user}/groups?action=add',
                     headers=headers,
                     data=json.dumps({"groups": [group_id]}))
            resp.raise_for_status()
            resp = self.app.delete(f'/v1/group/{group_id}', headers=headers)
            self.assertEqual(resp.status_code, 200)
            resp = self.app.get(f'/v1/user/{user}/groups', headers=headers)
            groups = json.loads(resp.body)['groups']
            self.assertNotIn(group_id, groups)

        with self.subTest("delete a group that does not exist."):
            resp = self.app.delete(f'/v1/group/{group_id}', headers=headers)
            self.assertEqual(resp.status_code, 404)
Beispiel #8
0
 def test_role_default(self):
     with self.subTest(
             "a role is set to default policy when role.create is called without a statement."
     ):
         role_name = "test_role_default"
         role = Role.create(role_name)
         self.assertEqual(role.name, role_name)
         self.assertJSONEqual(role.get_policy(),
                              self.default_role_statement)
 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)
Beispiel #10
0
 def test_put_username_roles(self):
     tests = [
         {
             'name': "*****@*****.**",
             'action': 'add',
             'json_request_body': {
                 "roles": [Role.create("test_put_username_roles_role_0").name]
             },
             'responses': [
                 {'code': 200},
                 {'code': 304}
             ]
         },
         {
             'name': "*****@*****.**",
             'action': 'remove',
             'json_request_body': {
                 "roles": [Role.create("test_put_username_roles_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/user/{test["name"]}/roles/')
             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_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)
Beispiel #11
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)
Beispiel #12
0
    def test_role_statement(self):
        role_name = "test_role_specified"
        statement = create_test_IAMPolicy(role_name)
        role = Role.create(role_name, statement)
        with self.subTest(
                "a role is created with specified statement when role.create is called with a statement"
        ):
            self.assertEqual(role.name, role_name)

        with self.subTest(
                "a roles statement is retrieved when role.get_policy() is called"
        ):
            self.assertJSONEqual(role.get_policy(), statement)

        with self.subTest(
                "a roles statement is changed when role.get_policy() is assigned"
        ):
            statement = create_test_IAMPolicy(f"UserPolicySomethingElse")
            role.set_policy(statement)
            self.assertJSONEqual(role.get_policy(), statement)

        with self.subTest(
                "Error raised when setting policy to an invalid statement"):
            with self.assertRaises(FusilladeHTTPException):
                role.set_policy({"Statement": "Something else"})
            self.assertJSONEqual(role.get_policy(), statement)

        statement = create_test_statements(150)
        with self.subTest(
                "an error is returned when a policy that exceeds 10 Kb for a pre-existing role"
        ):
            with self.assertRaises(FusilladeHTTPException) as ex:
                role.set_policy(statement)

        with self.subTest(
                "an error is returned when a policy that exceeds 10 Kb for a new role"
        ):
            with self.assertRaises(FusilladeHTTPException) as ex:
                Role.create("test_role_specified_2", statement)
Beispiel #13
0
def _modify_roles(cloud_node, request):
    action = request.args['action']
    resp = {
        'roles': request.json['roles'],
        'action': action,
        f'{cloud_node.object_type}_id': cloud_node.name
    }
    try:
        Role.exists(request.json['roles'])
        if action == 'add':
            cloud_node.add_roles(request.json['roles'])
        elif action == 'remove':
            cloud_node.remove_roles(request.json['roles'])
    except cd_client.exceptions.BatchWriteException as ex:
        # TODO inspect the error. Return 304 if link exists error. Return 404 if object does not exist error.
        resp['msg'] = ex.response['Error']['Message']
        code = 304
    else:
        resp[
            'msg'] = f"{cloud_node.object_type}'s roles successfully modified."
        code = 200
    return resp, code
Beispiel #14
0
def backup_users():
    users = []
    for name in list_node(User, 'users'):
        user = User(name)
        info = {
            'name': user.name,
            'status': user.status,
            'policies': format_policies([(p, user.get_policy(p)) for p in user.allowed_policy_types]),
            'roles': [Role(object_ref=r).name for r in user.roles]
        }
        users.append(info)
    print("USERS:", *users, sep='\n\t')
    return users
Beispiel #15
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
    def test_eval(self):
        actions = ['test:readproject', 'test:writeproject', 'test:deleteproject']
        resource_type = 'test_type'
        test_type = ResourceType.create(resource_type, actions)
        access_level = 'Reader'
        resource_policy = {
            "Version": "2012-10-17",
            "Statement": [
                {
                    "Principal": "*",
                    "Sid": "project_reader",
                    "Effect": "Allow",
                    "Action": ['test:readproject'],
                    "Resource": f"{self.arn_prefix}{resource_type}/*"
                }
            ]
        }
        test_type.create_policy(access_level, resource_policy, 'ResourcePolicy')
        user = User.provision_user('test_user')
        type_id = '1234455'
        resource = f'{self.arn_prefix}{resource_type}/{type_id}'

        with self.subTest("A user does not have access when they only have permitting resource_policy and no "
                          "permitting IAMPolicy"):
            test_id = test_type.create_id(type_id)
            test_id.add_principals([user], access_level)
            x = get_resource_authz_parameters(user.name, resource)
            resp = evaluate_policy(user.name, ['test:readproject'], [resource], x['IAMPolicy'], x['ResourcePolicy'])
            self.assertFalse(resp['result'])

        with self.subTest("A user has a access when they have a permitting resource policy and IAMPolicy"):
            IAMpolicy = {
                "Statement": [
                    {
                        "Sid": "project_reader",
                        "Effect": "Allow",
                        "Action": [
                            "test:readproject"
                        ],
                        "Resource": f"{self.arn_prefix}{resource_type}/*"
                    }
                ]
            }
            role = Role.create('project_reader', IAMpolicy)

            user.add_roles([role.name])
            x = get_resource_authz_parameters(user.name, resource)
            resp = evaluate_policy(user.name, ['test:readproject'], [resource], x['IAMPolicy'], x['ResourcePolicy'])
            self.assertTrue(resp['result'])
Beispiel #17
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)
Beispiel #18
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)
Beispiel #19
0
def post_role(token_info: dict):
    json_body = request.json
    Role.create(json_body['role_id'],
                statement=json_body.get('policy'),
                creator=get_email_claim(token_info))
    return make_response(f"New role {json_body['role_id']} created.", 201)
Beispiel #20
0
def delete_role(token_info: dict, role_id):
    Role(role_id).delete_node()
    return make_response(f"{role_id} deleted.", 200)
Beispiel #21
0
def put_role_policy(token_info: dict, role_id: str):
    role = Role(role_id)
    role.set_policy(request.json['policy'])
    return make_response('Role policy updated.', 200)
Beispiel #22
0
def get_role(token_info: dict, role_id: str):
    role = Role(role_id)
    return make_response(jsonify(role.get_info()), 200)
Beispiel #23
0
    def test_roles(self):
        name = "*****@*****.**"
        test_roles = [(f"Role_{i}", create_test_IAMPolicy(f"RolePolicy{i}"))
                      for i in range(5)]
        roles = [Role.create(*i).name 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 = User.provision_user(name)
        user_role_names = [Role(None, role).name for role in user.roles]
        with self.subTest("a user has the default_user roles when created."):
            self.assertEqual(user_role_names, [])

        role_name, role_statement = test_roles[0]
        with self.subTest("A user has one role when a role is added."):
            user.add_roles([role_name])
            user_role_names = [Role(None, role).name for role in user.roles]
            self.assertEqual(user_role_names, [role_name])

        with self.subTest(
                "An error is raised when adding a role a user already has."):
            with self.assertRaises(
                    cd_client.exceptions.BatchWriteException) as ex:
                user.add_roles([role_name])
                self.assertTrue('LinkNameAlreadyInUseException' in
                                ex.response['Error']['Message'])

        with self.subTest(
                "An error is raised when adding a role that does not exist."):
            with self.assertRaises(
                    cd_client.exceptions.BatchWriteException) as ex:
                user.add_roles(["ghost_role"])
                self.assertTrue(ex.response['Error']['Message'].endswith(
                    "/ role / ghost_role\\' does not exist.'"))

        user.set_policy(self.default_policy)
        with self.subTest(
                "A user inherits a roles policies when a role is added to a user."
        ):
            policies = [
                p['policy_document']
                for p in user.get_authz_params()['IAMPolicy']
            ]
            self.assertJSONListEqual(policies, [
                user.get_policy(), role_statement, *self.default_user_policies
            ])

        with self.subTest(
                "A role is removed from user when remove role is called."):
            user.remove_roles([role_name])
            self.assertEqual(user.roles, [])

        with self.subTest(
                "A user has multiple roles when multiple roles are added to user."
        ):
            user.add_roles(role_names)
            user_role_names = [Role(None, role).name for role in user.roles]
            self.assertEqual(sorted(user_role_names), role_names)

        with self.subTest(
                "A user inherits multiple role policies when the user has multiple roles."
        ):
            policies = [
                p['policy_document']
                for p in user.get_authz_params()['IAMPolicy']
            ]
            self.assertJSONListEqual(policies, [
                user.get_policy(), *self.default_user_policies,
                *role_statements
            ])

        with self.subTest(
                "A user's roles are listed when a listing a users roles."):
            user_role_names = [Role(None, role).name for role in user.roles]
            self.assertListEqual(sorted(user_role_names), role_names)

        with self.subTest(
                "Multiple roles are removed from a user when a multiple roles are specified for removal."
        ):
            user.remove_roles(role_names)
            self.assertEqual(user.roles, [])
    def test_post_group(self):
        tests = [
            {
                'name': f'201 returned when creating a group',
                'json_request_body': {
                    "group_id": "test_post_group_Group0"

                },
                'response': {
                    'code': 201
                }
            },
            {
                'name': f'201 returned when creating a group with role only',
                'json_request_body': {
                    "group_id": "test_post_group_Group1",
                    "roles": [Role.create("test_post_group_role_02").name]
                },
                'response': {
                    'code': 201
                }
            },
            {
                'name': f'201 returned when creating a group with policy only',
                'json_request_body': {
                    "group_id": "test_post_group_Group2",
                    "policy": create_test_IAMPolicy("policy_03")
                },
                'response': {
                    'code': 201
                }
            },
            {
                'name': f'201 returned when creating a group with role and policy',
                'json_request_body': {
                    "group_id": "test_post_group_Group3",
                    "roles": [Role.create("test_post_group_role_04").name],
                    "policy": create_test_IAMPolicy("policy_04")
                },
                'response': {
                    'code': 201
                }
            },
            {
                'name': f'400 returned when creating a group without group_id',
                'json_request_body': {
                    "roles": [Role.create("test_post_group_role_05").name],
                    "policy": create_test_IAMPolicy("policy_05")
                },
                'response': {
                    'code': 400
                }
            },
            {
                'name': f'409 returned when creating a group that already exists',
                'json_request_body': {
                    "group_id": "test_post_group_Group3"
                },
                'response': {
                    'code': 409
                }
            }
        ]
        tests.extend([{
            'name': f'201 returned when creating a role when name is {description}',
            'json_request_body': {
                "group_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': {
                "group_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'] == "400 returned when creating a group that already exists":
                    self.app.post('/v1/group', headers=headers, data=json.dumps(test['json_request_body']))
                resp = self.app.post('/v1/group', 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/group/{test["json_request_body"]["group_id"]}/', headers=headers)
                    self.assertEqual(test["json_request_body"]["group_id"], json.loads(resp.body)['group_id'])