Skip to content

Commit

Permalink
Merge pull request #1242 from apmechev/add_beeper_linkedin_bridge
Browse files Browse the repository at this point in the history
Add beeper LinkedIn bridge
  • Loading branch information
spantaleev authored Aug 23, 2021
2 parents e46c908 + 603ad7c commit 2ec06b7
Show file tree
Hide file tree
Showing 13 changed files with 643 additions and 0 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ Using this playbook, you can get the following services configured on your serve

- (optional) the [mautrix-signal](https://github.com/mautrix/signal) bridge for bridging your Matrix server to [Signal](https://www.signal.org/)

- (optional) the [beeper-linkedin](https://gitlab.com/beeper/linkedin) bridge for bridging your Matrix server to [LinkedIn](https://www.linkedin.com/)

- (optional) the [matrix-appservice-irc](https://github.com/matrix-org/matrix-appservice-irc) bridge for bridging your Matrix server to [IRC](https://wikipedia.org/wiki/Internet_Relay_Chat)

- (optional) the [matrix-appservice-discord](https://github.com/Half-Shot/matrix-appservice-discord) bridge for bridging your Matrix server to [Discord](https://discordapp.com/)
Expand Down
59 changes: 59 additions & 0 deletions docs/configuring-playbook-bridge-beeper-linkedin.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Setting up Beeper Linkedin (optional)

The playbook can install and configure [beeper-linkedin](https://gitlab.com/beeper/linkedin) for you. This bridge is based on the mautrix-python framework and can be configured in a similar way to the other mautrix bridges

See the project's [documentation](https://gitlab.com/beeper/linkedin/-/blob/master/README.md) to learn what it does and why it might be useful to you.

```yaml
matrix_beeper_linkedin_enabled: true
```
There are some additional things you may wish to configure about the bridge before you continue.
Encryption support is off by default. If you would like to enable encryption, add the following to your `vars.yml` file:
```yaml
matrix_beeper_linkedin_configuration_extension_yaml: |
bridge:
encryption:
allow: true
default: true
```

If you would like to be able to administrate the bridge from your account it can be configured like this:
```yaml
matrix_beeper_linkedin_configuration_extension_yaml: |
bridge:
permissions:
'@YOUR_USERNAME:YOUR_DOMAIN': admin
```

You may wish to look at `roles/matrix-bridge-beeper-linkedin/templates/config.yaml.j2` to find other things you would like to configure.


## Set up Double Puppeting

If you'd like to use [Double Puppeting](https://docs.mau.fi/bridges/general/double-puppeting.html) (hint: you most likely do), you have 2 ways of going about it.

### Method 1: automatically, by enabling Shared Secret Auth

The bridge will automatically perform Double Puppeting if you enable [Shared Secret Auth](configuring-playbook-shared-secret-auth.md) for this playbook.

This is the recommended way of setting up Double Puppeting, as it's easier to accomplish, works for all your users automatically, and has less of a chance of breaking in the future.


## Usage

You then need to start a chat with `@linkedinbot:YOUR_DOMAIN` (where `YOUR_DOMAIN` is your base domain, not the `matrix.` domain).

Send `login YOUR_LINKEDIN_EMAIL_ADDRESS` to the bridge bot to enable bridging for your LinkedIn account.

If you run into trouble, check the [Troubleshooting](#troubleshooting) section below.

After successfully enabling bridging, you may wish to [set up Double Puppeting](#set-up-double-puppeting), if you haven't already done so.


## Troubleshooting

### Bridge asking for 2FA even if you don't have 2FA enabled

If you don't have 2FA enabled and are logging in from a strange IP for the first time, LinkedIn will send an email with a one-time code. You can use this code to authorize the bridge session. In my experience, once the IP is authorized, you will not be asked again.
2 changes: 2 additions & 0 deletions docs/configuring-playbook.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ When you're done with all the configuration you'd like to do, continue with [Ins

- [Setting up Appservice IRC bridging](configuring-playbook-bridge-appservice-irc.md) (optional)

- [Setting up Beeper LinkedIn bridging](configuring-playbook-bridge-beeper-linkedin.md) (optional)

- [Setting up Appservice Discord bridging](configuring-playbook-bridge-appservice-discord.md) (optional)

- [Setting up Appservice Slack bridging](configuring-playbook-bridge-appservice-slack.md) (optional)
Expand Down
42 changes: 42 additions & 0 deletions group_vars/matrix_servers
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,42 @@ matrix_appservice_irc_database_password: "{{ matrix_synapse_macaroon_secret_key
######################################################################


######################################################################
#
# matrix-bridge-beeper-linkedin
#
######################################################################

# We don't enable bridges by default.
matrix_beeper_linkedin_enabled: false

matrix_beeper_linkedin_systemd_required_services_list: |
{{
['docker.service']
+
(['matrix-synapse.service'] if matrix_synapse_enabled else [])
+
(['matrix-postgres.service'] if matrix_postgres_enabled else [])
+
(['matrix-nginx-proxy.service'] if matrix_nginx_proxy_enabled else [])
}}

matrix_beeper_linkedin_appservice_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'linked.as.token') | to_uuid }}"

matrix_beeper_linkedin_homeserver_token: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'linked.hs.token') | to_uuid }}"

matrix_beeper_linkedin_login_shared_secret: "{{ matrix_synapse_ext_password_provider_shared_secret_auth_shared_secret if matrix_synapse_ext_password_provider_shared_secret_auth_enabled else '' }}"

matrix_beeper_linkedin_bridge_presence: "{{ matrix_synapse_presence_enabled if matrix_synapse_enabled else true }}"

matrix_beeper_linkedin_database_password: "{{ matrix_synapse_macaroon_secret_key | password_hash('sha512', 'maulinkedin.db') | to_uuid }}"

######################################################################
#
# /matrix-bridge-beeper-linkedin
#
######################################################################

######################################################################
#
# matrix-bridge-mautrix-facebook
Expand Down Expand Up @@ -1372,6 +1408,12 @@ matrix_postgres_additional_databases: |
'password': matrix_appservice_irc_database_password,
}] if (matrix_appservice_irc_enabled and matrix_appservice_irc_database_engine == 'postgres' and matrix_appservice_irc_database_hostname == 'matrix-postgres') else [])
+
([{
'name': matrix_beeper_linkedin_database_name,
'username': matrix_beeper_linkedin_database_username,
'password': matrix_beeper_linkedin_database_password,
}] if (matrix_beeper_linkedin_enabled and matrix_beeper_linkedin_database_engine == 'postgres' and matrix_beeper_linkedin_database_hostname == 'matrix-postgres') else [])
+
([{
'name': matrix_mautrix_facebook_database_name,
'username': matrix_mautrix_facebook_database_username,
Expand Down
100 changes: 100 additions & 0 deletions roles/matrix-bridge-beeper-linkedin/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# beeper-linkedin is a Matrix <-> LinkedIn bridge
# See: https://gitlab.com/beeper/linkedin

matrix_beeper_linkedin_enabled: true

matrix_beeper_linkedin_version: v0.5.0
# See: https://gitlab.com/beeper/linkedin/container_registry
matrix_beeper_linkedin_docker_image: "registry.gitlab.com/beeper/linkedin:{{ matrix_beeper_linkedin_version }}-amd64"
matrix_beeper_linkedin_docker_image_force_pull: "{{ matrix_beeper_linkedin_docker_image.endswith(':latest-amd64') }}"

matrix_beeper_linkedin_base_path: "{{ matrix_base_data_path }}/beeper-linkedin"
matrix_beeper_linkedin_config_path: "{{ matrix_beeper_linkedin_base_path }}/config"
matrix_beeper_linkedin_data_path: "{{ matrix_beeper_linkedin_base_path }}/data"

matrix_beeper_linkedin_homeserver_address: "{{ matrix_homeserver_container_url }}"
matrix_beeper_linkedin_homeserver_domain: "{{ matrix_domain }}"
matrix_beeper_linkedin_appservice_address: "http://matrix-beeper-linkedin:29319"

# A list of extra arguments to pass to the container
matrix_beeper_linkedin_container_extra_arguments: []

# List of systemd services that matrix-beeper-linkedin.service depends on.
matrix_beeper_linkedin_systemd_required_services_list: ['docker.service']

# List of systemd services that matrix-beeper-linkedin.service wants
matrix_beeper_linkedin_systemd_wanted_services_list: []

matrix_beeper_linkedin_appservice_token: ""
matrix_beeper_linkedin_homeserver_token: ""

matrix_beeper_linkedin_appservice_bot_username: linkedinbot


# Database-related configuration fields.
# Only Postgres is supported.
matrix_beeper_linkedin_database_engine: "postgres"

matrix_beeper_linkedin_database_username: 'matrix_beeper_linkedin'
matrix_beeper_linkedin_database_password: ""
matrix_beeper_linkedin_database_hostname: 'matrix-postgres'
matrix_beeper_linkedin_database_port: 5432
matrix_beeper_linkedin_database_name: 'matrix_beeper_linkedin'

matrix_beeper_linkedin_database_connection_string: 'postgresql://{{ matrix_beeper_linkedin_database_username }}:{{ matrix_beeper_linkedin_database_password }}@{{ matrix_beeper_linkedin_database_hostname }}:{{ matrix_beeper_linkedin_database_port }}/{{ matrix_beeper_linkedin_database_name }}?sslmode=disable'

matrix_beeper_linkedin_appservice_database_type: "{{
{
'postgres':'postgres',
}[matrix_beeper_linkedin_database_engine]
}}"

matrix_beeper_linkedin_appservice_database_uri: "{{
{
'postgres': matrix_beeper_linkedin_database_connection_string,
}[matrix_beeper_linkedin_database_engine]
}}"


# Can be set to enable automatic double-puppeting via Shared Secret Auth (https://github.com/devture/matrix-synapse-shared-secret-auth).
matrix_beeper_linkedin_login_shared_secret: ''

# Default beeper-linkedin configuration template which covers the generic use case.
# You can customize it by controlling the various variables inside it.
#
# For a more advanced customization, you can extend the default (see `matrix_beeper_linkedin_configuration_extension_yaml`)
# or completely replace this variable with your own template.
matrix_beeper_linkedin_configuration_yaml: "{{ lookup('template', 'templates/config.yaml.j2') }}"

matrix_beeper_linkedin_configuration_extension_yaml: |
# Your custom YAML configuration goes here.
# This configuration extends the default starting configuration (`matrix_beeper_linkedin_configuration_yaml`).
#
# You can override individual variables from the default configuration, or introduce new ones.
#
# If you need something more special, you can take full control by
# completely redefining `matrix_beeper_linkedin_configuration_yaml`.

matrix_beeper_linkedin_configuration_extension: "{{ matrix_beeper_linkedin_configuration_extension_yaml|from_yaml if matrix_beeper_linkedin_configuration_extension_yaml|from_yaml is mapping else {} }}"

# Holds the final configuration (a combination of the default and its extension).
# You most likely don't need to touch this variable. Instead, see `matrix_beeper_linkedin_configuration_yaml`.
matrix_beeper_linkedin_configuration: "{{ matrix_beeper_linkedin_configuration_yaml|from_yaml|combine(matrix_beeper_linkedin_configuration_extension, recursive=True) }}"

matrix_beeper_linkedin_registration_yaml: |
id: linkedin
url: {{ matrix_beeper_linkedin_appservice_address }}
as_token: "{{ matrix_beeper_linkedin_appservice_token }}"
hs_token: "{{ matrix_beeper_linkedin_homeserver_token }}"

sender_localpart: _bot_{{ matrix_beeper_linkedin_appservice_bot_username }}
rate_limited: false
namespaces:
users:
- regex: '^@linkedin_.+:{{ matrix_beeper_linkedin_homeserver_domain|regex_escape }}$'
exclusive: true
- exclusive: true
regex: '^@{{ matrix_beeper_linkedin_appservice_bot_username|regex_escape }}:{{ matrix_beeper_linkedin_homeserver_domain|regex_escape }}$'
de.sorunome.msc2409.push_ephemeral: true

matrix_beeper_linkedin_registration: "{{ matrix_beeper_linkedin_registration_yaml|from_yaml }}"
16 changes: 16 additions & 0 deletions roles/matrix-bridge-beeper-linkedin/tasks/init.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
- set_fact:
matrix_systemd_services_list: "{{ matrix_systemd_services_list + ['matrix-beeper-linkedin.service'] }}"
when: matrix_beeper_linkedin_enabled|bool

# If the matrix-synapse role is not used, these variables may not exist.
- set_fact:
matrix_synapse_container_extra_arguments: >
{{ matrix_synapse_container_extra_arguments|default([]) }}
+
["--mount type=bind,src={{ matrix_beeper_linkedin_config_path }}/registration.yaml,dst=/matrix-beeper-linkedin-registration.yaml,ro"]
matrix_synapse_app_service_config_files: >
{{ matrix_synapse_app_service_config_files|default([]) }}
+
{{ ["/matrix-beeper-linkedin-registration.yaml"] }}
when: matrix_beeper_linkedin_enabled|bool
21 changes: 21 additions & 0 deletions roles/matrix-bridge-beeper-linkedin/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
- import_tasks: "{{ role_path }}/tasks/init.yml"
tags:
- always

- import_tasks: "{{ role_path }}/tasks/validate_config.yml"
when: "run_setup|bool and matrix_beeper_linkedin_enabled|bool"
tags:
- setup-all
- setup-beeper-linkedin

- import_tasks: "{{ role_path }}/tasks/setup_install.yml"
when: "run_setup and matrix_beeper_linkedin_enabled"
tags:
- setup-all
- setup-beeper-linkedin

- import_tasks: "{{ role_path }}/tasks/setup_uninstall.yml"
when: "run_setup and not matrix_beeper_linkedin_enabled"
tags:
- setup-all
- setup-beeper-linkedin
56 changes: 56 additions & 0 deletions roles/matrix-bridge-beeper-linkedin/tasks/setup_install.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---

# If the matrix-synapse role is not used, `matrix_synapse_role_executed` won't exist.
# We don't want to fail in such cases.
- name: Fail if matrix-synapse role already executed
fail:
msg: >-
The matrix-bridge-beeper-linkedin role needs to execute before the matrix-synapse role.
when: "matrix_synapse_role_executed|default(False)"

- name: Ensure Beeper LinkedIn image is pulled
docker_image:
name: "{{ matrix_beeper_linkedin_docker_image }}"
source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}"
force_source: "{{ matrix_beeper_linkedin_docker_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}"
force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_beeper_linkedin_docker_image_force_pull }}"

- name: Ensure Beeper LinkedIn paths exists
file:
path: "{{ item }}"
state: directory
mode: 0750
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_groupname }}"
with_items:
- "{{ matrix_beeper_linkedin_base_path }}"
- "{{ matrix_beeper_linkedin_config_path }}"
- "{{ matrix_beeper_linkedin_data_path }}"

- name: Ensure beeper-linkedin config.yaml installed
copy:
content: "{{ matrix_beeper_linkedin_configuration|to_nice_yaml }}"
dest: "{{ matrix_beeper_linkedin_config_path }}/config.yaml"
mode: 0644
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_groupname }}"

- name: Ensure beeper-linkedin registration.yaml installed
copy:
content: "{{ matrix_beeper_linkedin_registration|to_nice_yaml }}"
dest: "{{ matrix_beeper_linkedin_config_path }}/registration.yaml"
mode: 0644
owner: "{{ matrix_user_username }}"
group: "{{ matrix_user_groupname }}"

- name: Ensure matrix-beeper-linkedin.service installed
template:
src: "{{ role_path }}/templates/systemd/matrix-beeper-linkedin.service.j2"
dest: "{{ matrix_systemd_path }}/matrix-beeper-linkedin.service"
mode: 0644
register: matrix_beeper_linkedin_systemd_service_result

- name: Ensure systemd reloaded after matrix-beeper-linkedin.service installation
service:
daemon_reload: yes
when: "matrix_beeper_linkedin_systemd_service_result.changed"
24 changes: 24 additions & 0 deletions roles/matrix-bridge-beeper-linkedin/tasks/setup_uninstall.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
---

- name: Check existence of matrix-beeper-linkedin service
stat:
path: "{{ matrix_systemd_path }}/matrix-beeper-linkedin.service"
register: matrix_beeper_linkedin_service_stat

- name: Ensure matrix-beeper-linkedin is stopped
service:
name: matrix-beeper-linkedin
state: stopped
daemon_reload: yes
when: "matrix_beeper_linkedin_service_stat.stat.exists"

- name: Ensure matrix-beeper-linkedin.service doesn't exist
file:
path: "{{ matrix_systemd_path }}/matrix-beeper-linkedin.service"
state: absent
when: "matrix_beeper_linkedin_service_stat.stat.exists"

- name: Ensure systemd reloaded after matrix-beeper-linkedin.service removal
service:
daemon_reload: yes
when: "matrix_beeper_linkedin_service_stat.stat.exists"
11 changes: 11 additions & 0 deletions roles/matrix-bridge-beeper-linkedin/tasks/validate_config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---

- name: Fail if required settings not defined
fail:
msg: >-
You need to define a required configuration setting (`{{ item }}`).
when: "vars[item] == ''"
with_items:
- "matrix_beeper_linkedin_appservice_token"
- "matrix_beeper_linkedin_homeserver_token"

Loading

0 comments on commit 2ec06b7

Please sign in to comment.