Configuration reference

Application configuration

When setting up application without a docker a .env file needs to be created in the root directory of the application. The .env.dist is a template with example, reference values. If you use a docker image, then you may use those variables as environment variables for the container.

# This file is a "template" of which env vars need to be defined for your application
# Copy this file to .env file for development, create environment variables when deploying to production
# https://symfony.com/doc/current/best_practices/configuration.html#infrastructure-related-configuration

# ========================================
# Symfony framework specific configuration
# ========================================

# possible values: prod, test, dev. Use "prod" for public instances. Use "test" installing the application and changing its configuration
APP_ENV=prod
#APP_SECRET=faec5e5fcf0ff499f53ecc30bdffc653
#TRUSTED_PROXIES=127.0.0.1,127.0.0.2
#TRUSTED_HOSTS=localhost,example.com


# =========
# Technical
# =========

# application domain (if empty, then it will be taken from Host header. If Host header is invalid, then fill this variable)
#APP_DOMAIN=

# how long can take request if it is expected, that it will take long (eg. file upload)
# please consider there if you have request buffering enabled in webserver, nginx has this by default
#LONG_EXECUTION_TIME=300
#TEMP_DIRECTORY=/tmp
#HTTP_TIMEOUT=30
#READ_ONLY=false

# Health check, will expose an endpoint http://your-app/health?code=some-code-there
# use it to connect your application into the monitoring. It will report storage, database health.
#HEALTH_CHECK_CODE=


# ==============
# Token settings
# ==============

# default expiration time for generated tokens
#TOKEN_EXPIRATION_TIME="+30 minutes"
# used for tokens encryption (tokens can be generated by external applications)
#ENC_TOKEN_PHRASE=test123


# ==============================
# Application connection details
# ==============================

# SQLite3 example
#DATABASE_PATH=./var/data.db
#DATABASE_DRIVER=pdo_sqlite

# MySQL example
#DATABASE_HOST=db_mysql
#DATABASE_USER=riotkit
#DATABASE_PASSWORD=riotkit
#DATABASE_NAME=file_repository
#DATABASE_VERSION=5.7
#DATABASE_DRIVER=pdo_mysql
#DATABASE_PORT=3306

# PostgreSQL example
#DATABASE_USER=riotkit
#DATABASE_PASSWORD=riotkit
#DATABASE_NAME=file_repository
#DATABASE_DRIVER=pdo_pgsql
#DATABASE_HOST=/var/run/postgresql
#DATABASE_HOST=192.168.1.161
#DATABASE_PORT=5432


# ===============
# Backups feature
# ===============

#BACKUP_ONE_VERSION_MAX_SIZE=4GB
#BACKUP_COLLECTION_MAX_SIZE=15GB
#BACKUP_MAX_VERSIONS=5

# ==========================================================================================
# Anti-Hotlink protection
# (NOTICE: Requires application to be restarted or ./bin/console cache:clear to be executed)
# ==========================================================================================

#ANTI_HOTLINK_PROTECTION_ENABLED=true
#ANTI_HOTLINK_RESTRICT_REGULAR_URLS=false
#ANTI_HOTLINK_URL=/stream/{accessToken}/{expirationTime}/{fileId}
#ANTI_HOTLINK_CRYPTO=md5
#ANTI_HOTLINK_SECRET_METHOD="\$http_x_expiration_time\$filename\$http_remote_addr MY-AWESOME-SUFFIX"


# =======
# Storage
# =======

#
#  Storage type
#
#    local: local filesystem
#    awss3: AWS S3, Minio.io or other compatible with AWS S3 interface
#    ftp: FTP/FTPS
#
#FS_ADAPTER=local

#
# === Local filesystem ===
#

# path, where for local filesystem the files should be stored. %kernel.root_dir% is the application main directory
#FS_LOCAL_DIRECTORY="%kernel.root_dir%/../var/uploads"

# (?) see: http://flysystem.thephpleague.com/docs/adapter/local/
#FS_LOCAL_LAZY=0

# file locking; 1 - LOCK_SH, 2 - LOCK_EX, 3 - LOCK_UN, 4 - LOCK_NB
#FS_LOCAL_WRITEFLAGS=

# how to handle symbolic links: 1 - skip links, 2 - disallow links
#FS_LOCAL_LINKHANDLING=

# permissions chmod eg. 0755
#FS_LOCAL_PERMISSIONS=

#
# === S3 ===
#

# set to enable S3 interface as adapter (supports Minio, and possibly Amazon AWS S3)
#FS_ADAPTER=awss3v3
# (advanced) Symfony service name of an S3 Client
#FS_AWSS3V3_CLIENT=s3_client
#FS_AWSS3V3_BUCKET=misc
#FS_AWSS3V3_PREFIX=
#FS_AWSS3V3_OPTIONS_ENDPOINT=http://localhost:9000
#FS_AWSS3V3_VERSION=latest
#FS_AWSS3V3_REGION=eu-central-1
#FS_AWSS3V3_KEY=some-key
#FS_AWSS3V3_SECRET=some-secret

#
# === FTP ===
#

# there you can enable FTP adapter
#FS_ADAPTER=ftp

# FTP host where to connect to, IP address or hostname
#FS_FTP_HOST=localhost

# FTP port to connect to
#FS_FTP_PORT=21

# FTP authorization: username
#FS_FTP_USERNAME=user

# FTP authorization: user's password
#FS_FTP_PASSWORD=password

# FTP directory where files will be stored in
#FS_FTP_ROOT=/

# Use SSL? (FTPS instead of FTP)
#FS_FTP_SSL=1

# Timeout
#FS_FTP_TIMEOUT=120

# Permissions for owner eg. 0755
#FS_FTP_PERMPRIVATE=

# Permissions for public (others) eg. 0400
#FS_FTP_PERMPUBLIC=

# Passive mode?
#FS_FTP_PASSIVE=0

Permissions list

You can get a permissions list by accessing an endpoint in your application:

GET /auth/roles?_token=test-token-full-permissions

There is also an always up-to-date permissions list, taken directly from the current version of the application for which the documentation you are browsing.

How to read the list by example:

/** Allows to upload images */
public const ROLE_UPLOAD_IMAGES            = 'upload.images';

Legend:

  • Between /** and */ is the description
  • upload.images is the role name that you need to know
<?php declare(strict_types=1);

namespace App\Domain;

/**
 * List of roles which could be required for a temporary token
 *
 *   There are 2 types of roles:
 *       - GRANT
 *       - RESTRICTION
 *
 *   They are distinguished because, we want to GRANT all rights to administrator for example, excluding RESTRICTION
 *   roles.
 *
 * @codeCoverageIgnore
 */
final class Roles
{
    public const TEST_TOKEN = 'test-token-full-permissions';

    //
    //
    // upload/creation
    //
    //

    /** Allows to upload images */
    public const ROLE_UPLOAD_IMAGES            = 'upload.images';

    /** Allows to upload video files */
    public const ROLE_UPLOAD_VIDEOS            = 'upload.videos';

    /** Allows to upload documents */
    public const ROLE_UPLOAD_DOCS              = 'upload.documents';

    /** Allows to submit backups */
    public const ROLE_UPLOAD_BACKUP            = 'upload.backup';

    /** Allows to upload ALL types of files regardless of mime type */
    public const ROLE_UPLOAD                   = 'upload.all';

    /** Enforce no password for all uploads for this token */
    public const ROLE_UPLOAD_ENFORCE_NO_PASSWORD = 'upload.enforce_no_password';

    /** Enforce token tags. In result every uploaded file will have tags specified in token regardless if they were sent in request */
    public const ROLE_UPLOAD_ENFORCE_TOKEN_TAGS = 'upload.enforce_tags_selected_in_token';

    public const ROLE_UPLOAD_ONLY_ONCE_SUCCESSFUL = 'upload.only_once_successful';

    //
    //
    // authentication and tokens
    //
    //

    /** User can check information about ANY token */
    public const ROLE_LOOKUP_TOKENS                = 'security.authentication_lookup';

    /** User can overwrite files */
    public const ROLE_ALLOW_OVERWRITE_FILES        = 'security.overwrite';

    /** User can generate tokens with ANY roles */
    public const ROLE_GENERATE_TOKENS              = 'security.generate_tokens';

    /** User can use technical endpoints to manage the application */
    public const ROLE_USE_TECHNICAL_ENDPOINTS      = 'security.use_technical_endpoints';

    /** User can expire other token, so it will be not valid anymore */
    public const ROLE_REVOKE_TOKENS                = 'security.revoke_tokens';

    /** Special: Marking - tokens with this marking will not be able to be revoked by non-administrators */
    public const ROLE_ADMINISTRATOR                = 'security.administrator';

    /** Allow to specify token id when creating a token */
    public const ROLE_CREATE_PREDICTABLE_TOKEN_IDS = 'security.create_predictable_token_ids';

    //
    //
    // deletion
    //
    //

    /** Delete files that do not have a password, and password protected without a password */
    public const ROLE_DELETE_ALL_FILES        = 'deletion.all_files_including_protected_and_unprotected';

    //
    //
    // browsing
    //
    //

    /** Allows to download ANY file, even if a file is password protected*/
    public const ROLE_VIEW_ALL_PROTECTED_FILES = 'view.any_file';

    /** List files from ANY tag that was requested, else the user can list only files by tags allowed in token */
    public const ROLE_BROWSE_LIST_OF_FILES_BY_ANY_TAG = 'view.files_from_all_tags';

    /** Define that the user can use the listing endpoint (basic usage) */
    public const ROLE_ACCESS_LISTING_ENDPOINT = 'view.can_use_listing_endpoint_at_all';

    //
    //
    // collections
    //
    //

    /** Allow person creating a new backup collection */
    public const ROLE_COLLECTION_ADD = 'collections.create_new';

    /** Allow to assign a specific id, when creating a collection */
    public const ROLE_COLLECTION_CUSTOM_ID = 'collections.create_new.with_custom_id';

    /** Allow creating backup collections that have no limits on size and length */
    public const ROLE_COLLECTION_ADD_WITH_INFINITE_LIMITS = 'collections.allow_infinite_limits';

    /** Edit collections where token is added as allowed */
    public const ROLE_MODIFY_ALLOWED_COLLECTIONS = 'collections.modify_details_of_allowed_collections';

    /** Allow to modify ALL collections. Collection don't have to allow such token which has this role */
    public const ROLE_COLLECTION_MODIFY_ANY_COLLECTION = 'collections.modify_any_collection_regardless_if_token_was_allowed_by_collection';

    /** Allow to browse any collection regardless of if the user token was allowed by it or not */
    public const ROLE_COLLECTION_VIEW_ANY_COLLECTION = 'collections.view_all_collections';

    /** Can use an endpoint that will allow to browse and search collections? */
    public const ROLE_CAN_USE_LISTING_COLLECTION_ENDPOINT = 'collections.can_use_listing_endpoint';

    /** Manage tokens in the collections where our current token is already added as allowed */
    public const ROLE_CAN_MANAGE_TOKENS_IN_ALLOWED_COLLECTIONS = 'collections.manage_tokens_in_allowed_collections';

    /** Delete collections where token is added as allowed */
    public const ROLE_CAN_DELETE_ALLOWED_COLLECTIONS = 'collections.delete_allowed_collections';

    /** Upload to allowed collections */
    public const ROLE_CAN_UPLOAD_TO_ALLOWED_COLLECTIONS = 'collections.upload_to_allowed_collections';

    /** List versions for collections where the token was added as allowed */
    public const ROLE_LIST_VERSIONS_FOR_ALLOWED_COLLECTIONS = 'collections.list_versions_for_allowed_collections';

    /** Delete versions only from collections where the token was added as allowed */
    public const ROLE_DELETE_VERSIONS_IN_ALLOWED_COLLECTIONS = 'collections.delete_versions_for_allowed_collections';

    /** Collection manager: Create, edit, delete collections */
    public const GROUP_COLLECTION_MANAGER = [
        self::ROLE_COLLECTION_ADD,
        self::ROLE_COLLECTION_ADD_WITH_INFINITE_LIMITS,
        self::ROLE_COLLECTION_MODIFY_ANY_COLLECTION,
        self::ROLE_COLLECTION_VIEW_ANY_COLLECTION,
        self::ROLE_CAN_USE_LISTING_COLLECTION_ENDPOINT,
        self::ROLE_CAN_MANAGE_TOKENS_IN_ALLOWED_COLLECTIONS,
        self::ROLE_MODIFY_ALLOWED_COLLECTIONS,
        self::ROLE_CAN_UPLOAD_TO_ALLOWED_COLLECTIONS,
        self::ROLE_LIST_VERSIONS_FOR_ALLOWED_COLLECTIONS,
        self::ROLE_DELETE_VERSIONS_IN_ALLOWED_COLLECTIONS
    ];

    public const GRANTS_LIST = [
        self::ROLE_UPLOAD_IMAGES,
        self::ROLE_UPLOAD_DOCS,
        self::ROLE_UPLOAD_BACKUP,
        self::ROLE_UPLOAD,
        self::ROLE_LOOKUP_TOKENS,
        self::ROLE_ALLOW_OVERWRITE_FILES,
        self::ROLE_GENERATE_TOKENS,
        self::ROLE_USE_TECHNICAL_ENDPOINTS,
        self::ROLE_DELETE_ALL_FILES,
        self::ROLE_VIEW_ALL_PROTECTED_FILES,
        self::ROLE_BROWSE_LIST_OF_FILES_BY_ANY_TAG,
        self::ROLE_ACCESS_LISTING_ENDPOINT,
        self::ROLE_REVOKE_TOKENS,
        self::ROLE_ADMINISTRATOR,

        self::ROLE_COLLECTION_ADD,
        self::ROLE_COLLECTION_CUSTOM_ID,
        self::ROLE_COLLECTION_ADD_WITH_INFINITE_LIMITS,
        self::ROLE_CAN_DELETE_ALLOWED_COLLECTIONS,
        self::ROLE_COLLECTION_MODIFY_ANY_COLLECTION,
        self::ROLE_MODIFY_ALLOWED_COLLECTIONS,
        self::ROLE_COLLECTION_VIEW_ANY_COLLECTION,
        self::ROLE_CAN_USE_LISTING_COLLECTION_ENDPOINT,
        self::ROLE_CAN_MANAGE_TOKENS_IN_ALLOWED_COLLECTIONS,
        self::ROLE_CAN_UPLOAD_TO_ALLOWED_COLLECTIONS,
        self::ROLE_LIST_VERSIONS_FOR_ALLOWED_COLLECTIONS,
        self::ROLE_DELETE_VERSIONS_IN_ALLOWED_COLLECTIONS
    ];

    public const RESTRICTIONS_LIST = [
        self::ROLE_UPLOAD_ENFORCE_NO_PASSWORD,
        self::ROLE_UPLOAD_ENFORCE_TOKEN_TAGS,
        self::ROLE_UPLOAD_ONLY_ONCE_SUCCESSFUL
    ];

    public static function getRolesList(): array
    {
        return \array_merge(self::GRANTS_LIST, self::RESTRICTIONS_LIST);
    }

    /**
     * The test token is available only in APP_ENV=test
     *
     * @param string|null $tokenId
     * @return bool
     */
    public static function isTestToken(?string $tokenId): bool
    {
        return $tokenId === static::TEST_TOKEN;
    }
}

Docker container extra parameters

Parameters passed to docker container are mostly application configuration parameters, but not only. There exists extra parameters that are implemented by the docker container itself, they are listed below:

   
Name and example Description
WAIT_FOR_HOST=db_mysql:3306 (optional) Waits up to 2 minutes for host to be up when starting a container
SENTRY_DSN=url-here (optional) Enables integration with sentry.io, so all failures will be logged there
SECURITY_ADMIN_TOKEN=… (optional) Create admin auth token of given UUIDv4 on container startup

PostgreSQL support

  1. Required extensions to enable in PostgreSQL:
  • uuid-ossp (CREATE EXTENSION “uuid-ossp”;)
  1. Configuration example:

UNIX Socket example:

DATABASE_URL: ""
DATABASE_HOST: "/var/run/postgresql"
DATABASE_NAME: "rojava"
DATABASE_PASSWORD: "rojava"
DATABASE_USER: "riotkit"
DATABASE_DRIVER=pdo_pgsql

DATABASE_CHARSET=UTF8
DATABASE_COLLATE=pl_PL.UTF8
DATABASE_VERSION=10.10

IPv4 example:

DATABASE_URL: ""
DATABASE_HOST: "192.168.2.161"
DATABASE_NAME: "rojava"
DATABASE_PASSWORD: "rojava"
DATABASE_USER: "riotkit"
DATABASE_DRIVER=pdo_pgsql

DATABASE_CHARSET=UTF8
DATABASE_COLLATE=pl_PL.UTF8
DATABASE_VERSION=10.10
  1. “SQLSTATE[21000]: Cardinality violation: 7 ERROR: more than one row returned by a subquery used as an expression”

This is an unresolved issue in the Doctrine DBAL driver that we use. To work around it, please create a separate database, user and use default schema “public” for the application.