Application Settings ==================== These settings control the behaviour of the application in addition to the default Django settings. Depending on whether you're running the dev or prod configuration, settings can be changed in the :code:`.dev.env` or :code:`.prod.env` file, respectively. This file is referred to as :code:`.env` below. .. contents:: List of Settings Axes Settings ------------- These settings control the behavior of Django Axes, which protects against brute-force login attempts. For full details, see the `Django Axes configuration documentation `_. AXES_FAILURE_LIMIT ^^^^^^^^^^^^^^^^^^ .. table:: ============ ========= Default Type ============ ========= 5 int ============ ========= Sets the maximum number of failed login attempts before a user is locked out. **.env Example:** :: #file: .env AXES_FAILURE_LIMIT=5 AXES_WARNING_THRESHOLD ^^^^^^^^^^^^^^^^^^^^^^ .. table:: ============ ========= Default Type ============ ========= 3 int ============ ========= Sets the number of failed login attempts after which a warning is shown to the user before lockout. Must be less than ``AXES_FAILURE_LIMIT``. **.env Example:** :: #file: .env AXES_WARNING_THRESHOLD=3 AXES_COOLOFF_TIME ^^^^^^^^^^^^^^^^^^ .. table:: ============ ========= Default Type ============ ========= 0.5 float ============ ========= Sets the lockout period (in hours) after the failure limit is reached. For example, 0.5 is 30 minutes. **.env Example:** :: #file: .env AXES_COOLOFF_TIME=0.5 Other Axes-related settings are also available in ``app/app/settings/base.py`` for advanced configuration. Security -------- SECRET_KEY ^^^^^^^^^^ *Django's secret key for cryptographic signing* .. table:: ======================= ========= Default Type ======================= ========= Development key only string ======================= ========= The SECRET_KEY is a critical security setting used by Django for cryptographic signing, including: - Session security and CSRF protection - Password reset tokens and user authentication - Secure cookies and form validation - Digital signatures for sensitive data In development, a default key is provided for convenience, but **you must set a strong, unique SECRET_KEY for production deployments**. The application will fail to start in production without this setting. **.env Example:** :: # file: .prod.env SECRET_KEY=your-very-long-random-secret-key-with-letters-numbers-and-symbols **Generating a Strong Secret Key:** You can generate a secure SECRET_KEY using Python: :: python -c "import secrets; print(secrets.token_urlsafe(50))" RECAPTCHA_PUBLIC_KEY ^^^^^^^^^^^^^^^^^^^^ *Google reCAPTCHA v2 public site key for user verification* .. table:: ======================= ========= Default Type ======================= ========= None (required in prod) string ======================= ========= The public site key for Google reCAPTCHA v2 integration. This key is visible to users and used to display the reCAPTCHA widget on forms. **Required in production environments** - The application will fail to start if this is not set when deployed. **Optional in development** - reCAPTCHA is disabled for local testing and development. **.env Example:** :: # file: .prod.env RECAPTCHA_PUBLIC_KEY=6LcXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX **Getting reCAPTCHA Keys:** Sign up for reCAPTCHA keys at: https://www.google.com/recaptcha/intro/index.html RECAPTCHA_PRIVATE_KEY ^^^^^^^^^^^^^^^^^^^^^ *Google reCAPTCHA v2 private secret key for server-side verification* .. table:: ======================= ========= Default Type ======================= ========= None (required in prod) string ======================= ========= The private secret key for Google reCAPTCHA v2 integration. This key is used server-side to verify user responses and should be kept confidential. **Required in production environments** - The application will fail to start if this is not set when deployed. **Optional in development** - reCAPTCHA is disabled for local testing and development. **.env Example:** :: # file: .prod.env RECAPTCHA_PRIVATE_KEY=6LcXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX .. warning:: Keep your private key secure and never commit it to version control or expose it in client-side code. Application Features -------------------- SIGN_UP_ENABLED ^^^^^^^^^^^^^^^ *Choose whether new users can sign up* .. table:: ============ ========= Default Type ============ ========= True bool ============ ========= You may want to create users manually to tightly control who has access to the application. In this case, you will want to disable signing up so that no new users can be created without an admin creating them. **.env Example:** :: #file: .env SIGN_UP_ENABLED=false FILE_UPLOAD_ENABLED ^^^^^^^^^^^^^^^^^^^ *Choose whether to allow file uploads* .. table:: ============ ========= Default Type ============ ========= True bool ============ ========= Sets whether file uploads are allowed. If they are *not* allowed (disabled), then only metadata is submitted to the application. **.env Example:** :: #file: .env FILE_UPLOAD_ENABLED=false USE_DATE_WIDGETS ^^^^^^^^^^^^^^^^ *Use JavaScript date widgets* .. table:: ============ ========= Default Type ============ ========= True bool ============ ========= If set to True, a date picker widget is used for date fields. If set to False, input text fields with an input mask are used instead. **.env Example:** :: #file: .env USE_DATE_WIDGETS=false Services -------- These settings control connections to services external to the Django application. This include: - `ClamAV `_ for virus checking - `MySQL `_ Database - `Redis `_ task broker CLAMAV_ENABLED ^^^^^^^^^^^^^^ *Whether ClamAV malware checking is enabled* .. table:: =============== ========= Default Type =============== ========= True bool =============== ========= Enables/disables whether ClamAV malware checking is enabled. If the :ref:`FILE_UPLOAD_ENABLED` setting is disabled, this option has no effect. **.env Example:** :: #file: .env CLAMAV_ENABLED=True CLAMAV_HOST ^^^^^^^^^^^ *The name of the host ClamAV is running on* .. table:: =============== ========= Default Type =============== ========= clamav string =============== ========= Chooses the host where ClamAV is running. If :ref:`CLAMAV_ENABLED` is FALSE, this setting does not have any effect. **.env Example:** :: #file: .env CLAMAV_HOST=clamav CLAMAV_PORT ^^^^^^^^^^^ *The port ClamAV is running on* .. table:: =============== ========= Default Type =============== ========= 3310 int =============== ========= Chooses the port where ClamAV is accessible on the :ref:`CLAMAV_HOST`. If :ref:`CLAMAV_ENABLED` is FALSE, this setting does not have any effect. **.env Example:** :: #file: .env CLAMAV_PORT=3310 REDIS_HOST ^^^^^^^^^^ *The name of the host Redis is running on* .. table:: =============== ========= Default Type =============== ========= redis string =============== ========= Chooses the host where Redis is running. Redis is used in tandem with RQ to store ephemeral info about asynchronous jobs. **.env Example:** :: #file: .env REDIS_HOST=my-redis REDIS_PORT ^^^^^^^^^^ *The port Redis is running on* .. table:: =============== ========= Default Type =============== ========= 6379 int =============== ========= Chooses the port where Redis is accessible on the :ref:`REDIS_HOST`. **.env Example:** :: #file: .env REDIS_PORT=6379 REDIS_PASSWORD ^^^^^^^^^^^^^^ *The password required to connect to Redis* .. table:: =============== ========= Default Type =============== ========= "" string =============== ========= By default, Redis **does not require a password**. If you would prefer to set one up, you can, and then use this setting to control the password. The default empty value is fine if you are using the application's default Redis configuration. **.env Example:** :: #file: .env REDIS_PASSWORD=a-strong-password-here Cache Controls -------------- Redis is used for both the async task queue and caching certain pages that can be cached. The cache ``max-age`` and key prefix can be controlled via settings in the environment variables. CACHE_MIDDLEWARE_SECONDS ^^^^^^^^^^^^^^^^^^^^^^^^ *Sets the number of seconds pages are cached for.* .. table:: =============== ========= Default Type =============== ========= 86400 int =============== ========= This setting does not have any effect on the dev container, it is only used in the production configuration. Changing this variable changes `the CACHE_MIDDLEWARE_SECONDS Django setting `_. By default, pages are cached for a day. **.env Example:** :: #file: .env CACHE_MIDDLEWARE_SECONDS=3600 CACHE_MIDDLEWARE_KEY_PREFIX ^^^^^^^^^^^^^^^^^^^^^^^^^^^ *Cache prefix for this instance of the application.* .. table:: =============== ========= Default Type =============== ========= 86400 int =============== ========= You can ignore this setting if you do not have multiple instances of the application each sharing a cache. Changing this variable changes `the CACHE_MIDDLEWARE_KEY_PREFIX Django setting `_. You should use a different prefix for each instance of the application so that there are no cache collisions across different instances of the application. **.env Example:** :: #file: .env CACHE_MIDDLEWARE_KEY_PREFIX=secure-record-transfer-05 File Upload Controls -------------------- These settings have no effect if :ref:`FILE_UPLOAD_ENABLED` is False. ACCEPTED_FILE_FORMATS ^^^^^^^^^^^^^^^^^^^^^ *Choose what files (by extension) can be uploaded* .. table:: =============== ======================= Default Type =============== ======================= See below string (special syntax) =============== ======================= Accepted files are grouped by type of file. The default accepted file extensions are: - Audio - mp3 - wav - flac - Document - docx - odt - pdf - txt - Image - jpg - jpeg - png - gif - Spreadsheet - xlsx - csv - Video - mkv - mp4 This setting has a special structured syntax, that looks like: :: File Group Name:ext,ext,ext|Other Group Name:ext,ext File extensions are grouped by name. File groups are split by the pipe | character, and file extensions are split by comma. The file extensions are used to determine what a user is allowed to upload. The group name is used to create a human-readable extent statement about the quantity and type of files the user uploaded. If the :ref:`FILE_UPLOAD_ENABLED` setting is disabled, this option has no effect. .. warning:: **Security Warning: Compressed File Formats** Including compressed file formats in your accepted file formats may pose security risks. The application does not currently analyze the contents of compressed files, which means malicious files could be uploaded within compressed archives without detection. For a full list of compressed file extensions that are detected by the application, please refer to :class:`~recordtransfer.constants.FileExtensions.COMPRESSED` in the constants module. Consider carefully whether you need to accept compressed file formats, and if possible, restrict uploads to uncompressed file types only. .. warning:: **Security Warning: HTML Files** Including HTML files in your accepted file formats may expose you to cross-site scripting attacks. Note that HTML files *are* sanitized for script tags when uploaded. Use your discretion when deciding to enable HTML uploads. Here are some examples based on what you might want to accept (note that you can only specify the ACCEPTED_FILE_FORMATS variable *once*): :: #file: .env # Only PDFs ACCEPTED_FILE_FORMATS="PDF:pdf" # Audio or Video ACCEPTED_FILE_FORMATS="Audio:mp3,wav|Video:mkv,mp4" # Excel spreadsheets ACCEPTED_FILE_FORMATS="Excel Workbook:xlsx|Excel Macro Workbook:xlsm|Excel 1997-2003 Workbook:xls" # Images and documents ACCEPTED_FILE_FORMATS="Document:pdf,docx,txt|Image:jpeg,jpg,png,gif,tif,tiff" MAX_SINGLE_UPLOAD_SIZE_MB ^^^^^^^^^^^^^^^^^^^^^^^^^ *Choose the maximum size (in MB) an uploaded file is allowed to be* .. table:: ============ ========= Default Type ============ ========= 64 int ============ ========= Sets the maximum allowed size a single file can be when uploaded with the submission form. The size is expressed in **MB**, *not* MiB. If the :ref:`FILE_UPLOAD_ENABLED` setting is disabled, this option has no effect. **.env Example:** :: #file: .env MAX_SINGLE_UPLOAD_SIZE_MB=512 MAX_TOTAL_UPLOAD_SIZE_MB ^^^^^^^^^^^^^^^^^^^^^^^^ *Choose the maximum total size (in MB) of a file transfer* .. table:: ============ ========= Default Type ============ ========= 256 int ============ ========= Sets the maximum allowed total size of all files being transferred at one time. The size is expressed in **MB**, *not* MiB. If the :ref:`FILE_UPLOAD_ENABLED` setting is disabled, this option has no effect. **.env Example:** :: #file: .env MAX_TOTAL_UPLOAD_SIZE_MB=1024 MAX_TOTAL_UPLOAD_COUNT ^^^^^^^^^^^^^^^^^^^^^^ *Choose the maximum number of files can be transferred* .. table:: ============ ========= Default Type ============ ========= 40 int ============ ========= Sets the maximum number of files that can be transferred at one time with the submission form. If the :ref:`FILE_UPLOAD_ENABLED` setting is disabled, this option has no effect. **.env Example:** :: #file: .env MAX_TOTAL_UPLOAD_COUNT=10 Upload Session Controls ----------------------- These settings have no effect if :ref:`FILE_UPLOAD_ENABLED` is False. UPLOAD_SESSION_MAX_CONCURRENT_OPEN ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ *Number of upload sessions a user is allowed to have open at one time* .. table:: ============ ========= Default Type ============ ========= 8 int ============ ========= Sets the maximum number of upload sessions a user is allowed to have open at one time. If a user wants to start a new submission but already has too many upload sessions open, they are re-directed to a page that says why they are not allowed to make another session. This feature can be deactivated by setting the value to -1. **.env Example:** :: #file: .env UPLOAD_SESSION_MAX_CONCURRENT_OPEN=1440 UPLOAD_SESSION_EXPIRE_AFTER_INACTIVE_MINUTES ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ *Number of minutes of inactivity after which an upload session expires* .. table:: ============ ========= Default Type ============ ========= 1440 int ============ ========= Sets the number of minutes of inactivity after which an upload session expires. Defaults to 1440 minutes (24 hours). This feature can be deactivated by setting the value to -1. **.env Example:** :: #file: .env UPLOAD_SESSION_EXPIRE_AFTER_INACTIVE_MINUTES=1440 UPLOAD_SESSION_EXPIRING_REMINDER_MINUTES ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ *Number of minutes before upload session expiration when a reminder should be sent* .. table:: ============ ========= Default Type ============ ========= 480 int ============ ========= Sets the number of minutes before upload session expiration when a reminder should be sent. Defaults to 480 minutes (8 hours). This feature can be deactivated by setting the value to -1. If :ref:`UPLOAD_SESSION_EXPIRE_AFTER_INACTIVE_MINUTES` is set to -1, this feature will be deactivated. **.env Example:** :: #file: .env UPLOAD_SESSION_EXPIRING_REMINDER_MINUTES=480 UPLOAD_SESSION_EXPIRED_CLEANUP_SCHEDULE ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ *Cron schedule expression for cleaning up expired upload sessions* .. table:: ============== ========= Default Type ============== ========= "0 2 \* \* \*" string ============== ========= Sets the cron schedule expression for cleaning up expired upload sessions. Defaults to "0 2 \* \* \*" (runs at 2 AM daily). See the `crontab manual page `_ for a guide on the syntax. This feature can be deactivated by setting the value to an empty string (""). If :ref:`UPLOAD_SESSION_EXPIRE_AFTER_INACTIVE_MINUTES` is set to -1, this feature will be deactivated. **.env Example:** :: #file: .env UPLOAD_SESSION_EXPIRED_CLEANUP_SCHEDULE="0 2 * * *" In-Progress Submission Controls ------------------------------- IN_PROGRESS_SUBMISSION_EXPIRING_EMAIL_SCHEDULE ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ *Cron schedule expression for sending reminder emails for in-progress submissions with expiring upload sessions* .. table:: =============== ========= Default Type =============== ========= "0 \* \* \* \*" string =============== ========= Sets the cron schedule expression for sending reminder emails for in-progress submissions with expiring upload sessions. Defaults to "0 \* \* \* \*" (runs every hour at minute zero). See the `crontab manual page `_ for a guide on the syntax. This feature can be deactivated by setting the value to an empty string (""). If :ref:`UPLOAD_SESSION_EXPIRE_AFTER_INACTIVE_MINUTES` is set to -1, this feature will be deactivated. **.env Example:** :: #file: .env IN_PROGRESS_SUBMISSION_EXPIRING_EMAIL_SCHEDULE="0 * * * *" Storage Locations ----------------- Files in this application are stored in two different places depending on the state of the submission. This chart follows the journey of the places a file is stored at while it's being uploaded: .. mermaid:: :caption: File upload flow flowchart TD A[User's Host] -. upload via HTTPS .-> B[TEMP_STORAGE_FOLDER] B -. session expires .-> C[Delete Files] B -. submit form .-> D[UPLOAD_STORAGE_FOLDER] TEMP_STORAGE_FOLDER ^^^^^^^^^^^^^^^^^^^ *Choose storage location for files to initially be uploaded to* .. table:: =========================================== =========================================== ====== Default in Dev Default in Prod Type =========================================== =========================================== ====== /opt/secure-record-transfer/app/media/temp/ /opt/secure-record-transfer/app/media/temp/ string =========================================== =========================================== ====== While files are being uploaded, but before a submission is made, files are uploaded to the temp storage folder. This is a temporary space where files are uploaded before they are moved to permanent storage, i.e., the :ref:`UPLOAD_STORAGE_FOLDER`. Files in this space are subject to upload session expiry, so files in this location may be deleted if a user uploads files and doesn't submit the form. See: :ref:`Upload Session Controls`. This directory **must** be a sub-directory of the media directory so that NGINX can find these files. **.env Example:** :: #file: .env UPLOAD_STORAGE_FOLDER=/path/to/upload/folder UPLOAD_STORAGE_FOLDER ^^^^^^^^^^^^^^^^^^^^^ *Choose storage location for "permanent" uploaded files* .. table:: ====================================================== ====================================================== ====== Default in Dev Default in Prod Type ====================================================== ====================================================== ====== /opt/secure-record-transfer/app/media/uploaded_files/ /opt/secure-record-transfer/app/media/uploaded_files/ string ====================================================== ====================================================== ====== After a submission is made, files from the :ref:`TEMP_STORAGE_FOLDER` are moved to this location. This location is therefore where all the 'permanent' uploaded files are stored. Unlike the temporary storage folder, files in this space are **not** subject to deletion, unless an UploadSession is deleted from the admin site. The word permanent is sometimes "quoted" because there are no controls that guarantee a file is unchanged in this directory. **.env Example:** :: #file: .env UPLOAD_STORAGE_FOLDER=/path/to/upload/folder Checksums --------- BAG_CHECKSUMS ^^^^^^^^^^^^^ *Choose the checksum algorithms used to create BagIt manifests* .. table:: ======= ======================== Default Type ======= ======================== sha512 string (comma-separated) ======= ======================== When BagIt is run, the selected algorithm(s) are used to generate manifests for the files as well as the tag files in the Bag. Multiple algorithms can be used, separated by commas. Avoid setting these algorithms directly in :code:`settings.py`, as there is some pre-processing of the selected algorithms needed to make sure they're formatted correctly. **.env Example:** :: #file: .env BAG_CHECKSUMS=sha1,blake2b,md5 Data Formatting and Defaults ---------------------------- The following variables control how metadata is formatted, as well as defines default values to use when generating CAAIS metadata a value is not specified in the form. By leaving default values empty, they are not used. APPROXIMATE_DATE_FORMAT ^^^^^^^^^^^^^^^^^^^^^^^ *Choose estimated date format* .. table:: ====================== ========= Default Type ====================== ========= :code:`'[ca. {date}]'` string ====================== ========= A format string for the date to indicate an approximate date. The string variable :code:`{date}` must be present for the date format to be used. **.env Example:** :: #file: .env APPROXIMATE_DATE_FORMAT='Circa. {date}' CAAIS_UNKNOWN_DATE_TEXT ^^^^^^^^^^^^^^^^^^^^^^^ *Change the "Unknown date" text* .. table:: ====================== ========= Default Type ====================== ========= Unknown date string ====================== ========= A string to use in the CAAIS metadata when a user indicates that a date is not known. **.env Example:** :: #file: .env CAAIS_UNKNOWN_DATE_TEXT='Not known' CAAIS_UNKNOWN_START_DATE ^^^^^^^^^^^^^^^^^^^^^^^^ *Change the unknown start date* .. table:: ====================== ========= Default Type ====================== ========= 1800-01-01 string ====================== ========= A yyyy-mm-dd formatted date that is used for the start of a date range when an unknown date is encountered when parsing a date for CAAIS. **.env Example:** :: #file: .env CAAIS_UNKNOWN_START_DATE='1900-01-01' CAAIS_UNKNOWN_END_DATE ^^^^^^^^^^^^^^^^^^^^^^ *Change the unknown end date* .. table:: ====================== ========= Default Type ====================== ========= 2010-01-01 string ====================== ========= A yyyy-mm-dd formatted date that is used for the end of a date range when an unknown date is encountered when parsing a date for CAAIS. **.env Example:** :: #file: .env CAAIS_UNKNOWN_END_DATE='1999-12-31' CAAIS_DEFAULT_UPDATE_TYPE ^^^^^^^^^^^^^^^^^^^^^^^^^ *Default creation or revision type for metadata updates* .. table:: ======= ========= Default Type ======= ========= Update string ======= ========= When metadata records are updated through the Django admin interface, a DateOfCreationOrRevision entry is automatically created to track changes. This setting controls the name of the creation/revision type used for these updates. **.env Example:** :: #file: .env CAAIS_DEFAULT_UPDATE_TYPE='Record Updated' Testing ------- SELENIUM_TESTS_HEADLESS_MODE ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ *Controls whether Selenium tests run in headless mode* .. table:: ======= ========= Default Type ======= ========= False boolean ======= ========= When set to ``True``, Selenium tests will run in headless mode (without a visible browser window). This is useful for CI/CD environments or when running tests in the background. When ``False``, browser windows will be visible during test execution. :: # file .env SELENIUM_TESTS_HEADLESS_MODE=True