34 Commits

Author SHA1 Message Date
dakriy
f780994996
feat(legacy): add config option for group separator in header auth (#3181)
### Description

Not all forward auth solutions use a comma for group seperator.

**This is a new feature**:

Yes

**I have updated the documentation to reflect these changes**:

Yes

### **Links**

[Authentik uses `|` so may as well make the group separator
configurable](https://docs.goauthentik.io/docs/add-secure-apps/providers/proxy/)
2025-07-16 20:32:34 +02:00
dakriy
2985d8554a
feat(legacy): trused header sso auth (#3095)
### Description

Allows LibreTime to support Trusted Header SSO Authentication.

**This is a new feature**:

Yes

**I have updated the documentation to reflect these changes**:

Yes

### Testing Notes

**What I did:**

I spun up an Authelia/Traefik pair and configured them to protect
LibreTime according to Authelia's documentation, I then tested that you
could log in via the trusted headers, and tested that old methods of
authentication were not affected.

**How you can replicate my testing:**

Using the following `docker-compose.yml` file

```yml
services:
  postgres:
    image: postgres:15
    networks:
      - internal
    volumes:
      - postgres_data:/var/lib/postgresql/data
    environment:
      POSTGRES_USER: ${POSTGRES_USER:-libretime}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-libretime} # Change me !
    healthcheck:
      test: pg_isready -U libretime

  rabbitmq:
    image: rabbitmq:3.13-alpine
    networks:
      - internal
    environment:
      RABBITMQ_DEFAULT_VHOST: ${RABBITMQ_DEFAULT_VHOST:-/libretime}
      RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER:-libretime}
      RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS:-libretime} # Change me !
    healthcheck:
      test: nc -z 127.0.0.1 5672

  playout:
    image: ghcr.io/libretime/libretime-playout:${LIBRETIME_VERSION:-latest}
    networks:
      - internal
    init: true
    ulimits:
      nofile: 1024
    depends_on:
      - rabbitmq
    volumes:
      - ${LIBRETIME_CONFIG_FILEPATH:-./config.yml}:/etc/libretime/config.yml:ro
      - libretime_playout:/app
    environment:
      LIBRETIME_GENERAL_PUBLIC_URL: http://nginx:8080

  liquidsoap:
    image: ghcr.io/libretime/libretime-playout:${LIBRETIME_VERSION:-latest}
    networks:
      - internal
    command: /usr/local/bin/libretime-liquidsoap
    init: true
    ulimits:
      nofile: 1024
    ports:
      - 8001:8001
      - 8002:8002
    depends_on:
      - rabbitmq
    volumes:
      - ${LIBRETIME_CONFIG_FILEPATH:-./config.yml}:/etc/libretime/config.yml:ro
      - libretime_playout:/app
    environment:
      LIBRETIME_GENERAL_PUBLIC_URL: http://nginx:8080

  analyzer:
    image: ghcr.io/libretime/libretime-analyzer:${LIBRETIME_VERSION:-latest}
    networks:
      - internal
    init: true
    ulimits:
      nofile: 1024
    depends_on:
      - rabbitmq
    volumes:
      - ${LIBRETIME_CONFIG_FILEPATH:-./config.yml}:/etc/libretime/config.yml:ro
      - libretime_storage:/srv/libretime
    environment:
      LIBRETIME_GENERAL_PUBLIC_URL: http://nginx:8080

  worker:
    image: ghcr.io/libretime/libretime-worker:${LIBRETIME_VERSION:-latest}
    networks:
      - internal
    init: true
    ulimits:
      nofile: 1024
    depends_on:
      - rabbitmq
    volumes:
      - ${LIBRETIME_CONFIG_FILEPATH:-./config.yml}:/etc/libretime/config.yml:ro
    environment:
      LIBRETIME_GENERAL_PUBLIC_URL: http://nginx:8080

  api:
    image: ghcr.io/libretime/libretime-api:${LIBRETIME_VERSION:-latest}
    networks:
      - internal
    init: true
    ulimits:
      nofile: 1024
    depends_on:
      - postgres
      - rabbitmq
    volumes:
      - ${LIBRETIME_CONFIG_FILEPATH:-./config.yml}:/etc/libretime/config.yml:ro
      - libretime_storage:/srv/libretime

  legacy:
    image: ghcr.io/libretime/libretime-legacy:${LIBRETIME_VERSION:-latest}
    networks:
      - internal
    init: true
    ulimits:
      nofile: 1024
    depends_on:
      - postgres
      - rabbitmq
    volumes:
      - ${LIBRETIME_CONFIG_FILEPATH:-./config.yml}:/etc/libretime/config.yml:ro
      - libretime_assets:/var/www/html
      - libretime_storage:/srv/libretime

  nginx:
    image: nginx
    networks:
      - internal
      - net
    ports:
      - 8080:8080
    depends_on:
      - legacy
    volumes:
      - libretime_assets:/var/www/html:ro
      - libretime_storage:/srv/libretime:ro
      - ${NGINX_CONFIG_FILEPATH:-./nginx.conf}:/etc/nginx/conf.d/default.conf:ro
    labels:
      - 'traefik.enable=true'
      - 'traefik.docker.network=libretime_net'
      - 'traefik.http.routers.libretime.rule=Host(`libretime.example.com`)'
      - 'traefik.http.routers.libretime.entrypoints=https'
      - 'traefik.http.routers.libretime.tls=true'
      - 'traefik.http.routers.libretime.tls.options=default'
      - 'traefik.http.routers.libretime.middlewares=authelia@docker'
      - 'traefik.http.services.libretime.loadbalancer.server.port=8080'

  icecast:
    image: ghcr.io/libretime/icecast:2.4.4
    networks:
      - internal
    ports:
      - 8000:8000
    environment:
      ICECAST_SOURCE_PASSWORD: ${ICECAST_SOURCE_PASSWORD:-hackme} # Change me !
      ICECAST_ADMIN_PASSWORD: ${ICECAST_ADMIN_PASSWORD:-hackme} # Change me !
      ICECAST_RELAY_PASSWORD: ${ICECAST_RELAY_PASSWORD:-hackme} # Change me !

  traefik:
    image: traefik:v2.11.12
    container_name: traefik
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    networks:
      - net
    labels:
      - 'traefik.enable=true'
      - 'traefik.http.routers.api.rule=Host(`traefik.example.com`)'
      - 'traefik.http.routers.api.entrypoints=https'
      - 'traefik.http.routers.api.service=api@internal'
      - 'traefik.http.routers.api.tls=true'
      - 'traefik.http.routers.api.tls.options=default'
      - 'traefik.http.routers.api.middlewares=authelia@docker'
    ports:
      - '80:80'
      - '443:443'
    command:
      - '--api'
      - '--providers.docker=true'
      - '--providers.docker.exposedByDefault=false'
      - '--entrypoints.http=true'
      - '--entrypoints.http.address=:80'
      - '--entrypoints.http.http.redirections.entrypoint.to=https'
      - '--entrypoints.http.http.redirections.entrypoint.scheme=https'
      - '--entrypoints.https=true'
      - '--entrypoints.https.address=:443'
      - '--log=true'
      - '--log.level=DEBUG'

  authelia:
    image: authelia/authelia
    container_name: authelia
    networks:
      - net
    volumes:
      - ./authelia:/config
    labels:
      - 'traefik.enable=true'
      - 'traefik.http.routers.authelia.rule=Host(`auth.example.com`)'
      - 'traefik.http.routers.authelia.entrypoints=https'
      - 'traefik.http.routers.authelia.tls=true'
      - 'traefik.http.routers.authelia.tls.options=default'
      - 'traefik.http.middlewares.authelia.forwardauth.address=http://authelia:9091/api/authz/forward-auth'  # yamllint disable-line rule:line-length
      - 'traefik.http.middlewares.authelia.forwardauth.trustForwardHeader=true'
      - 'traefik.http.middlewares.authelia.forwardauth.authResponseHeaders=Remote-User,Remote-Groups,Remote-Name,Remote-Email'  # yamllint disable-line rule:line-length
      - 'traefik.http.services.authelia.loadbalancer.server.port=9091'
    restart: unless-stopped
    environment:
      - TZ=America/Los_Angeles

volumes:
  postgres_data: {}
  libretime_storage: {}
  libretime_assets: {}
  libretime_playout: {}

networks:
  internal:
  net:
```

The following libretime dev config modification:
```yml
general:
  public_url: https://libretime.example.com
  auth: LibreTime_Auth_Adaptor_Header

header_auth:
  group_map:
    host: lt-host
    program_manager: lt-pm
    admin: lt-admin
    superadmin: lt-superadmin
```

And the following authelia config file:

```yml
---
###############################################################
#                   Authelia configuration                    #
###############################################################

server:
  address: 'tcp://:9091'
  buffers:
    read: 16384
    write: 16384

log:
  level: 'debug'

totp:
  issuer: 'authelia.com'

identity_validation:
  reset_password:
    jwt_secret: 'a_very_important_secret'

authentication_backend:
  file:
    path: '/config/users_database.yml'

access_control:
  default_policy: 'deny'
  rules:
    - domain: 'traefik.example.com'
      policy: 'one_factor'
    - domain: 'libretime.example.com'
      policy: 'one_factor'

session:
  secret: 'insecure_session_secret'

  cookies:
    - name: 'authelia_session'
      domain: 'example.com'  # Should match whatever your root protected domain is
      authelia_url: 'https://auth.example.com'
      expiration: '1 hour'  # 1 hour
      inactivity: '5 minutes'  # 5 minutes

regulation:
  max_retries: 3
  find_time: '2 minutes'
  ban_time: '5 minutes'

storage:
  encryption_key: 'you_must_generate_a_random_string_of_more_than_twenty_chars_and_configure_this'
  local:
    path: '/config/db.sqlite3'

notifier:
  filesystem:
    filename: '/config/notification.txt'
...
```

And the following authelia users database:

```yml
---
###############################################################
#                         Users Database                      #
###############################################################

# This file can be used if you do not have an LDAP set up.

# List of users
users:
  test:
    disabled: false
    displayname: "First Last"
    password: "$argon2id$v=19$m=16,t=2,p=1$SWVVVzcySlRLUEFkWWh2eA$qPs1ZmzmDXR/9WckDzIN9Q"
    email: test@example.com
    groups:
      - admins
      - dev
      - lt-admin
...
```

add the following entries to your `hosts` file:

```
127.0.0.1 traefik.example.com
127.0.0.1 auth.example.com
127.0.0.1 libretime.example.com
```

Then visit `libretime.example.com` in your browser, and login as the
user `test` with password of `password`. You should then be taken to the
LibreTime homepage, and when you click on login, you should be
automatically logged in.

### **Links**

https://www.authelia.com/integration/trusted-header-sso/introduction/
https://doc.traefik.io/traefik/middlewares/http/forwardauth/

---------

Co-authored-by: Kyle Robbertze <paddatrapper@users.noreply.github.com>
2024-12-07 10:21:57 +00:00
maxtim
06af18b84e
feat(playout): configure device for alsa and pulseaudio system outputs (#2654)
### Description

Add hardware configuration to liquidsoap so that users may
set hardware output in config.yml.

---------

Co-authored-by: jo <ljonas@riseup.net>
2023-12-29 15:22:43 +01:00
Jonas L
083ee3f1dd
feat!: default system output is now pulseaudio (#2842)
BREAKING CHANGE: The default system output
(`stream.outputs.system[].kind`) changed from `alsa` to `pulseaudio`.
Make sure to update your configuration file if you rely on the default
system output.

Closes #2542
2023-12-27 18:23:40 +01:00
Jonas L
0d2d1a2673
feat!: the general.secret_key configuration field is now required (#2841)
BREAKING CHANGE: The `general.secret_key` configuration field is now
required. Make sure to update your configuration file and add a secret
key.

Closes #2426
2023-12-27 18:15:47 +01:00
Jonas L
b2e512cbcd
feat: add mobile devices stream config field (#2744) 2023-10-14 08:13:04 +01:00
jo
c2c0be1fbc feat(api): add email configuration 2023-06-02 07:44:34 +01:00
jo
b2fc3a5ecf feat(playout): allow harbor ssl configuration 2023-04-24 14:58:34 +01:00
Jonas L
d800c5e280
feat: use secret_key config field instead of api_key (#2444)
Fixes #2426
2023-03-22 09:14:11 +00:00
jo
09a75570f3 fix: include version variable inside containers 2022-09-26 13:25:35 +02:00
Jonas L
9b3207b8a4
feat: move timezone preference to config file (#2096)
BREAKING CHANGE: The timezone preference moved to the configuration
file.
2022-09-14 12:48:08 +02:00
jo
e874db24c5 fix(legacy): config default values are not sanitized 2022-09-06 20:44:21 +02:00
jo
37b8b17ed3 feat(playout): allow liquidsoap listen address configuration 2022-09-06 13:21:54 +02:00
jo
5bf62dd9cb feat(legacy): read stream config from file
- We don't delete the stream preferences from the database to prevent data loss. This will be handled in a future release.
2022-09-06 13:21:54 +02:00
jo
090a5c93ac fix(legacy): look in /legacy for a VERSION file 2022-09-04 17:49:28 +02:00
jo
252ab00a8e style(legacy): format config 2022-09-04 17:49:28 +02:00
jo
0dd96345c9 chore(legacy): fix config validator name 2022-08-25 10:52:38 +02:00
jo
e8785124e0 feat(legacy): add config dot notation access 2022-08-11 13:17:39 +02:00
jo
f483852ccd refactor(legacy): clean config
- sort imports
- improve indentation
- rename internal_values to legacy_values
- reorder functions
 remove unused isYesValue
2022-08-11 13:17:39 +02:00
jo
21254b048d feat(legacy): setup config schema validation
BREAKING CHANGE: Unrecognized values in the configuration file will
raise validation errors, please make sure to cleanup your configuration
file.
2022-08-11 11:26:16 +02:00
jo
712ecd70b4 chore(legacy): remove exploded public_url config
Replace exploded public_url parts with validated url object.
2022-07-08 11:03:10 +02:00
jo
f7bb6e7592 feat: move storage path setting to configuration file
- change default storage path to /srv/libretime
- remove music dirs table
- use /tmp for testing storage
- storage dir should always have a trailing slash
2022-06-08 23:23:08 +02:00
jo
eb8e7b3415 feat: move allowed cors url to configuration file
- don't set cors origins form field as readonly and add deprecation notice.
2022-06-08 23:23:08 +02:00
jo
e4439390fe feat: change config file format to yaml
- docs: add link to yaml.org

BREAKING: The `ini` configuration file format changed to `yml`. Please
rewrite your configuration file using the yaml format.
2022-06-08 23:23:08 +02:00
jo
241105f0a0 fix(legacy): load vendors during config init
Propel does not have the vendors loaded, even if they are loaded during 'preload.php'.
2022-04-25 16:45:01 +02:00
jo
751d430bcc feat: replace exploded base_* with public_url
Fixes #1574

BREAKING CHANGE: The `general` section in the config schema has changed: the `general.base_*`, `general.protocol` and `general.force_ssl` configuration fields have been replaced with a single `general.public_url` field. Be sure to use a valid url with the new configuration field.
2022-04-25 16:45:01 +02:00
Jonas L
69d8eae845
style(legacy): fix code format with php-cs-fixer (#1674) 2022-03-14 12:15:04 +02:00
jo
f088cc2873 feat(legacy): clean config parsing and add defaults
BREAKING CHANGE: The configuration schema has changed:
- The `rabbitmq.*` configuration fields now have defaults.
- The `current_backend.storage_backend` configuration field
  now defaults to the only valid value `file`.
- The `general.cache_ahead_hours` configuration field now defaults to 1.
2022-02-23 13:18:05 +02:00
jo
4d868fac00 feat: remove unused web_server_user config entry
- remove InstallStorageDirectory function

BREAKING CHANGE: The configuration schema has changed:
- The `general.web_server_user` configuration field is
not used anymore.
2022-02-23 13:18:05 +02:00
Jonas L
3245216869
feat(legacy): add db config defaults and allow custom port (#1559)
* feat(legacy): allow custom port for database connection

- fix heredoc for php72

* update test config db section

* update sample config db section

* update api db config

* use defaults for database config section

* update documentation

* more documentation for migration
2022-02-04 16:03:01 +02:00
Jonas L
729a7b99e0
feat(legacy): consolidate constants (#1558)
* remove unused file

* fix paths leading slash

* remove useless imports

* refactor(legacy): use constants everywhere

* fix path leading slash

* remove useless import

* consolidate legacy contants

* format code

* reuse LIBRETIME_CONFIG_DIR

* fix test config path

* remove ci legacy log dir creation

* some logs improvements
2022-02-04 12:00:41 +02:00
jo
d52c6184b9 Format code using php-cs-fixer 2021-10-12 11:07:56 +02:00
jo
c4c89eae19 Fix paths after legacy rename 2021-10-11 13:43:39 +02:00
jo
3e18d42c8b Rename airtime_mvc/ to legacy/ 2021-10-11 13:43:25 +02:00