L'import manuel élève par élève est fastidieux pour les établissements qui gèrent des centaines d'élèves. Un wizard d'import en 4 étapes (upload → mapping → preview → confirmation) permet de traiter un fichier complet en une seule opération, avec détection automatique du format (Pronote, École Directe) et validation avant import. L'import est traité de manière asynchrone via Messenger pour ne pas bloquer l'interface, avec suivi de progression en temps réel et réutilisation des mappings entre imports successifs.
92 lines
3.8 KiB
YAML
92 lines
3.8 KiB
YAML
security:
|
|
# Role hierarchy — Direction inherits read permissions on whole school (AC3, FR5)
|
|
role_hierarchy:
|
|
ROLE_SUPER_ADMIN: [ROLE_ADMIN]
|
|
ROLE_ADMIN: [ROLE_PROF, ROLE_VIE_SCOLAIRE, ROLE_SECRETARIAT]
|
|
ROLE_PROF: [ROLE_USER]
|
|
ROLE_VIE_SCOLAIRE: [ROLE_USER]
|
|
ROLE_SECRETARIAT: [ROLE_USER]
|
|
ROLE_PARENT: [ROLE_USER]
|
|
ROLE_ELEVE: [ROLE_USER]
|
|
|
|
# https://symfony.com/doc/current/security.html#registering-the-user-hashing-passwords
|
|
password_hashers:
|
|
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: 'auto'
|
|
# Named hasher for domain services (decoupled from User entity)
|
|
common:
|
|
algorithm: auto
|
|
|
|
# https://symfony.com/doc/current/security.html#loading-the-user-the-user-provider
|
|
providers:
|
|
# User provider for API authentication (Story 1.4)
|
|
app_user_provider:
|
|
id: App\Administration\Infrastructure\Security\DatabaseUserProvider
|
|
# Super Admin authentication — master database, not per-tenant (Story 2.10)
|
|
super_admin_provider:
|
|
id: App\SuperAdmin\Infrastructure\Security\SuperAdminUserProvider
|
|
# Chain provider: tries super admin first, then tenant user
|
|
all_users_provider:
|
|
chain:
|
|
providers: ['super_admin_provider', 'app_user_provider']
|
|
|
|
firewalls:
|
|
dev:
|
|
pattern: ^/(_(profiler|wdt)|css|images|js)/
|
|
security: false
|
|
# Monitoring endpoints - no authentication, restricted by IP in production
|
|
monitoring:
|
|
pattern: ^/(health|metrics)$
|
|
stateless: true
|
|
security: false
|
|
api_login:
|
|
pattern: ^/api/login$
|
|
stateless: true
|
|
json_login:
|
|
check_path: /api/login
|
|
username_path: email
|
|
password_path: password
|
|
success_handler: lexik_jwt_authentication.handler.authentication_success
|
|
failure_handler: App\Administration\Infrastructure\Security\LoginFailureHandler
|
|
provider: all_users_provider
|
|
super_admin_api:
|
|
pattern: ^/api/super-admin
|
|
stateless: true
|
|
jwt: ~
|
|
provider: super_admin_provider
|
|
api_public:
|
|
pattern: ^/api/(activation-tokens|activate|token/(refresh|logout)|password/(forgot|reset)|docs)(/|$)
|
|
stateless: true
|
|
security: false
|
|
api:
|
|
pattern: ^/api
|
|
stateless: true
|
|
jwt: ~
|
|
provider: all_users_provider
|
|
main:
|
|
lazy: true
|
|
provider: app_user_provider
|
|
|
|
# Easy way to control access for large sections of your site
|
|
# Note: Only the *first* access control that matches will be used
|
|
access_control:
|
|
- { path: ^/api/docs, roles: PUBLIC_ACCESS }
|
|
- { path: ^/api/super-admin, roles: ROLE_SUPER_ADMIN }
|
|
- { path: ^/api/login, roles: PUBLIC_ACCESS }
|
|
- { path: ^/api/activation-tokens, roles: PUBLIC_ACCESS }
|
|
- { path: ^/api/activate, roles: PUBLIC_ACCESS }
|
|
- { path: ^/api/token/refresh, roles: PUBLIC_ACCESS }
|
|
- { path: ^/api/token/logout, roles: PUBLIC_ACCESS }
|
|
- { path: ^/api/password/forgot, roles: PUBLIC_ACCESS }
|
|
- { path: ^/api/password/reset, roles: PUBLIC_ACCESS }
|
|
- { path: ^/api/import, roles: ROLE_ADMIN }
|
|
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
|
|
|
|
when@test:
|
|
security:
|
|
password_hashers:
|
|
Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface:
|
|
algorithm: auto
|
|
cost: 4 # Lowest possible value for bcrypt
|
|
time_cost: 3 # Lowest possible value for argon
|
|
memory_cost: 10 # Lowest possible value for argon
|