Compare commits

..

2 Commits

Author SHA1 Message Date
4a67f38f11 meta: bump collection to 0.7.0 2024-10-02 20:58:52 +02:00
23301a0a86 feat(oidc_user_backend): add ansible role 2024-09-29 22:18:55 +02:00
12 changed files with 265 additions and 148 deletions

View File

@ -1,6 +1,6 @@
namespace: finallycoffee namespace: finallycoffee
name: nextcloud name: nextcloud
version: 0.6.1 version: 0.7.0
readme: README.md readme: README.md
authors: authors:
- transcaffeine <transcaffeine@finally.coffee> - transcaffeine <transcaffeine@finally.coffee>

View File

@ -4,26 +4,23 @@ Configure OIDC user backends in nextcloud using this ansible role.
This role can be run multiple times with different arguments in order to This role can be run multiple times with different arguments in order to
configure multiple oidc-based user backends. configure multiple oidc-based user backends.
> [!WARNING]
> This role is not production ready or finished
## Configuration ## Configuration
Set `oidc_user_occ_user_oidc_provider_identifier` to a unique identifier. Set `oidc_user_backend_provider_identifier` to a unique identifier.
Populate your provider information in the `oidc_user_config_(settings_)` Populate your provider information in the `oidc_user_backend_config_provider_provider_(settings_)`
like this: like this:
```yaml ```yaml
oidc_user_config_identifier: my_provider oidc_user_backend_config_provider_identifier: my_provider
oidc_user_config_discovery_endpoint: https://idp.example.com/ oidc_user_backend_config_provider_discovery_endpoint: https://idp.example.com/
oidc_user_config_client_id: my-client-id oidc_user_backend_config_provider_client_id: my-client-id
oidc_user_config_client_secret: my-client-secret oidc_user_backend_config_provider_client_secret: my-client-secret
# All options to the occ command are avaible in the # All options to the occ command are avaible in the
# `oidc_user_config_settings_` namespace # `oidc_user_backend_config_provider_settings_` namespace
oidc_user_config_settings_unique_id: true oidc_user_backend_config_provider_settings_unique_id: true
oidc_user_config_settings_send_id_token_hint: true oidc_user_backend_config_provider_settings_send_id_token_hint: true
oidc_user_config_settings_mapping_display_name: name oidc_user_backend_config_provider_settings_mapping_display_name: name
oidc_user_config_settings_mapping_uid: preferred_username oidc_user_backend_config_provider_settings_mapping_uid: preferred_username
oidc_user_config_settings_mapping_email: email oidc_user_backend_config_provider_settings_mapping_email: email
``` ```

View File

@ -1,47 +0,0 @@
---
oidc_user_deployment_method: host
oidc_user_deployment_become_user: ~
oidc_user_deployment_method_docker_container_name: nextcloud
oidc_user_deployment_method_podman_container_name: nextcloud
oidc_user_occ_command: "php occ"
oidc_user_occ_user_oidc_provider_identifier: ~
oidc_user_config_identifier: ~
oidc_user_config_client_id: ~
oidc_user_config_client_secret: ~
oidc_user_config_discovery_endpoint: ~
oidc_user_config_end_session_endpoint: ~
oidc_user_config_scopes:
- openid
- email
- profile
oidc_user_config_settings_unique_id: true
oidc_user_config_settings_check_bearer: true
oidc_user_config_settings_send_id_token_hint: true
oidc_user_config_settings_bearer_provisioning: false
oidc_user_config_settings_extra_claims: []
oidc_user_config_settings_provider_based_id: false
oidc_user_config_settings_group_provisioning: false
oidc_user_config_settings_mapping_display_name: name
oidc_user_config_settings_mapping_email: email
oidc_user_config_settings_mapping_quota: ~
oidc_user_config_settings_mapping_uid: sub
oidc_user_config_settings_mapping_groups: ~
oidc_user_config_settings_mapping_address: ~
oidc_user_config_settings_mapping_street_address: ~
oidc_user_config_settings_mapping_postal_code: ~
oidc_user_config_settings_mapping_locality: ~
oidc_user_config_settings_mapping_region: ~
oidc_user_config_settings_mapping_country: ~
oidc_user_config_settings_mapping_website: ~
oidc_user_config_settings_mapping_avatar: ~
oidc_user_config_settings_mapping_twitter: ~
oidc_user_config_settings_mapping_fediverse: ~
oidc_user_config_settings_mapping_organisation: ~
oidc_user_config_settings_mapping_role: ~
oidc_user_config_settings_mapping_headline: ~
oidc_user_config_settings_mapping_biography: ~
oidc_user_config_settings_mapping_phone: ~
oidc_user_config_settings_mapping_gender: ~

View File

@ -0,0 +1,40 @@
---
oidc_user_backend_config_provider_identifier: ~
oidc_user_backend_config_provider_client_id: ~
oidc_user_backend_config_provider_client_secret: ~
oidc_user_backend_config_provider_discovery_endpoint: ~
oidc_user_backend_config_provider_end_session_endpoint: ~
oidc_user_backend_config_provider_scopes:
- openid
- email
- profile
oidc_user_backend_config_provider_settings_unique_uid: true
oidc_user_backend_config_provider_settings_check_bearer: true
oidc_user_backend_config_provider_settings_send_id_token_hint: true
oidc_user_backend_config_provider_settings_bearer_provisioning: false
oidc_user_backend_config_provider_settings_extra_claims: []
oidc_user_backend_config_provider_settings_provider_based_id: false
oidc_user_backend_config_provider_settings_group_provisioning: false
oidc_user_backend_config_provider_settings_mapping_display_name: name
oidc_user_backend_config_provider_settings_mapping_email: email
oidc_user_backend_config_provider_settings_mapping_quota: ~
oidc_user_backend_config_provider_settings_mapping_uid: sub
oidc_user_backend_config_provider_settings_mapping_groups: ~
oidc_user_backend_config_provider_settings_mapping_address: ~
oidc_user_backend_config_provider_settings_mapping_street_address: ~
oidc_user_backend_config_provider_settings_mapping_postal_code: ~
oidc_user_backend_config_provider_settings_mapping_locality: ~
oidc_user_backend_config_provider_settings_mapping_region: ~
oidc_user_backend_config_provider_settings_mapping_country: ~
oidc_user_backend_config_provider_settings_mapping_website: ~
oidc_user_backend_config_provider_settings_mapping_avatar: ~
oidc_user_backend_config_provider_settings_mapping_twitter: ~
oidc_user_backend_config_provider_settings_mapping_fediverse: ~
oidc_user_backend_config_provider_settings_mapping_organisation: ~
oidc_user_backend_config_provider_settings_mapping_role: ~
oidc_user_backend_config_provider_settings_mapping_headline: ~
oidc_user_backend_config_provider_settings_mapping_biography: ~
oidc_user_backend_config_provider_settings_mapping_phone: ~
oidc_user_backend_config_provider_settings_mapping_gender: ~

View File

@ -0,0 +1,5 @@
---
oidc_user_backend_deployment_method: host
oidc_user_backend_deployment_become_user: ~
oidc_user_backend_deployment_method_docker_container_name: nextcloud
oidc_user_backend_deployment_method_podman_container_name: nextcloud

View File

@ -0,0 +1,15 @@
---
oidc_user_backend_occ_command: "php occ"
oidc_user_backend_occ_user_oidc_provider_identifier: >-2
{{ oidc_user_backend_config_provider_identifier }}
oidc_user_backend_force_update: false
oidc_user_backend_occ_user_oidc_provider_set_command: >-2
{{ oidc_user_backend_occ_command }} user_oidc:provider
{{ oidc_user_backend_occ_user_oidc_provider_options }}
{{ oidc_user_backend_occ_user_oidc_provider_identifier }}
oidc_user_backend_occ_user_oidc_provider_list_command: >-2
{{ oidc_user_backend_occ_command }} user_oidc:provider --output=json
oidc_user_backend_occ_user_oidc_provider_get_command: >-2
{{ oidc_user_backend_occ_command }} user_oidc:provider --output=json
{{ oidc_user_backend_occ_user_oidc_provider_identifier }}

View File

@ -0,0 +1,41 @@
---
- name: Execute OCC command (host)
ansible.builtin.command:
cmd: "{{ oidc_user_backend_occ_command_to_exec }}"
become_user: "{{ oidc_user_backend_occ_user_to_become }}"
register: oidc_user_backend_occ_command_result_host
when: oidc_user_backend_deployment_method == 'host'
- name: Execute OCC command (docker)
community.docker.docker_container_exec:
container: >-2
{{ oidc_user_backend_deployment_method_docker_container_name }}
command: "{{ oidc_user_backend_occ_command_to_exec }}"
user: "{{ oidc_user_backend_occ_user_to_become | default(omit, true) }}"
register: oidc_user_backend_occ_command_result_docker
when: oidc_user_backend_deployment_method == 'docker'
- name: Execute OCC command (podman)
containers.podman.podman_container_exec:
name: >-2
{{ oidc_user_backend_deployment_method_podman_container_name }}
command: "{{ oidc_user_backend_occ_command_to_exec }}"
user: "{{ oidc_user_backend_occ_user_to_become | default(omit, true) }}"
register: oidc_user_backend_occ_command_result_podman
when: oidc_user_backend_deployment_method == 'podman'
- name: Register result into variable
ansible.builtin.set_fact: {
"{{ oidc_user_backend_occ_command_result_var }}" : "{{
oidc_user_backend_occ_command_result.stdout | string | from_json
}}"
}
vars:
oidc_user_backend_occ_result_map:
host: "{{ oidc_user_backend_occ_command_result_host }}"
docker: "{{ oidc_user_backend_occ_command_result_docker }}"
podman: "{{ oidc_user_backend_occ_command_result_podman }}"
oidc_user_backend_occ_command_result: >-2
{{ oidc_user_backend_occ_result_map[oidc_user_backend_deployment_method]
| default(false, true) }}
when: oidc_user_backend_occ_command_result_var | default(false, true)

View File

@ -1,29 +1,52 @@
--- ---
- name: Check if deployment method is supported - name: Check if deployment method is supported
ansible.builtin.fail: ansible.builtin.fail:
msg: >-2 msg: >-2
Deployment method '{{ oidc_user_deployment_method }}' is not supported! Deployment method '{{ oidc_user_backend_deployment_method }}' is not supported!
Supported are: {{ oidc_user_deployment_methods | join(', ') }} Supported are: {{ oidc_user_backend_deployment_methods | join(', ') }}
when: oidc_user_deployment_method not in oidc_user_deployment_methods when: oidc_user_backend_deployment_method not in oidc_user_backend_deployment_methods
- name: Configure OIDC provider - name: Lookup become user info
ansible.builtin.command: ansible.builtin.user:
cmd: "{{ oidc_user_occ_user_oidc_provider_set_command }}" name: "{{ oidc_user_backend_deployment_become_user }}"
become_user: "{{ oidc_user_deployment_become_user }}" state: present
become: "{{ oidc_user_deployment_become_user | default(false, true) }}" check_mode: true
when: oidc_user_deployment_method == 'host' register: oidc_user_backend_deployment_become_user_info
when: oidc_user_backend_deployment_become_user | default(false, true)
- name: Configure OIDC provider (docker) - name: Retrieve configured providers
community.docker.docker_container_exec: ansible.builtin.include_tasks:
container: "{{ oidc_user_deployment_method_docker_container_name }}" file: execute-occ.yml
command: "{{ oidc_user_occ_user_oidc_provider_set_command }}" vars:
user: "{{ oidc_user_deployment_become_user | default(omit, true) }}" oidc_user_backend_occ_command_to_exec: >-
when: oidc_user_deployment_method == 'docker' {{ oidc_user_backend_occ_user_oidc_provider_get_command }}
oidc_user_backend_occ_user_to_become: "{{ oidc_user_backend_deployment_become_user_info.uid }}"
oidc_user_backend_occ_command_result_var: "oidc_user_backend_occ_user_oidc_provider"
- name: Configure OIDC provider (podman) - name: Check if provider information should be updated
containers.podman.podman_container_exec: set_fact:
name: "{{ oidc_user_deployment_method_podman_container_name }}" oidc_user_backend_backend_force_update: true
command: "{{ oidc_user_occ_user_oidc_provider_set_command }}" loop: "{{ lookup('ansible.utils.to_paths', oidc_user_backend_occ_user_oidc_provider) | dict2items }}"
user: "{{ oidc_user_deployment_become_user | default(omit, true) }}" loop_control:
when: oidc_user_deployment_method == 'podman' label: "{{ item.key }}"
vars:
target_config: >-2
{{ lookup('ansible.utils.to_paths', oidc_user_backend_occ_user_oidc_config_provider_dict) }}
when:
- item.key not in oidc_user_backend_occ_user_oidc_provider_ignored_settings
- (item.value != None) and (target_config[item.key] != None)
- >-2
(target_config[item.key] != None) | ternary(
(item.value != target_config[item.key]),
(item.value | string | length > 0)
)
- name: Update configuration for provider '{{ oidc_user_backend_config_provider_identifier }}'
ansible.builtin.include_tasks:
file: execute-occ.yml
vars:
oidc_user_backend_occ_command_to_exec: >-
{{ oidc_user_backend_occ_user_oidc_provider_set_command }}
oidc_user_backend_occ_user_to_become: "{{ oidc_user_backend_deployment_become_user_info.uid }}"
oidc_user_backend_occ_command_result_var: ~
when: oidc_user_backend_backend_force_update | default(false, true)

View File

@ -1,63 +0,0 @@
---
oidc_user_deployment_methods:
- host
- docker
- podman
oidc_user_occ_user_oidc_options_dict:
clientid: "{{ oidc_user_config_client_id }}"
clientsecret: "{{ oidc_user_config_client_secret }}"
discoveryuri: "{{ oidc_user_config_discovery_endpoint }}"
endsessionendpointuri: "{{ oidc_user_config_end_session_endpoint }}"
scope: "'{{ oidc_user_config_scopes | default([], true) | join(' ') }}'"
"unique-uid": >-2
{{ oidc_user_config_settings_unique_id | bool | ternary(1, 0) }}
"check-bearer": >-2
{{ oidc_user_config_settings_check_bearer | bool | ternary(1, 0) }}
"send-id-token-hint": >-2
{{ oidc_user_config_settings_send_id_token_hint | bool | ternary(1, 0) }}
"group-provisioning": >-2
{{ oidc_user_config_settings_group_provisioning | bool | ternary(1, 0) }}
"extra-claims": >-2
{{ (oidc_user_config_settings_extra_claims | default([]) | length > 0)
| ternary(oidc_user_config_settings_extra_claims | join(' ') | quote, '') }}
oidc_user_occ_user_oidc_mapping_options_dict:
"display-name": "{{ oidc_user_config_settings_mapping_display_name }}"
email: "{{ oidc_user_config_settings_mapping_email }}"
quota: "{{ oidc_user_config_settings_mapping_quota }}"
uid: "{{ oidc_user_config_settings_mapping_uid }}"
groups: "{{ oidc_user_config_settings_mapping_groups }}"
website: "{{ oidc_user_config_settings_mapping_website }}"
avatar: "{{ oidc_user_config_settings_mapping_avatar }}"
twitter: "{{ oidc_user_config_settings_mapping_twitter }}"
fediverse: "{{ oidc_user_config_settings_mapping_fediverse }}"
organisation: "{{ oidc_user_config_settings_mapping_organisation }}"
role: "{{ oidc_user_config_settings_mapping_role }}"
headline: "{{ oidc_user_config_settings_mapping_headline }}"
biography: "{{ oidc_user_config_settings_mapping_biography }}"
phone: "{{ oidc_user_config_settings_mapping_phone }}"
gender: "{{ oidc_user_config_settings_mapping_gender }}"
address: "{{ oidc_user_config_settings_mapping_address }}"
street_address: "{{ oidc_user_config_settings_mapping_street_address }}"
postal_code: "{{ oidc_user_config_settings_mapping_postal_code }}"
locality: "{{ oidc_user_config_settings_mapping_locality }}"
region: "{{ oidc_user_config_settings_mapping_region }}"
country: "{{ oidc_user_config_settings_mapping_country }}"
oidc_user_occ_user_oidc_provider_options: >-2
{% for tuple in oidc_user_occ_user_oidc_options_dict | dict2items %}
{% if tuple.value | default(false, true) %}
--{{ tuple.key }}={{ tuple.value }}
{% endif %}
{% endfor %}
{% for tuple in oidc_user_occ_user_oidc_mapping_options_dict | dict2items %}
{% if tuple.value | default(false, true) %}
--mapping-{{ tuple.key }}={{ tuple.value }}
{% endif %}
{% endfor %}
oidc_user_occ_user_oidc_provider_set_command: >-2
{{ oidc_user_occ_command }} user_oidc:provider
{{ oidc_user_occ_user_oidc_provider_options }}
{{ oidc_user_occ_user_oidc_provider_identifier }}

View File

@ -0,0 +1,9 @@
---
oidc_user_backend_deployment_methods:
- host
- docker
- podman
oidc_user_backend_occ_user_oidc_provider_ignored_settings:
- 'id'
- 'settings.bearerProvisioning'

View File

@ -0,0 +1,43 @@
---
# JSON structure of the `occ` response with `--output=json`
oidc_user_backend_occ_user_oidc_config_provider_dict:
identifier: "{{ oidc_user_backend_config_provider_identifier }}"
clientId: "{{ oidc_user_backend_config_provider_client_id }}"
clientSecret: "{{ oidc_user_backend_config_provider_client_secret }}"
discoveryEndpoint: "{{ oidc_user_backend_config_provider_discovery_endpoint }}"
endSessionEndpoint: "{{ oidc_user_backend_config_provider_end_session_endpoint }}"
scope: "{{ oidc_user_backend_config_provider_scopes | default([], true) | join(' ') }}"
settings:
uniqueUid: >-2
{{ oidc_user_backend_config_provider_settings_unique_uid | bool }}
providerBasedId: >-2
{{ oidc_user_backend_config_provider_settings_provider_based_id | bool }}
checkBearer: >-2
{{ oidc_user_backend_config_provider_settings_check_bearer | bool }}
sendIdTokenHint: >-2
{{ oidc_user_backend_config_provider_settings_send_id_token_hint | bool }}
groupProvisioning: >-2
{{ oidc_user_backend_config_provider_settings_group_provisioning | bool }}
extraClaims: >-2
{{ oidc_user_backend_config_provider_settings_extra_claims | default([]) | join(' ') }}
mappingDisplayName: "{{ oidc_user_backend_config_provider_settings_mapping_display_name }}"
mappingEmail: "{{ oidc_user_backend_config_provider_settings_mapping_email }}"
mappingQuota: "{{ oidc_user_backend_config_provider_settings_mapping_quota }}"
mappingUid: "{{ oidc_user_backend_config_provider_settings_mapping_uid }}"
mappingGroups: "{{ oidc_user_backend_config_provider_settings_mapping_groups }}"
mappingWebsite: "{{ oidc_user_backend_config_provider_settings_mapping_website }}"
mappingAvatar: "{{ oidc_user_backend_config_provider_settings_mapping_avatar }}"
mappingTwitter: "{{ oidc_user_backend_config_provider_settings_mapping_twitter }}"
mappingFediverse: "{{ oidc_user_backend_config_provider_settings_mapping_fediverse }}"
mappingOrganisation: "{{ oidc_user_backend_config_provider_settings_mapping_organisation }}"
mappingRole: "{{ oidc_user_backend_config_provider_settings_mapping_role }}"
mappingHeadline: "{{ oidc_user_backend_config_provider_settings_mapping_headline }}"
mappingBiography: "{{ oidc_user_backend_config_provider_settings_mapping_biography }}"
mappingPhonenumber: "{{ oidc_user_backend_config_provider_settings_mapping_phone }}"
mappingGender: "{{ oidc_user_backend_config_provider_settings_mapping_gender }}"
mappingAddress: "{{ oidc_user_backend_config_provider_settings_mapping_address }}"
mappingStreetaddress: "{{ oidc_user_backend_config_provider_settings_mapping_street_address }}"
mappingPostalcode: "{{ oidc_user_backend_config_provider_settings_mapping_postal_code }}"
mappingLocality: "{{ oidc_user_backend_config_provider_settings_mapping_locality }}"
mappingRegion: "{{ oidc_user_backend_config_provider_settings_mapping_region }}"
mappingCountry: "{{ oidc_user_backend_config_provider_settings_mapping_country }}"

View File

@ -0,0 +1,54 @@
---
# Structure how `occ user_oidc:provider [options] [<identifier>]` expects them
oidc_user_backend_occ_user_oidc_provider_options_dict:
clientid: "{{ oidc_user_backend_config_provider_client_id }}"
clientsecret: "{{ oidc_user_backend_config_provider_client_secret }}"
discoveryuri: "{{ oidc_user_backend_config_provider_discovery_endpoint }}"
endsessionendpointuri: "{{ oidc_user_backend_config_provider_end_session_endpoint }}"
scope: "'{{ oidc_user_backend_config_provider_scopes | default([], true) | join(' ') }}'"
"unique-uid": >-2
{{ oidc_user_backend_config_provider_settings_unique_uid | bool | ternary(1, 0) }}
"check-bearer": >-2
{{ oidc_user_backend_config_provider_settings_check_bearer | bool | ternary(1, 0) }}
"send-id-token-hint": >-2
{{ oidc_user_backend_config_provider_settings_send_id_token_hint | bool | ternary(1, 0) }}
"group-provisioning": >-2
{{ oidc_user_backend_config_provider_settings_group_provisioning | bool | ternary(1, 0) }}
"extra-claims": >-2
{{ (oidc_user_backend_config_provider_settings_extra_claims | default([]) | length > 0)
| ternary(oidc_user_backend_config_provider_settings_extra_claims | join(' ') | quote, '') }}
oidc_user_backend_occ_user_oidc_provider_mapping_options_dict:
"display-name": "{{ oidc_user_backend_config_provider_settings_mapping_display_name }}"
email: "{{ oidc_user_backend_config_provider_settings_mapping_email }}"
quota: "{{ oidc_user_backend_config_provider_settings_mapping_quota }}"
uid: "{{ oidc_user_backend_config_provider_settings_mapping_uid }}"
groups: "{{ oidc_user_backend_config_provider_settings_mapping_groups }}"
website: "{{ oidc_user_backend_config_provider_settings_mapping_website }}"
avatar: "{{ oidc_user_backend_config_provider_settings_mapping_avatar }}"
twitter: "{{ oidc_user_backend_config_provider_settings_mapping_twitter }}"
fediverse: "{{ oidc_user_backend_config_provider_settings_mapping_fediverse }}"
organisation: "{{ oidc_user_backend_config_provider_settings_mapping_organisation }}"
role: "{{ oidc_user_backend_config_provider_settings_mapping_role }}"
headline: "{{ oidc_user_backend_config_provider_settings_mapping_headline }}"
biography: "{{ oidc_user_backend_config_provider_settings_mapping_biography }}"
phone: "{{ oidc_user_backend_config_provider_settings_mapping_phone }}"
gender: "{{ oidc_user_backend_config_provider_settings_mapping_gender }}"
address: "{{ oidc_user_backend_config_provider_settings_mapping_address }}"
street_address: "{{ oidc_user_backend_config_provider_settings_mapping_street_address }}"
postal_code: "{{ oidc_user_backend_config_provider_settings_mapping_postal_code }}"
locality: "{{ oidc_user_backend_config_provider_settings_mapping_locality }}"
region: "{{ oidc_user_backend_config_provider_settings_mapping_region }}"
country: "{{ oidc_user_backend_config_provider_settings_mapping_country }}"
oidc_user_backend_occ_user_oidc_provider_options: >-2
{% for tuple in oidc_user_backend_occ_user_oidc_provider_options_dict | dict2items %}
{% if tuple.value | default(false, true) %}
--{{ tuple.key }}={{ tuple.value }}
{% endif %}
{% endfor %}
{% for tuple in oidc_user_backend_occ_user_oidc_provider_mapping_options_dict | dict2items %}
{% if tuple.value | default(false, true) %}
--mapping-{{ tuple.key }}={{ tuple.value }}
{% endif %}
{% endfor %}