docs: add production debugging guide for position permissions

Added comprehensive troubleshooting section:
- Django shell diagnostic script
- SQL queries to check database state
- Permission cache clearing instructions
- Template debugging
- Common issues and solutions
- Complete test results table (13/13 PASSED)

All tests confirmed PositionRoleBackend logic is correct.
If buttons still don't appear, issue is likely:
1. Permission caching (needs re-login)
2. LDAP group sync not working
3. Database missing Position→Groups→Permissions links
This commit is contained in:
admin i 2025-12-08 14:06:01 +03:00
parent 66406d94ad
commit 4a6b92f5f8

View File

@ -451,5 +451,257 @@ WHERE employees_position_groups.position_id = ?
---
**Документ создан:** 2025-01-XX
**Последнее обновление:** После фикса Permission creation pattern
**Статус:** 🔄 Отладка тестовой инфраструктуры
**Последнее обновление:** ✅ ВСЕ ТЕСТЫ ПРОШЛИ (13/13 PASSED)
**Статус:** ✅ Готово к production тестированию
## ВАЖНО: Что Делать Дальше
### ✅ Что Мы Выяснили
**Тесты показали, что логика `PositionRoleBackend` работает ПРАВИЛЬНО!**
- ✅ Пользователи с должностями получают права из групп
- ✅ Права обновляются при смене должности
- ✅ Права удаляются при снятии должности
- ✅ `has_perm()` и `get_all_permissions()` работают корректно
- ✅ Добавлена проверка `is_active` (исправили баг)
### 🔍 Где Искать Проблему
Если кнопки **всё ещё не появляются** в production, проблема НЕ в коде, а в:
1. **Кэширование прав Django**
- Django кэширует права в `_perm_cache` и `_user_perm_cache`
- После изменения должности нужен перелогин или очистка кэша
2. **LDAP синхронизация групп**
- Проверить что `Position.groups` содержит правильные группы
- Проверить что `Group.permissions` содержит нужные права
3. **Порядок AUTHENTICATION_BACKENDS**
- `PositionRoleBackend` должен быть в списке (сейчас на 4 месте ✅)
- Возможно другие backend'ы блокируют его работу
### 📋 Чеклист Отладки Production
#### Шаг 1: Проверить Права в Django Shell
```python
from django.contrib.auth import get_user_model
User = get_user_model()
# Замените на реального пользователя
user = User.objects.get(username='имя_пользователя')
print(f"1. Position: {user.position}")
print(f"2. Position Groups: {user.position.groups.all() if user.position else 'NO POSITION'}")
if user.position:
for group in user.position.groups.all():
print(f" - Group: {group.name}")
print(f" Permissions: {list(group.permissions.values_list('codename', flat=True))}")
print(f"\n3. User Permissions:")
print(f" All Permissions: {user.get_all_permissions()}")
print(f" Has feed.publish_company_post: {user.has_perm('feed.publish_company_post')}")
print(f" Has documents.add_document: {user.has_perm('documents.add_document')}")
```
**Ожидаемый результат:**
- `Position` должен быть не `None`
- `Position.groups` должны содержать группы
- `Group.permissions` должны включать нужные права
- `user.get_all_permissions()` должен возвращать права из должности
- `user.has_perm('feed.publish_company_post')` должен быть `True`
#### Шаг 2: Проверить Базу Данных
```sql
-- Проверить связь User → Employee → Position
SELECT u.username, e.id, p.name
FROM auth_user u
JOIN employees_employee e ON e.user_id = u.id
LEFT JOIN employees_position p ON e.position_id = p.id
WHERE u.username = 'имя_пользователя';
-- Проверить связь Position → Groups
SELECT p.name AS position, g.name AS group_name
FROM employees_position p
JOIN employees_position_groups pg ON pg.position_id = p.id
JOIN auth_group g ON pg.group_id = g.id
WHERE p.id = <position_id>;
-- Проверить связь Group → Permissions
SELECT g.name AS group_name, p.codename
FROM auth_group g
JOIN auth_group_permissions gp ON gp.group_id = g.id
JOIN auth_permission p ON gp.permission_id = p.id
WHERE g.id IN (
SELECT group_id FROM employees_position_groups
WHERE position_id = <position_id>
);
```
#### Шаг 3: Очистить Кэш Прав
```python
from django.contrib.auth import get_user_model
User = get_user_model()
user = User.objects.get(username='имя_пользователя')
# Очистить кэши прав
if hasattr(user, '_perm_cache'):
delattr(user, '_perm_cache')
if hasattr(user, '_user_perm_cache'):
delattr(user, '_user_perm_cache')
# Или просто получить fresh instance
user = User.objects.get(id=user.id)
# Проверить снова
print(user.has_perm('feed.publish_company_post'))
```
#### Шаг 4: Проверить Template Context
В шаблоне `feed/feed_list.html`:
```django
{# DEBUG: Покажите права пользователя #}
{% if user.is_authenticated %}
<p>User: {{ user.username }}</p>
<p>Position: {{ user.position }}</p>
<p>Has publish_company_post: {{ perms.feed.publish_company_post }}</p>
<p>Has publish_department_post: {{ perms.feed.publish_department_post }}</p>
<p>Is Staff: {{ user.is_staff }}</p>
{% endif %}
```
#### Шаг 5: Проверить Middleware
В `settings.py` убедитесь что есть:
```python
MIDDLEWARE = [
...
'django.contrib.auth.middleware.AuthenticationMiddleware',
...
]
```
#### Шаг 6: Перезапустить Сервер
```bash
# Остановить
Ctrl+C
# Очистить кэш (если используется Redis/Memcached)
python manage.py shell
>>> from django.core.cache import cache
>>> cache.clear()
>>> exit()
# Запустить снова
python manage.py runserver
```
#### Шаг 7: Перелогинить Пользователя
- Попросите пользователя выйти из системы
- Войти заново
- Проверить видимость кнопок
### 🐛 Возможные Проблемы
#### Проблема 1: Position.groups пустые
**Симптом:** `user.position.groups.all()` возвращает пустой список
**Решение:**
```python
from employees.models import Position
from django.contrib.auth.models import Group
# Найти или создать группу
pub_group = Group.objects.get(name="publishers")
# Назначить группу должности
position = Position.objects.get(name="Инженер")
position.groups.add(pub_group)
```
#### Проблема 2: Group.permissions пустые
**Симптом:** `group.permissions.all()` возвращает пустой список
**Решение:**
```python
from django.contrib.auth.models import Group, Permission
from django.contrib.contenttypes.models import ContentType
# Найти Content Type
ct = ContentType.objects.get(app_label="feed", model="post")
# Найти или создать Permission
perm = Permission.objects.filter(
codename="publish_company_post",
content_type=ct
).first()
if not perm:
perm = Permission.objects.create(
codename="publish_company_post",
name="Can publish company post",
content_type=ct
)
# Добавить в группу
pub_group = Group.objects.get(name="publishers")
pub_group.permissions.add(perm)
```
#### Проблема 3: LDAP не синхронизирует группы
**Симптом:** В LDAP нет группы `POS_Инженер`
**Решение:**
```python
from employees.models import Position
from employees.ldap.services import PositionService
position = Position.objects.get(name="Инженер")
dn = PositionService._ensure_position_group(position)
print(f"LDAP Group DN: {dn}")
```
### <20> Итоговая Таблица Результатов Тестов
| Тест | Статус | Что проверяет |
|------|--------|---------------|
| test_user_without_position_has_no_permissions | ✅ PASS | Без должности = нет прав |
| test_user_with_position_gets_permissions | ✅ PASS | С должностью = права есть |
| test_position_change_updates_permissions | ✅ PASS | Смена должности обновляет права |
| test_remove_position_removes_permissions | ✅ PASS | Удаление должности убирает права |
| test_multiple_users_with_same_position | ✅ PASS | Несколько user одна должность |
| test_superuser_has_all_permissions | ✅ PASS | Superuser имеет все права |
| test_position_group_permissions_are_additive | ✅ PASS | Несколько групп складываются |
| test_get_all_permissions_includes_position_perms | ✅ PASS | get_all_permissions() работает |
| test_position_without_groups_grants_no_permissions | ✅ PASS | Должность без групп = нет прав |
| test_inactive_user_has_no_permissions | ✅ PASS | Неактивный user = нет прав |
| test_position_permissions_with_direct_user_permissions | ✅ PASS | Прямые + должность аддитивны |
| test_feed_permissions_through_position | ✅ PASS | Реальные feed права работают |
| test_documents_permissions_through_position | ✅ PASS | Реальные document права работают |
### 🎯 Рекомендации
1. **Запустить отладочный скрипт** (Шаг 1) чтобы увидеть текущее состояние
2. **Проверить LDAP синхронизацию** группы для должности
3. **Очистить кэш** и перелогинить пользователя
4. **Если проблема остаётся:** Показать вывод отладочного скрипта
**Результат должен быть:** Кнопки появляются у пользователей с нужными должностями! 🎉
---
**Документ создан:** 2025-01-XX
**Последнее обновление:** ✅ ВСЕ ТЕСТЫ ПРОШЛИ (13/13 PASSED)
**Статус:** ✅ Готово к production тестированию