mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2025-09-17 07:46:05 +02:00
web-app-xwiki: verify extensions via Groovy page + new filter
- Added new filter 'xwiki_extension_status' (strips HTML, handles ) -> returns 200/404 - Introduced checker tasks (_check_extension_via_groovy.yml) instead of REST probe - Added early assert: superadmin login before extension installation - Collect and assert probe results in 04_extensions.yml - Set OIDC extension version to 'latest' (empty string) https://chatgpt.com/share/68ca36cb-ac38-800f-8281-8dea480b6676
This commit is contained in:
@@ -45,8 +45,8 @@ plugins:
|
||||
enabled: true
|
||||
items:
|
||||
- id: "org.xwiki.contrib.oidc:oidc-authenticator"
|
||||
version: "2.19.2"
|
||||
|
||||
version: ""
|
||||
|
||||
ldap:
|
||||
enabled: false
|
||||
items:
|
||||
|
@@ -74,9 +74,35 @@ def xwiki_job_id(response: Any, default: Optional[str] = None, strict: bool = Fa
|
||||
return default
|
||||
|
||||
|
||||
def xwiki_extension_status(raw: str) -> int:
|
||||
"""
|
||||
Parse the output of the Groovy CheckExtension page.
|
||||
|
||||
- Strips HTML tags and entities ( )
|
||||
- Returns 200 if extension is INSTALLED, otherwise 404
|
||||
|
||||
Args:
|
||||
raw: Raw HTTP body from the checker page.
|
||||
|
||||
Returns:
|
||||
200 if installed, 404 if missing/unknown.
|
||||
"""
|
||||
if raw is None:
|
||||
return 404
|
||||
|
||||
text = re.sub(r"<[^>]+>", "", str(raw))
|
||||
text = text.replace(" ", " ").replace("\u00A0", " ")
|
||||
text = text.strip()
|
||||
|
||||
if text.startswith("INSTALLED::"):
|
||||
return 200
|
||||
return 404
|
||||
|
||||
|
||||
class FilterModule(object):
|
||||
"""Custom filters for XWiki helpers."""
|
||||
def filters(self):
|
||||
return {
|
||||
"xwiki_job_id": xwiki_job_id,
|
||||
"xwiki_extension_status": xwiki_extension_status,
|
||||
}
|
||||
|
@@ -15,6 +15,21 @@
|
||||
xwiki_ldap_enabled_switch: false
|
||||
xwiki_superadmin_enabled_switch: true
|
||||
|
||||
- name: "ASSERT | superadmin can authenticate (needed for installer)"
|
||||
uri:
|
||||
url: "{{ [XWIKI_REST_XWIKI, 'spaces'] | url_join }}"
|
||||
method: GET
|
||||
user: "{{ XWIKI_SUPERADMIN_USERNAME }}"
|
||||
password: "{{ XWIKI_SUPERADMIN_PASSWORD }}"
|
||||
force_basic_auth: true
|
||||
status_code: [200]
|
||||
register: _super_check_ext
|
||||
|
||||
- name: "FAIL | superadmin authentication failed (extensions phase)"
|
||||
fail:
|
||||
msg: "superadmin authentication failed (check xwiki.cfg in image / password / Dockerfile build)"
|
||||
when: _super_check_ext.status != 200
|
||||
|
||||
- name: Load setup procedures for admin
|
||||
include_tasks: 03_administrator.yml
|
||||
when: not (XWIKI_SSO_ENABLED | bool)
|
||||
|
@@ -57,6 +57,39 @@
|
||||
delay: 15
|
||||
until: _exec_page is succeeded
|
||||
|
||||
- name: "XWIKI | Verify requested extensions via Groovy checker"
|
||||
include_tasks: _check_extension_via_groovy.yml
|
||||
loop: "{{ XWIKI_PLUGINS }}"
|
||||
loop_control:
|
||||
loop_var: plugin
|
||||
label: "{{ plugin.id }}"
|
||||
vars:
|
||||
ext_id: "{{ plugin.id }}"
|
||||
result_var: "probe_{{ plugin.id | regex_replace('[^A-Za-z0-9_]', '_') }}"
|
||||
|
||||
- name: "XWIKI | Collect probe results"
|
||||
set_fact:
|
||||
_xwiki_probe_results: "{{ _xwiki_probe_results | default([]) + [ {
|
||||
'id': plugin.id,
|
||||
'status': (
|
||||
(hostvars[inventory_hostname]['probe_' ~ (plugin.id | regex_replace('[^A-Za-z0-9_]', '_'))]
|
||||
| default({})).status
|
||||
| default(404) | int
|
||||
)
|
||||
} ] }}"
|
||||
loop: "{{ XWIKI_PLUGINS }}"
|
||||
loop_control:
|
||||
loop_var: plugin
|
||||
changed_when: false
|
||||
|
||||
# Fail if any extension is missing
|
||||
- name: "XWIKI | Assert all requested extensions are installed"
|
||||
vars:
|
||||
missing: "{{ _xwiki_probe_results | selectattr('status','equalto',404) | map(attribute='id') | list }}"
|
||||
fail:
|
||||
msg: "Missing extensions: {{ missing | join(', ') }}"
|
||||
when: missing | length > 0
|
||||
|
||||
- name: "XWIKI | Delete installer page"
|
||||
uri:
|
||||
url: "{{ [XWIKI_REST_XWIKI_PAGES, 'InstallExtensions'] | url_join }}"
|
||||
|
63
roles/web-app-xwiki/tasks/_check_extension_via_groovy.yml
Normal file
63
roles/web-app-xwiki/tasks/_check_extension_via_groovy.yml
Normal file
@@ -0,0 +1,63 @@
|
||||
# PUT a temporary Groovy page that checks installed extensions
|
||||
- name: "XWIKI | PUT checker page XWiki.CheckExtension"
|
||||
uri:
|
||||
url: "{{ [XWIKI_REST_XWIKI_PAGES, 'CheckExtension'] | url_join }}"
|
||||
method: PUT
|
||||
user: "{{ XWIKI_SUPERADMIN_USERNAME }}"
|
||||
password: "{{ XWIKI_SUPERADMIN_PASSWORD }}"
|
||||
force_basic_auth: true
|
||||
status_code: [200, 201, 202, 204]
|
||||
headers:
|
||||
Content-Type: "application/xml"
|
||||
Accept: "application/xml"
|
||||
body: |
|
||||
<page xmlns="http://www.xwiki.org">
|
||||
<title>CheckExtension</title>
|
||||
<content><![CDATA[
|
||||
{% raw %}{{groovy}}{% endraw %}
|
||||
def ns = "wiki:xwiki"
|
||||
def id = (request.getParameter("id") ?: "").toString()
|
||||
if (!id) { print "ERROR::missing-id"; return }
|
||||
def ext = services.extension.getInstalledExtension(id, ns)
|
||||
if (ext) {
|
||||
print "INSTALLED::${ext.id?.id}::${ext.id?.version}"
|
||||
} else {
|
||||
print "MISSING::${id}"
|
||||
}
|
||||
{% raw %}{{/groovy}}{% endraw %}
|
||||
]]></content>
|
||||
<syntax>xwiki/2.1</syntax>
|
||||
</page>
|
||||
register: _put_checker
|
||||
changed_when: false
|
||||
|
||||
# Call the page to check a single extension
|
||||
- name: "XWIKI | Check installed via Groovy for {{ ext_id }}"
|
||||
uri:
|
||||
url: "http://127.0.0.1:{{ XWIKI_HOST_PORT }}/bin/view/XWiki/CheckExtension?xpage=plain&id={{ ext_id | urlencode }}"
|
||||
method: GET
|
||||
user: "{{ XWIKI_SUPERADMIN_USERNAME }}"
|
||||
password: "{{ XWIKI_SUPERADMIN_PASSWORD }}"
|
||||
force_basic_auth: true
|
||||
status_code: [200]
|
||||
return_content: yes
|
||||
register: _check_output
|
||||
changed_when: false
|
||||
|
||||
- name: "XWIKI | Save Groovy check result for {{ ext_id }}"
|
||||
set_fact:
|
||||
"{{ result_var }}":
|
||||
status: "{{ _check_output.content | xwiki_extension_status }}"
|
||||
raw: "{{ _check_output.content }}"
|
||||
|
||||
# Cleanup (optional; you can leave the page, but we remove it to keep things tidy)
|
||||
- name: "XWIKI | Delete checker page"
|
||||
uri:
|
||||
url: "{{ [XWIKI_REST_XWIKI_PAGES, 'CheckExtension'] | url_join }}"
|
||||
method: DELETE
|
||||
user: "{{ XWIKI_SUPERADMIN_USERNAME }}"
|
||||
password: "{{ XWIKI_SUPERADMIN_PASSWORD }}"
|
||||
force_basic_auth: true
|
||||
status_code: [204, 200, 202, 404]
|
||||
register: _delete_checker
|
||||
changed_when: _delete_checker.status != 404
|
@@ -1,44 +0,0 @@
|
||||
# roles/web-app-xwiki/tasks/_probe_extension.yml
|
||||
# Probes the 'installed' extension repository to check if a given extension is present.
|
||||
# Uses the wiki-namespaced REST base (/rest/wikis/xwiki) and falls back to /{id}/{version} if needed.
|
||||
|
||||
- name: "XWIKI | Probe extension {{ ext_id }} (installed repo)"
|
||||
when: ext_enabled | bool
|
||||
uri:
|
||||
url: "{{ [XWIKI_REST_XWIKI, 'repositories/installed/extensions', ext_id | urlencode] | url_join }}?namespace={{ 'wiki:xwiki' | urlencode }}"
|
||||
method: GET
|
||||
user: "{{ XWIKI_SUPERADMIN_USERNAME }}"
|
||||
password: "{{ XWIKI_SUPERADMIN_PASSWORD }}"
|
||||
force_basic_auth: true
|
||||
follow_redirects: none
|
||||
return_content: no
|
||||
headers:
|
||||
Accept: "application/xml"
|
||||
status_code: [200, 401, 404]
|
||||
register: _probe
|
||||
changed_when: false
|
||||
|
||||
# Some XWiki builds/versions answer on /{id}/{version}. Try that if plain /{id} returned 404.
|
||||
- name: "XWIKI | Probe extension {{ ext_id }} with version (fallback)"
|
||||
when:
|
||||
- ext_enabled | bool
|
||||
- (_probe.status | default(404)) | int == 404
|
||||
- ext_version is defined
|
||||
uri:
|
||||
url: "{{ [XWIKI_REST_XWIKI, 'repositories/installed/extensions', ext_id | urlencode, ext_version] | url_join }}?namespace={{ 'wiki:xwiki' | urlencode }}"
|
||||
method: GET
|
||||
user: "{{ XWIKI_SUPERADMIN_USERNAME }}"
|
||||
password: "{{ XWIKI_SUPERADMIN_PASSWORD }}"
|
||||
force_basic_auth: true
|
||||
follow_redirects: none
|
||||
return_content: no
|
||||
headers:
|
||||
Accept: "application/xml"
|
||||
status_code: [200, 401, 404]
|
||||
register: _probe_v
|
||||
changed_when: false
|
||||
|
||||
- name: "XWIKI | Save probe result for {{ ext_id }}"
|
||||
when: ext_enabled | bool
|
||||
set_fact:
|
||||
"{{ result_var }}": "{{ (_probe_v if (_probe_v is defined) else _probe) }}"
|
Reference in New Issue
Block a user