mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-08-30 15:28:12 +02:00
Added auto snippet for webserver injection
This commit is contained in:
56
roles/sys-srv-web-inj-compose/filter_plugins/inj_snippets.py
Normal file
56
roles/sys-srv-web-inj-compose/filter_plugins/inj_snippets.py
Normal file
@@ -0,0 +1,56 @@
|
||||
# roles/sys-srv-web-inj-compose/filter_plugins/inj_snippets.py
|
||||
"""
|
||||
Jinja filter: `inj_features(kind)` filters a list of features to only those
|
||||
that actually provide the corresponding snippet template file.
|
||||
|
||||
- kind='head' -> roles/sys-srv-web-inj-<feature>/templates/head_sub.j2
|
||||
- kind='body' -> roles/sys-srv-web-inj-<feature>/templates/body_sub.j2
|
||||
|
||||
If the feature's role directory (roles/sys-srv-web-inj-<feature>) does not
|
||||
exist, this filter raises FileNotFoundError.
|
||||
|
||||
Usage in a template:
|
||||
{% set head_features = SRV_WEB_INJ_COMP_FEATURES_ALL | inj_features('head') %}
|
||||
{% set body_features = SRV_WEB_INJ_COMP_FEATURES_ALL | inj_features('body') %}
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
# This file lives at: roles/sys-srv-web-inj-compose/filter_plugins/inj_snippets.py
|
||||
_THIS_DIR = os.path.dirname(__file__)
|
||||
_ROLE_DIR = os.path.abspath(os.path.join(_THIS_DIR, "..")) # roles/sys-srv-web-inj-compose
|
||||
_ROLES_DIR = os.path.abspath(os.path.join(_ROLE_DIR, "..")) # roles
|
||||
|
||||
def _feature_role_dir(feature: str) -> str:
|
||||
return os.path.join(_ROLES_DIR, f"sys-srv-web-inj-{feature}")
|
||||
|
||||
def _has_snippet(feature: str, kind: str) -> bool:
|
||||
if kind not in ("head", "body"):
|
||||
raise ValueError("kind must be 'head' or 'body'")
|
||||
|
||||
role_dir = _feature_role_dir(feature)
|
||||
if not os.path.isdir(role_dir):
|
||||
raise FileNotFoundError(
|
||||
f"[inj_snippets] Expected role directory not found for feature "
|
||||
f"'{feature}': {role_dir}"
|
||||
)
|
||||
|
||||
path = os.path.join(role_dir, "templates", f"{kind}_sub.j2")
|
||||
return os.path.exists(path)
|
||||
|
||||
def inj_features_filter(features, kind: str = "head"):
|
||||
if not isinstance(features, (list, tuple)):
|
||||
return []
|
||||
# Validation + filtering in one pass; will raise if a role dir is missing.
|
||||
valid = []
|
||||
for f in features:
|
||||
name = str(f)
|
||||
if _has_snippet(name, kind):
|
||||
valid.append(name)
|
||||
return valid
|
||||
|
||||
class FilterModule(object):
|
||||
def filters(self):
|
||||
return {
|
||||
"inj_features": inj_features_filter,
|
||||
}
|
@@ -39,6 +39,8 @@
|
||||
- name: Reinitialize 'inj_enabled' for '{{ domain }}', after modification by CDN
|
||||
set_fact:
|
||||
inj_enabled: "{{ applications | inj_enabled(application_id, SRV_WEB_INJ_COMP_FEATURES_ALL) }}"
|
||||
inj_head_features: "{{ SRV_WEB_INJ_COMP_FEATURES_ALL | inj_features('head') }}"
|
||||
inj_body_features: "{{ SRV_WEB_INJ_COMP_FEATURES_ALL | inj_features('body') }}"
|
||||
|
||||
- name: "Activate Corporate CSS for '{{ domain }}'"
|
||||
include_role:
|
||||
|
@@ -1,15 +1,10 @@
|
||||
{# roles/sys-srv-web-inj-compose/templates/location.lua.j2 #}
|
||||
{% macro push_snippets(list_name, features) -%}
|
||||
{% for f in features -%}
|
||||
{% if inj_enabled.get(f) -%}
|
||||
{% set kind = list_name | regex_replace('_snippets$','') %}
|
||||
{% for f in features if inj_enabled.get(f) -%}
|
||||
{{ list_name }}[#{{ list_name }} + 1] = [=[
|
||||
{%- include
|
||||
'roles/sys-srv-web-inj-' ~ f ~
|
||||
'/templates/' ~
|
||||
('head' if list_name == 'head_snippets' else 'body') ~
|
||||
'_sub.j2'
|
||||
-%}
|
||||
{%- include 'roles/sys-srv-web-inj-' ~ f ~ '/templates/' ~ kind ~ '_sub.j2' -%}
|
||||
]=]
|
||||
{% endif -%}
|
||||
{% endfor -%}
|
||||
{%- endmacro %}
|
||||
|
||||
@@ -48,7 +43,7 @@ body_filter_by_lua_block {
|
||||
local whole = table.concat(ngx.ctx.buf)
|
||||
ngx.ctx.buf = nil -- clear buffer
|
||||
|
||||
-- remove html CSP, due to management via infinito nexus policies
|
||||
-- remove html CSP, due to management via Infinito.Nexus policies
|
||||
whole = whole:gsub(
|
||||
'<meta[^>]-http%-equiv=["\']Content%-Security%-Policy["\'][^>]->%s*',
|
||||
''
|
||||
@@ -57,21 +52,21 @@ body_filter_by_lua_block {
|
||||
-- build a list of head-injection snippets
|
||||
local head_snippets = {}
|
||||
|
||||
{{ push_snippets('head_snippets', ['css','matomo','desktop','javascript','logout']) }}
|
||||
{{ push_snippets('head_snippets', inj_head_features) }}
|
||||
|
||||
-- inject all collected snippets right before </head>
|
||||
local head_payload = table.concat(head_snippets, "\n") .. "</head>"
|
||||
whole = string.gsub(whole, "</head>", head_payload)
|
||||
whole = ngx.re.gsub(whole, "</head>", head_payload, "ijo", nil, 1)
|
||||
|
||||
-- build a list of body-injection snippets
|
||||
local body_snippets = {}
|
||||
|
||||
{{ push_snippets('body_snippets', ['matomo','logout','desktop']) }}
|
||||
{{ push_snippets('body_snippets', inj_body_features) }}
|
||||
|
||||
-- inject all collected snippets right before </body>
|
||||
local body_payload = table.concat(body_snippets, "\n") .. "</body>"
|
||||
whole = string.gsub(whole, "</body>", body_payload)
|
||||
whole = ngx.re.gsub(whole, "</body>", body_payload, "ijo", nil, 1)
|
||||
|
||||
-- finally send the modified HTML out
|
||||
ngx.arg[1] = whole
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user