diff options
author | Stonewall Jackson <stonewall@sacredheartsc.com> | 2023-02-04 01:23:43 -0500 |
---|---|---|
committer | Stonewall Jackson <stonewall@sacredheartsc.com> | 2023-02-04 01:52:13 -0500 |
commit | 0261e875679f1bf63c8d689da7fc7e014597885d (patch) | |
tree | 3f19cd74a0c1070944f75437f30b098d6ef2ffcb /roles/sabredav | |
download | selfhosted-0261e875679f1bf63c8d689da7fc7e014597885d.tar.gz selfhosted-0261e875679f1bf63c8d689da7fc7e014597885d.zip |
initial commit
Diffstat (limited to 'roles/sabredav')
-rw-r--r-- | roles/sabredav/defaults/main.yml | 7 | ||||
-rw-r--r-- | roles/sabredav/tasks/composer.yml | 10 | ||||
-rw-r--r-- | roles/sabredav/tasks/database.yml | 46 | ||||
-rw-r--r-- | roles/sabredav/tasks/freeipa.yml | 27 | ||||
-rw-r--r-- | roles/sabredav/tasks/main.yml | 77 | ||||
-rw-r--r-- | roles/sabredav/templates/var/www/sabredav/server.php.j2 | 61 | ||||
-rw-r--r-- | roles/sabredav/vars/main.yml | 60 |
7 files changed, 288 insertions, 0 deletions
diff --git a/roles/sabredav/defaults/main.yml b/roles/sabredav/defaults/main.yml new file mode 100644 index 0000000..87b98ee --- /dev/null +++ b/roles/sabredav/defaults/main.yml @@ -0,0 +1,7 @@ +sabredav_version: master +sabredav_user: s-sabredav +sabredav_db_name: sabredav +sabredav_db_host: '{{ postgresql_host }}' +sabredav_imip_from: calendar-noreply@{{ email_domain }} +sabredav_access_group: role-dav-access +sabredav_kerberized_cidrs: '{{ kerberized_cidrs }}' diff --git a/roles/sabredav/tasks/composer.yml b/roles/sabredav/tasks/composer.yml new file mode 100644 index 0000000..c3aaedd --- /dev/null +++ b/roles/sabredav/tasks/composer.yml @@ -0,0 +1,10 @@ +- name: download composer installer + get_url: + url: '{{ sabredav_composer_url }}' + dest: /tmp/composer-setup.php + +- name: install composer + command: >- + php /tmp/composer-setup.php + --install-dir=/usr/local/bin + --filename=composer diff --git a/roles/sabredav/tasks/database.yml b/roles/sabredav/tasks/database.yml new file mode 100644 index 0000000..0089788 --- /dev/null +++ b/roles/sabredav/tasks/database.yml @@ -0,0 +1,46 @@ +- name: create database + postgresql_db: + name: '{{ sabredav_db_name }}' + state: present + delegate_to: "{{ postgresql_inventory_host }}" + become: yes + become_user: postgres + +- name: create database user + postgresql_user: + name: '{{ sabredav_user }}' + db: '{{ sabredav_db_name }}' + priv: ALL + state: present + delegate_to: "{{ postgresql_inventory_host }}" + become: yes + become_user: postgres + +- name: check if database schema is initialized + postgresql_query: + login_user: '{{ sabredav_user }}' + login_host: '{{ sabredav_db_host }}' + db: '{{ sabredav_db_name }}' + query: SELECT 1 FROM calendars + become: yes + become_user: apache + environment: + GSS_USE_PROXY: 'yes' + register: sabredav_check_db + failed_when: no + +- name: initialize database schema + postgresql_query: + login_user: '{{ sabredav_user }}' + login_host: '{{ sabredav_db_host }}' + db: '{{ sabredav_db_name }}' + path_to_script: '{{ sabredav_home }}/pgsql.schema.sql' + as_single_query: yes + become: yes + become_user: apache + environment: + GSS_USE_PROXY: 'yes' + when: + - sabredav_check_db.msg is defined + - sabredav_check_db.msg is search('relation "calendars" does not exist') + diff --git a/roles/sabredav/tasks/freeipa.yml b/roles/sabredav/tasks/freeipa.yml new file mode 100644 index 0000000..d2c841e --- /dev/null +++ b/roles/sabredav/tasks/freeipa.yml @@ -0,0 +1,27 @@ +- name: create user + ipauser: + ipaadmin_principal: '{{ ipa_user }}' + ipaadmin_password: '{{ ipa_pass }}' + name: '{{ sabredav_user }}' + loginshell: /sbin/nologin + homedir: '{{ sabredav_home }}' + givenname: SabreDAV + sn: Service Account + state: present + run_once: yes + +- name: retrieve user keytab + include_role: + name: freeipa_keytab + vars: + keytab_principal: '{{ sabredav_user }}' + keytab_path: '{{ sabredav_keytab }}' + +- name: create access group + ipagroup: + ipaadmin_principal: '{{ ipa_user }}' + ipaadmin_password: '{{ ipa_pass }}' + name: '{{ sabredav_access_group }}' + nonposix: yes + state: present + run_once: yes diff --git a/roles/sabredav/tasks/main.yml b/roles/sabredav/tasks/main.yml new file mode 100644 index 0000000..36b8326 --- /dev/null +++ b/roles/sabredav/tasks/main.yml @@ -0,0 +1,77 @@ +- name: install packages + dnf: + name: '{{ sabredav_packages }}' + state: present + +- name: create webroot + file: + path: '{{ sabredav_home }}' + state: directory + +- name: clone git repository + git: + repo: '{{ sabredav_git_repo }}' + dest: '{{ sabredav_home }}' + version: '{{ sabredav_version }}' + +- name: set permissions on writeable directories + file: + path: '{{ sabredav_home }}/{{ item }}' + state: directory + mode: 0770 + owner: apache + group: apache + setype: httpd_sys_rw_content_t + loop: '{{ sabredav_writable_dirs }}' + +- name: set selinux context on writeable directories + sefcontext: + target: '{{ sabredav_home }}/{{ item }}(/.*)?' + setype: httpd_sys_rw_content_t + state: present + loop: '{{ sabredav_writable_dirs }}' + register: sabredav_writeable_sefcontext + tags: selinux + +- name: apply selinux context to writeable directories + command: 'restorecon -R {{ sabredav_home }}/{{ item }}' + when: sabredav_writeable_sefcontext.results[index].changed + loop: '{{ sabredav_writable_dirs }}' + loop_control: + index_var: index + tags: selinux + +- import_tasks: freeipa.yml + tags: freeipa + +- name: configure gssproxy for kerberized postgres + include_role: + name: gssproxy_client + vars: + gssproxy_name: sabredav + gssproxy_section: service/php-fpm + gssproxy_client_keytab: '{{ sabredav_keytab }}' + gssproxy_cred_usage: initiate + gssproxy_euid: apache + +- name: check if composer is installed + stat: + path: /usr/local/bin/composer + register: stat_composer + +- name: install composer + include_tasks: composer.yml + when: not stat_composer.stat.exists + +- name: install dependencies using composer + composer: + command: install + working_dir: '{{ sabredav_home }}' + +- name: generate sabredav configuration + template: + src: '{{ sabredav_home[1:] }}/server.php.j2' + dest: '{{ sabredav_home }}/server.php' + +- import_tasks: database.yml + tags: database diff --git a/roles/sabredav/templates/var/www/sabredav/server.php.j2 b/roles/sabredav/templates/var/www/sabredav/server.php.j2 new file mode 100644 index 0000000..36bc973 --- /dev/null +++ b/roles/sabredav/templates/var/www/sabredav/server.php.j2 @@ -0,0 +1,61 @@ +<?php + +// timezone +date_default_timezone_set('UTC'); + +// database +$pdo = new PDO('pgsql:dbname={{ sabredav_db_name }};host={{ sabredav_db_host }}', '{{ sabredav_user }}'); +$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); + +// autoloader +require_once 'vendor/autoload.php'; + +// freeipa +$ipa = new \FreeIPA\Connection(); +$allowedGroups = ['{{ sabredav_access_group }}']; + +// backends +$principalBackend = new \FreeIPA\PrincipalBackend($ipa, $allowedGroups); +$caldavBackend = new \Sabre\CalDAV\Backend\PDO($pdo); +$carddavBackend = new \Sabre\CardDAV\Backend\PDO($pdo); +$authBackend = new \FreeIPA\AuthBackend($ipa, $caldavBackend, $carddavBackend, $allowedGroups); +$lockBackend = new \Sabre\DAV\Locks\Backend\PDO($pdo); + +// directory structure +$server = new Sabre\DAV\Server([ + new \Sabre\CalDAV\Principal\Collection($principalBackend), + new \Sabre\CalDAV\CalendarRoot($principalBackend, $caldavBackend), + new \Sabre\CardDAV\AddressBookRoot($principalBackend, $carddavBackend), + new \Sabre\DAVACL\FS\HomeCollection($principalBackend, __DIR__.'/webdav') +]); + +// plugins +$server->addPlugin(new \Sabre\DAV\Auth\Plugin($authBackend,'SabreDAV')); +$server->addPlugin(new \Sabre\DAV\Browser\Plugin()); +$server->addPlugin(new \Sabre\DAV\Sync\Plugin()); +$server->addPlugin(new \Sabre\DAV\Sharing\Plugin()); + +$aclPlugin = new \Sabre\DAVACL\Plugin(); +$aclPlugin->hideNodesFromListings = true; +$server->addPlugin($aclPlugin); + +// webdav plugins +$server->addPlugin(new \Sabre\DAV\Locks\Plugin($lockBackend)); +$server->addPlugin(new \Sabre\DAV\Browser\GuessContentType()); +$server->addPlugin(new \Sabre\DAV\TemporaryFileFilterPlugin(__DIR__.'/tmpdata')); + +// caldav plugins +$server->addPlugin(new \Sabre\CalDAV\Plugin()); +$server->addPlugin(new \Sabre\CalDAV\Schedule\Plugin()); +$server->addPlugin(new \Sabre\CalDAV\Schedule\IMipPlugin('{{ sabredav_imip_from }}')); +$server->addPlugin(new \Sabre\CalDAV\Subscriptions\Plugin()); +$server->addPlugin(new \Sabre\CalDAV\Notifications\Plugin()); +$server->addPlugin(new \Sabre\CalDAV\SharingPlugin()); +$server->addPlugin(new \Sabre\CalDAV\ICSExportPlugin()); + +// carddav plugins +$server->addPlugin(new \Sabre\CardDAV\Plugin()); +$server->addPlugin(new \Sabre\CardDAV\VCFExportPlugin()); + +// lets goooooo +$server->exec(); diff --git a/roles/sabredav/vars/main.yml b/roles/sabredav/vars/main.yml new file mode 100644 index 0000000..6463d37 --- /dev/null +++ b/roles/sabredav/vars/main.yml @@ -0,0 +1,60 @@ +sabredav_packages: + - php + - php-json + - php-ldap + - php-mbstring + - php-opcache + - php-pdo + - php-pgsql + - php-pecl-zip + - php-xml + - python3-psycopg2 + - git + +sabredav_composer_url: https://getcomposer.org/installer + +sabredav_git_repo: https://github.com/sacredheartsc/sabredav-freeipa + +sabredav_home: /var/www/sabredav +sabredav_keytab: /var/lib/gssproxy/clients/{{ sabredav_user }}.keytab + +sabredav_writable_dirs: + - webdav + - tmpdata + +sabredav_php_environment: + GSS_USE_PROXY: 'yes' + +sabredav_php_flags: + output_buffering: no + always_populate_raw_post_data: no + mbstring.func_overload: no + +sabredav_archive_shell: >- + TIMESTAMP=$(date +%Y%m%d%H%M%S); + tar czf "webdav-${TIMESTAMP}.tar.gz" + --transform "s|^\.|webdav-${TIMESTAMP}|" + -C "{{ sabredav_home }}/webdav" . + +sabredav_apache_config: | + Redirect /.well-known/caldav /server.php + Redirect /.well-known/carddav /server.php + + RewriteEngine On + RewriteCond %{REQUEST_URI} !^/\.well-known/ + RewriteRule .* /server.php [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L] + + <Location /> + AuthName "FreeIPA Single Sign-On" + <If "{% for cidr in sabredav_kerberized_cidrs %}-R '{{ cidr }}'{% if not loop.last %} || {% endif %}{% endfor %}"> + AuthType GSSAPI + GssapiLocalName On + {{ apache_gssapi_session_config }} + </If> + <Else> + AuthType Basic + AuthBasicProvider ldap + </Else> + {{ apache_ldap_config }} + Require ldap-attribute memberof=cn={{ sabredav_access_group }},{{ freeipa_group_basedn }} + </Location> |