For now, the reconciliation requests are imported through CSV in the Django admin, which sends confirmation email to both addresses. When both are checked, the actual reconciliation is processed, and all user-related content is updated. ## Purpose Fix #1616 // Replaces #1708 For now, the reconciliation requests are imported through CSV in the Django admin, which sends confirmation email to both addresses. When both are checked, the actual reconciliation is processed, and all user-related content is updated. ## Proposal - [x] New `UserReconciliationCsvImport` model to manage the import of reconciliation requests through a task (`user_reconciliation_csv_import_job`) - [x] New `UserReconciliation` model to store the user reconciliation requests themselves (a row = a `active_user`/`inactive_user` pair) - [x] On save, a confirmation email is sent to the users - [x] A `process_reconciliation` admin action process the action on the requested entries, if both emails have been checked. - [x] Bulk update the `DocumentAccess` items, while managing the case where both users have access to the document (keeping the higher role) - [x] Bulk update the `LinkTrace` items, while managing the case where both users have link traces to the document - [x] Bulk update the `DocumentFavorite` items, while managing the case where both users have put the document in their favorites - [x] Bulk update the comment system items (`Thread`, `Comment` and `Reaction` items) - [x] Bulk update the `is_active` status on both users - [x] New `USER_RECONCILIATION_FORM_URL` env variable for the "make a new request" URL in an email. - [x] Write unit tests - [x] Remove the unused `email_user()` method on `User`, replaced with `send_email()` similar to the one on the `Document` model ## Demo page reconciliation success <img width="1149" height="746" alt="image" src="https://github.com/user-attachments/assets/09ba2b38-7af3-41fa-a64f-ce3c4fd8548d" /> --------- Co-authored-by: Anthony LC <anthony.le-courric@mail.numerique.gouv.fr>
93 lines
3.1 KiB
Plaintext
93 lines
3.1 KiB
Plaintext
# Django
|
|
DJANGO_ALLOWED_HOSTS=*
|
|
DJANGO_SECRET_KEY=ThisIsAnExampleKeyForDevPurposeOnly
|
|
DJANGO_SETTINGS_MODULE=impress.settings
|
|
DJANGO_SUPERUSER_PASSWORD=admin
|
|
|
|
# Logging
|
|
# Set to DEBUG level for dev only
|
|
LOGGING_LEVEL_HANDLERS_CONSOLE=INFO
|
|
LOGGING_LEVEL_LOGGERS_ROOT=INFO
|
|
LOGGING_LEVEL_LOGGERS_APP=INFO
|
|
|
|
# Python
|
|
PYTHONPATH=/app
|
|
|
|
# impress settings
|
|
|
|
# Mail
|
|
DJANGO_EMAIL_BRAND_NAME="La Suite Numérique"
|
|
DJANGO_EMAIL_HOST="mailcatcher"
|
|
DJANGO_EMAIL_LOGO_IMG="http://localhost:3000/assets/logo-suite-numerique.png"
|
|
DJANGO_EMAIL_PORT=1025
|
|
DJANGO_EMAIL_URL_APP="http://localhost:3000"
|
|
|
|
# Backend url
|
|
IMPRESS_BASE_URL="http://localhost:8072"
|
|
|
|
# Media
|
|
STORAGES_STATICFILES_BACKEND=django.contrib.staticfiles.storage.StaticFilesStorage
|
|
AWS_S3_ENDPOINT_URL=http://minio:9000
|
|
AWS_S3_ACCESS_KEY_ID=impress
|
|
AWS_S3_SECRET_ACCESS_KEY=password
|
|
MEDIA_BASE_URL=http://localhost:8083
|
|
|
|
# OIDC
|
|
OIDC_OP_JWKS_ENDPOINT=http://nginx:8083/realms/impress/protocol/openid-connect/certs
|
|
OIDC_OP_AUTHORIZATION_ENDPOINT=http://localhost:8083/realms/impress/protocol/openid-connect/auth
|
|
OIDC_OP_TOKEN_ENDPOINT=http://nginx:8083/realms/impress/protocol/openid-connect/token
|
|
OIDC_OP_USER_ENDPOINT=http://nginx:8083/realms/impress/protocol/openid-connect/userinfo
|
|
OIDC_OP_INTROSPECTION_ENDPOINT=http://nginx:8083/realms/impress/protocol/openid-connect/token/introspect
|
|
|
|
OIDC_RP_CLIENT_ID=impress
|
|
OIDC_RP_CLIENT_SECRET=ThisIsAnExampleKeyForDevPurposeOnly
|
|
OIDC_RP_SIGN_ALGO=RS256
|
|
OIDC_RP_SCOPES="openid email"
|
|
|
|
LOGIN_REDIRECT_URL=http://localhost:3000
|
|
LOGIN_REDIRECT_URL_FAILURE=http://localhost:3000
|
|
LOGOUT_REDIRECT_URL=http://localhost:3000
|
|
|
|
OIDC_REDIRECT_ALLOWED_HOSTS="localhost:8083,localhost:3000"
|
|
OIDC_AUTH_REQUEST_EXTRA_PARAMS={"acr_values": "eidas1"}
|
|
|
|
# Store OIDC tokens in the session. Needed by search/ endpoint.
|
|
# OIDC_STORE_ACCESS_TOKEN = True
|
|
# OIDC_STORE_REFRESH_TOKEN = True # Store the encrypted refresh token in the session.
|
|
|
|
# Must be a valid Fernet key (32 url-safe base64-encoded bytes)
|
|
# To create one, use the bin/fernetkey command.
|
|
# OIDC_STORE_REFRESH_TOKEN_KEY="your-32-byte-encryption-key=="
|
|
|
|
# User reconciliation
|
|
USER_RECONCILIATION_FORM_URL=http://localhost:3000
|
|
|
|
# AI
|
|
AI_FEATURE_ENABLED=true
|
|
AI_BASE_URL=https://openaiendpoint.com
|
|
AI_API_KEY=password
|
|
AI_MODEL=llama
|
|
|
|
# Collaboration
|
|
COLLABORATION_API_URL=http://y-provider-development:4444/collaboration/api/
|
|
COLLABORATION_BACKEND_BASE_URL=http://app-dev:8000
|
|
COLLABORATION_SERVER_ORIGIN=http://localhost:3000
|
|
COLLABORATION_SERVER_SECRET=my-secret
|
|
COLLABORATION_WS_NOT_CONNECTED_READY_ONLY=true
|
|
COLLABORATION_WS_URL=ws://localhost:4444/collaboration/ws/
|
|
|
|
DJANGO_SERVER_TO_SERVER_API_TOKENS=server-api-token
|
|
Y_PROVIDER_API_BASE_URL=http://y-provider-development:4444/api/
|
|
Y_PROVIDER_API_KEY=yprovider-api-key
|
|
|
|
DOCSPEC_API_URL=http://docspec:4000/conversion
|
|
|
|
# Theme customization
|
|
THEME_CUSTOMIZATION_CACHE_TIMEOUT=15
|
|
|
|
# Indexer (disabled)
|
|
# SEARCH_INDEXER_CLASS="core.services.search_indexers.SearchIndexer"
|
|
SEARCH_INDEXER_SECRET=find-api-key-for-docs-with-exactly-50-chars-length # Key generated by create_demo in Find app.
|
|
SEARCH_INDEXER_URL="http://find:8000/api/v1.0/documents/index/"
|
|
SEARCH_INDEXER_QUERY_URL="http://find:8000/api/v1.0/documents/search/"
|