From c2e100b1aa8253617f1e48b510d564d906cec350 Mon Sep 17 00:00:00 2001 From: Fenris Wolf Date: Thu, 9 Oct 2025 01:49:09 +0200 Subject: [PATCH] [task-406] owncloud --- roles/authelia-for-owncloud/cfg.schema.json | 97 +++++++++++ .../authelia-for-owncloud/defaults/main.json | 25 ++- roles/authelia-for-owncloud/tasks/main.json | 132 ++++++++++----- .../authelia-client-conf-android.json.j2 | 26 ++- .../authelia-client-conf-desktop.json.j2 | 27 +++- .../authelia-client-conf-ios.json.j2 | 27 +++- .../authelia-client-conf-web.json.j2 | 29 +++- roles/authelia-for-owncloud/vardef.json | 34 ---- roles/owncloud-and-nginx/cfg.schema.json | 31 ++++ roles/owncloud-and-nginx/defaults/main.json | 7 +- roles/owncloud-and-nginx/tasks/main.json | 13 +- roles/owncloud-and-nginx/templates/conf.j2 | 14 +- roles/owncloud-and-nginx/vardef.json | 20 --- roles/owncloud/cfg.schema.json | 152 ++++++++++++++++++ roles/owncloud/defaults/main.json | 30 ++-- roles/owncloud/info.md | 15 +- roles/owncloud/tasks/main.json | 65 ++++++-- roles/owncloud/templates/csp.yaml.j2 | 7 + roles/owncloud/templates/env.j2 | 88 ++++++---- roles/owncloud/templates/systemd_unit.j2 | 8 +- roles/owncloud/vardef.json | 75 --------- 21 files changed, 628 insertions(+), 294 deletions(-) create mode 100644 roles/authelia-for-owncloud/cfg.schema.json delete mode 100644 roles/authelia-for-owncloud/vardef.json create mode 100644 roles/owncloud-and-nginx/cfg.schema.json delete mode 100644 roles/owncloud-and-nginx/vardef.json create mode 100644 roles/owncloud/cfg.schema.json create mode 100644 roles/owncloud/templates/csp.yaml.j2 delete mode 100644 roles/owncloud/vardef.json diff --git a/roles/authelia-for-owncloud/cfg.schema.json b/roles/authelia-for-owncloud/cfg.schema.json new file mode 100644 index 0000000..4532214 --- /dev/null +++ b/roles/authelia-for-owncloud/cfg.schema.json @@ -0,0 +1,97 @@ +{ + "nullable": false, + "type": "object", + "properties": { + "owncloud_url_base": { + "nullable": false, + "type": "string" + }, + "web": { + "nullable": true, + "type": "object", + "properties": { + "client_id": { + "nullable": false, + "type": "string", + "default": "owncloud_web" + } + }, + "additionalProperties": false, + "required": [ + ], + "default": { + } + }, + "desktop": { + "nullable": true, + "type": "object", + "properties": { + "client_id": { + "nullable": false, + "type": "string", + "default": "xdXOt13JKxym1B1QcEncf2XDkLAexMBFwiT9j6EfhhHFJhs2KM9jbjTmf8JBXE69" + }, + "client_secret": { + "nullable": false, + "type": "string", + "default": "UBntmLjC2yYCeHwsyj73Uwo9TAaecAetRwMw0xYcvNL9yRdLSUi0hUAHfvCHFeFh" + } + }, + "additionalProperties": false, + "required": [ + ], + "default": { + } + }, + "android": { + "nullable": true, + "type": "object", + "properties": { + "client_id": { + "nullable": false, + "type": "string", + "default": "e4rAsNUSIUs0lF4nbv9FmCeUkTlV9GdgTLDH1b5uie7syb90SzEVrbN7HIpmWJeD" + }, + "client_secret": { + "nullable": false, + "type": "string", + "default": "dInFYGV33xKzhbRmpqQltYNdfLdJIfJ9L5ISoKhNoT9qZftpdWSP71VrpGR9pmoD" + } + }, + "additionalProperties": false, + "required": [ + ], + "default": { + } + }, + "ios": { + "nullable": true, + "type": "object", + "properties": { + "client_id": { + "nullable": false, + "type": "string", + "default": "mxd5OQDk6es5LzOzRvidJNfXLUZS2oN3oUFeXPP8LpPrhx3UroJFduGEYIBOxkY1" + }, + "client_secret": { + "nullable": false, + "type": "string", + "default": "KFeFWWEZO9TkisIQzR3fo7hfiMXlOpaqP8CFuTbSHzV1TUuGECglPxpiVKJfOXIx" + } + }, + "additionalProperties": false, + "required": [ + ], + "default": { + } + } + }, + "additionalProperties": false, + "required": [ + "owncloud_url_base", + "web", + "desktop", + "android", + "ios" + ] +} diff --git a/roles/authelia-for-owncloud/defaults/main.json b/roles/authelia-for-owncloud/defaults/main.json index 4daa968..ad9f859 100644 --- a/roles/authelia-for-owncloud/defaults/main.json +++ b/roles/authelia-for-owncloud/defaults/main.json @@ -1,10 +1,19 @@ { - "var_authelia_for_owncloud_owncloud_url_base": "https://owncloud.example.org", - "var_authelia_for_owncloud_web_client_id": "owncloud_web", - "var_authelia_for_owncloud_android_client_id": "owncloud_android", - "var_authelia_for_owncloud_android_client_secret": "REPLACE_ME", - "var_authelia_for_owncloud_ios_client_id": "owncloud_ios", - "var_authelia_for_owncloud_ios_client_secret": "REPLACE_ME", - "var_authelia_for_owncloud_desktop_client_id": "xdXOt13JKxym1B1QcEncf2XDkLAexMBFwiT9j6EfhhHFJhs2KM9jbjTmf8JBXE69", - "var_authelia_for_owncloud_desktop_client_secret": "UBntmLjC2yYCeHwsyj73Uwo9TAaecAetRwMw0xYcvNL9yRdLSUi0hUAHfvCHFeFh" + "cfg_authelia_for_owncloud_defaults": { + "web": { + "client_id": "owncloud_web" + }, + "desktop": { + "client_id": "xdXOt13JKxym1B1QcEncf2XDkLAexMBFwiT9j6EfhhHFJhs2KM9jbjTmf8JBXE69", + "client_secret": "UBntmLjC2yYCeHwsyj73Uwo9TAaecAetRwMw0xYcvNL9yRdLSUi0hUAHfvCHFeFh" + }, + "android": { + "client_id": "e4rAsNUSIUs0lF4nbv9FmCeUkTlV9GdgTLDH1b5uie7syb90SzEVrbN7HIpmWJeD", + "client_secret": "dInFYGV33xKzhbRmpqQltYNdfLdJIfJ9L5ISoKhNoT9qZftpdWSP71VrpGR9pmoD" + }, + "ios": { + "client_id": "mxd5OQDk6es5LzOzRvidJNfXLUZS2oN3oUFeXPP8LpPrhx3UroJFduGEYIBOxkY1", + "client_secret": "KFeFWWEZO9TkisIQzR3fo7hfiMXlOpaqP8CFuTbSHzV1TUuGECglPxpiVKJfOXIx" + } + } } diff --git a/roles/authelia-for-owncloud/tasks/main.json b/roles/authelia-for-owncloud/tasks/main.json index 99c0626..8c956db 100644 --- a/roles/authelia-for-owncloud/tasks/main.json +++ b/roles/authelia-for-owncloud/tasks/main.json @@ -1,50 +1,96 @@ [ { - "name": "configuration | compute client secret hash | web", - "become": true, - "ansible.builtin.shell": { - "cmd": "authelia crypto hash generate bcrypt --password {{var_authelia_for_owncloud_web_client_secret}} | cut --delimiter=' ' --fields='2-'" - }, - "register": "temp_authelia_for_owncloud_web_client_secret_hashed" - }, - { - "name": "configuration | compute client secret hash | android", - "become": true, - "ansible.builtin.shell": { - "cmd": "authelia crypto hash generate bcrypt --password {{var_authelia_for_owncloud_android_client_secret}} | cut --delimiter=' ' --fields='2-'" - }, - "register": "temp_authelia_for_owncloud_android_client_secret_hashed" - }, - { - "name": "configuration | compute client secret hash | ios", - "become": true, - "ansible.builtin.shell": { - "cmd": "authelia crypto hash generate bcrypt --password {{var_authelia_for_owncloud_ios_client_secret}} | cut --delimiter=' ' --fields='2-'" - }, - "register": "temp_authelia_for_owncloud_ios_client_secret_hashed" - }, - { - "name": "configuration | compute client secret hash | desktop", - "become": true, - "ansible.builtin.shell": { - "cmd": "authelia crypto hash generate bcrypt --password {{var_authelia_for_owncloud_desktop_client_secret}} | cut --delimiter=' ' --fields='2-'" - }, - "register": "temp_authelia_for_owncloud_desktop_client_secret_hashed" - }, - { - "name": "configuration | emplace", - "become": true, - "loop": [ - {"src": "authelia-client-conf-web.json.j2", "dest": "/etc/authelia/conf.d/clients/owncloud-web.json"}, - {"src": "authelia-client-conf-desktop.json.j2", "dest": "/etc/authelia/conf.d/clients/owncloud-desktop.json"}, - {"src": "authelia-client-conf-android.json.j2", "dest": "/etc/authelia/conf.d/clients/owncloud-android.json"}, - {"src": "authelia-client-conf-ios.json.j2", "dest": "/etc/authelia/conf.d/clients/owncloud-ios.json"} - ], - "ansible.builtin.template": { - "src": "{{item.src}}", - "dest": "{{item.dest}}" + "name": "show vars", + "when": "switch_show_vars", + "ansible.builtin.debug": { + "var": "vars.cfg_authelia_for_owncloud" } }, + { + "name": "configuration | client", + "block": [ + { + "name": "configuration | client | web", + "when": "cfg_authelia_for_owncloud.web != None", + "block": [ + { + "name": "emplace", + "become": true, + "ansible.builtin.template": { + "src": "authelia-client-conf-web.json.j2", + "dest": "/etc/authelia/conf.d/clients/owncloud-web.json" + } + } + ] + }, + { + "name": "configuration | client | desktop", + "when": "cfg_authelia_for_owncloud.desktop != None", + "block": [ + { + "name": "compute client secret hash", + "become": true, + "ansible.builtin.shell": { + "cmd": "authelia crypto hash generate bcrypt --password {{cfg_authelia_for_owncloud.desktop.client_secret}} | cut --delimiter=' ' --fields='2-'" + }, + "register": "temp_authelia_for_owncloud_desktop_client_secret_hashed" + }, + { + "name": "emplace", + "become": true, + "ansible.builtin.template": { + "src": "authelia-client-conf-desktop.json.j2", + "dest": "/etc/authelia/conf.d/clients/owncloud-desktop.json" + } + } + ] + }, + { + "name": "configuration | client | android", + "when": "cfg_authelia_for_owncloud.android != None", + "block": [ + { + "name": "compute client secret hash", + "become": true, + "ansible.builtin.shell": { + "cmd": "authelia crypto hash generate bcrypt --password {{cfg_authelia_for_owncloud.android.client_secret}} | cut --delimiter=' ' --fields='2-'" + }, + "register": "temp_authelia_for_owncloud_android_client_secret_hashed" + }, + { + "name": "emplace", + "become": true, + "ansible.builtin.template": { + "src": "authelia-client-conf-android.json.j2", + "dest": "/etc/authelia/conf.d/clients/owncloud-android.json" + } + } + ] + }, + { + "name": "configuration | client | ios", + "when": "cfg_authelia_for_owncloud.ios != None", + "block": [ + { + "name": "compute client secret hash", + "become": true, + "ansible.builtin.shell": { + "cmd": "authelia crypto hash generate bcrypt --password {{cfg_authelia_for_owncloud.ios.client_secret}} | cut --delimiter=' ' --fields='2-'" + }, + "register": "temp_authelia_for_owncloud_ios_client_secret_hashed" + }, + { + "name": "emplace", + "become": true, + "ansible.builtin.template": { + "src": "authelia-client-conf-ios.json.j2", + "dest": "/etc/authelia/conf.d/clients/owncloud-ios.json" + } + } + ] + } + ] + }, { "name": "configuration | apply", "become": true, diff --git a/roles/authelia-for-owncloud/templates/authelia-client-conf-android.json.j2 b/roles/authelia-for-owncloud/templates/authelia-client-conf-android.json.j2 index b47cbc0..7c39744 100644 --- a/roles/authelia-for-owncloud/templates/authelia-client-conf-android.json.j2 +++ b/roles/authelia-for-owncloud/templates/authelia-client-conf-android.json.j2 @@ -1,19 +1,33 @@ { - "client_id": "{{var_authelia_for_owncloud_android_client_id}}", + "client_id": "{{cfg_authelia_for_owncloud.android.client_id}}", "client_secret": "{{temp_authelia_for_owncloud_android_client_secret_hashed.stdout}}", "client_name": "ownCloud | Android Client", + + "public": false, "authorization_policy": "one_factor", + "require_pkce": true, + "pkce_challenge_method": "S256", "scopes": [ "openid", + "offline_access", "groups", "profile", - "email", - "offline_access" + "email" + ], + "redirect_uris": [ + "oc://android.owncloud.com" + + + ], "response_types": [ "code" ], - "redirect_uris": [ - "oc://android.owncloud.com" - ] + "grant_types": [ + "authorization_code", + "refresh_token" + ], + "access_token_signed_response_alg": "none", + "userinfo_signed_response_alg": "none", + "token_endpoint_auth_method": "client_secret_basic" } diff --git a/roles/authelia-for-owncloud/templates/authelia-client-conf-desktop.json.j2 b/roles/authelia-for-owncloud/templates/authelia-client-conf-desktop.json.j2 index 4338426..2b33bf2 100644 --- a/roles/authelia-for-owncloud/templates/authelia-client-conf-desktop.json.j2 +++ b/roles/authelia-for-owncloud/templates/authelia-client-conf-desktop.json.j2 @@ -1,20 +1,33 @@ { - "client_id": "{{var_authelia_for_owncloud_desktop_client_id}}", + "client_id": "{{cfg_authelia_for_owncloud.desktop.client_id}}", "client_secret": "{{temp_authelia_for_owncloud_desktop_client_secret_hashed.stdout}}", "client_name": "ownCloud | Desktop Client", + + "public": false, "authorization_policy": "one_factor", + "require_pkce": true, + "pkce_challenge_method": "S256", "scopes": [ "openid", + "offline_access", "groups", "profile", - "email", - "offline_access" - ], - "response_types": [ - "code" + "email" ], "redirect_uris": [ "http://127.0.0.1", "http://localhost" - ] + + + ], + "response_types": [ + "code" + ], + "grant_types": [ + "authorization_code", + "refresh_token" + ], + "access_token_signed_response_alg": "none", + "userinfo_signed_response_alg": "none", + "token_endpoint_auth_method": "client_secret_basic" } diff --git a/roles/authelia-for-owncloud/templates/authelia-client-conf-ios.json.j2 b/roles/authelia-for-owncloud/templates/authelia-client-conf-ios.json.j2 index e529c5d..01eefe2 100644 --- a/roles/authelia-for-owncloud/templates/authelia-client-conf-ios.json.j2 +++ b/roles/authelia-for-owncloud/templates/authelia-client-conf-ios.json.j2 @@ -1,20 +1,33 @@ { - "client_id": "{{var_authelia_for_owncloud_ios_client_id}}", + "client_id": "{{cfg_authelia_for_owncloud.ios.client_id}}", "client_secret": "{{temp_authelia_for_owncloud_ios_client_secret_hashed.stdout}}", "client_name": "ownCloud | iOS Client", + + "public": false, "authorization_policy": "one_factor", + "require_pkce": true, + "pkce_challenge_method": "S256", "scopes": [ "openid", + "offline_access", "groups", "profile", - "email", - "offline_access" - ], - "response_types": [ - "code" + "email" ], "redirect_uris": [ "oc://ios.owncloud.com", "oc.ios://ios.owncloud.com" - ] + + + ], + "response_types": [ + "code" + ], + "grant_types": [ + "authorization_code", + "refresh_token" + ], + "access_token_signed_response_alg": "none", + "userinfo_signed_response_alg": "none", + "token_endpoint_auth_method": "client_secret_basic" } diff --git a/roles/authelia-for-owncloud/templates/authelia-client-conf-web.json.j2 b/roles/authelia-for-owncloud/templates/authelia-client-conf-web.json.j2 index 45b6983..8a30c04 100644 --- a/roles/authelia-for-owncloud/templates/authelia-client-conf-web.json.j2 +++ b/roles/authelia-for-owncloud/templates/authelia-client-conf-web.json.j2 @@ -1,20 +1,33 @@ { - "client_id": "{{var_authelia_for_owncloud_web_client_id}}", + "client_id": "{{cfg_authelia_for_owncloud.web.client_id}}", + "client_name": "ownCloud | Web Client", + "lifespan": "long", "public": true, "authorization_policy": "one_factor", + "require_pkce": true, + "pkce_challenge_method": "S256", "scopes": [ "openid", - "email", + "offline_access", + "groups", "profile", - "groups" + "email" + ], + "redirect_uris": [ + "https://{{cfg_authelia_for_owncloud.owncloud_url_base}}", + "https://{{cfg_authelia_for_owncloud.owncloud_url_base}}/oidc-callback.html", + "https://{{cfg_authelia_for_owncloud.owncloud_url_base}}/oidc-silent-redirect.html", + "https://{{cfg_authelia_for_owncloud.owncloud_url_base}}/apps/openidconnect/redirect" ], "response_types": [ "code" ], - "redirect_uris": [ - "{{var_authelia_for_owncloud_owncloud_url_base}}", - "{{var_authelia_for_owncloud_owncloud_url_base}}/oidc-callback.html", - "{{var_authelia_for_owncloud_owncloud_url_base}}/oidc-silent-redirect.html" - ] + "grant_types": [ + "authorization_code", + "refresh_token" + ], + "access_token_signed_response_alg": "none", + "userinfo_signed_response_alg": "none", + "token_endpoint_auth_method": "none" } diff --git a/roles/authelia-for-owncloud/vardef.json b/roles/authelia-for-owncloud/vardef.json deleted file mode 100644 index 531604d..0000000 --- a/roles/authelia-for-owncloud/vardef.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "owncloud_url_base": { - "type": "string", - "mandatory": false - }, - "web_client_id": { - "type": "string", - "mandatory": false - }, - "android_client_id": { - "type": "string", - "mandatory": false - }, - "android_client_secret": { - "type": "string", - "mandatory": true - }, - "ios_client_id": { - "type": "string", - "mandatory": false - }, - "ios_client_secret": { - "type": "string", - "mandatory": true - }, - "dektop_client_id": { - "type": "string", - "mandatory": false - }, - "desktop_client_secret": { - "type": "string", - "mandatory": false - } -} diff --git a/roles/owncloud-and-nginx/cfg.schema.json b/roles/owncloud-and-nginx/cfg.schema.json new file mode 100644 index 0000000..070ca31 --- /dev/null +++ b/roles/owncloud-and-nginx/cfg.schema.json @@ -0,0 +1,31 @@ +{ + "nullable": false, + "type": "object", + "properties": { + "domain": { + "nullable": false, + "type": "string" + }, + "tls_mode": { + "nullable": false, + "type": "string", + "enum": [ + "disable", + "enable", + "force" + ], + "default": "force" + }, + "maximum_upload_size": { + "nullable": false, + "type": "string", + "default": "1G" + } + }, + "additionalProperties": false, + "required": [ + "domain", + "tls_mode", + "maximum_upload_size" + ] +} diff --git a/roles/owncloud-and-nginx/defaults/main.json b/roles/owncloud-and-nginx/defaults/main.json index 9ad192e..cc7e319 100644 --- a/roles/owncloud-and-nginx/defaults/main.json +++ b/roles/owncloud-and-nginx/defaults/main.json @@ -1,5 +1,6 @@ { - "var_owncloud_and_nginx_domain": "owncloud.example.org", - "var_owncloud_and_nginx_tls_mode": "force", - "var_owncloud_and_nginx_maximum_upload_size": "1G" + "cfg_owncloud_and_nginx_defaults": { + "tls_mode": "force", + "maximum_upload_size": "1G" + } } diff --git a/roles/owncloud-and-nginx/tasks/main.json b/roles/owncloud-and-nginx/tasks/main.json index 004dfa3..19e3f42 100644 --- a/roles/owncloud-and-nginx/tasks/main.json +++ b/roles/owncloud-and-nginx/tasks/main.json @@ -1,4 +1,11 @@ [ + { + "name": "show vars", + "when": "switch_show_vars", + "ansible.builtin.debug": { + "var": "vars.cfg_owncloud_and_nginx" + } + }, { "name": "deactivate default site", "become": true, @@ -12,7 +19,7 @@ "become": true, "ansible.builtin.template": { "src": "conf.j2", - "dest": "/etc/nginx/sites-available/{{var_owncloud_and_nginx_domain}}" + "dest": "/etc/nginx/sites-available/{{cfg_owncloud_and_nginx.domain}}" } }, { @@ -20,8 +27,8 @@ "become": true, "ansible.builtin.file": { "state": "link", - "src": "/etc/nginx/sites-available/{{var_owncloud_and_nginx_domain}}", - "dest": "/etc/nginx/sites-enabled/{{var_owncloud_and_nginx_domain}}" + "src": "/etc/nginx/sites-available/{{cfg_owncloud_and_nginx.domain}}", + "dest": "/etc/nginx/sites-enabled/{{cfg_owncloud_and_nginx.domain}}" } }, { diff --git a/roles/owncloud-and-nginx/templates/conf.j2 b/roles/owncloud-and-nginx/templates/conf.j2 index 85e67ab..db4e6ac 100644 --- a/roles/owncloud-and-nginx/templates/conf.j2 +++ b/roles/owncloud-and-nginx/templates/conf.j2 @@ -1,7 +1,7 @@ {% macro owncloud_common() %} location / { proxy_pass http://localhost:9200; - client_max_body_size {{var_owncloud_and_nginx_maximum_upload_size}}; + client_max_body_size {{cfg_owncloud_and_nginx.maximum_upload_size}}; } {% endmacro %} @@ -9,24 +9,24 @@ server { listen 80; listen [::]:80; - server_name {{var_owncloud_and_nginx_domain}}; + server_name {{cfg_owncloud_and_nginx.domain}}; -{% if var_owncloud_and_nginx_tls_mode == 'force' %} +{% if cfg_owncloud_and_nginx.tls_mode == 'force' %} return 301 https://$http_host$request_uri; {% else %} {{ owncloud_common() }} {% endif %} } -{% if var_owncloud_and_nginx_tls_mode != 'disable' %} +{% if cfg_owncloud_and_nginx.tls_mode != 'disable' %} server { listen 443 ssl; listen [::]:443 ssl; - server_name {{var_owncloud_and_nginx_domain}}; + server_name {{cfg_owncloud_and_nginx.domain}}; - ssl_certificate_key /etc/ssl/private/{{var_owncloud_and_nginx_domain}}.pem; - ssl_certificate /etc/ssl/fullchains/{{var_owncloud_and_nginx_domain}}.pem; + ssl_certificate_key /etc/ssl/private/{{cfg_owncloud_and_nginx.domain}}.pem; + ssl_certificate /etc/ssl/fullchains/{{cfg_owncloud_and_nginx.domain}}.pem; include /etc/nginx/ssl-hardening.conf; {{ owncloud_common() }} diff --git a/roles/owncloud-and-nginx/vardef.json b/roles/owncloud-and-nginx/vardef.json deleted file mode 100644 index 7872cb8..0000000 --- a/roles/owncloud-and-nginx/vardef.json +++ /dev/null @@ -1,20 +0,0 @@ - -{ - "domain": { - "type": "string", - "mandatory": false - }, - "tls_mode": { - "type": "string", - "options": [ - "disable", - "enable", - "force" - ], - "mandatory": false - }, - "maximum_upload_size": { - "type": "string", - "mandatory": false - } -} diff --git a/roles/owncloud/cfg.schema.json b/roles/owncloud/cfg.schema.json new file mode 100644 index 0000000..6c3c59d --- /dev/null +++ b/roles/owncloud/cfg.schema.json @@ -0,0 +1,152 @@ +{ + "nullable": false, + "type": "object", + "properties": { + "user": { + "nullable": false, + "type": "string", + "default": "owncloud" + }, + "directory": { + "nullable": false, + "type": "string", + "default": "/opt/owncloud" + }, + "version": { + "nullable": false, + "type": "string", + "default": "7.2.0" + }, + "platform": { + "nullable": false, + "type": "string", + "default": "linux-amd64" + }, + "domain": { + "nullable": false, + "type": "string" + }, + "admin_password": { + "nullable": false, + "type": "string" + }, + "authentication": { + "anyOf": [ + { + "nullable": false, + "type": "object", + "properties": { + "kind": { + "type": "string", + "enum": ["internal"], + "default": "internal" + }, + "data": { + "nullable": false, + "type": "object", + "properties": { + }, + "additionalProperties": false, + "required": [ + ], + "default": { + } + } + }, + "additionalProperties": false, + "required": [ + "kind", + "data" + ] + }, + { + "nullable": false, + "type": "object", + "properties": { + "kind": { + "type": "string", + "enum": ["authelia"], + "default": "authelia" + }, + "data": { + "nullable": false, + "type": "object", + "properties": { + "url_base": { + "nullable": false, + "type": "string" + }, + "web": { + "nullable": true, + "type": "object", + "properties": { + "client_id": { + "type": "string", + "mandatory": false, + "default": "owncloud_web" + } + }, + "additionalProperties": false, + "required": [ + "client_id" + ], + "default": { + } + } + }, + "additionalProperties": false, + "required": [ + "url_base", + "web" + ] + } + }, + "additionalProperties": false, + "required": [ + "kind", + "data" + ] + } + ] + }, + "public_share": { + "nullable": false, + "type": "object", + "properties": { + "password_necessity": { + "nullable": false, + "type": "string", + "enum": [ + "nothing", + "writable", + "all" + ], + "default": "writable" + }, + "password_policy_active": { + "nullable": false, + "type": "boolean", + "default": true + } + }, + "additionalProperties": false, + "required": [ + "password_necessity", + "password_policy_active" + ], + "default": { + } + } + }, + "additionalProperties": false, + "required": [ + "user", + "directory", + "version", + "platform", + "domain", + "admin_password", + "authentication", + "public_share" + ] +} diff --git a/roles/owncloud/defaults/main.json b/roles/owncloud/defaults/main.json index 1101e12..94f4742 100644 --- a/roles/owncloud/defaults/main.json +++ b/roles/owncloud/defaults/main.json @@ -1,18 +1,16 @@ { - "var_owncloud_user": "owncloud", - "var_owncloud_directory": "/opt/owncloud", - "var_owncloud_version": "5.0.0", - "var_owncloud_platform": "linux-amd64", - "var_owncloud_domain": "owncloud.example.org", - "var_owncloud_admin_password": "REPLACE_ME", - "var_owncloud_authentication_kind": "internal", - "var_owncloud_authentication_data_authelia_url_base": "https://authelia.example.org", - "var_owncloud_authentication_data_authelia_web_client_id": "owncloud_web", - "var_owncloud_authentication_data_authelia_web_client_secret": "REPLACE_ME", - "var_owncloud_authentication_data_authelia_android_client_id": "owncloud_android", - "var_owncloud_authentication_data_authelia_android_client_secret": "REPLACE_ME", - "var_owncloud_authentication_data_authelia_ios_client_id": "owncloud_ios", - "var_owncloud_authentication_data_authelia_ios_client_secret": "REPLACE_ME", - "var_owncloud_public_share_password_necessity": "writable", - "var_owncloud_public_share_password_policy_active": true + "cfg_owncloud_defaults": { + "user": "owncloud", + "directory": "/opt/owncloud", + "version": "7.2.0", + "platform": "linux-amd64", + "domain": "owncloud.example.org", + "authentication": { + "kind": "internal" + }, + "public_share": { + "password_necessity": "writable", + "password_policy_active": true + } + } } diff --git a/roles/owncloud/info.md b/roles/owncloud/info.md index b74ee6d..d8d8e95 100644 --- a/roles/owncloud/info.md +++ b/roles/owncloud/info.md @@ -7,13 +7,26 @@ Cloud-Plattform [ownCloud](https://owncloud.com/) (the rewrite in Go named "Infi - [ownCloud-Dokumentation | How to install ownCloud Infinite Scale Tech Preview in three easy steps](https://owncloud.com/news/howto-install-owncloud-infinite-scale-tech-preview/) - [ownCloud-Dokumentation | oCIS](https://owncloud.dev/ocis/) -- [ownCloud-Dokumentation | Service | Proxy](https://doc.owncloud.com/ocis/next/deployment/services/s-list/proxy.html) +- [ownCloud-Dokumentation | Upgrading](https://doc.owncloud.com/ocis/next/migration/upgrading-ocis.html) +- [ownCloud-Dokumentation | env var types](https://doc.owncloud.com/ocis/next/deployment/services/envvar-types-description.html) - [ownCloud-Dokumentation | Service | Web](https://doc.owncloud.com/ocis/next/deployment/services/s-list/web.html) +- [ownCloud-Dokumentation | Service | Proxy](https://doc.owncloud.com/ocis/next/deployment/services/s-list/proxy.html) - [ownCloud-Dokumentation | Service | Sharing](https://doc.owncloud.com/ocis/next/deployment/services/s-list/sharing.html) - [GitHub | ocis](https://github.com/owncloud/ocis/) - [ownCloud-Foren | OCIS + Authelia](https://central.owncloud.org/t/ocis-authelia/44222) +## Bemerkungen + +- die `.ocis/config/ocis.yaml` wird erzeugt auf Grundlage der `.env` +- `.ocis/config/ocis.yaml` sollte niemals einfach neu erstellt werden, da man sich sonst nicht mehr einloggen kann +- wenn man sich plötzlich nicht mehr über OIDC anmelden kann, kann das daran lieget, dass `.ocis/idm/ldap.crt` abgelaufen ist — siehe dazu [diesen Thread](https://central.owncloud.org/t/certificate-error-after-upgrade-to-5-0-0-from-4-0-6/47824/7); man könnte auch `OCIS_LDAP_INSECURE` auf `true` setzen, aber naja… + + ## ToDo - Download prüfen +- `csp.yaml` einsetzen +- prüfen ob folgende `.env`-Variablen gebraucht werden: + - `PROXY_OIDC_ISSUER` + - `PROXY_OIDC_SKIP_USER_INFO` diff --git a/roles/owncloud/tasks/main.json b/roles/owncloud/tasks/main.json index 0a6e356..af5b1b3 100644 --- a/roles/owncloud/tasks/main.json +++ b/roles/owncloud/tasks/main.json @@ -1,39 +1,70 @@ [ + { + "name": "show vars", + "when": "switch_show_vars", + "ansible.builtin.debug": { + "var": "vars.cfg_owncloud" + } + }, { "name": "user", "become": true, "ansible.builtin.user": { - "name": "{{var_owncloud_user}}", + "name": "{{cfg_owncloud.user}}", "create_home": true, - "home": "{{var_owncloud_directory}}" + "home": "{{cfg_owncloud.directory}}" } }, { "name": "download", "become": true, - "become_user": "{{var_owncloud_user}}", + "become_user": "{{cfg_owncloud.user}}", "ansible.builtin.get_url": { - "url": "https://download.owncloud.com/ocis/ocis/stable/{{var_owncloud_version}}/ocis-{{var_owncloud_version}}-{{var_owncloud_platform}}", - "dest": "{{var_owncloud_directory}}/ocis", + "url": "https://download.owncloud.com/ocis/ocis/stable/{{cfg_owncloud.version}}/ocis-{{cfg_owncloud.version}}-{{cfg_owncloud.platform}}", + "dest": "{{cfg_owncloud.directory}}/ocis", "mode": "u+rx" } }, + { + "name": "directories", + "become": true, + "become_user": "{{cfg_owncloud.user}}", + "loop": [ + "log" + ], + "ansible.builtin.file": { + "state": "directory", + "recurse": true, + "path": "{{cfg_owncloud.directory}}/{{item}}" + } + }, + { + "name": "csp", + "become": true, + "become_user": "{{cfg_owncloud.user}}", + "ansible.builtin.template": { + "src": "csp.yaml.j2", + "mode": "644", + "dest": "{{cfg_owncloud.directory}}/csp.yaml" + } + }, + { + "name": "env", + "become": true, + "become_user": "{{cfg_owncloud.user}}", + "ansible.builtin.template": { + "src": "env.j2", + "mode": "644", + "dest": "{{cfg_owncloud.directory}}/.env" + } + }, { "name": "setup", "become": true, - "become_user": "{{var_owncloud_user}}", + "become_user": "{{cfg_owncloud.user}}", "ansible.builtin.shell": { - "chdir": "{{var_owncloud_directory}}", - "cmd": "rm -f {{var_owncloud_directory}}/.ocis/config/ocis.yaml && ./ocis init --insecure no --admin-password={{var_owncloud_admin_password}}" - } - }, - { - "name": "configuration", - "become": true, - "become_user": "{{var_owncloud_user}}", - "ansible.builtin.template": { - "src": "env.j2", - "dest": "{{var_owncloud_directory}}/.env" + "chdir": "{{cfg_owncloud.directory}}", + "cmd": "./ocis init --insecure no --admin-password={{cfg_owncloud.admin_password}}" } }, { diff --git a/roles/owncloud/templates/csp.yaml.j2 b/roles/owncloud/templates/csp.yaml.j2 new file mode 100644 index 0000000..2373aa5 --- /dev/null +++ b/roles/owncloud/templates/csp.yaml.j2 @@ -0,0 +1,7 @@ +directives: + connect-src: + - '''self''' + - 'https://{{cfg_owncloud.domain}}' +{% if cfg_owncloud.authentication.kind == 'authelia' %} + - '{{cfg_owncloud.authentication.data.url_base}}' +{% endif %} diff --git a/roles/owncloud/templates/env.j2 b/roles/owncloud/templates/env.j2 index 1c53400..e11062a 100644 --- a/roles/owncloud/templates/env.j2 +++ b/roles/owncloud/templates/env.j2 @@ -1,44 +1,62 @@ -OCIS_URL="https://{{var_owncloud_domain}}" -OCIS_INSECURE="false" - -PROXY_TLS="false" - -{% if var_owncloud_authentication_kind == 'internal' %} -PROXY_AUTOPROVISION_ACCOUNTS="false" +## web client +WEB_LOG_LEVEL=info +WEB_LOG_FILE={{cfg_owncloud.directory}}/log/web +WEB_LOG_PRETTY=true +WEB_LOG_COLOR=true +{% if cfg_owncloud.authentication.kind == 'internal' %} +{% endif %} +{% if cfg_owncloud.authentication.kind == 'authelia' %} +WEB_OIDC_AUTHORITY={{cfg_owncloud.authentication.data.url_base}} +WEB_OIDC_CLIENT_ID={{cfg_owncloud.authentication.data.web.client_id}} +WEB_OIDC_RESPONSE_TYPE=code +WEB_OIDC_SCOPE=openid profile email groups +WEB_OPTION_LOGIN_URL={{cfg_owncloud.authentication.data.url_base}} +WEB_OPTION_LOGOUT_URL={{cfg_owncloud.authentication.data.url_base}} +WEB_UI_THEME_SERVER=https://{{cfg_owncloud.domain}} +WEB_UI_CONFIG_SERVER=https://{{cfg_owncloud.domain}} {% endif %} -{% if var_owncloud_authentication_kind == 'authelia' %} -OCIS_OIDC_CLIENT_ID="{{var_owncloud_authentication_data_authelia_web_client_id}}" -OCIS_OIDC_ISSUER="{{var_owncloud_authentication_data_authelia_url_base}}" - -PROXY_AUTOPROVISION_ACCOUNTS="true" -PROXY_OIDC_REWRITE_WELLKNOWN="true" -PROXY_OIDC_ACCESS_TOKEN_VERIFY_METHOD="none" -PROXY_OIDC_INSECURE="false" -PROXY_USER_OIDC_CLAIM="name" -PROXY_USER_CS3_CLAIM="username" - -WEB_OIDC_AUTHORITY="{{var_owncloud_authentication_data_authelia_url_base}}" -WEB_OIDC_METADATA_URL="{{var_owncloud_authentication_data_authelia_url_base}}/.well-known/openid-configuration" -WEB_OIDC_CLIENT_ID="{{var_owncloud_authentication_data_authelia_web_client_id}}" -WEB_OIDC_SCOPE="openid profile email groups" +## other clients +PROXY_LOG_LEVEL=info +PROXY_LOG_FILE={{cfg_owncloud.directory}}/log/proxy +PROXY_LOG_PRETTY=true +PROXY_LOG_COLOR=true +PROXY_CSP_CONFIG_FILE_LOCATION={{cfg_owncloud.directory}}/csp.yaml +PROXY_TLS=false +{% if cfg_owncloud.authentication.kind == 'internal' %} +PROXY_AUTOPROVISION_ACCOUNTS=false +{% endif %} +{% if cfg_owncloud.authentication.kind == 'authelia' %} +OCIS_URL=https://{{cfg_owncloud.domain}} +PROXY_OIDC_ISSUER={{cfg_owncloud.authentication.data.url_base}} +PROXY_OIDC_REWRITE_WELLKNOWN=true +PROXY_OIDC_ACCESS_TOKEN_VERIFY_METHOD=none +PROXY_OIDC_SKIP_USER_INFO=false +PROXY_AUTOPROVISION_ACCOUNTS=true +PROXY_AUTOPROVISION_CLAIM_USERNAME=preferred_username +PROXY_AUTOPROVISION_CLAIM_EMAIL=email +PROXY_AUTOPROVISION_CLAIM_DISPLAYNAME=name +PROXY_AUTOPROVISION_CLAIM_GROUPS=groups +PROXY_USER_OIDC_CLAIM=preferred_username +PROXY_USER_CS3_CLAIM=username {% endif %} -{% if var_owncloud_public_share_password_necessity == 'nothing' %} -OCIS_SHARING_PUBLIC_SHARE_MUST_HAVE_PASSWORD="false" -OCIS_SHARING_PUBLIC_WRITEABLE_SHARE_MUST_HAVE_PASSWORD="false" +## sharing +{% if cfg_owncloud.public_share.password_necessity == 'nothing' %} +OCIS_SHARING_PUBLIC_SHARE_MUST_HAVE_PASSWORD=false +OCIS_SHARING_PUBLIC_WRITEABLE_SHARE_MUST_HAVE_PASSWORD=false {% endif %} -{% if var_owncloud_public_share_password_necessity == 'writable' %} -OCIS_SHARING_PUBLIC_SHARE_MUST_HAVE_PASSWORD="false" -OCIS_SHARING_PUBLIC_WRITEABLE_SHARE_MUST_HAVE_PASSWORD="true" +{% if cfg_owncloud.public_share.password_necessity == 'writable' %} +OCIS_SHARING_PUBLIC_SHARE_MUST_HAVE_PASSWORD=false +OCIS_SHARING_PUBLIC_WRITEABLE_SHARE_MUST_HAVE_PASSWORD=true {% endif %} -{% if var_owncloud_public_share_password_necessity == 'all' %} -OCIS_SHARING_PUBLIC_SHARE_MUST_HAVE_PASSWORD="true" -OCIS_SHARING_PUBLIC_WRITEABLE_SHARE_MUST_HAVE_PASSWORD="true" +{% if cfg_owncloud.public_share.password_necessity == 'all' %} +OCIS_SHARING_PUBLIC_SHARE_MUST_HAVE_PASSWORD=true +OCIS_SHARING_PUBLIC_WRITEABLE_SHARE_MUST_HAVE_PASSWORD=true {% endif %} - -{% if var_owncloud_public_share_password_policy_active %} -OCIS_SHARING_PASSWORD_POLICY_DISABLED="false" +{% if cfg_owncloud.public_share.password_policy_active %} +OCIS_SHARING_PASSWORD_POLICY_DISABLED=false {% else %} -OCIS_SHARING_PASSWORD_POLICY_DISABLED="true" +OCIS_SHARING_PASSWORD_POLICY_DISABLED=true {% endif %} + diff --git a/roles/owncloud/templates/systemd_unit.j2 b/roles/owncloud/templates/systemd_unit.j2 index 7e43971..8db49d4 100644 --- a/roles/owncloud/templates/systemd_unit.j2 +++ b/roles/owncloud/templates/systemd_unit.j2 @@ -3,12 +3,12 @@ Description=ownCloud After=network.target [Service] -WorkingDirectory={{var_owncloud_directory}} -EnvironmentFile={{var_owncloud_directory}}/.env -ExecStart={{var_owncloud_directory}}/ocis server +WorkingDirectory={{cfg_owncloud.directory}} +EnvironmentFile={{cfg_owncloud.directory}}/.env +ExecStart={{cfg_owncloud.directory}}/ocis server Type=simple Restart=always -User={{var_owncloud_user}} +User={{cfg_owncloud.user}} [Install] WantedBy=default.target diff --git a/roles/owncloud/vardef.json b/roles/owncloud/vardef.json deleted file mode 100644 index 6641a03..0000000 --- a/roles/owncloud/vardef.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "user": { - "type": "string", - "mandatory": false - }, - "directory": { - "type": "string", - "mandatory": false - }, - "version": { - "type": "string", - "mandatory": false - }, - "platform": { - "type": "string", - "mandatory": false - }, - "domain": { - "type": "string", - "mandatory": false - }, - "admin_password": { - "type": "string", - "mandatory": true - }, - "authentication_kind": { - "type": "string", - "mandatory": false, - "options": [ - "internal", - "authelia" - ] - }, - "authentication_data_authelia_url_base": { - "type": "string", - "mandatory": false - }, - "authentication_data_authelia_web_client_id": { - "type": "string", - "mandatory": false - }, - "authentication_data_authelia_web_client_secret": { - "type": "string", - "mandatory": false - }, - "authentication_data_authelia_android_client_id": { - "type": "string", - "mandatory": false - }, - "authentication_data_authelia_android_client_secret": { - "type": "string", - "mandatory": false - }, - "authentication_data_authelia_ios_client_id": { - "type": "string", - "mandatory": false - }, - "authentication_data_authelia_ios_client_secret": { - "type": "string", - "mandatory": false - }, - "public_share_password_necessity": { - "type": "string", - "mandatory": false, - "options": [ - "nothing", - "writable", - "all" - ] - }, - "public_share_password_policy_active": { - "type": "boolean", - "mandatory": false - } -}