Optimized Nextcloud for OIDC flavor login and adapted user administrator credentials

This commit is contained in:
Kevin Veen-Birkenbach 2025-02-25 15:17:56 +01:00
parent ab258cb6dd
commit 9a9bae4f2c
47 changed files with 393 additions and 95 deletions

View File

@ -9,10 +9,18 @@ primary_domain_tld: "localhost" # Top Le
primary_domain_sld: "cymais" # Second Level Domain of the server
primary_domain: "{{primary_domain_sld}}.{{primary_domain_tld}}" # Primary Domain of the server
# Helper Variables
_users_administrator_username: "{{ users.administrator.username | default('administrator') }}"
_users_administrator_email: "{{ users.administrator.email | default(_users_administrator_username ~ '@' ~ primary_domain) }}"
# Administrator
administrator_username: "administrator" # Username of the administrator
administrator_email: "{{administrator_username}}@{{primary_domain}}" # Email of the administrator
# administrator_initial_password: Null # Example initialisation password needs to be set in inventory file
default_users:
administrator:
username: "{{_users_administrator_username}}" # Username of the administrator
email: "{{_users_administrator_email}}" # Email of the administrator
# initial_password: Null # Example initialisation password needs to be set in inventory file
uid: 1001 # Posix User ID
gid: 1001 # Posix Group ID
# Test Email
test_email: "test@{{primary_domain}}"

View File

@ -16,8 +16,8 @@ defaults_applications:
akaunting:
version: "latest"
company_name: "{{primary_domain}}"
company_email: "{{administrator_email}}"
setup_admin_email: "{{administrator_email}}"
company_email: "{{users.administrator.email}}"
setup_admin_email: "{{users.administrator.email}}"
database:
central_storage: True
@ -44,7 +44,9 @@ defaults_applications:
## Bluesky
bluesky:
administrator_email: "{{administrator_email}}"
users:
administrator:
email: "{{users.administrator.email}}"
pds:
version: "latest"
#jwt_secret: # Needs to be defined in inventory file - Use: openssl rand -base64 64 | tr -d '\n'
@ -70,14 +72,15 @@ defaults_applications:
oidc:
enabled: true # Activate OIDC. Plugin is not working yet
database:
central_storage: True
central_storage: True
## Funkwhale
funkwhale:
version: "1.4.0"
ldap_enabled: True # Enables LDAP by default
ldap:
enabled: True # Enables LDAP by default
database:
central_storage: True
central_storage: True
## Gitea
gitea:
@ -98,10 +101,13 @@ defaults_applications:
## Keycloak
keycloak:
version: "latest"
administrator_username: "{{administrator_username}}" # Administrator Username for Keycloak
ldap_enabled: True # Enables LDAP by default
users:
administrator:
username: "{{users.administrator.username}}" # Administrator Username for Keycloak
ldap:
enabled: True # Enables LDAP by default
database:
central_storage: True
central_storage: True
# database_password: # Needs to be defined in inventory file
# administrator_password: # Needs to be defined in inventory file
@ -109,7 +115,7 @@ defaults_applications:
ldap:
lam:
version: "latest"
administrator_password: "{{administrator_initial_password}}" # CHANGE for security reasons
administrator_password: "{{users.administrator.initial_password}}" # CHANGE for security reasons
openldap:
version: "latest"
network:
@ -119,8 +125,11 @@ defaults_applications:
phpldapadmin:
version: "2.0.0-dev" # @todo Attention: Change this as fast as released to latest
webinterface: "lam" # The webinterface which should be used. Possible: lam and phpldapadmin
administrator_username: "{{administrator_username}}"
ldap_enabled: True # Should have the same value as applications.ldap.openldap.network.local.
users:
administrator:
username: "{{users.administrator.username}}"
ldap:
enabled: True # Should have the same value as applications.ldap.openldap.network.local.
force_import: false # Forces the import of the LDIF files when set to true
oauth2_proxy:
enabled: true # Activate the OAuth2 Proxy for the LDAP Webinterface
@ -134,7 +143,9 @@ defaults_applications:
## Listmonk
listmonk:
administrator_username: "{{administrator_username}}" # Listmonk administrator account username
users:
administrator:
username: "{{users.administrator.username}}" # Listmonk administrator account username
public_api_activated: False # Security hole. Can be used for spaming
version: "latest" # Docker Image version
setup: false # Set true in inventory file to execute the setup and initializing procedures
@ -197,7 +208,9 @@ defaults_applications:
## Matrix
matrix:
administrator_username: "{{administrator_username}}" # Accountname of the matrix admin
users:
administrator:
username: "{{users.administrator.username}}" # Accountname of the matrix admin
playbook_tags: "setup-all,start" # For the initial update use: install-all,ensure-matrix-users-created,start
role: "compose" # Role to setup Matrix. Valid values: ansible, compose
server_name: "{{primary_domain}}" # Adress for the account names etc.
@ -214,8 +227,10 @@ defaults_applications:
## Moodle
moodle:
site_titel: "Global Learning Academy on {{primary_domain}}"
administrator_name: "{{administrator_username}}"
administrator_email: "{{administrator_email}}"
users:
administrator:
username: "{{users.administrator.username}}"
email: "{{users.administrator.email}}"
version: "latest"
database:
central_storage: True
@ -228,17 +243,26 @@ defaults_applications:
## Nextcloud
nextcloud:
version: "production" # @see https://nextcloud.com/blog/nextcloud-release-channels-and-how-to-track-them/
ldap_enabled: True # Enables LDAP by default, missing ansible setup tasks @todo setup
version: "production" # @see https://nextcloud.com/blog/nextcloud-release-channels-and-how-to-track-them/
ldap:
enabled: True # Enables LDAP by default, missing ansible setup tasks @todo setup
oidc:
enabled: true # Activate OIDC for Nextcloud
force_import: False # Forces the import of the LDIF files
enabled: true # Activate OIDC for Nextcloud
# floavor decides which OICD plugin should be used.
# Available options: login, sociallogin
# @see https://apps.nextcloud.com/apps/oidc_login
# @see https://apps.nextcloud.com/apps/sociallogin
flavor: "sociallogin" # Keeping on sociallogin because the other option is not implemented yet
force_import: False # Forces the import of the LDIF files
database:
central_storage: True
central_storage: True
credentials:
# database_password: Null # Needs to be set in inventory file
administrator_username: "{{administrator_username}}"
administrator_initial_password: "{{administrator_initial_password}}"
# database_password: Null # Needs to be set in inventory file
users:
administrator:
username: "{{users.administrator.username}}"
initial_password: "{{users.administrator.initial_password}}"
default_quota: '1000000000' # Quota to assign if no quota is specified in the OIDC response (bytes)
## OAuth2 Proxy
oauth2_proxy:
@ -255,7 +279,8 @@ defaults_applications:
application: "proxy"
port: "80"
# cookie_secret: None # Set via openssl rand -hex 16
ldap_enabled: True # Enables LDAP by default
ldap:
enabled: True # Enables LDAP by default
database:
central_storage: True
css:
@ -312,7 +337,9 @@ defaults_applications:
## YOURLS
yourls:
administrator_username: "{{administrator_username}}"
users:
administrator:
username: "{{users.administrator.username}}"
version: "latest"
oauth2_proxy:
enabled: true

View File

@ -39,7 +39,7 @@ ldap:
# Defines the base Distinguished Name (DN) for the LDAP directory, constructed from the second-level domain (SLD) and top-level domain (TLD).
root: "{{_ldap_dn_base}}"
# Specifies the Distinguished Name (DN) of the LDAP administrator, combining the admin's username with the LDAP root domain.
administrator: "cn={{applications.ldap.administrator_username}},{{_ldap_dn_base}}"
administrator: "cn={{applications.ldap.users.administrator.username}},{{_ldap_dn_base}}"
# Dn from which the users should be read
users: "ou=users,{{_ldap_dn_base}}"
# Dn from which the groups should be read

View File

@ -16,14 +16,14 @@ defaults_service_provider:
logo: https://cloud.veen.world/s/logo_cymais_512x512/download
favicon: https://cloud.veen.world/s/veen_world_favicon/download
contact:
bluesky: "{{ '@' ~ administrator_username ~ '.' ~ domains.bluesky_api if 'bluesky' in group_names else '' }}"
bluesky: "{{ '@' ~ users.administrator.username ~ '.' ~ domains.bluesky_api if 'bluesky' in group_names else '' }}"
email: "contact@{{ primary_domain }}"
mastodon: "{{ '@' ~ administrator_username ~ '@' ~ domains.mastodon if 'mastodon' in group_names else '' }}"
matrix: "{{ '@' ~ administrator_username ~ ':' ~ domains.matrix_synapse if 'matrix' in group_names else '' }}"
peertube: "{{ '@' ~ administrator_username ~ '@' ~ domains.peertube if 'peertube' in group_names else '' }}"
pixelfed: "{{ '@' ~ administrator_username ~ '@' ~ domains.pixelfed if 'pixelfed' in group_names else '' }}"
mastodon: "{{ '@' ~ users.administrator.username ~ '@' ~ domains.mastodon if 'mastodon' in group_names else '' }}"
matrix: "{{ '@' ~ users.administrator.username ~ ':' ~ domains.matrix_synapse if 'matrix' in group_names else '' }}"
peertube: "{{ '@' ~ users.administrator.username ~ '@' ~ domains.peertube if 'peertube' in group_names else '' }}"
pixelfed: "{{ '@' ~ users.administrator.username ~ '@' ~ domains.pixelfed if 'pixelfed' in group_names else '' }}"
phone: "+0 000 000 404"
wordpress: "{{ '@' ~ administrator_username ~ '@' ~ domains.wordpress[0] if 'wordpress' in group_names else '' }}"
wordpress: "{{ '@' ~ users.administrator.username ~ '@' ~ domains.wordpress[0] if 'wordpress' in group_names else '' }}"
legal:
editorial_responsible: "Johannes Gutenberg"

View File

@ -2,6 +2,10 @@
- name: Merge variables
hosts: all
tasks:
- name: Merge users
set_fact:
users: "{{ default_users | combine(users, recursive=True) }}"
- name: Merge system_email definitions
set_fact:
system_email: "{{ default_system_email | combine(system_email | default({}, true), recursive=True) }}"
@ -49,10 +53,11 @@
# Add new merged variables here
debug:
msg:
domains: "{{domains}}"
applications: "{{applications}}"
oidc: "{{oidc}}"
service_provider: "{{service_provider}}"
domains: "{{domains}}"
applications: "{{applications}}"
oidc: "{{oidc}}"
service_provider: "{{service_provider}}"
users: "{{users}}"
when: enable_debug | bool
- name: update device

View File

@ -1,5 +1,5 @@
PDS_HOSTNAME="{{domains.bluesky_api}}"
PDS_ADMIN_EMAIL="{{applications.bluesky.administrator_email}}"
PDS_ADMIN_EMAIL="{{applications.bluesky.users.administrator.email}}"
PDS_SERVICE_DID="did:web:{{domains.bluesky_api}}"
# See https://mattdyson.org/blog/2024/11/self-hosting-bluesky-pds/

View File

@ -48,7 +48,7 @@ env:
#DOCKER_USE_HOSTNAME: true
## on initial signup example 'user1@example.com,user2@example.com'
DISCOURSE_DEVELOPER_EMAILS: {{administrator_email}}
DISCOURSE_DEVELOPER_EMAILS: {{users.administrator.email}}
# SMTP ADDRESS, username, and password are required
# WARNING the char '#' in SMTP password can cause problems!
@ -120,8 +120,8 @@ run:
- exec: rails r "SiteSetting.username_change_period = 0" # Deactivate changing of username
# Activate Administrator User
#- exec: printf '{{administrator_email}}\n{{administrator_initial_password}}\n{{administrator_initial_password}}\nY\n' | rake admin:create
#- exec: rails r "User.find_by_email('{{administrator_email}}').update(username: '{{administrator_username}}')"
#- exec: printf '{{users.administrator.email}}\n{{users.administrator.initial_password}}\n{{users.administrator.initial_password}}\nY\n' | rake admin:create
#- exec: rails r "User.find_by_email('{{users.administrator.email}}').update(username: '{{users.administrator.username}}')"
# The following code is just an inspiration, how to connect with the oidc account. as long as this is not set the admini account needs to be manually connected with oidc
# docker exec -it discourse_application rails runner "user = User.find_by_email('test@flock.town'); UserAuth.create(user_id: user.id, provider: 'oidc', uid: 'eindeutige_oidc_id', info: { name: user.username, email: user.email })"

View File

@ -27,5 +27,5 @@ SMTP_STARTTLS= {{ 'on' if system_email.start_tls else 'off' }}
SMTP_FROM= {{system_email.local}}
# Administrator Credentials
FRIENDICA_ADMIN_MAIL= {{administrator_email}}
MAILNAME= {{administrator_email}}
FRIENDICA_ADMIN_MAIL= {{users.administrator.email}}
MAILNAME= {{users.administrator.email}}

View File

@ -100,7 +100,7 @@ DJANGO_SETTINGS_MODULE=config.settings.production
# Generate one using `openssl rand -base64 45`, for example
DJANGO_SECRET_KEY={{funkwhale_django_secret}}
{% if applications[application_id].ldap_enabled | bool %}
{% if applications[application_id].ldap.enabled | bool %}
# LDAP settings
# Use the following options to allow authentication on your Funkwhale instance
# using a LDAP directory.

View File

@ -10,7 +10,7 @@ KC_HTTP_ENABLED= true
KC_HEALTH_ENABLED= true
KC_METRICS_ENABLED= true
KEYCLOAK_ADMIN= "{{applications.keycloak.administrator_username}}"
KEYCLOAK_ADMIN= "{{applications.keycloak.users.administrator.username}}"
KEYCLOAK_ADMIN_PASSWORD= "{{applications.keycloak.administrator_password}}"
KC_DB= postgres
KC_DB_URL= jdbc:postgresql://{{database_host}}/{{database_name}}
@ -18,5 +18,5 @@ KC_DB_USERNAME= {{database_username}}
KC_DB_PASSWORD= {{database_password}}
# If the initial administrator already exists and the environment variables are still present at startup, an error message stating the failed creation of the initial administrator is shown in the logs. Keycloak ignores the values and starts up correctly.
KC_BOOTSTRAP_ADMIN_USERNAME= {{administrator_username}}
KC_BOOTSTRAP_ADMIN_PASSWORD= {{administrator_initial_password}}
KC_BOOTSTRAP_ADMIN_USERNAME= {{users.administrator.username}}
KC_BOOTSTRAP_ADMIN_PASSWORD= {{users.administrator.initial_password}}

View File

@ -62,7 +62,7 @@ EOF
```
### Show all Entires
### Show all Entries
```bash
docker exec --env LDAP_ADMIN_PASSWORD="$LDAP_ADMIN_PASSWORD" -it openldap bash -c "ldapsearch -LLL -o ldif-wrap=no -x -D 'cn=administrator,dc=veen,dc=world' -w \"\$LDAP_ADMIN_PASSWORD\" -b 'dc=veen,dc=world'";
```

View File

@ -2,7 +2,9 @@
shell: >
docker exec -i openldap ldapmodify -Y EXTERNAL -H ldapi:/// -f {{ldif_docker_path}}01_member_of_configuration.ldif
listen: "Import LDIF files"
ignore_errors: true # @todo check if this works
# @todo Remove the following ignore errors when setting up a new server
# Just here because debugging would take to much time
ignore_errors: true
- name: Refint Module Activation for OpenLDAP
shell: >
@ -10,7 +12,9 @@
listen: "Import LDIF files"
register: ldapadd_result
failed_when: ldapadd_result.rc not in [0, 68]
ignore_errors: true # @todo check if this works
# @todo Remove the following ignore errors when setting up a new server
# Just here because debugging would take to much time
ignore_errors: true
- name: Refint Overlay Configuration for OpenLDAP
shell: >
@ -18,15 +22,24 @@
listen: "Import LDIF files"
register: ldapadd_result
failed_when: ldapadd_result.rc not in [0, 68]
ignore_errors: true # @todo check if this works
# @todo Remove the following ignore errors when setting up a new server
# Just here because debugging would take to much time
ignore_errors: true
- name: "Import users, groups, etc. to LDAP"
shell: >
docker exec -i openldap ldapadd -x -D "{{ldap.dn.administrator}}" -w "{{ldap.bind_credential}}" -c -f "{{ldif_docker_path}}import/{{ item | basename | regex_replace(r'\.j2$', '') }}"
docker exec -i openldap ldapadd -x -D "{{ldap.dn.administrator}}" -w "{{ldap.bind_credential}}" -c -f "{{ldif_docker_path}}data/{{ item | basename | regex_replace('\.j2$', '') }}"
register: ldapadd_result
changed_when: "'adding new entry' in ldapadd_result.stdout"
# Allow return code 0 (all entries added) or 68 (entry already exists)
failed_when: ldapadd_result.rc not in [0, 68]
failed_when: ldapadd_result.rc not in [0, 20, 68]
listen: "Import LDIF files"
ignore_errors: true
loop: "{{ lookup('fileglob', role_path ~ '/templates/ldif/import/*.j2', wantlist=True) }}"
loop: "{{ lookup('fileglob', role_path ~ '/templates/ldif/data/*.j2', wantlist=True) }}"
- name: "Import schemas"
shell: >
docker exec -i openldap ldapadd -Y EXTERNAL -H ldapi:/// -f "{{ldif_docker_path}}schema/{{ item | basename | regex_replace('\.j2$', '') }}"
register: ldapadd_result
changed_when: "'adding new entry' in ldapadd_result.stdout"
failed_when: ldapadd_result.rc not in [0, 80]
listen: "Import LDIF files"
loop: "{{ lookup('fileglob', role_path ~ '/templates/ldif/schema/*.j2', wantlist=True) }}"

View File

@ -1,3 +1,5 @@
# In own task file for easier looping
- name: "Create LDIF files at {{ ldif_host_path }}/{{ folder }}"
template:
src: "{{ item }}"

View File

@ -3,7 +3,7 @@
# GENERAL
## Database
LDAP_ADMIN_USERNAME= {{applications.ldap.administrator_username}} # LDAP database admin user.
LDAP_ADMIN_USERNAME= {{applications.ldap.users.administrator.username}} # LDAP database admin user.
LDAP_ADMIN_PASSWORD= {{applications.ldap.administrator_database_password}} # LDAP database admin password.
## Users
@ -14,7 +14,7 @@ LDAP_ROOT= {{ldap.dn.root}} # LDAP baseDN (or su
## Admin
LDAP_ADMIN_DN= {{ldap.dn.administrator}}
LDAP_CONFIG_ADMIN_ENABLED= yes
LDAP_CONFIG_ADMIN_USERNAME= {{applications.ldap.administrator_username}}
LDAP_CONFIG_ADMIN_USERNAME= {{applications.ldap.users.administrator.username}}
LDAP_CONFIG_ADMIN_PASSWORD= {{applications.ldap.administrator_password}}
# Network

View File

@ -26,6 +26,11 @@
#
# IMPORTANT: All groups created before enabling this module must be deleted and recreated,
# as the overlay only assigns the "member" attribute when a new group is created.
# @todo Solve the following error:
#fatal: [echoserver]: FAILED! => {"changed": true, "cmd": "docker exec -i openldap ldapmodify -Y EXTERNAL -H ldapi:/// -f /tmp/ldif/01_member_of_configuration.ldif\n", "delta": "0:00:00.059605", "end": "2025-02-25 12:01:18.218851", "msg": "non-zero return code", "rc": 247, "start": "2025-02-25 12:01:18.159246", "stderr": "SASL/EXTERNAL authentication started\nSASL username: gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth\nSASL SSF: 0\nldapmodify: modify operation type is missing at line 2, entry \"cn=module,cn=config\"", "stderr_lines": ["SASL/EXTERNAL authentication started", "SASL username: gidNumber=0+uidNumber=1001,cn=peercred,cn=external,cn=auth", "SASL SSF: 0", "ldapmodify: modify operation type is missing at line 2, entry \"cn=module,cn=config\""], "stdout": "", "stdout_lines": []}
dn: cn=module,cn=config
cn: module
objectClass: olcModuleList

View File

@ -9,16 +9,18 @@ description: Container for application access profiles
#######################################################################
# Create Admin User
#######################################################################
dn: uid={{administrator_username}},{{ldap.dn.users}}
dn: uid={{users.administrator.username}},{{ldap.dn.users}}
objectClass: top
objectClass: inetOrgPerson
objectClass: posixAccount
uid: {{administrator_username}}
uid: {{users.administrator.username}}
sn: Administrator
cn: Administrator
userPassword: {SSHA}CHANGE_THIS_PASSWORD
loginShell: /bin/bash
homeDirectory: /home/admin
uidNumber: {{users.administrator.uid}}
gidNumber: {{users.administrator.gid}}
#######################################################################
# Add Admin User to All Application Role Groups
@ -29,11 +31,11 @@ homeDirectory: /home/admin
dn: cn={{ app }}-administrator,{{ ldap.dn.application_roles }}
changetype: modify
add: roleOccupant
roleOccupant: uid={{administrator_username}},{{ldap.dn.users}}
roleOccupant: uid={{users.administrator.username}},{{ldap.dn.users}}
dn: cn={{ app }}-user,{{ ldap.dn.application_roles }}
changetype: modify
add: roleOccupant
roleOccupant: uid={{administrator_username}},{{ldap.dn.users}}
roleOccupant: uid={{users.administrator.username}},{{ldap.dn.users}}
{% endfor %}

View File

@ -0,0 +1,16 @@
# nextcloud.schema
# This schema is deactivated, because with keycloak it's impossible to set schemas to new created users
# Until then the managament is done over keycloak
# @todo activate in ldap
dn: cn=nextcloud,cn=schema,cn=config
objectClass: olcSchemaConfig
cn: nextcloud
olcAttributeTypes: ( 1.3.6.1.4.1.99999.1 NAME 'nextcloudQuota'
DESC 'Quota for Nextcloud'
EQUALITY caseIgnoreMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{64} )
olcObjectClasses: ( 1.3.6.1.4.1.99999.2 NAME 'nextcloudUser'
DESC 'Auxiliary class for Nextcloud attributes'
AUXILIARY
MAY ( nextcloudQuota ) )

View File

@ -0,0 +1 @@
This folder contains schemas for the different applications to import

View File

@ -9,4 +9,5 @@ ldif_docker_path: "/tmp/ldif/"
ldap.dn.application_roles: "ou=application_roles,{{ldap.dn.root}}"
ldif_types:
- configuration
- import
- data
- schema

View File

@ -9,7 +9,7 @@ address = "0.0.0.0:9000"
# be replaced with a better multi-user, role-based authentication system.
# IMPORTANT: Leave both values empty to disable authentication on admin
# only where an external authentication is already setup.
# admin_username = "{{applications.listmonk.administrator_username}}"
# admin_username = "{{applications.listmonk.users.administrator.username}}"
# admin_password = "{{listmonk_admin_password}}"
# Deactivated for newer versions

View File

@ -24,6 +24,6 @@
- name: create administrator account
command:
cmd: "docker compose -p mailu exec admin flask mailu admin {{administrator_username}} {{primary_domain}} {{applications.mailu.initial_administrator_password}}"
cmd: "docker compose -p mailu exec admin flask mailu admin {{users.administrator.username}} {{primary_domain}} {{applications.mailu.initial_administrator_password}}"
chdir: "{{docker_compose.directories.instance}}"
ignore_errors: true

View File

@ -5,15 +5,15 @@
command:
cmd: "docker compose exec -u root web sed -i '/- administrator/d' config/settings.yml"
chdir: "{{docker_compose.directories.instance}}"
when: administrator_username == "administrator"
when: users.administrator.username == "administrator"
- name: Create admin account via tootctl
command:
cmd: 'docker compose exec -u root web bash -c "RAILS_ENV=production bin/tootctl accounts create {{administrator_username}} --email {{administrator_email}} --confirmed --role Owner"'
cmd: 'docker compose exec -u root web bash -c "RAILS_ENV=production bin/tootctl accounts create {{users.administrator.username}} --email {{users.administrator.email}} --confirmed --role Owner"'
chdir: "{{docker_compose.directories.instance}}"
ignore_errors: true
- name: Approve the administrator account in Mastodon
command:
cmd: docker compose exec -u root web bash -c "RAILS_ENV=production bin/tootctl accounts modify {{administrator_username}} --approve"
cmd: docker compose exec -u root web bash -c "RAILS_ENV=production bin/tootctl accounts modify {{users.administrator.username}} --approve"
chdir: "{{docker_compose.directories.instance}}"

View File

@ -46,7 +46,7 @@ devture_traefik_config_entrypoint_web_forwardedHeaders_insecure: true
# you won't be required to define this variable (see `docs/configuring-playbook-ssl-certificates.md`).
#
# Example value: someone@example.com
devture_traefik_config_certificatesResolvers_acme_email: "{{administrator_email}}"
devture_traefik_config_certificatesResolvers_acme_email: "{{users.administrator.email}}"
# A Postgres password to use for the superuser Postgres user (called `matrix` by default).
#

View File

@ -134,7 +134,7 @@
- name: create admin account
command:
cmd: docker compose exec -it synapse register_new_matrix_user -u {{applications.matrix.administrator_username}} -p {{matrix_admin_password}} -a -c /data/homeserver.yaml http://localhost:8008
cmd: docker compose exec -it synapse register_new_matrix_user -u {{applications.matrix.users.administrator.username}} -p {{matrix_admin_password}} -a -c /data/homeserver.yaml http://localhost:8008
chdir: "{{ docker_compose.directories.instance }}"
ignore_errors: true
when: applications.matrix.setup | bool

View File

@ -381,7 +381,7 @@ bridge:
permissions:
"*": relay
"{{applications.matrix.server_name}}": user
"@{{applications.matrix.administrator_username}}:{{applications.matrix.server_name}}": admin
"@{{applications.matrix.users.administrator.username}}:{{applications.matrix.server_name}}": admin
relay:
# Whether relay mode should be allowed. If allowed, `!fb set-relay` can be used to turn any

View File

@ -360,7 +360,7 @@ bridge:
permissions:
"*": relay
"{{applications.matrix.server_name}}": user
"@{{applications.matrix.administrator_username}}:{{applications.matrix.server_name}}": admin
"@{{applications.matrix.users.administrator.username}}:{{applications.matrix.server_name}}": admin
relay:
# Whether relay mode should be allowed. If allowed, `!ig set-relay` can be used to turn any

View File

@ -275,7 +275,7 @@ bridge:
permissions:
"*": relay
"{{applications.matrix.server_name}}": user
"@{{applications.matrix.administrator_username}}:{{applications.matrix.server_name}}": admin
"@{{applications.matrix.users.administrator.username}}:{{applications.matrix.server_name}}": admin
# Settings for relay mode
relay:

View File

@ -279,7 +279,7 @@ bridge:
permissions:
"*": relay
"{{applications.matrix.server_name}}": user
"@{{applications.matrix.administrator_username}}:{{applications.matrix.server_name}}": admin
"@{{applications.matrix.users.administrator.username}}:{{applications.matrix.server_name}}": admin
# Logging config. See https://github.com/tulir/zeroconfig for details.
logging:

View File

@ -532,7 +532,7 @@ bridge:
"*": "relaybot"
"public.{{applications.matrix.server_name}}": "user"
"{{applications.matrix.server_name}}": "full"
"@{{applications.matrix.administrator_username}}:{{applications.matrix.server_name}}": "admin"
"@{{applications.matrix.users.administrator.username}}:{{applications.matrix.server_name}}": "admin"
# Options related to the message relay Telegram bot.
relaybot:

View File

@ -435,7 +435,7 @@ bridge:
permissions:
"*": relay
"{{applications.matrix.server_name}}": user
"@{{applications.matrix.administrator_username}}:{{applications.matrix.server_name}}": admin
"@{{applications.matrix.users.administrator.username}}:{{applications.matrix.server_name}}": admin
# Settings for relay mode
relay:

View File

@ -28,7 +28,7 @@ web_client_location: "https://{{domains.matrix_element}}"
public_baseurl: "https://{{domains.matrix_synapse}}"
trusted_key_servers:
- server_name: "matrix.org"
admin_contact: 'mailto:{{administrator_email}}'
admin_contact: 'mailto:{{users.administrator.email}}'
email:
smtp_host: "{{system_email.host}}"

View File

@ -9,5 +9,5 @@ MOODLE_SSLPROXY=yes
MOODLE_REVERSE_PROXY=yes
MOODLE_USERNAME={{applications.moodle.administrator_name}}
MOODLE_PASSWORD={{moodle_user_password}}
MOODLE_EMAIL={{applications.moodle.administrator_email}}
MOODLE_EMAIL={{applications.moodle.users.administrator.email}}
BITNAMI_DEBUG={% if enable_debug | bool %}true{% else %}false{% endif %}

View File

@ -22,13 +22,13 @@
- name: "copy docker-compose.yml and env file"
include_tasks: copy-docker-compose-and-env.yml
- name: Include OIDC-specific tasks
include_tasks: oidc.yml
- name: "Include OIDC-specific tasks with flavor {{applications[application_id].oidc.flavor}}"
include_tasks: "oidc_{{applications[application_id].oidc.flavor}}.yml"
when: applications[application_id].oidc.enabled | bool
- name: Include LDAP specific tasks
include_tasks: ldap.yml
when: applications[application_id].ldap_enabled | bool
when: applications[application_id].ldap.enabled | bool
- name: Include Config specific tasks
include_tasks: config.yml

View File

@ -0,0 +1 @@
# @todo implement this flavor

View File

@ -22,7 +22,7 @@ MAIL_FROM_ADDRESS= "{{system_email.local}}"
MAIL_DOMAIN= "{{system_email.domain}}"
# Initial Admin Data
NEXTCLOUD_ADMIN_USER= "{{applications[application_id].credentials.administrator_username}}"
NEXTCLOUD_ADMIN_PASSWORD= "{{applications[application_id].credentials.administrator_initial_password}}"
NEXTCLOUD_ADMIN_USER= "{{applications[application_id].users.administrator.username}}"
NEXTCLOUD_ADMIN_PASSWORD= "{{applications[application_id].users.administrator.initial_password}}"
NEXTCLOUD_TRUSTED_DOMAINS= "{{domains[application_id]}}"

View File

@ -0,0 +1,212 @@
# Check out: https://github.com/pulsejet/nextcloud-oidc-login
$CONFIG = array (
// Some Nextcloud options that might make sense here
'allow_user_to_change_display_name' => false,
'lost_password_link' => 'disabled',
// URL of provider. All other URLs are auto-discovered from .well-known
'oidc_login_provider_url' => 'https://{{domains.keycloak}}',
// Client ID and secret registered with the provider
'oidc_login_client_id' => '{{oidc.client.id}}',
'oidc_login_client_secret' => '{{oidc.client.secret}}',
// Automatically redirect the login page to the provider
'oidc_login_auto_redirect' => false,
// Redirect to this page after logging out the user
'oidc_login_logout_url' => 'https://{{domains[application_id]}}',
// If set to true the user will be redirected to the
// logout endpoint of the OIDC provider after logout
// in Nextcloud. After successfull logout the OIDC
// provider will redirect back to 'oidc_login_logout_url' (MUST be set).
'oidc_login_end_session_redirect' => false,
// Quota to assign if no quota is specified in the OIDC response (bytes)
//
// NOTE: If you want to allow NextCloud to manage quotas, omit this option. Do not set it to
// zero or -1 or ''.
'oidc_login_default_quota' => '{{applications[application_id].default_quota}}',
// Login button text
'oidc_login_button_text' => 'Log in with OpenID',
// Hide the NextCloud password change form.
'oidc_login_hide_password_form' => true,
// Use ID Token instead of UserInfo
'oidc_login_use_id_token' => false,
// Attribute map for OIDC response. Available keys are:
// * id: Unique identifier for username
// * name: Full name
// If set to null, existing display name won't be overwritten
// * mail: Email address
// If set to null, existing email address won't be overwritten
// * quota: Nextcloud storage quota
// * home: Home directory location. A symlink or external storage to this location is used
// * ldap_uid: LDAP uid to search for when running in proxy mode
// * groups: Array or space separated string of Nextcloud groups for the user.
// Note that the name here corresponds to the GID of the group and not the display name
// In the admin panel, the GID may be obtained from the URL when editing a group
// * login_filter: Array or space separated string. If 'oidc_login_filter_allowed_values' is
// set, it is checked against these values.
// * photoURL: The URL of the user avatar. The nextcloud server will download the picture
// at user login. This may lead to security issues. Use with care.
// This will only be effective if oidc_login_update_avatar is enabled.
// * is_admin: If this value is truthy, the user is added to the admin group (optional)
//
// The attributes in the OIDC response are flattened by adding the nested
// array key as the prefix and an underscore. Thus,
//
// $profile = [
// 'id' => 1234,
// 'attributes' => [
// 'uid' => 'myuid',
// 'abc' => 'xyz'
// ],
// 'list' => ['one', 'two']
// ];
//
// would become,
//
// $profile = [
// 'id' => 1234,
// 'attributes' => [
// 'uid' => 'myuid',
// 'abc' => 'xyz'
// ],
// 'attributes_uid' => 'myuid',
// 'attributes_abc' => 'xyz',
// 'list' => ['one', 'two'],
// 'list_0' => 'one',
// 'list_1' => 'two',
// 'list_one' => 'one',
// 'list_two' => 'two',
// ]
//
// https://openid.net/specs/openid-connect-core-1_0.html#StandardClaims
//
// note: on Keycloak, OIDC name claim = "${given_name} ${family_name}" or one of them if any is missing
//
'oidc_login_attributes' => array (
'id' => 'username',
'name' => 'name',
'mail' => 'email',
'quota' => 'nextcloudQuota',
'home' => 'homeDirectory',
'ldap_uid' => 'uid',
'groups' => 'ownCloudGroups',
'login_filter' => 'realm_access_roles',
// 'photoURL' => 'picture',
// 'is_admin' => 'ownCloudAdmin',
),
// Default group to add users to (optional, defaults to nothing)
// 'oidc_login_default_group' => 'oidc',
// DEPRECATED: This option will be removed in a future release. Use
// 'login_filter' and 'oidc_login_filter_allowed_values' instead.
//
// Allow only users in configured group(s) to access Nextcloud. In case the user
// is not assigned to this group (read from oidc_login_attributes) the login
// will not be allowed for this user.
//
// Must be specified as an array of groups that are allowed to access Nextcloud.
// e.g. 'oidc_login_allowed_groups' => array('group1', 'group2')
'oidc_login_allowed_groups' => null,
// Allow only users in configured value(s) to access Nextcloud. In case the user
// is not assigned to this value (read from oidc_login_attributes) the login
// will not be allowed for this user.
//
// Must be specified as an array of values (e.g. roles) that are allowed to
// access Nextcloud. e.g. 'oidc_login_filter_allowed_values' => array('role1', 'role2')
'oidc_login_filter_allowed_values' => null,
// Use external storage instead of a symlink to the home directory
// Requires the files_external app to be enabled
'oidc_login_use_external_storage' => false,
// Set OpenID Connect scope
'oidc_login_scope' => 'openid profile',
// Run in LDAP proxy mode
// In this mode, instead of creating users of its own, OIDC login
// will get the existing user from an LDAP database and only
// perform authentication with OIDC. All user data will be derived
// from the LDAP database instead of the OIDC user response
//
// The `id` attribute in `oidc_login_attributes` must return the
// "Internal Username" (see expert settings in LDAP integration)
'oidc_login_proxy_ldap' => {{applications[application_id].ldap.enabled | string | lower}},
// Disable creation of users new to Nextcloud from OIDC login.
// A user may be known to the IdP but not (yet) known to Nextcloud.
// This setting controls what to do in this case.
// - 'true' (default): if the user authenticates to the IdP but is not known to Nextcloud,
// then they will be returned to the login screen and not allowed entry;
// - 'false': if the user authenticates but is not yet known to Nextcloud,
// then the user will be automatically created; note that with this setting,
// you will be allowing (or relying on) a third-party (the IdP) to create new users
'oidc_login_disable_registration' => true,
// Fallback to direct login if login from OIDC fails
// Note that no error message will be displayed if enabled
'oidc_login_redir_fallback' => false,
// Use an alternative login page
// This page will be php-included instead of a redirect if specified
// For example, setting it to `assets/login.php` will use that file
// in the nextcloud base directory
// Note: the PHP variable $OIDC_LOGIN_URL is available for redirect URI
// Note: you may want to try setting `oidc_login_logout_url` to your
// base URL if you face issues regarding re-login after logout
'oidc_login_alt_login_page' => false,
// For development, you may disable TLS verification. Default value is `true`
// which should be kept in production
'oidc_login_tls_verify' => true,
// If you get your groups from the oidc_login_attributes, you might want
// to create them if they are not already existing, Default is `false`.
'oidc_create_groups' => false,
// Enable use of WebDAV via OIDC bearer token.
'oidc_login_webdav_enabled' => false,
// Enable authentication with user/password for DAV clients that do not
// support token authentication (e.g. DAVx⁵)
'oidc_login_password_authentication' => false,
// The time in seconds used to cache public keys from provider.
// The default value is 1 day.
'oidc_login_public_key_caching_time' => 86400,
// The minimum time in seconds to wait between requests to the jwks_uri endpoint.
// Avoids that the provider will be DoSed when someone requests with unknown kids.
// The default is 10 seconds.
'oidc_login_min_time_between_jwks_requests' => 10,
// The time in seconds used to cache the OIDC well-known configuration from the provider.
// The default value is 1 day.
'oidc_login_well_known_caching_time' => 86400,
// If true, nextcloud will download user avatars on login.
// This may lead to security issues as the server does not control
// which URLs will be requested. Use with care.
'oidc_login_update_avatar' => false,
// If true, the default Nextcloud proxy won't be used to make internals OIDC call.
// The default is false.
'oidc_login_skip_proxy' => false,
// Code challenge method for PKCE flow.
// Possible values are:
// - 'S256'
// - 'plain'
// The default value is empty, which won't apply the PKCE flow.
'oidc_login_code_challenge_method' => '',
);

View File

@ -3,5 +3,5 @@ YOURLS_DB_USER: "{{database_username}}"
YOURLS_DB_PASS: "{{database_password}}"
YOURLS_DB_NAME: "{{database_name}}"
YOURLS_SITE: "https://{{domains[application_id]}}"
YOURLS_USER: "{{applications.yourls.administrator_username}}"
YOURLS_USER: "{{applications.yourls.users.administrator.username}}"
YOURLS_PASS: "{{yourls_administrator_password}}"

View File

@ -1,6 +1,6 @@
- name: "recieve dedicated certificate for {{ domain }}"
command: >-
certbot certonly --agree-tos --email {{ administrator_email }}
certbot certonly --agree-tos --email {{ users.administrator.email }}
--non-interactive --webroot -w /var/lib/letsencrypt/ -d {{ domain }}
{{ '--test-cert' if mode_test | bool else '' }}
when:
@ -10,7 +10,7 @@
- name: "recieve wildcard certificate for *{{ primary_domain }}"
command: >-
certbot certonly --agree-tos --email {{ administrator_email }}
certbot certonly --agree-tos --email {{ users.administrator.email }}
--non-interactive --webroot -w /var/lib/letsencrypt/ -d {{ primary_domain }} -d *.{{ primary_domain }}
{{ '--test-cert' if mode_test | bool else '' }}
when:

View File

@ -776,6 +776,11 @@ input:checked {
border-color: var(--color-70);
}
option {
background-color: var(--color-82);
color: var(--color-99);
}
/* Tables (Borders and Header Colors) */
th, td {
border-color: var(--color-70);
@ -863,7 +868,7 @@ html[native-dark-active] .btn, .btn {
}
/* Keycloak */
div#app header, div#app header *{
div#app header{
background-color: var(--color-60);
/* New Gradient based on original background (60 -5, 60, 60 +1, 60 +5) */
background: linear-gradient({{ range(0, 361) | random }}deg, var(--color-55), var(--color-60), var(--color-61), var(--color-65));

View File

@ -5,7 +5,7 @@ This Ansible role configures Nginx to perform 301 redirects from one domain to a
## Role Variables
- `domain_mappings`: A list of objects with `source` and `target` properties specifying the domains to redirect from and to.
- `administrator_email`: The email used for SSL certificate registration with Let's Encrypt.
- `users.administrator.email`: The email used for SSL certificate registration with Let's Encrypt.
## Dependencies

View File

@ -1,7 +1,7 @@
#!/bin/bash
/usr/bin/sendmail -t <<ERRMAIL
To: {{administrator_email}}
To: {{users.administrator.email}}
From: systemd <{{system_email.from}}>
Subject: $1
Content-Transfer-Encoding: 8bit

View File

@ -2,7 +2,7 @@
user:
name: administrator
update_password: on_create
password: "{{ administrator_initial_password | password_hash('sha512') }}"
password: "{{ users.administrator.initial_password | password_hash('sha512') }}"
create_home: yes
generate_ssh_key: yes
ssh_key_type: rsa

View File

@ -4,7 +4,7 @@ networks:
central_{{ database_type }}:
external: true
{% endif %}
{% if applications[application_id].ldap_enabled|default(false)|bool and applications.ldap.openldap.network.local|bool %}
{% if applications[application_id].get('ldap', {}).get('enabled', false)|bool and applications.ldap.openldap.network.local|bool %}
central_ldap:
external: true
{% endif %}

View File

@ -3,7 +3,7 @@
{% if applications[application_id].database.central_storage | bool and database_type is defined %}
central_{{ database_type }}:
{% endif %}
{% if applications[application_id].ldap_enabled|default(false)|bool and applications.ldap.openldap.network.local|bool %}
{% if applications[application_id].get('ldap', {}).get('enabled', false)|bool and applications.ldap.openldap.network.local|bool %}
central_ldap:
{% endif %}
default: