327 lines
16 KiB
Python
327 lines
16 KiB
Python
"""
|
||
Интеграционные тесты для системы RBAC.
|
||
|
||
Проверяет работу системы ролей и разрешений в реальных сценариях
|
||
с учетом наследования ролей.
|
||
"""
|
||
|
||
import pytest
|
||
import time
|
||
from unittest.mock import patch, MagicMock
|
||
import json
|
||
|
||
from orm.author import Author
|
||
from orm.community import Community, CommunityAuthor
|
||
from rbac.api import (
|
||
initialize_community_permissions,
|
||
get_permissions_for_role,
|
||
user_has_permission,
|
||
roles_have_permission
|
||
)
|
||
from storage.db import local_session
|
||
from storage.redis import redis
|
||
|
||
|
||
@pytest.fixture
|
||
def simple_user(db_session):
|
||
"""Создает простого тестового пользователя"""
|
||
# Очищаем любые существующие записи с этим ID/email
|
||
db_session.query(Author).where(
|
||
(Author.id == 200) | (Author.email == "simple_user@example.com")
|
||
).delete()
|
||
db_session.commit()
|
||
|
||
user = Author(
|
||
id=200,
|
||
email="simple_user@example.com",
|
||
name="Simple User",
|
||
slug="simple-user",
|
||
)
|
||
user.set_password("password123")
|
||
db_session.add(user)
|
||
db_session.commit()
|
||
|
||
yield user
|
||
|
||
# Очистка после теста
|
||
try:
|
||
# Удаляем связанные записи CommunityAuthor
|
||
db_session.query(CommunityAuthor).where(CommunityAuthor.author_id == user.id).delete(synchronize_session=False)
|
||
# Удаляем самого пользователя
|
||
db_session.query(Author).where(Author.id == user.id).delete()
|
||
db_session.commit()
|
||
except Exception as e:
|
||
print(f"Ошибка при очистке тестового пользователя: {e}")
|
||
|
||
|
||
@pytest.fixture
|
||
def test_community(db_session, simple_user):
|
||
"""Создает тестовое сообщество"""
|
||
import uuid
|
||
|
||
# Генерируем уникальный slug
|
||
unique_slug = f"integration-test-{uuid.uuid4().hex[:8]}"
|
||
|
||
community = Community(
|
||
name="Integration Test Community",
|
||
slug=unique_slug,
|
||
desc="Community for integration RBAC tests",
|
||
created_by=simple_user.id,
|
||
created_at=int(time.time())
|
||
)
|
||
db_session.add(community)
|
||
db_session.commit()
|
||
|
||
yield community
|
||
|
||
# Очистка после теста
|
||
try:
|
||
db_session.query(Community).where(Community.id == community.id).delete()
|
||
db_session.commit()
|
||
except Exception as e:
|
||
print(f"Ошибка при очистке тестового сообщества: {e}")
|
||
|
||
|
||
@pytest.fixture(autouse=True)
|
||
def setup_redis(test_community):
|
||
"""Настройка Redis для каждого теста"""
|
||
# FakeRedis уже подключен, ничего не делаем
|
||
yield
|
||
|
||
# Очищаем данные тестового сообщества из Redis
|
||
try:
|
||
# Используем execute вместо delete
|
||
redis.execute("DEL", f"community:roles:{test_community.id}")
|
||
except Exception:
|
||
pass
|
||
|
||
|
||
class TestRBACIntegrationWithInheritance:
|
||
"""Интеграционные тесты с учетом наследования ролей"""
|
||
|
||
def test_author_role_inheritance_integration(self, db_session, simple_user, test_community):
|
||
"""Интеграционный тест наследования ролей для author"""
|
||
# pytest.skip("RBAC integration тесты временно отключены из-за проблем с Redis")
|
||
# TODO: Implement test logic
|
||
assert True # Placeholder assertion
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_editor_role_inheritance_integration(self, db_session, simple_user, test_community):
|
||
"""Интеграционный тест наследования ролей для editor"""
|
||
from rbac.api import initialize_community_permissions, user_has_permission
|
||
from orm.community import CommunityAuthor
|
||
|
||
# Инициализируем разрешения для сообщества
|
||
await initialize_community_permissions(test_community.id)
|
||
|
||
# Создаем CommunityAuthor с ролью editor
|
||
ca = CommunityAuthor(
|
||
community_id=test_community.id,
|
||
author_id=simple_user.id,
|
||
roles="editor"
|
||
)
|
||
db_session.add(ca)
|
||
db_session.commit()
|
||
|
||
# Проверяем базовые разрешения reader (editor наследует их через author)
|
||
reader_permissions = ["shout:read", "topic:read", "collection:read"]
|
||
for perm in reader_permissions:
|
||
has_permission = await user_has_permission(simple_user.id, perm, test_community.id, db_session)
|
||
assert has_permission, f"Editor должен наследовать разрешение {perm} от reader через author"
|
||
|
||
# Проверяем разрешения author (editor наследует их напрямую)
|
||
author_permissions = ["draft:create", "shout:create", "collection:create"]
|
||
for perm in author_permissions:
|
||
has_permission = await user_has_permission(simple_user.id, perm, test_community.id, db_session)
|
||
assert has_permission, f"Editor должен наследовать разрешение {perm} от author"
|
||
|
||
# Проверяем специфичные разрешения editor
|
||
editor_permissions = ["shout:delete_any", "shout:update_any", "topic:create"]
|
||
for perm in editor_permissions:
|
||
has_permission = await user_has_permission(simple_user.id, perm, test_community.id, db_session)
|
||
assert has_permission, f"Editor должен иметь разрешение {perm}"
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_admin_role_inheritance_integration(self, db_session, simple_user, test_community):
|
||
"""Интеграционный тест наследования ролей для admin"""
|
||
from rbac.api import initialize_community_permissions, user_has_permission
|
||
from orm.community import CommunityAuthor
|
||
|
||
# Инициализируем разрешения для сообщества
|
||
await initialize_community_permissions(test_community.id)
|
||
|
||
# Создаем CommunityAuthor с ролью admin
|
||
ca = CommunityAuthor(
|
||
community_id=test_community.id,
|
||
author_id=simple_user.id,
|
||
roles="admin"
|
||
)
|
||
db_session.add(ca)
|
||
db_session.commit()
|
||
|
||
# Проверяем что admin наследует разрешения author
|
||
author_permissions = ["draft:create", "shout:create", "collection:create"]
|
||
for perm in author_permissions:
|
||
has_permission = await user_has_permission(simple_user.id, perm, test_community.id, db_session)
|
||
assert has_permission, f"Admin должен наследовать разрешение {perm} от author"
|
||
|
||
# Проверяем специфичные разрешения admin
|
||
admin_permissions = ["shout:delete_any", "author:delete_any", "community:delete_any"]
|
||
for perm in admin_permissions:
|
||
has_permission = await user_has_permission(simple_user.id, perm, test_community.id, db_session)
|
||
assert has_permission, f"Admin должен иметь разрешение {perm}"
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_expert_role_inheritance_integration(self, db_session, simple_user, test_community):
|
||
"""Интеграционный тест наследования ролей для expert"""
|
||
from rbac.api import initialize_community_permissions, user_has_permission
|
||
from orm.community import CommunityAuthor
|
||
|
||
# Инициализируем разрешения для сообщества
|
||
await initialize_community_permissions(test_community.id)
|
||
|
||
# Создаем CommunityAuthor с ролью expert
|
||
ca = CommunityAuthor(
|
||
community_id=test_community.id,
|
||
author_id=simple_user.id,
|
||
roles="expert"
|
||
)
|
||
db_session.add(ca)
|
||
db_session.commit()
|
||
|
||
# Проверяем что expert наследует разрешения reader
|
||
reader_permissions = ["shout:read", "topic:read", "collection:read"]
|
||
for perm in reader_permissions:
|
||
has_permission = await user_has_permission(simple_user.id, perm, test_community.id, db_session)
|
||
assert has_permission, f"Expert должен наследовать разрешение {perm} от reader"
|
||
|
||
# Проверяем специфичные разрешения expert
|
||
expert_permissions = ["reaction:create:PROOF", "reaction:create:DISPROOF", "reaction:create:AGREE"]
|
||
for perm in expert_permissions:
|
||
has_permission = await user_has_permission(simple_user.id, perm, test_community.id, db_session)
|
||
assert has_permission, f"Expert должен иметь разрешение {perm}"
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_artist_role_inheritance_integration(self, db_session, simple_user, test_community):
|
||
"""Интеграционный тест наследования ролей для artist"""
|
||
from rbac.api import initialize_community_permissions, user_has_permission
|
||
from orm.community import CommunityAuthor
|
||
|
||
# Инициализируем разрешения для сообщества
|
||
await initialize_community_permissions(test_community.id)
|
||
|
||
# Создаем CommunityAuthor с ролью artist
|
||
ca = CommunityAuthor(
|
||
community_id=test_community.id,
|
||
author_id=simple_user.id,
|
||
roles="artist"
|
||
)
|
||
db_session.add(ca)
|
||
db_session.commit()
|
||
|
||
# Проверяем что artist наследует разрешения author
|
||
author_permissions = ["draft:create", "shout:create", "collection:create"]
|
||
for perm in author_permissions:
|
||
has_permission = await user_has_permission(simple_user.id, perm, test_community.id, db_session)
|
||
assert has_permission, f"Artist должен наследовать разрешение {perm} от author"
|
||
|
||
# Проверяем специфичные разрешения artist
|
||
artist_permissions = ["reaction:create:CREDIT", "reaction:read:CREDIT"]
|
||
for perm in artist_permissions:
|
||
has_permission = await user_has_permission(simple_user.id, perm, test_community.id, db_session)
|
||
assert has_permission, f"Artist должен иметь разрешение {perm}"
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_multiple_roles_inheritance_integration(self, db_session, simple_user, test_community):
|
||
"""Интеграционный тест наследования для пользователя с несколькими ролями"""
|
||
from rbac.api import initialize_community_permissions, user_has_permission
|
||
from orm.community import CommunityAuthor
|
||
|
||
# Инициализируем разрешения для сообщества
|
||
await initialize_community_permissions(test_community.id)
|
||
|
||
# Создаем CommunityAuthor с несколькими ролями
|
||
ca = CommunityAuthor(
|
||
community_id=test_community.id,
|
||
author_id=simple_user.id,
|
||
roles="author,expert"
|
||
)
|
||
db_session.add(ca)
|
||
db_session.commit()
|
||
|
||
# Проверяем разрешения от author
|
||
author_permissions = ["draft:create", "shout:create"]
|
||
for perm in author_permissions:
|
||
has_permission = await user_has_permission(simple_user.id, perm, test_community.id, db_session)
|
||
assert has_permission, f"Пользователь с ролями author,expert должен иметь разрешение {perm}"
|
||
|
||
# Проверяем разрешения от expert
|
||
expert_permissions = ["reaction:create:PROOF", "reaction:create:DISPROOF"]
|
||
for perm in expert_permissions:
|
||
has_permission = await user_has_permission(simple_user.id, perm, test_community.id, db_session)
|
||
assert has_permission, f"Пользователь с ролями author,expert должен иметь разрешение {perm}"
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_roles_have_permission_inheritance_integration(self, db_session, test_community):
|
||
"""Интеграционный тест функции roles_have_permission с учетом наследования"""
|
||
from rbac.api import initialize_community_permissions, roles_have_permission
|
||
|
||
# Инициализируем разрешения для сообщества
|
||
await initialize_community_permissions(test_community.id)
|
||
|
||
# Проверяем что admin роли имеют разрешения author
|
||
has_permission = await roles_have_permission(["admin"], "draft:create", test_community.id)
|
||
assert has_permission, "Admin должен наследовать разрешение draft:create от author"
|
||
|
||
# Проверяем что editor роли имеют разрешения reader
|
||
has_permission = await roles_have_permission(["editor"], "shout:read", test_community.id)
|
||
assert has_permission, "Editor должен наследовать разрешение shout:read от reader"
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_permission_denial_inheritance_integration(self, db_session, simple_user, test_community):
|
||
"""Интеграционный тест отказа в разрешениях с учетом наследования"""
|
||
from rbac.api import initialize_community_permissions, user_has_permission
|
||
from orm.community import CommunityAuthor
|
||
|
||
# Инициализируем разрешения для сообщества
|
||
await initialize_community_permissions(test_community.id)
|
||
|
||
# Создаем CommunityAuthor с ролью reader
|
||
ca = CommunityAuthor(
|
||
community_id=test_community.id,
|
||
author_id=simple_user.id,
|
||
roles="reader"
|
||
)
|
||
db_session.add(ca)
|
||
db_session.commit()
|
||
|
||
# Проверяем что reader НЕ имеет разрешения author
|
||
author_permissions = ["draft:create", "shout:create"]
|
||
for perm in author_permissions:
|
||
has_permission = await user_has_permission(simple_user.id, perm, test_community.id, db_session)
|
||
assert not has_permission, f"Reader НЕ должен иметь разрешение {perm}"
|
||
|
||
@pytest.mark.asyncio
|
||
async def test_deep_inheritance_chain_integration(self, db_session, simple_user, test_community):
|
||
"""Интеграционный тест глубокой цепочки наследования ролей"""
|
||
from rbac.api import initialize_community_permissions, user_has_permission
|
||
from orm.community import CommunityAuthor
|
||
|
||
# Инициализируем разрешения для сообщества
|
||
await initialize_community_permissions(test_community.id)
|
||
|
||
# Создаем CommunityAuthor с ролью admin
|
||
ca = CommunityAuthor(
|
||
community_id=test_community.id,
|
||
author_id=simple_user.id,
|
||
roles="admin"
|
||
)
|
||
db_session.add(ca)
|
||
db_session.commit()
|
||
|
||
# Проверяем глубокую цепочку наследования: admin -> author -> reader
|
||
reader_permissions = ["shout:read", "topic:read"]
|
||
for perm in reader_permissions:
|
||
has_permission = await user_has_permission(simple_user.id, perm, test_community.id, db_session)
|
||
assert has_permission, f"Admin должен наследовать разрешение {perm} через цепочку admin->author->reader"
|