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
# Checksum generation salt (important for the security, needs to be not guessable)
#ENC_SALT=some-salt


# ==============================
# 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

# ===========
# SecureCopy
# ===========
#REPLICATION_MODE=primary

# ===============================
# System-wide encryption settings
# ===============================
#ENC_ALGORITHM=aes-256-cbc
#ENC_DIGEST_ALGORITHM=sha512
#ENC_DIGEST_ROUNDS=6000

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';
    public const INTERNAL_CONSOLE_TOKEN = 'internal-console-token';

    //
    //
    // 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 browse/search for tokens */
    public const ROLE_SEARCH_FOR_TOKENS            = 'security.search_for_tokens';

    /** 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';

    /** Prevent token user from seeing other tokens in listings */
    public const ROLE_CANNOT_SEE_FULL_TOKEN_ID     = 'security.cannot_see_full_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';

    /** Can see extra, technical metadata such as storage path in the listing */
    public const ROLE_CAN_SEE_EXTRA_ADMIN_METADATA = 'view.can_see_admin_metadata_in_listing';

    //
    //
    // SecureCopy domain
    //
    //

    /** Can use SecureCopy at all? */
    public const ROLE_SECURE_COPY_READ_DATA_STREAM = 'securecopy.stream';

    /** Read SecureCopy secrets: Encryption method, password, initialization vector. With following role can read secrets of any token in the system. */
    public const ROLE_READ_SECURE_COPY_SECRETS = 'securecopy.all_secrets_read';

    //
    //
    // 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';

    /** Can list tokens in all collections, where our token is added */
    public const ROLE_CAN_LIST_TOKENS_IN_COLLECTION = 'collections.can_list_tokens_in_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';

    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_SEARCH_FOR_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_CAN_SEE_EXTRA_ADMIN_METADATA,
        self::ROLE_REVOKE_TOKENS,
        self::ROLE_ADMINISTRATOR,

        // collections
        self::ROLE_COLLECTION_ADD,
        self::ROLE_COLLECTION_CUSTOM_ID,
        self::ROLE_COLLECTION_ADD_WITH_INFINITE_LIMITS,
        self::ROLE_CAN_DELETE_ALLOWED_COLLECTIONS,
        self::ROLE_CAN_LIST_TOKENS_IN_COLLECTION,
        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,

        // securecopy
        self::ROLE_SECURE_COPY_READ_DATA_STREAM,
        self::ROLE_READ_SECURE_COPY_SECRETS
    ];

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

    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;
    }

    /**
     * Internal token is used only in CLI commands
     * Cannot be used within any remote access (eg. via HTTP)
     *
     * @param string|null $tokenId
     * @return bool
     */
    public static function isInternalApplicationToken(?string $tokenId): bool
    {
        return $tokenId === static::INTERNAL_CONSOLE_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
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
CACHE_ADAPTER_TYPE (optional) Defaults to cache.adapter.filesystem, see: Symfony cache documentation
CACHE_REDIS_URL (optional) Defaults to redis://localhost
CACHE_MEMCACHED_PROVIDER (optional) Defaults to memcached://localhost

Redis/Memcached cache support

Docker container defines CACHE_ADAPTER_TYPE, CACHE_REDIS_URL and CACHE_MEMCACHED_PROVIDER that should be set in order to use a distributed cache server.

Without a docker container you need to fill up a file in config/packages/cache.yaml to point to your cache server.

# Used by Docker container to write values and overwrite cache.yaml

framework:
    cache:
        app: "cache.adapter.filesystem"

        # providers
        default_redis_provider: "redis://localhost"
        default_memcached_provider: "memcached://localhost"

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.