mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-05-14 09:14:56 +02:00
Solved oauth2 proxy configuration bugs
This commit is contained in:
parent
9ea92ea9ec
commit
7ce480bd5c
@ -1,4 +1,4 @@
|
|||||||
- name: "set _tmp_database_application_id (Needed due to lazzy loading issue)"
|
- name: "set database_application_id (Needed due to lazzy loading issue)"
|
||||||
set_fact:
|
set_fact:
|
||||||
database_application_id: "{{ application_id }}"
|
database_application_id: "{{ application_id }}"
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
- name: "Transfering oauth2-proxy-keycloak.cfg.j2 to {{docker_compose.directories.volumes}}"
|
- name: "Transfering oauth2-proxy-keycloak.cfg.j2 to {{docker_compose.directories.volumes}}"
|
||||||
template:
|
template:
|
||||||
src: oauth2-proxy-keycloak.cfg.j2
|
src: oauth2-proxy-keycloak.cfg.j2
|
||||||
dest: "{{docker_compose.directories.volumes}}{{applications.oauth2_proxy.configuration_file}}"
|
dest: "{{docker_compose.directories.volumes}}{{applications[application_id].configuration_file}}"
|
||||||
notify:
|
notify:
|
||||||
- docker compose project setup
|
- docker compose project setup
|
@ -1,20 +1,20 @@
|
|||||||
http_address = "0.0.0.0:4180"
|
http_address = "0.0.0.0:4180"
|
||||||
cookie_secret = "{{ applications[application_id].credentials.oauth2_proxy_cookie_secret }}"
|
cookie_secret = "{{ applications[oauth2_proxy_application_id].credentials.oauth2_proxy_cookie_secret }}"
|
||||||
email_domains = "{{primary_domain}}"
|
email_domains = "{{ primary_domain }}"
|
||||||
cookie_secure = "true" # True is necessary to force the cookie set via https
|
cookie_secure = "true" # True is necessary to force the cookie set via https
|
||||||
upstreams = "http://{{applications[application_id].oauth2_proxy.application}}:{{applications[application_id].oauth2_proxy.port}}"
|
upstreams = "http://{{ applications[oauth2_proxy_application_id].oauth2_proxy.application }}:{{ applications[oauth2_proxy_application_id].oauth2_proxy.port }}"
|
||||||
cookie_domains = ["{{domain}}", "{{domains.keycloak}}"] # Required so cookie can be read on all subdomains.
|
cookie_domains = ["{{ domain }}", "{{ domains.keycloak }}"] # Required so cookie can be read on all subdomains.
|
||||||
whitelist_domains = [".{{primary_domain}}"] # Required to allow redirection back to original requested target.
|
whitelist_domains = [".{{ primary_domain }}"] # Required to allow redirection back to original requested target.
|
||||||
|
|
||||||
# keycloak provider
|
# keycloak provider
|
||||||
client_secret = "{{oidc.client.secret}}"
|
client_secret = "{{ oidc.client.secret }}"
|
||||||
client_id = "{{oidc.client.id}}"
|
client_id = "{{ oidc.client.id }}"
|
||||||
redirect_url = "{{ web_protocol }}://{{domain}}/oauth2/callback"
|
redirect_url = "{{ web_protocol }}://{{domain}}/oauth2/callback"
|
||||||
oidc_issuer_url = "{{oidc.client.issuer_url}}"
|
oidc_issuer_url = "{{ oidc.client.issuer_url }}"
|
||||||
provider = "oidc"
|
provider = "oidc"
|
||||||
provider_display_name = "Keycloak"
|
provider_display_name = "Keycloak"
|
||||||
|
|
||||||
# role restrictions
|
# role restrictions
|
||||||
#cookie_roles = "realm_access.roles"
|
#cookie_roles = "realm_access.roles"
|
||||||
#allowed_groups = "{{applications.oauth2_proxy.allowed_roles}}" # This is not correct here. needs to be placed in applications @todo move there when implementing
|
#allowed_groups = "{{ applications[oauth2_proxy_application_id].allowed_roles }}" # This is not correct here. needs to be placed in applications @todo move there when implementing
|
||||||
# @see https://chatgpt.com/share/67f42607-bf68-800f-b587-bd56fe9067b5
|
# @see https://chatgpt.com/share/67f42607-bf68-800f-b587-bd56fe9067b5
|
1
roles/docker-oauth2-proxy/vars/main.yml
Normal file
1
roles/docker-oauth2-proxy/vars/main.yml
Normal file
@ -0,0 +1 @@
|
|||||||
|
application_id: oauth2-proxy
|
@ -7,8 +7,13 @@
|
|||||||
src: "{{ vhost_template_src }}"
|
src: "{{ vhost_template_src }}"
|
||||||
dest: "{{ configuration_destination }}"
|
dest: "{{ configuration_destination }}"
|
||||||
notify: restart nginx
|
notify: restart nginx
|
||||||
|
|
||||||
|
- name: "set oauth2_proxy_application_id (Needed due to lazzy loading issue)"
|
||||||
|
set_fact:
|
||||||
|
oauth2_proxy_application_id: "{{ application_id }}"
|
||||||
|
when: "{{applications[application_id].get('features', {}).get('oauth2', False)}}"
|
||||||
|
|
||||||
- name: "include the docker-oauth2-proxy role {{domain}}"
|
- name: "include the docker-oauth2-proxy role {{domain}}"
|
||||||
include_role:
|
include_role:
|
||||||
name: docker-oauth2-proxy
|
name: docker-oauth2-proxy
|
||||||
when: final_oauth2_enabled | bool
|
when: "{{applications[application_id].get('features', {}).get('oauth2', False)}}"
|
@ -1,2 +1 @@
|
|||||||
configuration_destination: "{{nginx.directories.http.servers}}{{domain}}.conf"
|
configuration_destination: "{{nginx.directories.http.servers}}{{domain}}.conf"
|
||||||
final_oauth2_enabled: "{{applications[application_id].get('features', {}).get('oauth2', False)}}"
|
|
92
tests/unit/test_configuration_filters.py
Normal file
92
tests/unit/test_configuration_filters.py
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
# tests/unit/test_configuration_filters.py
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
from filter_plugins.configuration_filters import (
|
||||||
|
is_feature_enabled,
|
||||||
|
get_csp_whitelist,
|
||||||
|
get_csp_flags,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class TestConfigurationFilters(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
# Sample applications data for testing
|
||||||
|
self.applications = {
|
||||||
|
'app1': {
|
||||||
|
'features': {
|
||||||
|
'oauth2': True,
|
||||||
|
},
|
||||||
|
'csp': {
|
||||||
|
'whitelist': {
|
||||||
|
# directive with a list
|
||||||
|
'script-src': ['https://example.com'],
|
||||||
|
# directive with a single string
|
||||||
|
'connect-src': 'https://api.example.com',
|
||||||
|
},
|
||||||
|
'flags': {
|
||||||
|
# both flags for script-src
|
||||||
|
'script-src': {
|
||||||
|
'unsafe_eval': True,
|
||||||
|
'unsafe_inline': False,
|
||||||
|
},
|
||||||
|
# only unsafe_inline for style-src
|
||||||
|
'style-src': {
|
||||||
|
'unsafe_inline': True,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'app2': {
|
||||||
|
# no features or csp defined
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
# Tests for is_feature_enabled
|
||||||
|
def test_is_feature_enabled_true(self):
|
||||||
|
self.assertTrue(is_feature_enabled(self.applications, 'oauth2', 'app1'))
|
||||||
|
|
||||||
|
def test_is_feature_enabled_false_missing_feature(self):
|
||||||
|
self.assertFalse(is_feature_enabled(self.applications, 'nonexistent', 'app1'))
|
||||||
|
|
||||||
|
def test_is_feature_enabled_false_missing_app(self):
|
||||||
|
self.assertFalse(is_feature_enabled(self.applications, 'oauth2', 'unknown_app'))
|
||||||
|
|
||||||
|
# Tests for get_csp_whitelist
|
||||||
|
def test_get_csp_whitelist_returns_list_as_is(self):
|
||||||
|
result = get_csp_whitelist(self.applications, 'app1', 'script-src')
|
||||||
|
self.assertEqual(result, ['https://example.com'])
|
||||||
|
|
||||||
|
def test_get_csp_whitelist_wraps_string_in_list(self):
|
||||||
|
result = get_csp_whitelist(self.applications, 'app1', 'connect-src')
|
||||||
|
self.assertEqual(result, ['https://api.example.com'])
|
||||||
|
|
||||||
|
def test_get_csp_whitelist_empty_when_not_defined(self):
|
||||||
|
result = get_csp_whitelist(self.applications, 'app1', 'frame-src')
|
||||||
|
self.assertEqual(result, [])
|
||||||
|
|
||||||
|
def test_get_csp_whitelist_empty_when_app_missing(self):
|
||||||
|
result = get_csp_whitelist(self.applications, 'nonexistent_app', 'script-src')
|
||||||
|
self.assertEqual(result, [])
|
||||||
|
|
||||||
|
# Tests for get_csp_flags
|
||||||
|
def test_get_csp_flags_includes_unsafe_eval(self):
|
||||||
|
result = get_csp_flags(self.applications, 'app1', 'script-src')
|
||||||
|
self.assertIn("'unsafe-eval'", result)
|
||||||
|
self.assertNotIn("'unsafe-inline'", result)
|
||||||
|
|
||||||
|
def test_get_csp_flags_includes_unsafe_inline(self):
|
||||||
|
result = get_csp_flags(self.applications, 'app1', 'style-src')
|
||||||
|
self.assertIn("'unsafe-inline'", result)
|
||||||
|
self.assertNotIn("'unsafe-eval'", result)
|
||||||
|
|
||||||
|
def test_get_csp_flags_empty_when_none_configured(self):
|
||||||
|
result = get_csp_flags(self.applications, 'app1', 'connect-src')
|
||||||
|
self.assertEqual(result, [])
|
||||||
|
|
||||||
|
def test_get_csp_flags_empty_when_app_missing(self):
|
||||||
|
result = get_csp_flags(self.applications, 'nonexistent_app', 'script-src')
|
||||||
|
self.assertEqual(result, [])
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
Loading…
x
Reference in New Issue
Block a user