From 0a9f436300e3e257fb50b718349d41d10d079342 Mon Sep 17 00:00:00 2001 From: Jakob Meier Date: Tue, 31 Oct 2023 15:17:47 +0100 Subject: [PATCH] Initiali commit Added ability to setup the meta module and some core database services --- .gitignore | 2 + ansible.cfg | 8 + group_vars/all/default.yml | 38 ++++ roles/meta.sr.ht/tasks/config.yml | 135 +++++++++++++ roles/meta.sr.ht/tasks/db.yml | 15 ++ roles/meta.sr.ht/tasks/main.yml | 15 ++ roles/meta.sr.ht/tasks/nginx.yml | 13 ++ roles/meta.sr.ht/templates/nginx.conf | 38 ++++ roles/meta.sr.ht/templates/schema.psql | 265 +++++++++++++++++++++++++ roles/sr.ht-core/tasks/config.yml | 20 ++ roles/sr.ht-core/tasks/db.yml | 12 ++ roles/sr.ht-core/tasks/main.yml | 7 + roles/sr.ht-core/tasks/packages.yml | 35 ++++ roles/sr.ht-core/templates/config.ini | 100 ++++++++++ roles/sr.ht-core/templates/email.priv | 3 + roles/sr.ht-core/templates/email.pub | 3 + run.yml | 13 ++ 17 files changed, 722 insertions(+) create mode 100644 .gitignore create mode 100644 ansible.cfg create mode 100644 group_vars/all/default.yml create mode 100644 roles/meta.sr.ht/tasks/config.yml create mode 100644 roles/meta.sr.ht/tasks/db.yml create mode 100644 roles/meta.sr.ht/tasks/main.yml create mode 100644 roles/meta.sr.ht/tasks/nginx.yml create mode 100644 roles/meta.sr.ht/templates/nginx.conf create mode 100644 roles/meta.sr.ht/templates/schema.psql create mode 100644 roles/sr.ht-core/tasks/config.yml create mode 100644 roles/sr.ht-core/tasks/db.yml create mode 100644 roles/sr.ht-core/tasks/main.yml create mode 100644 roles/sr.ht-core/tasks/packages.yml create mode 100644 roles/sr.ht-core/templates/config.ini create mode 100644 roles/sr.ht-core/templates/email.priv create mode 100644 roles/sr.ht-core/templates/email.pub create mode 100644 run.yml diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..be89823 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +group_vars/all/secrets.yml +hosts.yml diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..96591dc --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,8 @@ +[defaults] +inventory = hosts.yml +# disable cowsay - yes it looks beautiful, but is bloats the output +nocows = True + +[ssh_connections] +# significantly speed up ssh +pipelining = true diff --git a/group_vars/all/default.yml b/group_vars/all/default.yml new file mode 100644 index 0000000..259be6a --- /dev/null +++ b/group_vars/all/default.yml @@ -0,0 +1,38 @@ +--- +# has to be one of https://mirror.sr.ht/alpine/ +# NOTE: As of 29.10.2023 the edge version is outdated +alpine_host_version: "v3.17" + +srht_site_name: "sourcehut" +srht_site_info: "https://sourcehut.org" +srht_site_blurb: "the hacker forge" +srht_owner_name: "Drew DeVault" +srht_owner_email: "sir@cmpwn.com" +srht_domain: "example.com" +srht_protocol: "https" +srht_smtp_host: "" +srht_smtp_port: "" +srht_smtp_from: "" +srht_smtp_encryption: "starttls" +srht_smtp_auth: "plain" +srht_smtp_user: "" +srht_smtp_password: "" +srht_smtp_error_to: "" +srht_smtp_error_from: "" +srht_enable_registration: "yes" + + +# before running, you have to copy the pgp private and public key +# put the key id here +srht_pgp_key_id: "" +# the public key itself (without begin/end blocks) here +srht_email_pubkey: "" +# the private key itself (without begin/end blocks) here +srht_email_privkey: "" + +# the following values have to be generated in advance +# to do so have a look at: +# https://git.sr.ht/~sircmpwn/core.sr.ht/tree/master/item/srht-keygen +srht_private_key: "" +srht_service_key: "" +srht_network_key: "" diff --git a/roles/meta.sr.ht/tasks/config.yml b/roles/meta.sr.ht/tasks/config.yml new file mode 100644 index 0000000..eff85d2 --- /dev/null +++ b/roles/meta.sr.ht/tasks/config.yml @@ -0,0 +1,135 @@ +--- +- name: Ensure the meta.sr.ht config is injected + ansible.builtin.blockinfile: + path: /etc/sr.ht/config.ini + marker: "#-- {mark} ANSIBLE meta.sr.ht --#" + block: | + [meta.sr.ht] + # + # URL meta.sr.ht is being served at (protocol://domain) + origin={{ srht_protocol }}://meta.{{ srht_domain }} + # + # Address and port to bind the debug server to + debug-host=0.0.0.0 + debug-port=5000 + # + # Configures the SQLAlchemy connection string for the database. + connection-string=postgresql://postgres@127.0.0.1/metasrht?sslmode=disable + # + # Set to "yes" to automatically run migrations on package upgrade. + migrate-on-upgrade=yes + # + # The redis connection used for the webhooks worker + webhooks=redis://127.0.0.1:6379/1 + # + # If "yes", the user will be sent the stock sourcehut welcome emails after + # signup (requires cron to be configured properly). These are specific to the + # sr.ht instance so you probably want to patch these before enabling this. + welcome-emails=no + + # + # Origin URL for the API + # By default, the API port is 100 more than the web port + #api-origin=http://127.0.0.1:5100 + + [meta.sr.ht::api] + # + # Maximum complexity of GraphQL queries. The higher this number, the more work + # that API clients can burden the API backend with. Complexity is equal to the + # number of discrete fields which would be returned to the user. 200 is a good + # default. + max-complexity=200 + + # + # The maximum time the API backend will spend processing a single API request. + # + # See https://golang.org/pkg/time/#ParseDuration + max-duration=3s + + # + # Set of IP subnets which are permitted to utilize internal API + # authentication. This should be limited to the subnets from which your + # *.sr.ht services are running. + # + # Comma-separated, CIDR notation. + internal-ipnet=127.0.0.0/8,::1/128,192.168.0.0/16,10.0.0.0/8 + + [meta.sr.ht::settings] + # + # If "no", public registration will not be permitted. + registration={{ srht_enable_registration }} + # + # Where to redirect new users upon registration + onboarding-redirect={{ srht_protocol }}://{{ srht_domain }} + + [meta.sr.ht::aliases] + # + # You can add aliases for the client IDs of commonly used OAuth clients here. + # + # Example: + # git.sr.ht=12345 + + [meta.sr.ht::billing] + # + # "yes" to enable the billing system + enabled=no + # + # Get your keys at https://dashboard.stripe.com/account/apikeys + stripe-public-key= + stripe-secret-key= + + [meta.sr.ht::auth] + # + # What authentication method to use. + # builtin: use sr.ht builtin authentication + # unix-pam: use Unix PAM authentication + #auth-method=builtin + + [meta.sr.ht::auth::unix-pam] + # + # The default email domain to assign to newly created users when they first log + # in. + # User's email will be set to @ + email-default-domain=example.com + # + # The PAM service to use for logging in. + #service=sshd + # + # Whether to automatically create new users when authentication succeeds but the + # user is not in the database. + create-users=yes + # + # The UNIX group users need to belong to to have access to sourcehut. + # If set, + # only users belonging to this group will be able to log into the site. + # If unset, any user on the system is able to log in if PAM authentication + # succeeds. + user-group= + # + # The UNIX group users need to belong to to have administrator permissions. + # If set, administrator status on the site will be synced with group + # association. Additionally, any user of this group will also be able to access + # sourcehut even if they are not in the group specified in user-group. + # If unset, administrator status can be manually assigned from the web + # interface. + admin-group=wheel + register: conf + +- name: Enable & start meta.sr.ht service + ansible.builtin.service: + name: meta.sr.ht + state: restarted + enabled: true + when: conf.changed +- name: Enable & start meta.sr.ht api service + ansible.builtin.service: + name: meta.sr.ht-api + state: restarted + enabled: true + when: conf.changed +- name: Enable & start meta.sr.ht webhooks service + ansible.builtin.service: + name: meta.sr.ht-webhooks + state: restarted + enabled: true + when: conf.changed diff --git a/roles/meta.sr.ht/tasks/db.yml b/roles/meta.sr.ht/tasks/db.yml new file mode 100644 index 0000000..42ffc42 --- /dev/null +++ b/roles/meta.sr.ht/tasks/db.yml @@ -0,0 +1,15 @@ +--- +- name: Copy database schema to host + ansible.builtin.template: + src: schema.psql + dest: /tmp/metasrht.psql + +- name: Create database + community.postgresql.postgresql_db: + name: metasrht + +- name: Ensure database layout + community.postgresql.postgresql_db: + name: metasrht + state: restore + target: /tmp/metasrht.psql diff --git a/roles/meta.sr.ht/tasks/main.yml b/roles/meta.sr.ht/tasks/main.yml new file mode 100644 index 0000000..d58b39d --- /dev/null +++ b/roles/meta.sr.ht/tasks/main.yml @@ -0,0 +1,15 @@ +--- +- name: Install meta.sr.ht packages + community.general.apk: + name: + - meta.sr.ht + state: latest + +- name: Setup Database + ansible.builtin.import_tasks: db.yml + +- name: Setup config & services + ansible.builtin.import_tasks: config.yml + +- name: Setup nginx + ansible.builtin.import_tasks: nginx.yml diff --git a/roles/meta.sr.ht/tasks/nginx.yml b/roles/meta.sr.ht/tasks/nginx.yml new file mode 100644 index 0000000..f33e947 --- /dev/null +++ b/roles/meta.sr.ht/tasks/nginx.yml @@ -0,0 +1,13 @@ +--- +- name: Copy nginx config file + ansible.builtin.template: + src: nginx.conf + dest: /etc/nginx/http.d/meta.sr.ht.conf + register: nginxconf + +- name: Start & enable nginx + ansible.builtin.service: + name: nginx + state: restarted + enabled: true + when: nginxconf.changed diff --git a/roles/meta.sr.ht/templates/nginx.conf b/roles/meta.sr.ht/templates/nginx.conf new file mode 100644 index 0000000..97dbe3b --- /dev/null +++ b/roles/meta.sr.ht/templates/nginx.conf @@ -0,0 +1,38 @@ +server { + include sourcehut.conf; + server_name meta.{{ srht_domain }}; + + location ^~ /.well-known { + root /var/www; + } + + location = /robots.txt { + root /var/www; + } + + location / { + proxy_pass http://127.0.0.1:5000; + include headers.conf; + add_header Content-Security-Policy "default-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; script-src 'self' 'unsafe-inline' *.stripe.com *.stripe.network; frame-src *.stripe.com *.stripe.network always; frame-ancestors 'none'" always; + include web.conf; + } + + location /register { + proxy_pass http://127.0.0.1:5000; + add_header Content-Security-Policy "default-src 'none'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; script-src 'self' 'unsafe-inline' *.stripe.com *.stripe.network; frame-src *.stripe.com *.stripe.network; frame-ancestors 'none'" always; + } + + location /.well-known/oauth-authorization-server { + proxy_pass http://127.0.0.1:5000; + } + + location /query { + proxy_pass http://127.0.0.1:5100; + include graphql.conf; + } + + location /static { + root /usr/lib/$python/site-packages/metasrht; + expires 30d; + } +} diff --git a/roles/meta.sr.ht/templates/schema.psql b/roles/meta.sr.ht/templates/schema.psql new file mode 100644 index 0000000..269bfed --- /dev/null +++ b/roles/meta.sr.ht/templates/schema.psql @@ -0,0 +1,265 @@ +CREATE TYPE auth_method AS ENUM ( + 'OAUTH_LEGACY', + 'OAUTH2', + 'COOKIE', + 'INTERNAL', + 'WEBHOOK' +); + +CREATE TYPE webhook_event AS ENUM ( + 'PROFILE_UPDATE', + 'PGP_KEY_ADDED', + 'PGP_KEY_REMOVED', + 'SSH_KEY_ADDED', + 'SSH_KEY_REMOVED' +); + +CREATE TABLE "user" ( + id serial PRIMARY KEY, + created timestamp without time zone NOT NULL, + updated timestamp without time zone NOT NULL, + username character varying(256) NOT NULL UNIQUE, + password character varying(256) NOT NULL, + email character varying(256) NOT NULL UNIQUE, + new_email character varying(256), + user_type character varying NOT NULL, + confirmation_hash character varying(128), + url character varying(256), + location character varying(256), + bio character varying(4096), + pgp_key_id integer, + reset_hash character varying(128), + reset_expiry timestamp without time zone, + stripe_customer character varying(256), + payment_cents integer DEFAULT 0 NOT NULL, + payment_interval character varying DEFAULT 'monthly'::character varying, + payment_due timestamp without time zone, + welcome_emails integer DEFAULT 0 NOT NULL, + oauth_revocation_token character varying(256), + suspension_notice character varying(4096) +); + +CREATE TABLE audit_log_entry ( + id serial PRIMARY KEY, + created timestamp without time zone NOT NULL, + user_id integer NOT NULL REFERENCES "user"(id) ON DELETE CASCADE, + ip_address character varying(50) NOT NULL, + event_type character varying(256) NOT NULL, + details character varying(512) +); + +CREATE TABLE invoice ( + id serial PRIMARY KEY, + created timestamp without time zone NOT NULL, + updated timestamp without time zone NOT NULL, + cents integer NOT NULL, + user_id integer NOT NULL REFERENCES "user"(id) ON DELETE CASCADE, + valid_thru timestamp without time zone NOT NULL, + source character varying(256) NOT NULL +); + +CREATE TABLE pgpkey ( + id serial PRIMARY KEY, + created timestamp without time zone, + user_id integer REFERENCES "user"(id) ON DELETE CASCADE, + key character varying(32768) NOT NULL, + fingerprint bytea NOT NULL UNIQUE, + expiration timestamp without time zone +); + +ALTER TABLE "user" + ADD CONSTRAINT user_pgp_key_id_fkey + FOREIGN KEY (pgp_key_id) REFERENCES pgpkey(id) ON DELETE SET NULL; + +CREATE TABLE sshkey ( + id serial PRIMARY KEY, + created timestamp without time zone, + user_id integer REFERENCES "user"(id) ON DELETE CASCADE, + key character varying(4096) NOT NULL, + fingerprint character varying(512) NOT NULL UNIQUE, + comment character varying(256), + last_used timestamp without time zone, + b64_key character varying(4096), + key_type character varying(256) +); + +CREATE INDEX sshkey_md5_idx ON sshkey USING btree (md5((key)::text)); + +CREATE TABLE user_auth_factor ( + id serial PRIMARY KEY, + user_id integer NOT NULL UNIQUE REFERENCES "user"(id) ON DELETE CASCADE, + created timestamp without time zone NOT NULL, + updated timestamp without time zone NOT NULL, + factor_type character varying NOT NULL, + secret bytea, + extra json +); + +CREATE TABLE user_notes ( + id serial PRIMARY KEY, + created timestamp without time zone NOT NULL, + user_id integer NOT NULL REFERENCES "user"(id) ON DELETE CASCADE, + note character varying +); + +CREATE TABLE reserved_usernames ( + username varchar NOT NULL +); + +CREATE INDEX reserved_usernames_ix ON reserved_usernames(username); + +-- OAuth 2.0 +CREATE TABLE oauth2_client ( + id serial PRIMARY KEY, + created timestamp without time zone NOT NULL, + updated timestamp without time zone NOT NULL, + owner_id integer NOT NULL REFERENCES "user"(id) ON DELETE CASCADE, + client_uuid uuid NOT NULL, + client_secret_hash character varying(128) NOT NULL, + client_secret_partial character varying(8) NOT NULL, + redirect_url character varying, + client_name character varying(256) NOT NULL, + client_description character varying, + client_url character varying, + revoked boolean DEFAULT false NOT NULL +); + +CREATE TABLE oauth2_grant ( + id serial PRIMARY KEY, + issued timestamp without time zone NOT NULL, + expires timestamp without time zone NOT NULL, + comment character varying, + token_hash character varying(128) NOT NULL, + user_id integer NOT NULL REFERENCES "user"(id) ON DELETE CASCADE, + client_id integer REFERENCES oauth2_client(id) ON DELETE CASCADE +); + +-- GraphQL webhooks +CREATE TABLE gql_profile_wh_sub ( + id serial PRIMARY KEY, + created timestamp without time zone NOT NULL, + events webhook_event[] NOT NULL, + url character varying NOT NULL, + query character varying NOT NULL, + auth_method auth_method NOT NULL, + token_hash character varying(128), + grants character varying, + client_id uuid, + expires timestamp without time zone, + node_id character varying, + user_id integer NOT NULL REFERENCES "user"(id) ON DELETE CASCADE, + CONSTRAINT gql_profile_wh_sub_auth_method_check + CHECK ((auth_method = ANY(ARRAY['OAUTH2'::auth_method, 'INTERNAL'::auth_method]))), + CONSTRAINT gql_profile_wh_sub_check + CHECK (((auth_method = 'OAUTH2'::auth_method) = (token_hash IS NOT NULL))), + CONSTRAINT gql_profile_wh_sub_check1 + CHECK (((auth_method = 'OAUTH2'::auth_method) = (expires IS NOT NULL))), + CONSTRAINT gql_profile_wh_sub_check2 + CHECK (((auth_method = 'INTERNAL'::auth_method) = (node_id IS NOT NULL))), + CONSTRAINT gql_profile_wh_sub_events_check + CHECK ((array_length(events, 1) > 0)) +); + +CREATE INDEX gql_profile_wh_sub_token_hash_idx ON gql_profile_wh_sub USING btree (token_hash); + +CREATE TABLE gql_profile_wh_delivery ( + id serial PRIMARY KEY, + uuid uuid NOT NULL, + date timestamp without time zone NOT NULL, + event webhook_event NOT NULL, + subscription_id integer NOT NULL + REFERENCES gql_profile_wh_sub(id) ON DELETE CASCADE, + request_body character varying NOT NULL, + response_body character varying, + response_headers character varying, + response_status integer +); + +-- Legacy OAuth (TODO: Remove these) +CREATE TABLE oauthclient ( + id serial PRIMARY KEY, + created timestamp without time zone NOT NULL, + updated timestamp without time zone NOT NULL, + user_id integer REFERENCES "user"(id) ON DELETE CASCADE, + client_name character varying(256) NOT NULL, + client_id character varying(16) NOT NULL, + client_secret_hash character varying(128) NOT NULL, + client_secret_partial character varying(8) NOT NULL, + redirect_uri character varying(256), + preauthorized boolean DEFAULT false NOT NULL +); + +CREATE TABLE oauthscope ( + id serial PRIMARY KEY, + created timestamp without time zone NOT NULL, + updated timestamp without time zone NOT NULL, + client_id integer NOT NULL REFERENCES oauthclient(id) ON DELETE CASCADE, + name character varying(256) NOT NULL, + description character varying(512) NOT NULL, + write boolean NOT NULL +); + +CREATE TABLE oauthtoken ( + id serial PRIMARY KEY, + created timestamp without time zone NOT NULL, + updated timestamp without time zone NOT NULL, + expires timestamp without time zone NOT NULL, + user_id integer REFERENCES "user"(id) ON DELETE CASCADE, + client_id integer REFERENCES oauthclient(id) ON DELETE CASCADE, + token_hash character varying(128) NOT NULL, + token_partial character varying(8) NOT NULL, + scopes character varying(512) NOT NULL, + comment character varying(128) +); + +CREATE TABLE revocationurl ( + id serial PRIMARY KEY, + created timestamp without time zone NOT NULL, + updated timestamp without time zone NOT NULL, + token_id integer NOT NULL REFERENCES oauthtoken(id), + client_id integer NOT NULL REFERENCES oauthclient(id), + url character varying(2048) NOT NULL +); + +CREATE TABLE delegatedscope ( + id serial PRIMARY KEY, + created timestamp without time zone NOT NULL, + updated timestamp without time zone NOT NULL, + client_id integer NOT NULL REFERENCES oauthclient(id) ON DELETE CASCADE, + name character varying(256) NOT NULL, + description character varying(512) NOT NULL, + write boolean NOT NULL +); + +-- Legacy webhooks (TODO: Remove these) +CREATE TABLE user_webhook_subscription ( + id serial PRIMARY KEY, + created timestamp without time zone NOT NULL, + url character varying(2048) NOT NULL, + events character varying NOT NULL, + user_id integer REFERENCES "user"(id) ON DELETE CASCADE, + token_id integer REFERENCES oauthtoken(id) ON DELETE CASCADE +); + +CREATE TABLE user_webhook_delivery ( + id serial PRIMARY KEY, + uuid uuid NOT NULL, + created timestamp without time zone NOT NULL, + event character varying(256) NOT NULL, + url character varying(2048) NOT NULL, + payload character varying(16384) NOT NULL, + payload_headers character varying(16384) NOT NULL, + response character varying(16384), + response_status integer NOT NULL, + response_headers character varying(16384), + subscription_id integer REFERENCES user_webhook_subscription(id) ON DELETE CASCADE +); + +CREATE TABLE webhook_subscription ( + id serial PRIMARY KEY, + created timestamp without time zone NOT NULL, + url character varying(2048) NOT NULL, + events character varying NOT NULL, + user_id integer REFERENCES "user"(id) ON DELETE CASCADE, + client_id integer REFERENCES oauthclient(id) ON DELETE CASCADE +); diff --git a/roles/sr.ht-core/tasks/config.yml b/roles/sr.ht-core/tasks/config.yml new file mode 100644 index 0000000..0ea6c3d --- /dev/null +++ b/roles/sr.ht-core/tasks/config.yml @@ -0,0 +1,20 @@ +--- +- name: Ensure the sr.ht config directory exists + ansible.builtin.file: + path: /etc/sr.ht + state: directory + recurse: true + +- name: Create the email public key file + ansible.builtin.template: + src: email.pub + dest: /etc/sr.ht/email.pub +- name: Create the email private key file + ansible.builtin.template: + src: email.priv + dest: /etc/sr.ht/email.priv + +- name: Copy sr.ht config file (rerun if changed) + ansible.builtin.template: + src: config.ini + dest: /etc/sr.ht/config.ini diff --git a/roles/sr.ht-core/tasks/db.yml b/roles/sr.ht-core/tasks/db.yml new file mode 100644 index 0000000..b97fc37 --- /dev/null +++ b/roles/sr.ht-core/tasks/db.yml @@ -0,0 +1,12 @@ +--- +- name: Start & enbale postgres database + ansible.builtin.service: + name: postgresql + state: started + enabled: true + +- name: Start & enbale redis cache + ansible.builtin.service: + name: redis + state: started + enabled: true diff --git a/roles/sr.ht-core/tasks/main.yml b/roles/sr.ht-core/tasks/main.yml new file mode 100644 index 0000000..53c057f --- /dev/null +++ b/roles/sr.ht-core/tasks/main.yml @@ -0,0 +1,7 @@ +--- +- name: Install base packages + ansible.builtin.import_tasks: packages.yml +- name: Setup databases + ansible.builtin.import_tasks: db.yml +- name: Copy config file + ansible.builtin.import_tasks: config.yml diff --git a/roles/sr.ht-core/tasks/packages.yml b/roles/sr.ht-core/tasks/packages.yml new file mode 100644 index 0000000..27fd0f3 --- /dev/null +++ b/roles/sr.ht-core/tasks/packages.yml @@ -0,0 +1,35 @@ +--- +- name: Install Database + community.general.apk: + name: + - postgresql14 + - redis + state: latest + +- name: Install chron daemon + community.general.apk: + name: + - chrony + state: latest + +- name: Add sourcehut repos + ansible.builtin.lineinfile: + path: /etc/apk/repositories + line: "https://mirror.sr.ht/alpine/{{ alpine_host_version }}/sr.ht/" + insertbefore: "BOF" +- name: Fetch sourcehut signing key + ansible.builtin.get_url: + url: https://mirror.sr.ht/alpine/alpine@sr.ht.rsa.pub + dest: /etc/apk/keys/alpine@sr.ht.rsa.pub +- name: Update & Upgrade repositories + community.general.apk: + update_cache: true + upgrade: true + +- name: Install base sourcehut services + community.general.apk: + name: + - py3-srht + - sr.ht-nginx + - nginx + state: latest diff --git a/roles/sr.ht-core/templates/config.ini b/roles/sr.ht-core/templates/config.ini new file mode 100644 index 0000000..3011027 --- /dev/null +++ b/roles/sr.ht-core/templates/config.ini @@ -0,0 +1,100 @@ +[sr.ht] +# +# The name of your network of sr.ht-based sites +site-name={{ srht_site_name }} +# +# The top-level info page for your site +site-info={{ srht_site_info }} +# +site-blurb={{ srht_site_blurb }} +# +# If this != production, we add a banner to each page +environment=production +# +# Contact information for the site owners +owner-name={{ srht_owner_name }} +owner-email={{ srht_owner_email }} +# +# The source code for your fork of sr.ht +source-url=https://git.sr.ht/~sircmpwn/srht +# +# Link to your instance's privacy policy. Uses the sr.ht privacy policy as the +# default, which describes the information collected by the upstream SourceHut +# code. +privacy-policy=https://man.sr.ht/privacy.md +# +# A key used for encrypting session cookies. Use `srht-keygen service` to +# generate the service key. This must be shared between each node of the same +# service (e.g. git1.sr.ht and git2.sr.ht), but different services may use +# different keys. If you configure all of your services with the same +# config.ini, you may use the same service-key for all of them. +service-key={{ srht_service_key }} +# +# A secret key to encrypt internal messages with. Use `srht-keygen network` to +# generate this key. It must be consistent between all services and nodes. +network-key={{ srht_network_key }} +# +# The redis host URL. This is used for caching and temporary storage, and must +# be shared between nodes (e.g. git1.sr.ht and git2.sr.ht), but need not be +# shared between services. It may be shared between services, however, with no +# ill effect, if this better suits your infrastructure. +redis-host=redis://127.0.0.1:6379/1 +# +# Optional email address for reporting security-related issues. +security-address= +# +# The global domain of the site. If unset, the global domain will be determined +# from the service URL: each service is assumed to be a sub-domain of the global +# domain, i.e. of the form `meta.globaldomain.com`. +global-domain={{ srht_domain }} + +[objects] +# +# Configure S3-compatible object storage for services. Optional. +# +# Minio is recommended as a FOSS solution over AWS: https://min.io +s3-upstream= +s3-access-key= +s3-secret-key= + +[mail] +# +# Outgoing SMTP settings +smtp-host={{ srht_smtp_host }} +smtp-port={{ srht_smtp_port }} +smtp-from={{ srht_smtp_from }} +# +# Default: starttls +# Options: starttls, tls, insecure +smtp-encryption={{ srht_smtp_encryption }} +# +# Default: plain +# Options: plain, none +smtp-auth={{ srht_smtp_auth }} +# user / password are required if smtp-auth is plain +smtp-user={{ srht_smtp_user }} +smtp-password={{ srht_smtp_password }} +# +# Application exceptions are emailed to this address +error-to={{ srht_smtp_error_to }} +error-from={{ srht_smtp_error_from }} +# +# You should generate a PGP key to allow users to authenticate emails received +# from your services. Use `gpg --edit-key [key id]` to remove the password from +# your private key, then export it to a file and set pgp-privkey to the path to +# that file. pgp-pubkey should be set to the path to your public key, and +# pgp-key-id should be set to the key ID string. Outgoing emails are signed with +# this PGP key. +pgp-privkey=/etc/sr.ht/email.priv +pgp-pubkey=/etc/sr.ht/email.pub +pgp-key-id={{ srht_pgp_key_id }} + +[webhooks] +# +# base64-encoded Ed25519 key for signing webhook payloads. This should be +# consistent between all services. +# +# Use the `srht-keygen webhook` command to generate this key. Put the private +# key here and distribute the public key to anyone who would want to verify +# webhook payloads from your service. +private-key={{ srht_private_key }} diff --git a/roles/sr.ht-core/templates/email.priv b/roles/sr.ht-core/templates/email.priv new file mode 100644 index 0000000..277c092 --- /dev/null +++ b/roles/sr.ht-core/templates/email.priv @@ -0,0 +1,3 @@ +-----BEGIN PGP PRIVATE KEY BLOCK----- + +{{ srht_email_privkey }}-----END PGP PRIVATE KEY BLOCK----- diff --git a/roles/sr.ht-core/templates/email.pub b/roles/sr.ht-core/templates/email.pub new file mode 100644 index 0000000..f97a0f7 --- /dev/null +++ b/roles/sr.ht-core/templates/email.pub @@ -0,0 +1,3 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +{{ srht_email_pubkey }}-----END PGP PUBLIC KEY BLOCK----- diff --git a/run.yml b/run.yml new file mode 100644 index 0000000..ce8df9f --- /dev/null +++ b/run.yml @@ -0,0 +1,13 @@ +--- +############################################ +# SETUP BASE SOURCEHUT REQUIREMENTS +# including databases and the auth (meta) backend +############################################ +- name: Setup core sr.ht packages (required) + hosts: all + roles: + - role: sr.ht-core +- name: Setup meta.sr.ht (required) + hosts: all + roles: + - role: meta.sr.ht -- 2.38.5