From 769a658f0292885fb76d301b2386a53096248145 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thorben=20G=C3=BCnther?= Date: Wed, 18 May 2022 12:33:17 +0200 Subject: [PATCH] hedgedoc: Markdown editor Use as a substitution for bookstack. Bookstack does not support PostgreSQL as a database, maintaining MariaDB just for one service is a hassle. Furthermore hedgedoc does have an official package. --- playbooks/avalon.yml | 1 + roles/hedgedoc/files/hedgedoc.conf | 40 ++++++++++++++++ roles/hedgedoc/handlers/main.yml | 5 ++ roles/hedgedoc/tasks/main.yml | 48 +++++++++++++++++++ roles/hedgedoc/templates/config.json.j2 | 61 +++++++++++++++++++++++++ terraform_hetzner/locals.tf | 2 +- terraform_keycloak/keycloak.tf | 46 +++++++++++++++++++ 7 files changed, 202 insertions(+), 1 deletion(-) create mode 100644 roles/hedgedoc/files/hedgedoc.conf create mode 100644 roles/hedgedoc/handlers/main.yml create mode 100644 roles/hedgedoc/tasks/main.yml create mode 100644 roles/hedgedoc/templates/config.json.j2 diff --git a/playbooks/avalon.yml b/playbooks/avalon.yml index 92b3e2e..67cd365 100644 --- a/playbooks/avalon.yml +++ b/playbooks/avalon.yml @@ -51,3 +51,4 @@ - { role: gotify_app } - { role: matrix } - { role: coturn } + - { role: hedgedoc } diff --git a/roles/hedgedoc/files/hedgedoc.conf b/roles/hedgedoc/files/hedgedoc.conf new file mode 100644 index 0000000..afab380 --- /dev/null +++ b/roles/hedgedoc/files/hedgedoc.conf @@ -0,0 +1,40 @@ +map $http_upgrade $connection_upgrade { + default upgrade; + '' close; +} + +server { + include /etc/nginx/snippets/http.conf; + server_name hedgedoc.xenrox.net; +} + +server { + include /etc/nginx/snippets/https.conf; + server_name hedgedoc.xenrox.net; + + location / { + proxy_pass http://127.0.0.1:3002; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + } + + location /socket.io/ { + proxy_pass http://127.0.0.1:3002; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + proxy_set_header X-Forwarded-Proto $scheme; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection $connection_upgrade; + } + + location = /status { + return 403; + } + + location = /metrics { + return 403; + } +} diff --git a/roles/hedgedoc/handlers/main.yml b/roles/hedgedoc/handlers/main.yml new file mode 100644 index 0000000..72a3ad8 --- /dev/null +++ b/roles/hedgedoc/handlers/main.yml @@ -0,0 +1,5 @@ +--- +- name: Restart hedgedoc + ansible.builtin.systemd: + name: hedgedoc + state: restarted diff --git a/roles/hedgedoc/tasks/main.yml b/roles/hedgedoc/tasks/main.yml new file mode 100644 index 0000000..a8a73bb --- /dev/null +++ b/roles/hedgedoc/tasks/main.yml @@ -0,0 +1,48 @@ +--- +- name: Get secrets + ansible.builtin.set_fact: + hedgedoc_secrets: "{{ lookup('community.hashi_vault.hashi_vault', 'ansible/data/hedgedoc') }}" + +- name: Install + community.general.pacman: + name: hedgedoc + state: present + +- name: Create db user + community.general.postgresql_user: + name: hedgedoc + password: "{{ hedgedoc_secrets['psql_password'] }}" + become: true + become_user: postgres + no_log: true + +- name: Create db + community.general.postgresql_db: + db: hedgedoc + owner: hedgedoc + become: true + become_user: postgres + +- name: Configure + ansible.builtin.template: + src: config.json.j2 + dest: /etc/webapps/hedgedoc/config.json + owner: hedgedoc + group: hedgedoc + mode: 0600 + notify: Restart hedgedoc + +- name: Start and enable + ansible.builtin.systemd: + name: hedgedoc + enabled: true + state: started + +- name: Copy nginx conf + ansible.builtin.copy: + src: hedgedoc.conf + dest: /etc/nginx/nginx.d/hedgedoc.conf + owner: root + group: root + mode: 0644 + notify: restart nginx diff --git a/roles/hedgedoc/templates/config.json.j2 b/roles/hedgedoc/templates/config.json.j2 new file mode 100644 index 0000000..031f5f6 --- /dev/null +++ b/roles/hedgedoc/templates/config.json.j2 @@ -0,0 +1,61 @@ +{ + "production": { + "domain": "hedgedoc.xenrox.net", + "port": 3002, + "loglevel": "info", + "protocolUseSSL": true, + "allowAnonymous": false, + "allowAnonymousEdits": true, + "defaultPermission": "private", + "sessionSecret": "{{ hedgedoc_secrets['session_secret'] }}", + "email": false, + "hsts": { + "enable": true, + "maxAgeSeconds": 31536000, + "includeSubdomains": true, + "preload": true + }, + "csp": { + "enable": true, + "directives": {}, + "upgradeInsecureRequests": "true", + "addDefaults": true, + "addDisqus": true, + "addGoogleAnalytics": false, + "allowFraming": false, + "allowPDFEmbed": false + }, + "cookiePolicy": "lax", + "db": { + "username": "hedgedoc", + "password": "{{ hedgedoc_secrets['psql_password'] }}", + "database": "hedgedoc", + "host": "localhost", + "port": "5432", + "dialect": "postgres" + }, + "oauth2": { + "providerName": "Keycloak", + "userProfileURL": "https://keycloak.xenrox.net/auth/realms/xenrox/protocol/openid-connect/userinfo", + "userProfileUsernameAttr": "preferred_username", + "userProfileDisplayNameAttr": "name", + "userProfileEmailAttr": "email", + "tokenURL": "https://keycloak.xenrox.net/auth/realms/xenrox/protocol/openid-connect/token", + "authorizationURL": "https://keycloak.xenrox.net/auth/realms/xenrox/protocol/openid-connect/auth", + "clientID": "openid_hedgedoc", + "clientSecret": "{{ hedgedoc_secrets['oidc_secret'] }}", + "scope": "openid profile email roles", + "rolesClaim": "roles", + "accessRole": "hedgedoc" + }, + "minio": { + "accessKey": "{{ hedgedoc_secrets['s3_access'] }}", + "secretKey": "{{ hedgedoc_secrets['s3_secret'] }}", + "endPoint": "minio.xenrox.net", + "secure": true, + "port": 443 + }, + "s3bucket": "hedgedoc", + "imageUploadType": "minio" + } +} diff --git a/terraform_hetzner/locals.tf b/terraform_hetzner/locals.tf index 921ab8c..c342dbe 100644 --- a/terraform_hetzner/locals.tf +++ b/terraform_hetzner/locals.tf @@ -15,7 +15,7 @@ locals { "rooms", "pubsub", # oidc - "cloud", "grafana", "keycloak", "tube", "vault", "matrix", + "cloud", "grafana", "keycloak", "tube", "vault", "matrix", "hedgedoc", # minio "minio", "tube.minio", diff --git a/terraform_keycloak/keycloak.tf b/terraform_keycloak/keycloak.tf index 015993d..c8c7a4b 100644 --- a/terraform_keycloak/keycloak.tf +++ b/terraform_keycloak/keycloak.tf @@ -362,6 +362,52 @@ resource "keycloak_group_roles" "matrix" { role_ids = [keycloak_role.matrix.id] } +# Hedgedoc + +data "vault_generic_secret" "hedgedoc" { + path = "ansible/hedgedoc" +} + +resource "keycloak_openid_client" "hedgedoc_openid_client" { + realm_id = "xenrox" + client_id = "openid_hedgedoc" + client_secret = data.vault_generic_secret.hedgedoc.data["oidc_secret"] + + name = "Hedgedoc" + enabled = true + standard_flow_enabled = true + + access_type = "CONFIDENTIAL" + valid_redirect_uris = [ + "https://hedgedoc.xenrox.net/*" + ] +} + +resource "keycloak_openid_user_realm_role_protocol_mapper" "hedgedoc_user_realm_role_mapper" { + realm_id = "xenrox" + client_id = keycloak_openid_client.hedgedoc_openid_client.id + name = "user realm role mapper" + claim_name = "roles" + multivalued = true +} + +resource "keycloak_group" "hedgedoc" { + realm_id = "xenrox" + name = "Hedgedoc" +} + +resource "keycloak_role" "hedgedoc" { + realm_id = "xenrox" + name = "hedgedoc" + description = "Hedgedoc user" +} + +resource "keycloak_group_roles" "hedgedoc" { + realm_id = "xenrox" + group_id = keycloak_group.hedgedoc.id + role_ids = [keycloak_role.hedgedoc.id] +} + # Bookstack data "vault_generic_secret" "bookstack" { -- 2.44.0