def test_get_all_permission_grants_for_user(self):
        user_db = self.users['1_custom_role']
        role_db = self.roles['custom_role_1']
        permission_grants = rbac_service.get_all_permission_grants_for_user(user_db=user_db)
        self.assertItemsEqual(permission_grants, [])

        # Grant some permissions
        resource_db = self.resources['rule_1']
        permission_types = [PermissionType.RULE_CREATE, PermissionType.RULE_MODIFY]

        permission_grant = rbac_service.create_permission_grant_for_resource_db(
            role_db=role_db,
            resource_db=resource_db,
            permission_types=permission_types)

        # Retrieve all grants
        permission_grants = rbac_service.get_all_permission_grants_for_user(user_db=user_db)
        self.assertItemsEqual(permission_grants, [permission_grant])

        # Retrieve all grants, filter on resource with no grants
        permission_grants = rbac_service.get_all_permission_grants_for_user(user_db=user_db,
            resource_types=[ResourceType.PACK])
        self.assertItemsEqual(permission_grants, [])

        # Retrieve all grants, filter on resource with grants
        permission_grants = rbac_service.get_all_permission_grants_for_user(user_db=user_db,
            resource_types=[ResourceType.RULE])
        self.assertItemsEqual(permission_grants, [permission_grant])
Пример #2
0
    def sync_group_to_role_maps(self, group_to_role_map_apis):
        LOG.info("Synchronizing group to role maps...")

        # Retrieve all the mappings currently in the db
        group_to_role_map_dbs = rbac_service.get_all_group_to_role_maps()

        # 1. Delete all the existing mappings in the db
        group_to_role_map_to_delete = []
        for group_to_role_map_db in group_to_role_map_dbs:
            group_to_role_map_to_delete.append(group_to_role_map_db.id)

        GroupToRoleMapping.query(id__in=group_to_role_map_to_delete).delete()

        # 2. Insert all mappings read from disk
        for group_to_role_map_api in group_to_role_map_apis:
            source = getattr(group_to_role_map_api, "file_path", None)
            rbac_service.create_group_to_role_map(
                group=group_to_role_map_api.group,
                roles=group_to_role_map_api.roles,
                description=group_to_role_map_api.description,
                enabled=group_to_role_map_api.enabled,
                source=source,
            )

        LOG.info("Group to role map definitions synchronized.")
    def _insert_mock_roles(self):
        # Create some mock roles
        role_1_db = rbac_service.create_role(name='role_1')
        role_2_db = rbac_service.create_role(name='role_2')
        role_3_db = rbac_service.create_role(name='role_3')

        self.roles['role_1'] = role_1_db
        self.roles['role_2'] = role_2_db
        self.roles['role_3'] = role_3_db

        # Note: User use pymongo to insert mock data because we want to insert a
        # raw document and skip mongoengine to leave is_remote field unpopulated
        client = MongoClient()
        db = client['st2-test']
        db.user_role_assignment_d_b.insert_one({
            'user': '******',
            'role': 'role_1'
        })
        db.user_role_assignment_d_b.insert_one({
            'user': '******',
            'role': 'role_2'
        })
        db.user_role_assignment_d_b.insert_one({
            'user': '******',
            'role': 'role_3',
            'is_remote': False
        })
        db.user_role_assignment_d_b.insert_one({
            'user': '******',
            'role': 'role_4',
            'is_remote': True
        })

        return self.roles
    def test_sync_no_mappings_exist_for_the_provided_groups(self):
        syncer = RBACRemoteGroupToRoleSyncer()
        user_db = self.users['user_1']

        # Create mock mapping which maps CN=stormers,OU=groups,DC=stackstorm,DC=net
        # to "mock_remote_role_3" and "mock_remote_role_4"
        rbac_service.create_group_to_role_map(
            group='CN=stormers,OU=groups,DC=stackstorm,DC=net',
            roles=['mock_remote_role_3', 'mock_remote_role_4'],
            source='mappings/stormers.yaml')

        # Verify initial state
        role_dbs = rbac_service.get_roles_for_user(user_db=user_db,
                                                   include_remote=True)
        self.assertEqual(len(role_dbs), 2)
        self.assertEqual(role_dbs[0], self.roles['mock_local_role_1'])
        self.assertEqual(role_dbs[1], self.roles['mock_local_role_2'])

        groups = [
            'CN=testers1,OU=groups,DC=stackstorm,DC=net',
            'CN=testers2,OU=groups,DC=stackstorm,DC=net'
        ]

        # No mappings exist for the groups user is a member of so no new assignments should be
        # created
        result = syncer.sync(user_db=self.users['user_1'], groups=groups)
        created_role_assignment_dbs = result[0]
        removed_role_assignment_dbs = result[1]
        self.assertEqual(created_role_assignment_dbs, [])
        self.assertEqual(removed_role_assignment_dbs, [])
    def test_get_roles_for_user(self):
        # User with no roles
        user_db = self.users['no_roles']
        role_dbs = rbac_service.get_roles_for_user(user_db=user_db)
        self.assertItemsEqual(role_dbs, [])

        role_dbs = user_db.get_roles()
        self.assertItemsEqual(role_dbs, [])

        # User with one custom role
        user_db = self.users['1_custom_role']
        role_dbs = rbac_service.get_roles_for_user(user_db=user_db)
        self.assertItemsEqual(role_dbs, [self.roles['custom_role_1']])

        role_dbs = user_db.get_roles()
        self.assertItemsEqual(role_dbs, [self.roles['custom_role_1']])

        # User with remote roles
        user_db = self.users['user_5']
        role_dbs = user_db.get_roles()
        self.assertEqual(len(role_dbs), 4)

        user_db = self.users['user_5']
        role_dbs = user_db.get_roles(include_remote=True)
        self.assertEqual(len(role_dbs), 4)

        user_db = self.users['user_5']
        role_dbs = user_db.get_roles(include_remote=False)
        self.assertEqual(len(role_dbs), 3)
    def test_sync_role_assignments_no_assignment_file_on_disk(self):
        syncer = RBACDefinitionsDBSyncer()

        self._insert_mock_roles()

        # Initial state, no roles
        user_db = self.users['user_3']
        role_dbs = rbac_service.get_roles_for_user(user_db=user_db)
        self.assertItemsEqual(role_dbs, [])

        # Do the sync with two roles defined
        api = UserRoleAssignmentFileFormatAPI(username=user_db.name,
                                              roles=['role_1', 'role_2'],
                                              file_path='assignments/%s.yaml' %
                                              user_db.name)

        syncer.sync_users_role_assignments(role_assignment_apis=[api])

        role_dbs = rbac_service.get_roles_for_user(user_db=user_db)
        self.assertEqual(len(role_dbs), 2)
        self.assertEqual(role_dbs[0], self.roles['role_1'])
        self.assertEqual(role_dbs[1], self.roles['role_2'])

        # Do the sync with no roles - existing assignments should be removed from the databse
        syncer.sync_users_role_assignments(role_assignment_apis=[])

        role_dbs = rbac_service.get_roles_for_user(user_db=user_db)
        self.assertEqual(len(role_dbs), 0)
    def test_sync_assignments_user_doesnt_exist_in_db(self):
        # Make sure that the assignments for the users which don't exist in the db are still saved
        syncer = RBACDefinitionsDBSyncer()

        self._insert_mock_roles()

        username = '******'

        # Initial state, no roles
        user_db = UserDB(name=username)
        self.assertEqual(len(User.query(name=username)), 0)
        role_dbs = rbac_service.get_roles_for_user(user_db=user_db)
        self.assertItemsEqual(role_dbs, [])

        # Do the sync with two roles defined
        api = UserRoleAssignmentFileFormatAPI(
            username=user_db.name,
            roles=['role_1', 'role_2'],
            file_path='assignments/foobar.yaml')

        syncer.sync_users_role_assignments(role_assignment_apis=[api])

        role_dbs = rbac_service.get_roles_for_user(user_db=user_db)
        self.assertEqual(len(role_dbs), 2)
        self.assertEqual(role_dbs[0], self.roles['role_1'])
        self.assertEqual(role_dbs[1], self.roles['role_2'])
Пример #8
0
    def test_assign_role_to_user_ignore_already_exists_error(self):
        user_db = UserDB(name='test-user-10')
        user_db = User.add_or_update(user_db)

        role_assignment_db_1 = rbac_service.assign_role_to_user(
            role_db=self.roles['custom_role_1'],
            user_db=user_db,
            source='assignments/%s_10.yaml' % user_db.name)

        # 1. Without ignore errors
        self.assertRaises(StackStormDBObjectConflictError,
                          rbac_service.assign_role_to_user,
                          role_db=self.roles['custom_role_1'],
                          user_db=user_db,
                          source='assignments/%s_10.yaml' % user_db.name)

        # 2. With ignore errors
        role_assignment_db_2 = rbac_service.assign_role_to_user(
            role_db=self.roles['custom_role_1'],
            user_db=user_db,
            source='assignments/%s_10.yaml' % user_db.name,
            ignore_already_exists_error=True)

        self.assertEqual(role_assignment_db_1, role_assignment_db_2)
        self.assertEqual(role_assignment_db_1.id, role_assignment_db_2.id)
        self.assertEqual(role_assignment_db_1.user, role_assignment_db_2.user)
        self.assertEqual(role_assignment_db_1.role, role_assignment_db_2.role)
Пример #9
0
    def test_group_to_role_sync_is_performed_on_successful_auth_no_groups_returned(
            self):
        # Enable group sync
        cfg.CONF.set_override(group='rbac',
                              name='sync_remote_groups',
                              override=True)

        user_db = self.users['user_1']
        h = handlers.StandaloneAuthHandler()
        request = {}

        # Verify initial state
        role_dbs = rbac_service.get_roles_for_user(user_db=user_db,
                                                   include_remote=True)
        self.assertEqual(len(role_dbs), 2)
        self.assertEqual(role_dbs[0], self.roles['mock_local_role_1'])
        self.assertEqual(role_dbs[1], self.roles['mock_local_role_2'])

        # No groups configured should return early
        h._auth_backend.groups = []

        token = h.handle_auth(request,
                              headers={},
                              remote_addr=None,
                              remote_user=None,
                              authorization=('basic', DUMMY_CREDS))
        self.assertEqual(token.user, 'auser')

        # Verify nothing has changed
        role_dbs = rbac_service.get_roles_for_user(user_db=user_db,
                                                   include_remote=True)
        self.assertEqual(len(role_dbs), 2)
        self.assertEqual(role_dbs[0], self.roles['mock_local_role_1'])
        self.assertEqual(role_dbs[1], self.roles['mock_local_role_2'])
    def test_sync_user_assignments_multiple_custom_roles_assignments(self):
        syncer = RBACDefinitionsDBSyncer()

        self._insert_mock_roles()

        # Initial state, no roles
        role_dbs = rbac_service.get_roles_for_user(
            user_db=self.users['user_2'])
        self.assertItemsEqual(role_dbs, [])

        # Do the sync with two roles defined
        api = UserRoleAssignmentFileFormatAPI(
            username='******',
            roles=['role_1', 'role_2'],
            file_path='assignments/user2.yaml')
        syncer.sync_users_role_assignments(role_assignment_apis=[api])

        role_dbs = rbac_service.get_roles_for_user(
            user_db=self.users['user_2'])
        self.assertEqual(len(role_dbs), 2)
        self.assertEqual(role_dbs[0], self.roles['role_1'])
        self.assertEqual(role_dbs[1], self.roles['role_2'])
        role_assignment_dbs = rbac_service.get_role_assignments_for_user(
            user_db=self.users['user_2'])
        self.assertEqual(len(role_assignment_dbs), 2)
        self.assertEqual(role_assignment_dbs[0].source,
                         'assignments/user2.yaml')
        self.assertEqual(role_assignment_dbs[1].source,
                         'assignments/user2.yaml')
    def test_get_all_role_assignments(self):
        role_assignment_dbs = rbac_service.get_all_role_assignments(include_remote=True)
        self.assertEqual(len(role_assignment_dbs), 5)

        role_assignment_dbs = rbac_service.get_all_role_assignments(include_remote=False)
        self.assertEqual(len(role_assignment_dbs), 4)

        for role_assignment_db in role_assignment_dbs:
            self.assertFalse(role_assignment_db.is_remote)
Пример #12
0
    def test_insert_system_roles(self):
        role_dbs = rbac_service.get_all_roles()
        self.assertItemsEqual(role_dbs, [])

        insert_system_roles()

        role_dbs = rbac_service.get_all_roles()
        self.assertTrue(len(role_dbs), 3)

        role_names = [role_db.name for role_db in role_dbs]
        self.assertTrue('system_admin' in role_names)
        self.assertTrue('admin' in role_names)
        self.assertTrue('observer' in role_names)
    def test_sync_user_assignments_multiple_sources_same_role_assignment(self):
        syncer = RBACDefinitionsDBSyncer()

        self._insert_mock_roles()

        # Initial state, no roles
        role_dbs = rbac_service.get_roles_for_user(
            user_db=self.users['user_2'])
        self.assertItemsEqual(role_dbs, [])

        # Do the sync with role defined in separate files
        assignment1 = UserRoleAssignmentFileFormatAPI(
            username='******',
            roles=['role_1'],
            file_path='assignments/user2a.yaml')

        assignment2 = UserRoleAssignmentFileFormatAPI(
            username='******',
            roles=['role_1'],
            file_path='assignments/user2b.yaml')

        syncer.sync_users_role_assignments(
            role_assignment_apis=[assignment1, assignment2])

        role_dbs = rbac_service.get_roles_for_user(
            user_db=self.users['user_2'])
        self.assertEqual(len(role_dbs), 1)
        self.assertEqual(role_dbs[0], self.roles['role_1'])

        role_assignment_dbs = rbac_service.get_role_assignments_for_user(
            user_db=self.users['user_2'])
        self.assertEqual(len(role_assignment_dbs), 2)

        sources = [r.source for r in role_assignment_dbs]
        self.assertIn('assignments/user2a.yaml', sources)
        self.assertIn('assignments/user2b.yaml', sources)

        # Do another sync with one assignment file removed - only one assignment should be left
        syncer.sync_users_role_assignments(role_assignment_apis=[assignment2])

        role_dbs = rbac_service.get_roles_for_user(
            user_db=self.users['user_2'])
        self.assertEqual(len(role_dbs), 1)
        self.assertEqual(role_dbs[0], self.roles['role_1'])

        role_assignment_dbs = rbac_service.get_role_assignments_for_user(
            user_db=self.users['user_2'])
        self.assertEqual(len(role_assignment_dbs), 1)

        sources = [r.source for r in role_assignment_dbs]
        self.assertIn('assignments/user2b.yaml', sources)
    def test_sync_remote_assignments_are_not_manipulated(self):
        # Verify remote assignments are not manipulated.
        syncer = RBACDefinitionsDBSyncer()

        self._insert_mock_roles()

        # Initial state, no roles
        user_db = UserDB(name='doesntexistwhaha')
        role_dbs = rbac_service.get_roles_for_user(user_db=user_db)
        self.assertItemsEqual(role_dbs, [])

        # Create mock remote role assignment
        role_db = self.roles['role_3']
        source = 'assignments/%s.yaml' % user_db.name
        role_assignment_db = rbac_service.assign_role_to_user(role_db=role_db,
                                                              user_db=user_db,
                                                              source=source,
                                                              is_remote=True)
        self.assertTrue(role_assignment_db.is_remote)

        # Verify assignment has been created
        role_dbs = rbac_service.get_roles_for_user(user_db=user_db)
        self.assertItemsEqual(role_dbs, [self.roles['role_3']])

        # Do the sync with two roles defined - verify remote role assignment hasn't been
        # manipulated with.
        api = UserRoleAssignmentFileFormatAPI(username=user_db.name,
                                              roles=['role_1', 'role_2'],
                                              file_path='assignments/%s.yaml' %
                                              user_db.name)

        syncer.sync_users_role_assignments(role_assignment_apis=[api])

        role_dbs = rbac_service.get_roles_for_user(user_db=user_db)
        self.assertEqual(len(role_dbs), 3)
        self.assertEqual(role_dbs[0], self.roles['role_1'])
        self.assertEqual(role_dbs[1], self.roles['role_2'])
        self.assertEqual(role_dbs[2], self.roles['role_3'])

        # Do sync with no roles - verify all roles except remote one are removed.
        api = UserRoleAssignmentFileFormatAPI(username=user_db.name,
                                              roles=[],
                                              file_path='assignments/%s.yaml' %
                                              user_db.name)

        syncer.sync_users_role_assignments(role_assignment_apis=[api])

        role_dbs = rbac_service.get_roles_for_user(user_db=user_db)
        self.assertEqual(len(role_dbs), 1)
        self.assertEqual(role_dbs[0], self.roles['role_3'])
    def setUp(self):
        super(RBACRemoteGroupToRoleSyncerTestCase, self).setUp()

        self.roles = {}
        self.role_assignments = {}

        # Insert mock local role assignments
        role_db = rbac_service.create_role(name='mock_local_role_1')
        user_db = self.users['user_1']
        source = 'assignments/%s.yaml' % user_db.name
        role_assignment_db_1 = rbac_service.assign_role_to_user(
            role_db=role_db, user_db=user_db, source=source, is_remote=False)

        self.roles['mock_local_role_1'] = role_db
        self.role_assignments['assignment_1'] = role_assignment_db_1

        role_db = rbac_service.create_role(name='mock_local_role_2')
        user_db = self.users['user_1']
        source = 'assignments/%s.yaml' % user_db.name
        role_assignment_db_2 = rbac_service.assign_role_to_user(
            role_db=role_db, user_db=user_db, source=source, is_remote=False)

        self.roles['mock_local_role_2'] = role_db
        self.role_assignments['assignment_2'] = role_assignment_db_2

        role_db = rbac_service.create_role(name='mock_remote_role_3')
        self.roles['mock_remote_role_3'] = role_db

        role_db = rbac_service.create_role(name='mock_remote_role_4')
        self.roles['mock_remote_role_4'] = role_db

        role_db = rbac_service.create_role(name='mock_role_5')
        self.roles['mock_role_5'] = role_db
    def test_grant_and_revoke_role(self):
        user_db = UserDB(name='test-user-1')
        user_db = User.add_or_update(user_db)

        # Initial state, no roles
        role_dbs = rbac_service.get_roles_for_user(user_db=user_db)
        self.assertItemsEqual(role_dbs, [])

        role_dbs = user_db.get_roles()
        self.assertItemsEqual(role_dbs, [])

        # Assign a role, should have one role assigned
        rbac_service.assign_role_to_user(
            role_db=self.roles['custom_role_1'], user_db=user_db,
            source='assignments/%s.yaml' % user_db.name)

        role_dbs = rbac_service.get_roles_for_user(user_db=user_db)
        self.assertItemsEqual(role_dbs, [self.roles['custom_role_1']])

        role_dbs = user_db.get_roles()
        self.assertItemsEqual(role_dbs, [self.roles['custom_role_1']])

        # Revoke previously assigned role, should have no roles again
        rbac_service.revoke_role_from_user(role_db=self.roles['custom_role_1'],
                                           user_db=user_db)

        role_dbs = rbac_service.get_roles_for_user(user_db=user_db)
        self.assertItemsEqual(role_dbs, [])
        role_dbs = user_db.get_roles()
        self.assertItemsEqual(role_dbs, [])
Пример #17
0
    def test_group_to_role_sync_is_performed_on_successful_auth_with_groups_and_mappings(
            self):
        # Enable group sync
        cfg.CONF.set_override(group='rbac',
                              name='sync_remote_groups',
                              override=True)

        user_db = self.users['user_1']
        h = handlers.StandaloneAuthHandler()
        request = {}

        # Single mapping, new remote assignment should be created
        rbac_service.create_group_to_role_map(
            group='CN=stormers,OU=groups,DC=stackstorm,DC=net',
            roles=['mock_role_3', 'mock_role_4'],
            source='mappings/stormers.yaml')

        # Verify initial state
        role_dbs = rbac_service.get_roles_for_user(user_db=user_db,
                                                   include_remote=True)
        self.assertEqual(len(role_dbs), 2)
        self.assertEqual(role_dbs[0], self.roles['mock_local_role_1'])
        self.assertEqual(role_dbs[1], self.roles['mock_local_role_2'])

        h._auth_backend.groups = ['CN=stormers,OU=groups,DC=stackstorm,DC=net']

        token = h.handle_auth(request,
                              headers={},
                              remote_addr=None,
                              remote_user=None,
                              authorization=('basic', DUMMY_CREDS))
        self.assertEqual(token.user, 'auser')

        # Verify a new role assignments based on the group mapping has been created
        role_dbs = rbac_service.get_roles_for_user(user_db=user_db,
                                                   include_remote=True)

        self.assertEqual(len(role_dbs), 4)
        self.assertEqual(role_dbs[0], self.roles['mock_local_role_1'])
        self.assertEqual(role_dbs[1], self.roles['mock_local_role_2'])
        self.assertEqual(role_dbs[2], self.roles['mock_role_3'])
        self.assertEqual(role_dbs[3], self.roles['mock_role_4'])
    def test_create_and_remove_permission_grant(self):
        role_db = self.roles['custom_role_2']
        resource_db = self.resources['rule_1']

        # Grant "ALL" permission to the resource
        permission_types = [PermissionType.RULE_ALL]
        rbac_service.create_permission_grant_for_resource_db(role_db=role_db,
                                                             resource_db=resource_db,
                                                             permission_types=permission_types)

        role_db.reload()
        self.assertItemsEqual(role_db.permission_grants, role_db.permission_grants)

        # Remove the previously granted permission
        rbac_service.remove_permission_grant_for_resource_db(role_db=role_db,
                                                             resource_db=resource_db,
                                                             permission_types=permission_types)

        role_db.reload()
        self.assertItemsEqual(role_db.permission_grants, [])
    def test_get_role_assignments_for_user(self):
        # Test a case where a document doesn't exist is_remote field and when it
        # does
        user_db = self.users['user_5']
        role_assignment_dbs = rbac_service.get_role_assignments_for_user(user_db=user_db,
                                                                         include_remote=False)
        self.assertEqual(len(role_assignment_dbs), 3)
        self.assertEqual(role_assignment_dbs[0].role, 'role_1')
        self.assertEqual(role_assignment_dbs[1].role, 'role_2')
        self.assertEqual(role_assignment_dbs[2].role, 'role_3')
        self.assertEqual(role_assignment_dbs[0].is_remote, False)
        self.assertEqual(role_assignment_dbs[1].is_remote, False)
        self.assertEqual(role_assignment_dbs[2].is_remote, False)

        user_db = self.users['user_5']
        role_assignment_dbs = rbac_service.get_role_assignments_for_user(user_db=user_db,
                                                                         include_remote=True)
        self.assertEqual(len(role_assignment_dbs), 4)
        self.assertEqual(role_assignment_dbs[3].role, 'role_4')
        self.assertEqual(role_assignment_dbs[3].is_remote, True)
    def test_sync_user_assignments_assignments_without_is_remote_are_deleted(
            self):
        # Test case which verifies roles without "is_remote" field (pre v2.3) are removed from the
        # database
        syncer = RBACDefinitionsDBSyncer()

        self._insert_mock_roles()

        # Initial state, 4 roles
        role_assignment_dbs = rbac_service.get_role_assignments_for_user(
            user_db=self.users['user_5'])
        self.assertEqual(len(role_assignment_dbs), 4)

        # All 3 non remote roles should have been deleted
        syncer.sync_users_role_assignments(role_assignment_apis=[])
        role_assignment_dbs = rbac_service.get_role_assignments_for_user(
            user_db=self.users['user_5'])
        self.assertEqual(len(role_assignment_dbs), 1)
        self.assertEqual(role_assignment_dbs[0].role, 'role_4')
        self.assertEqual(role_assignment_dbs[0].is_remote, True)
    def _insert_common_mock_roles(self):
        # Insert common mock roles
        admin_role_db = rbac_service.get_role_by_name(name=SystemRole.ADMIN)
        observer_role_db = rbac_service.get_role_by_name(name=SystemRole.OBSERVER)
        self.roles['admin_role'] = admin_role_db
        self.roles['observer_role'] = observer_role_db

        # Custom role 1 - no grants
        role_1_db = rbac_service.create_role(name='custom_role_1')
        self.roles['custom_role_1'] = role_1_db

        # Custom role 2 - one grant on pack_1
        # "pack_create" on pack_1
        grant_db = PermissionGrantDB(resource_uid=self.resources['pack_1'].get_uid(),
                                     resource_type=ResourceType.PACK,
                                     permission_types=[PermissionType.PACK_CREATE])
        grant_db = PermissionGrant.add_or_update(grant_db)
        permission_grants = [str(grant_db.id)]
        role_3_db = RoleDB(name='custom_role_pack_grant', permission_grants=permission_grants)
        role_3_db = Role.add_or_update(role_3_db)
        self.roles['custom_role_pack_grant'] = role_3_db
    def test_sync_no_groups_and_on_disk_definitions(self):
        syncer = RBACRemoteGroupToRoleSyncer()
        user_db = self.users['user_1']

        # Verify initial state
        role_dbs = rbac_service.get_roles_for_user(user_db=user_db,
                                                   include_remote=True)
        self.assertEqual(len(role_dbs), 2)
        self.assertEqual(role_dbs[0], self.roles['mock_local_role_1'])
        self.assertEqual(role_dbs[1], self.roles['mock_local_role_2'])

        # No groups - should result in no new remote assignments but existing local assignments
        # shouldn't be manipulated
        result = syncer.sync(user_db=self.users['user_1'], groups=[])
        created_role_assignment_dbs = result[0]
        removed_role_assignment_dbs = result[1]
        self.assertEqual(created_role_assignment_dbs, [])
        self.assertEqual(removed_role_assignment_dbs, [])

        role_dbs = rbac_service.get_roles_for_user(user_db=user_db,
                                                   include_remote=True)
        self.assertEqual(len(role_dbs), 2)
        self.assertEqual(role_dbs[0], self.roles['mock_local_role_1'])
        self.assertEqual(role_dbs[1], self.roles['mock_local_role_2'])

        # Groups but no mapping to role definitions, should result in no new remote assignments
        groups = ['CN=stormers,OU=groups,DC=stackstorm,DC=net']
        result = syncer.sync(user_db=self.users['user_1'], groups=groups)
        created_role_assignment_dbs = result[0]
        removed_role_assignment_dbs = result[1]
        self.assertEqual(created_role_assignment_dbs, [])
        self.assertEqual(removed_role_assignment_dbs, [])

        role_dbs = rbac_service.get_roles_for_user(user_db=user_db,
                                                   include_remote=True)
        self.assertEqual(len(role_dbs), 2)
        self.assertEqual(role_dbs[0], self.roles['mock_local_role_1'])
        self.assertEqual(role_dbs[1], self.roles['mock_local_role_2'])
    def test_sync_user_assignments_locally_removed_assignments_are_removed_from_db(
            self):
        syncer = RBACDefinitionsDBSyncer()

        self._insert_mock_roles()

        # Initial state, no roles
        role_dbs = rbac_service.get_roles_for_user(
            user_db=self.users['user_2'])
        self.assertItemsEqual(role_dbs, [])

        # Do the sync with two roles defined
        api = UserRoleAssignmentFileFormatAPI(
            username='******',
            roles=['role_1', 'role_2'],
            file_path='assignments/user2.yaml')

        syncer.sync_users_role_assignments(role_assignment_apis=[api])

        role_dbs = rbac_service.get_roles_for_user(
            user_db=self.users['user_2'])
        self.assertEqual(len(role_dbs), 2)
        self.assertEqual(role_dbs[0], self.roles['role_1'])
        self.assertEqual(role_dbs[1], self.roles['role_2'])

        # Do the sync with one role defined (one should be removed from the db)
        api = UserRoleAssignmentFileFormatAPI(
            username='******',
            roles=['role_2'],
            file_path='assignments/user2.yaml')

        syncer.sync_users_role_assignments(role_assignment_apis=[api])

        role_dbs = rbac_service.get_roles_for_user(
            user_db=self.users['user_2'])
        self.assertEqual(len(role_dbs), 1)
        self.assertEqual(role_dbs[0], self.roles['role_2'])
Пример #24
0
    def user_has_system_role(user_db):
        """
        :param user: User object to check for.
        :type user: :class:`UserDB`

        :rtype: ``bool``
        """
        user_role_dbs = rbac_service.get_roles_for_user(user_db=user_db)
        user_role_names = [role_db.name for role_db in user_role_dbs]

        if (SystemRole.SYSTEM_ADMIN in user_role_names
                or SystemRole.ADMIN in user_role_names
                or SystemRole.OBSERVER in user_role_names):
            return True

        return False
Пример #25
0
    def setUp(self):
        super(AuthHandlerRBACRoleSyncTestCase, self).setUp()

        cfg.CONF.set_override(group='auth', name='backend', override='mock')
        cfg.CONF.set_override(group='rbac',
                              name='backend',
                              override='enterprise')

        self.users = {}
        self.roles = {}
        self.role_assignments = {}

        # Insert some mock users
        user_1_db = UserDB(name='auser')
        user_1_db = User.add_or_update(user_1_db)
        self.users['user_1'] = user_1_db

        user_2_db = UserDB(name='buser')
        user_2_db = User.add_or_update(user_2_db)
        self.users['user_2'] = user_2_db

        # Insert mock local role assignments
        role_db = rbac_service.create_role(name='mock_local_role_1')
        user_db = self.users['user_1']
        source = 'assignments/%s.yaml' % user_db.name
        role_assignment_db_1 = rbac_service.assign_role_to_user(
            role_db=role_db, user_db=user_db, source=source, is_remote=False)

        self.roles['mock_local_role_1'] = role_db
        self.role_assignments['assignment_1'] = role_assignment_db_1

        role_db = rbac_service.create_role(name='mock_local_role_2')
        user_db = self.users['user_1']
        source = 'assignments/%s.yaml' % user_db.name
        role_assignment_db_2 = rbac_service.assign_role_to_user(
            role_db=role_db, user_db=user_db, source=source, is_remote=False)

        self.roles['mock_local_role_2'] = role_db
        self.role_assignments['assignment_2'] = role_assignment_db_2

        role_db = rbac_service.create_role(name='mock_role_3')
        self.roles['mock_role_3'] = role_db

        role_db = rbac_service.create_role(name='mock_role_4')
        self.roles['mock_role_4'] = role_db

        role_db = rbac_service.create_role(name='mock_role_5')
        self.roles['mock_role_5'] = role_db
    def test_sync_success_one_existing_remote_assignment(self):
        syncer = RBACRemoteGroupToRoleSyncer()
        user_db = self.users['user_1']

        # Create mock mapping which maps CN=stormers,OU=groups,DC=stackstorm,DC=net
        # to "mock_remote_role_3" and "mock_remote_role_4"
        rbac_service.create_group_to_role_map(
            group='CN=stormers,OU=groups,DC=stackstorm,DC=net',
            roles=['mock_remote_role_3', 'mock_remote_role_4'],
            source='mappings/stormers.yaml')

        # Assign existing remote mock_role_5 to the user
        role_db = self.roles['mock_role_5']
        source = 'mappings/stormers.yaml'
        rbac_service.assign_role_to_user(role_db=role_db,
                                         user_db=user_db,
                                         source=source,
                                         is_remote=True)

        # Verify initial state
        role_dbs = rbac_service.get_roles_for_user(user_db=user_db,
                                                   include_remote=True)
        self.assertEqual(len(role_dbs), 3)
        self.assertEqual(role_dbs[0], self.roles['mock_local_role_1'])
        self.assertEqual(role_dbs[1], self.roles['mock_local_role_2'])
        self.assertEqual(role_dbs[2], self.roles['mock_role_5'])

        groups = [
            'CN=stormers,OU=groups,DC=stackstorm,DC=net',
            'CN=testers,OU=groups,DC=stackstorm,DC=net'
        ]
        result = syncer.sync(user_db=self.users['user_1'], groups=groups)
        created_role_assignment_dbs = result[0]
        removed_role_assignment_dbs = result[1]
        self.assertEqual(len(created_role_assignment_dbs), 2)
        self.assertEqual(created_role_assignment_dbs[0].role,
                         'mock_remote_role_3')
        self.assertEqual(created_role_assignment_dbs[1].role,
                         'mock_remote_role_4')
        self.assertEqual(len(removed_role_assignment_dbs), 1)
        self.assertEqual(removed_role_assignment_dbs[0].role, 'mock_role_5')

        # User should have two new roles assigned now, but the existing "mock_role_5" remote role
        # removed since it wasn't specified in any mapping
        role_dbs = rbac_service.get_roles_for_user(user_db=user_db,
                                                   include_remote=True)
        self.assertEqual(len(role_dbs), 4)
        self.assertEqual(role_dbs[0], self.roles['mock_local_role_1'])
        self.assertEqual(role_dbs[1], self.roles['mock_local_role_2'])
        self.assertEqual(role_dbs[2], self.roles['mock_remote_role_3'])
        self.assertEqual(role_dbs[3], self.roles['mock_remote_role_4'])
    def test_sync_success_no_existing_remote_assignments(self):
        syncer = RBACRemoteGroupToRoleSyncer()
        user_db = self.users['user_1']

        # Create mock mapping which maps CN=stormers,OU=groups,DC=stackstorm,DC=net
        # to "mock_remote_role_3" and "mock_remote_role_4"
        rbac_service.create_group_to_role_map(
            group='CN=stormers,OU=groups,DC=stackstorm,DC=net',
            roles=['mock_remote_role_3', 'mock_remote_role_4'],
            source='mappings/stormers.yaml')

        # Verify initial state
        role_dbs = rbac_service.get_roles_for_user(user_db=user_db,
                                                   include_remote=True)
        self.assertEqual(len(role_dbs), 2)
        self.assertEqual(role_dbs[0], self.roles['mock_local_role_1'])
        role_assignment_dbs = rbac_service.get_role_assignments_for_user(
            user_db=self.users['user_1'])

        groups = [
            'CN=stormers,OU=groups,DC=stackstorm,DC=net',
            'CN=testers,OU=groups,DC=stackstorm,DC=net',
            # We repeat the same group to validate that repated groups are correctly de-duplicated
            'CN=stormers,OU=groups,DC=stackstorm,DC=net',
        ]
        result = syncer.sync(user_db=self.users['user_1'], groups=groups)
        created_role_assignment_dbs = result[0]
        removed_role_assignment_dbs = result[1]
        self.assertEqual(len(created_role_assignment_dbs), 2)
        self.assertEqual(created_role_assignment_dbs[0].role,
                         'mock_remote_role_3')
        self.assertEqual(created_role_assignment_dbs[1].role,
                         'mock_remote_role_4')
        self.assertEqual(removed_role_assignment_dbs, [])

        # User should have two new roles assigned now
        role_dbs = rbac_service.get_roles_for_user(user_db=user_db,
                                                   include_remote=True)
        self.assertEqual(len(role_dbs), 4)
        self.assertEqual(role_dbs[0], self.roles['mock_local_role_1'])
        self.assertEqual(role_dbs[1], self.roles['mock_local_role_2'])
        self.assertEqual(role_dbs[2], self.roles['mock_remote_role_3'])
        self.assertEqual(role_dbs[3], self.roles['mock_remote_role_4'])

        role_assignment_dbs = rbac_service.get_role_assignments_for_user(
            user_db=self.users['user_1'])
        self.assertEqual(len(role_assignment_dbs), 4)
        self.assertEqual(role_assignment_dbs[2].source,
                         'mappings/stormers.yaml')
        self.assertEqual(role_assignment_dbs[3].source,
                         'mappings/stormers.yaml')
Пример #28
0
    def user_has_role(user_db, role):
        """
        :param user: User object to check for.
        :type user: :class:`UserDB`

        :param role: Role name to check for.
        :type role: ``str``

        :rtype: ``bool``
        """
        assert isinstance(role, six.string_types)

        if not cfg.CONF.rbac.enable:
            return True

        user_role_dbs = rbac_service.get_roles_for_user(user_db=user_db)
        user_role_names = [role_db.name for role_db in user_role_dbs]

        return role in user_role_names
    def test_sync_user_assignments_role_doesnt_exist_in_db(self):
        syncer = RBACDefinitionsDBSyncer()

        self._insert_mock_roles()

        # Initial state, no roles
        role_dbs = rbac_service.get_roles_for_user(
            user_db=self.users['user_2'])
        self.assertItemsEqual(role_dbs, [])

        # Do the sync with role defined in separate files
        assignment1 = UserRoleAssignmentFileFormatAPI(
            username='******',
            roles=['doesnt_exist'],
            file_path='assignments/user2.yaml')

        expected_msg = ('Role "doesnt_exist" referenced in assignment file '
                        '"assignments/user2.yaml" doesn\'t exist')
        self.assertRaisesRegexp(ValueError,
                                expected_msg,
                                syncer.sync_users_role_assignments,
                                role_assignment_apis=[assignment1])
    def test_sync_success_one_mapping_is_disabled_on_second_sync_run(self):
        syncer = RBACRemoteGroupToRoleSyncer()
        user_db = self.users['user_1']

        # Create mock mapping which maps CN=stormers,OU=groups,DC=stackstorm,DC=net
        # to "mock_remote_role_3" and CN=testers,OU=groups,DC=stackstorm,DC=net to
        # "mock_remote_role_4"
        rbac_service.create_group_to_role_map(
            group='CN=stormers,OU=groups,DC=stackstorm,DC=net',
            roles=['mock_remote_role_3'],
            source='mappings/stormers.yaml',
            enabled=True)

        rbac_service.create_group_to_role_map(
            group='CN=testers,OU=groups,DC=stackstorm,DC=net',
            roles=['mock_remote_role_4'],
            source='mappings/testers.yaml',
            enabled=True)

        # Verify initial state
        role_dbs = rbac_service.get_roles_for_user(user_db=user_db,
                                                   include_remote=True)
        self.assertEqual(len(role_dbs), 2)
        self.assertEqual(role_dbs[0], self.roles['mock_local_role_1'])
        self.assertEqual(role_dbs[1], self.roles['mock_local_role_2'])

        groups = [
            'CN=stormers,OU=groups,DC=stackstorm,DC=net',
            'CN=testers,OU=groups,DC=stackstorm,DC=net'
        ]

        # Two new remote assignments should have been created
        # No mappings exist for the groups user is a member of so no new assignments should be
        # created
        result = syncer.sync(user_db=self.users['user_1'], groups=groups)
        created_role_assignment_dbs = result[0]
        removed_role_assignment_dbs = result[1]
        self.assertEqual(len(created_role_assignment_dbs), 2)
        self.assertEqual(created_role_assignment_dbs[0].role,
                         'mock_remote_role_3')
        self.assertEqual(created_role_assignment_dbs[1].role,
                         'mock_remote_role_4')
        self.assertEqual(removed_role_assignment_dbs, [])

        # Verify post sync run state - two new assignments should have been created
        role_dbs = rbac_service.get_roles_for_user(user_db=user_db,
                                                   include_remote=True)
        self.assertEqual(len(role_dbs), 4)
        self.assertEqual(role_dbs[0], self.roles['mock_local_role_1'])
        self.assertEqual(role_dbs[1], self.roles['mock_local_role_2'])
        self.assertEqual(role_dbs[2], self.roles['mock_remote_role_3'])
        self.assertEqual(role_dbs[3], self.roles['mock_remote_role_4'])

        # Disable second mapping - one assignment should be removed
        mapping_db = GroupToRoleMapping.get(
            group='CN=testers,OU=groups,DC=stackstorm,DC=net')
        mapping_db.enabled = False
        GroupToRoleMapping.add_or_update(mapping_db)

        result = syncer.sync(user_db=self.users['user_1'], groups=groups)
        created_role_assignment_dbs = result[0]
        removed_role_assignment_dbs = result[1]
        self.assertEqual(len(created_role_assignment_dbs), 1)
        self.assertEqual(len(removed_role_assignment_dbs), 2)
        self.assertEqual(created_role_assignment_dbs[0].role,
                         'mock_remote_role_3')
        self.assertEqual(removed_role_assignment_dbs[0].role,
                         'mock_remote_role_3')
        self.assertEqual(removed_role_assignment_dbs[1].role,
                         'mock_remote_role_4')

        # Verify post sync run state - mock_remote_role_4 assignment should be removed
        role_dbs = rbac_service.get_roles_for_user(user_db=user_db,
                                                   include_remote=True)
        self.assertEqual(len(role_dbs), 3)
        self.assertEqual(role_dbs[0], self.roles['mock_local_role_1'])
        self.assertEqual(role_dbs[1], self.roles['mock_local_role_2'])
        self.assertEqual(role_dbs[2], self.roles['mock_remote_role_3'])