aboutsummaryrefslogtreecommitdiffstats
path: root/roles/mediawiki
diff options
context:
space:
mode:
Diffstat (limited to 'roles/mediawiki')
-rw-r--r--roles/mediawiki/defaults/main.yml52
-rw-r--r--roles/mediawiki/files/var/www/mediawiki/robots.txt2
-rw-r--r--roles/mediawiki/meta/main.yml8
-rw-r--r--roles/mediawiki/tasks/database.yml50
-rw-r--r--roles/mediawiki/tasks/extension.yml12
-rw-r--r--roles/mediawiki/tasks/freeipa.yml40
-rw-r--r--roles/mediawiki/tasks/main.yml134
-rw-r--r--roles/mediawiki/templates/var/www/mediawiki/LocalSettings.php.j2288
-rw-r--r--roles/mediawiki/vars/main.yml125
9 files changed, 711 insertions, 0 deletions
diff --git a/roles/mediawiki/defaults/main.yml b/roles/mediawiki/defaults/main.yml
new file mode 100644
index 0000000..4b65d70
--- /dev/null
+++ b/roles/mediawiki/defaults/main.yml
@@ -0,0 +1,52 @@
+mediawiki_version: 1.39.1
+mediawiki_extension_version: REL1_39
+
+mediawiki_kerberized_cidrs: '{{ kerberized_cidrs }}'
+
+mediawiki_user: s-mediawiki
+mediawiki_db_name: mediawiki
+mediawiki_db_host: '{{ postgresql_host }}'
+
+mediawiki_access_group: role-wiki-access
+mediawiki_admin_group: role-wiki-admin
+
+mediawiki_max_upload_size: 50M
+mediawiki_max_upload_count: 32
+
+mediawiki_custom_namespaces: []
+
+mediawiki_use_subpages: true
+
+mediawiki_ldap_servers: '{{ freeipa_hosts }}'
+mediawiki_sysaccount_username: mediawiki
+
+mediawiki_site_name: '{{ organization }} Wiki'
+mediawiki_meta_namespace: "{{ organization | regex_replace('\\s*', '') }}"
+mediawiki_fqdn: '{{ ansible_fqdn }}'
+mediawiki_url: https://{{ mediawiki_fqdn }}
+
+mediawiki_admin_username: admin
+mediawiki_emergency_contact: root@{{ email_domain }}
+mediawiki_password_sender: wiki-noreply@{{ email_domain }}
+mediawiki_email_authentication: no
+
+mediawiki_local_timezone: '{{ timezone }}'
+mediawiki_language_code: en
+
+mediawiki_default_skin: vector
+mediawiki_default_mobile_skin: minerva
+
+mediawiki_disable_anonymous_read: no
+mediawiki_disable_anonymous_edit: yes
+
+mediawiki_block_wan_login: yes
+
+mediawiki_apc_shm_size: 256M
+
+mediawiki_skins:
+ - Vector
+ - MinervaNeue
+
+# mediawiki_logo_1x: /path/to/1x/logo.jpg
+# mediawiki_logo_icon: /path/to/icon/logo.jpg
+# mediawiki_logo_favicon: /path/to/favicon.ico
diff --git a/roles/mediawiki/files/var/www/mediawiki/robots.txt b/roles/mediawiki/files/var/www/mediawiki/robots.txt
new file mode 100644
index 0000000..c218f6f
--- /dev/null
+++ b/roles/mediawiki/files/var/www/mediawiki/robots.txt
@@ -0,0 +1,2 @@
+User-agent: *
+Disallow: /index.php?
diff --git a/roles/mediawiki/meta/main.yml b/roles/mediawiki/meta/main.yml
new file mode 100644
index 0000000..f0e6864
--- /dev/null
+++ b/roles/mediawiki/meta/main.yml
@@ -0,0 +1,8 @@
+dependencies:
+ - role: yum
+ yum_repositories: epel
+ tags: yum
+
+ - role: freeipa_system_account
+ system_account_username: '{{ mediawiki_sysaccount_username }}'
+ system_account_password: '{{ mediawiki_sysaccount_password }}'
diff --git a/roles/mediawiki/tasks/database.yml b/roles/mediawiki/tasks/database.yml
new file mode 100644
index 0000000..b00a8a1
--- /dev/null
+++ b/roles/mediawiki/tasks/database.yml
@@ -0,0 +1,50 @@
+- name: create postgresql database
+ postgresql_db:
+ name: '{{ mediawiki_db_name }}'
+ state: present
+ delegate_to: "{{ postgresql_host.split('.')[0] }}"
+ become: True
+ become_user: postgres
+
+- name: create postgresql user
+ postgresql_user:
+ name: '{{ mediawiki_user }}'
+ db: '{{ mediawiki_db_name }}'
+ priv: ALL
+ state: present
+ delegate_to: "{{ postgresql_host.split('.')[0] }}"
+ become: True
+ become_user: postgres
+
+- name: check if database schema is initialized
+ postgresql_query:
+ login_user: '{{ mediawiki_user }}'
+ login_host: '{{ mediawiki_db_host }}'
+ db: '{{ mediawiki_db_name }}'
+ query: SELECT 1 FROM mediawiki.page
+ become: True
+ become_user: apache
+ environment:
+ GSS_USE_PROXY: 'yes'
+ register: mediawiki_check_db
+ failed_when: false
+
+- name: initialize database schema
+ command: >
+ php {{ mediawiki_home }}/maintenance/install.php
+ --server {{ mediawiki_url }}
+ --dbuser {{ mediawiki_user }}
+ --dbname {{ mediawiki_db_name }}
+ --dbserver {{ mediawiki_db_host }}
+ --dbtype postgres
+ --pass {{ mediawiki_admin_password | quote }}
+ --scriptpath /
+ {{ mediawiki_site_name | quote }}
+ {{ mediawiki_admin_username }}
+ become: True
+ become_user: apache
+ environment:
+ GSS_USE_PROXY: 'yes'
+ when:
+ - mediawiki_check_db.msg is defined
+ - mediawiki_check_db.msg is search('relation "mediawiki.page" does not exist')
diff --git a/roles/mediawiki/tasks/extension.yml b/roles/mediawiki/tasks/extension.yml
new file mode 100644
index 0000000..02f5dc3
--- /dev/null
+++ b/roles/mediawiki/tasks/extension.yml
@@ -0,0 +1,12 @@
+- name: get url for extension tarball
+ uri:
+ url: 'https://www.mediawiki.org/w/index.php?title=Special:ExtensionDistributor&extdistname={{ extension_name }}&extdistversion={{ extension_version }}'
+ register: extension_distributor_resp
+
+- name: extract extension tarball
+ unarchive:
+ src: "{{ extension_distributor_resp.refresh.split(';') | map('trim') | select('search', '^url=') | first | regex_replace('^url=', '') }}"
+ remote_src: yes
+ dest: '{{ mediawiki_home }}/extensions'
+ owner: apache
+ group: apache
diff --git a/roles/mediawiki/tasks/freeipa.yml b/roles/mediawiki/tasks/freeipa.yml
new file mode 100644
index 0000000..565cdca
--- /dev/null
+++ b/roles/mediawiki/tasks/freeipa.yml
@@ -0,0 +1,40 @@
+- name: create mediawiki user
+ ipauser:
+ ipaadmin_principal: '{{ ipa_user }}'
+ ipaadmin_password: '{{ ipa_pass }}'
+ name: '{{ mediawiki_user }}'
+ loginshell: /sbin/nologin
+ homedir: '{{ mediawiki_home }}'
+ givenname: MediaWiki
+ sn: Service Account
+ state: present
+ run_once: True
+
+- name: create mediawiki groups
+ ipagroup:
+ ipaadmin_principal: '{{ ipa_user }}'
+ ipaadmin_password: '{{ ipa_pass }}'
+ name: '{{ item }}'
+ nonposix: yes
+ state: present
+ run_once: True
+ loop:
+ - '{{ mediawiki_access_group }}'
+ - '{{ mediawiki_admin_group }}'
+
+- name: retrieve mediawiki user keytab
+ include_role:
+ name: freeipa_keytab
+ vars:
+ keytab_principal: '{{ mediawiki_user }}'
+ keytab_path: '{{ mediawiki_keytab }}'
+
+- name: configure gssproxy for kerberized postgres
+ include_role:
+ name: gssproxy_client
+ vars:
+ gssproxy_name: mediawiki
+ gssproxy_section: service/php-fpm
+ gssproxy_client_keytab: '{{ mediawiki_keytab }}'
+ gssproxy_cred_usage: initiate
+ gssproxy_euid: apache
diff --git a/roles/mediawiki/tasks/main.yml b/roles/mediawiki/tasks/main.yml
new file mode 100644
index 0000000..d0c3820
--- /dev/null
+++ b/roles/mediawiki/tasks/main.yml
@@ -0,0 +1,134 @@
+- name: install packages
+ dnf:
+ name: '{{ mediawiki_packages }}'
+ state: present
+
+- name: set PHP APC cache size
+ lineinfile:
+ path: /etc/php.d/40-apcu.ini
+ regexp: ^apc\.shm_size=
+ line: apc.shm_size={{ mediawiki_apc_shm_size }}
+ state: present
+ notify: restart php-fpm
+
+- import_tasks: freeipa.yml
+ tags: freeipa
+
+- name: create mediawiki webroot
+ file:
+ path: '{{ mediawiki_home }}'
+ state: directory
+
+- name: get current mediawiki version
+ command: php {{ mediawiki_home }}/maintenance/version.php
+ become: True
+ become_user: apache
+ environment:
+ GSS_USE_PROXY: 'yes'
+ changed_when: no
+ failed_when: no
+ register: mediawiki_current_version
+
+- name: extract mediawiki tarball
+ unarchive:
+ src: '{{ mediawiki_tarball }}'
+ remote_src: yes
+ dest: '{{ mediawiki_home }}'
+ owner: apache
+ group: apache
+ extra_opts:
+ - '--strip-components=1'
+
+- name: set permissions on writeable directories
+ file:
+ path: '{{ mediawiki_home }}/{{ item }}'
+ state: directory
+ mode: 0770
+ owner: apache
+ group: apache
+ setype: _default
+ loop: '{{ mediawiki_writable_dirs }}'
+
+- name: set selinux context for writeable directories
+ sefcontext:
+ target: '{{ mediawiki_home }}/{{ item }}(/.*)?'
+ setype: httpd_sys_rw_content_t
+ state: present
+ loop: '{{ mediawiki_writable_dirs }}'
+ register: mediawiki_writeable_sefcontext
+ tags: selinux
+
+- name: apply selinux context to writeable directories
+ command: 'restorecon -R {{ mediawiki_home }}/{{ item }}'
+ when: mediawiki_writeable_sefcontext.results[index].changed
+ loop: '{{ mediawiki_writable_dirs }}'
+ loop_control:
+ index_var: index
+ tags: selinux
+
+- name: set selinux context for executable directories
+ sefcontext:
+ target: '{{ mediawiki_home }}/{{ item }}(/.*)?'
+ setype: httpd_sys_script_exec_t
+ state: present
+ loop: '{{ mediawiki_executable_dirs }}'
+ register: mediawiki_executable_sefcontext
+ tags: selinux
+
+- name: apply selinux context to executable directories
+ command: 'restorecon -R {{ mediawiki_home }}/{{ item }}'
+ when: mediawiki_executable_sefcontext.results[index].changed
+ loop: '{{ mediawiki_executable_dirs }}'
+ loop_control:
+ index_var: index
+ tags: selinux
+
+- import_tasks: database.yml
+ tags: database
+
+- name: generate LocalSettings.php
+ template:
+ src: '{{ mediawiki_home[1:] }}/LocalSettings.php.j2'
+ dest: '{{ mediawiki_home }}/LocalSettings.php'
+ owner: root
+ group: apache
+ mode: 0640
+ register: mediawiki_localsettings
+
+- name: install extensions
+ include_tasks: extension.yml
+ vars:
+ extension_name: '{{ item if item is string else item.name }}'
+ extension_version: '{{ mediawiki_extension_version if item is string else (item.version | default(mediawiki_extension_version)) }}'
+ loop: '{{ mediawiki_extensions }}'
+
+- name: update database schema
+ command: php {{ mediawiki_home }}/maintenance/update.php --quick
+ become: yes
+ become_user: apache
+ environment:
+ GSS_USE_PROXY: 'yes'
+ when: mediawiki_localsettings.changed or (mediawiki_current_version.rc == 0 and not mediawiki_current_version.stdout is search(mediawiki_version))
+
+- name: copy robots.txt
+ copy:
+ src: '{{ mediawiki_home[1:] }}/robots.txt'
+ dest: '{{ mediawiki_home }}/robots.txt'
+
+- name: copy 1x logo
+ copy:
+ src: '{{ mediawiki_logo_1x }}'
+ dest: '{{ mediawiki_home }}/resources/assets/{{ mediawiki_logo_1x | basename }}'
+ when: mediawiki_logo_1x is defined
+
+- name: copy icon logo
+ copy:
+ src: '{{ mediawiki_logo_icon }}'
+ dest: '{{ mediawiki_home }}/resources/assets/{{ mediawiki_logo_icon | basename }}'
+ when: mediawiki_logo_icon is defined
+
+- name: copy favicon
+ copy:
+ src: '{{ mediawiki_favicon }}'
+ dest: '{{ mediawiki_home }}/resources/assets/{{ mediawiki_favicon | basename }}'
+ when: mediawiki_favicon is defined
diff --git a/roles/mediawiki/templates/var/www/mediawiki/LocalSettings.php.j2 b/roles/mediawiki/templates/var/www/mediawiki/LocalSettings.php.j2
new file mode 100644
index 0000000..e94ca80
--- /dev/null
+++ b/roles/mediawiki/templates/var/www/mediawiki/LocalSettings.php.j2
@@ -0,0 +1,288 @@
+<?php
+
+### Protect against web entry
+if ( !defined( 'MEDIAWIKI' ) ) {
+ exit;
+}
+
+
+### Wiki Name
+$wgSitename = "{{ mediawiki_site_name }}";
+$wgMetaNamespace = "{{ mediawiki_meta_namespace }}";
+$wgServer = "{{ mediawiki_url }}";
+
+
+### Short URLs
+$wgScriptPath = "";
+$wgUsePathInfo = true;
+
+$actions = array( 'edit', 'watch', 'unwatch', 'delete','revert', 'rollback',
+ 'protect', 'unprotect', 'markpatrolled', 'render', 'submit', 'history', 'purge', 'info' );
+
+foreach ( $actions as $action ) {
+ $wgActionPaths[$action] = "/$1/$action";
+}
+
+$wgActionPaths['view'] = "/$1";
+$wgArticlePath = $wgActionPaths['view'];
+
+
+### Static Resources
+$wgResourceBasePath = $wgScriptPath;
+
+{% if mediawiki_logo_icon is defined %}
+$wgLogos['icon'] = "$wgResourceBasePath/resources/assets/{{ mediawiki_logo_icon | basename }}";
+{% endif %}
+{% if mediawiki_logo_1x is defined %}
+$wgLogos['1x'] = "$wgResourceBasePath/resources/assets/{{ mediawiki_logo_1x | basename }}";
+{% endif %}
+
+{% if mediawiki_favicon is defined %}
+$wgFavicon = "$wgResourceBasePath/resources/assets/{{ mediawiki_favicon | basename }}";
+{% endif %}
+
+
+### Email
+$wgEnableEmail = true;
+$wgEnableUserEmail = true;
+
+$wgEmergencyContact = "{{ mediawiki_emergency_contact }}";
+$wgPasswordSender = "{{ mediawiki_password_sender }}";
+
+$wgEnotifUserTalk = true;
+$wgEnotifWatchlist = true;
+$wgEmailAuthentication = {{ mediawiki_email_authentication | bool }};
+
+
+### Database settings
+$wgDBtype = "postgres";
+$wgDBserver = "{{ mediawiki_db_host }}";
+$wgDBname = "{{ mediawiki_db_name }}";
+$wgDBuser = "{{ mediawiki_user }}";
+$wgDBpassword = "";
+$wgDBport = "5432";
+$wgDBmwschema = "mediawiki";
+$wgSharedTables[] = "actor";
+
+
+### Caching
+$wgMainCacheType = CACHE_ACCEL;
+$wgMemCachedServers = [];
+$wgCacheDirectory = "$IP/cache";
+$wgUseFileCache = true;
+$wgUseGzip = true;
+
+
+### Images
+$wgEnableUploads = true;
+$wgUseImageMagick = true;
+$wgImageMagickConvertCommand = "/usr/bin/convert";
+
+
+### Don't reach out to the WWW
+$wgUseInstantCommons = false;
+$wgPingback = false;
+
+
+### Localization
+$wgLanguageCode = "{{ mediawiki_language_code }}";
+$wgLocaltimezone = "{{ mediawiki_local_timezone }}";
+
+
+### Secrets
+$wgSecretKey = "{{ mediawiki_secret_key }}";
+{% if mediawiki_upgrade_key is defined %}
+$wgUpgradeKey = "{{ mediawiki_upgrade_key }}";
+{% endif %}
+
+# Changing this will log out all existing sessions.
+$wgAuthenticationTokenVersion = "1";
+
+
+### Licensing
+$wgRightsPage = ""; # Set to the title of a wiki page that describes your license/copyright
+$wgRightsUrl = "";
+$wgRightsText = "";
+$wgRightsIcon = "";
+
+
+### Paths
+$wgDiff3 = "/usr/bin/diff3";
+
+
+### Permissions
+$wgGroupPermissions['*']['createaccount'] = false;
+$wgGroupPermissions['*']['autocreateaccount'] = true;
+
+{% if mediawiki_disable_anonymous_read %}
+$wgGroupPermissions['*']['read'] = false;
+{% endif %}
+
+{% if mediawiki_disable_anonymous_edit %}
+$wgGroupPermissions['*']['edit'] = false;
+{% endif %}
+
+$wgBlockDisablesLogin = true;
+
+
+### Skins
+$wgDefaultSkin = "{{ mediawiki_default_skin }}";
+
+{% for skin in mediawiki_skins %}
+wfLoadSkin( '{{ skin }}' );
+{% endfor %}
+
+
+### Custom namespaces
+{% for ns in mediawiki_custom_namespaces %}
+$wgExtraNamespaces[{{ ns.id }}] = '{{ ns.namespace }}';
+$wgExtraNamespaces[{{ ns.talk_id }}] = '{{ ns.namespace }}Talk';
+{% endfor %}
+
+
+### Subpages
+{% if mediawiki_use_subpages %}
+$wgNamespacesWithSubpages[NS_MAIN] = true;
+{% for ns in mediawiki_custom_namespaces %}
+$wgNamespacesWithSubpages[{{ ns.id }}] = true;
+$wgNamespacesWithSubpages[{{ ns.talk_id }}] = true;
+{% endfor %}
+{% endif %}
+
+
+### Custom groups
+{% for group in mediawiki_custom_namespaces
+ | selectattr('restrict', 'defined')
+ | map(attribute='restrict')
+ | map('dict2items')
+ | flatten
+ | map(attribute='value')
+ | unique
+ | difference(mediawiki_builtin_groups) %}
+$wgGroupPermissions['{{ group }}']['read'] = true;
+{% endfor %}
+
+
+### Extensions
+{% for extension in mediawiki_builtin_extensions + mediawiki_extensions %}
+wfLoadExtension( '{{ extension if extension is string else extension.name }}' );
+{% endfor %}
+
+
+### Extension: MobileFrontend
+$wgDefaultMobileSkin = '{{ mediawiki_default_mobile_skin }}';
+
+
+### Extension: WikiEditor
+$wgWikiEditorRealtimePreview = true;
+
+
+### Extension: LDAPAuthorization
+$LDAPAuthorizationAutoAuthRemoteUserStringParser = "username-at-domain";
+
+
+### Extension: LDAPAuthorization
+$LDAPProviderDefaultDomain = '{{ freeipa_realm }}';
+
+$LDAPProviderDomainConfigProvider = function() {
+ $config = [
+ '{{ freeipa_realm }}' => [
+ 'connection' => [
+ 'server' => '{{ mediawiki_ldap_servers | join(' ') }}',
+ 'user' => 'uid={{ mediawiki_sysaccount_username }},{{ freeipa_sysaccount_basedn }}',
+ 'pass' => '{{ mediawiki_sysaccount_password }}',
+ 'enctype' => 'tls',
+ 'options' => [
+ 'LDAP_OPT_DEREF' => 1
+ ],
+ 'basedn' => '{{ freeipa_basedn }}',
+ 'groupbasedn' => '{{ freeipa_group_basedn }}',
+ 'grouprequest' => 'MediaWiki\\Extension\\LDAPProvider\\UserGroupsRequest\\UserMemberOf::factory',
+ 'presearchusernamemodifiers' => [ 'lowercase' ],
+ 'userbasedn' => '{{ freeipa_user_basedn }}',
+ 'searchattribute' => 'uid',
+ 'searchstring' => 'uid=USER-NAME,{{ freeipa_user_basedn }}',
+ 'usernameattribute' => 'uid',
+ 'realnameattribute' => 'cn',
+ 'emailattribute' => 'mail'
+ ],
+ 'groupsync' => [
+ 'mechanism' => 'mappedgroups',
+ 'mapping' => [
+{% for group in mediawiki_custom_namespaces
+ | selectattr('restrict', 'defined')
+ | map(attribute='restrict')
+ | map('dict2items')
+ | flatten
+ | map(attribute='value')
+ | unique
+ | difference(mediawiki_builtin_groups) %}
+ '{{ group }}' => 'cn={{ group }},{{ freeipa_group_basedn }}',
+{% endfor %}
+ 'sysop' => 'cn={{ mediawiki_admin_group }},{{ freeipa_group_basedn }}',
+ 'interface-admin' => 'cn={{ mediawiki_admin_group }},{{ freeipa_group_basedn }}',
+ 'bureaucrat' => 'cn={{ mediawiki_admin_group }},{{ freeipa_group_basedn }}'
+ ]
+ ],
+ 'userinfo' => [
+ 'attributes-map' => [
+ 'email' => 'mail',
+ 'realname' => 'cn'
+ ]
+ ],
+ 'authorization' => [
+ 'rules' => [
+ 'groups' => [
+ 'required' => [
+ 'cn={{ mediawiki_access_group }},{{ freeipa_group_basedn }}',
+ 'cn={{ mediawiki_admin_group }},{{ freeipa_group_basedn }}'
+ ]
+ ]
+ ]
+ ]
+ ]
+ ];
+
+ return new \MediaWiki\Extension\LDAPProvider\DomainConfigProvider\InlinePHPArray( $config );
+};
+
+
+### Extension: PluggableAuth
+$wgPluggableAuth_ButtonLabel = 'Log In';
+
+
+### Extension: CodeMirror
+$wgDefaultUserOptions['usecodemirror'] = 1;
+$wgCodeMirrorEnableBracketMatching = true;
+$wgCodeMirrorLineNumberingNamespaces = null;
+
+
+### Extension: UploadWizard
+$wgUploadNavigationUrl = '/Special:UploadWizard';
+
+
+### Extension: Auth_remoteuser
+$wgAuthRemoteuserUserNameReplaceFilter = [
+ '@{{ freeipa_realm }}$' => ''
+];
+
+
+### Extension: Lockdown
+{% for ns in mediawiki_custom_namespaces | selectattr('restrict', 'defined') %}
+{% for r in ns.restrict | dict2items(key_name='perm', value_name='group') %}
+$wgNamespacePermissionLockdown[{{ ns.id }}]['{{ r.perm }}'] = {{ ([r.group] if r.group is string else r.group) | to_json }};
+$wgNamespacePermissionLockdown[{{ ns.talk_id }}]['{{ r.perm }}'] = {{ ([r.group] if r.group is string else r.group) | to_json }};
+{% endfor %}
+$wgNonincludableNamespaces[] = {{ ns.id }};
+$wgNonincludableNamespaces[] = {{ ns.talk_id }};
+{% endfor %}
+
+
+### Extension: VisualEditor
+$wgVisualEditorAvailableNamespaces = [
+{% for ns in mediawiki_custom_namespaces %}
+ '{{ ns.namespace }}' => true,
+ '{{ ns.namespace }}Talk' => true{% if not loop.last %},{% endif %}
+
+{% endfor %}
+];
diff --git a/roles/mediawiki/vars/main.yml b/roles/mediawiki/vars/main.yml
new file mode 100644
index 0000000..d82f2f4
--- /dev/null
+++ b/roles/mediawiki/vars/main.yml
@@ -0,0 +1,125 @@
+mediawiki_tarball: https://releases.wikimedia.org/mediawiki/{{ mediawiki_version | splitext | first }}/mediawiki-{{ mediawiki_version }}.tar.gz
+mediawiki_home: /var/www/mediawiki
+mediawiki_keytab: /var/lib/gssproxy/clients/{{ mediawiki_user }}.keytab
+
+mediawiki_packages:
+ - php
+ - php-json
+ - php-ldap
+ - php-mbstring
+ - php-opcache
+ - php-pdo
+ - php-pgsql
+ - php-xml
+ - php-intl
+ - php-gd
+ - php-pecl-apcu
+ - php-pecl-igbinary
+ - python3-psycopg2
+ - python3
+ - ImageMagick
+ - poppler-utils
+ - ghostscript
+ - varnish
+
+mediawiki_php_environment:
+ GSS_USE_PROXY: 'yes'
+
+mediawiki_php_admin_values:
+ post_max_size: '{{ mediawiki_max_upload_size }}'
+ upload_max_filesize: '{{ mediawiki_max_upload_size }}'
+ max_file_uploads: '{{ mediawiki_max_upload_count }}'
+
+mediawiki_writable_dirs:
+ - images
+ - cache
+
+mediawiki_executable_dirs:
+ - extensions/SyntaxHighlight_GeSHi/pygments
+
+mediawiki_builtin_extensions:
+ - WikiEditor
+ - VisualEditor
+ - MobileFrontend
+ - MultimediaViewer
+ - Math
+ - PageImages
+ - SyntaxHighlight_GeSHi
+ - PdfHandler
+
+mediawiki_extensions:
+ - PluggableAuth
+ - LDAPAuthorization
+ - LDAPAuthentication2
+ - LDAPProvider
+ - MobileFrontend
+ - LDAPGroups
+ - LDAPUserInfo
+ - Auth_remoteuser
+ - CodeMirror
+ - RelatedArticles
+ - UploadWizard
+ - Lockdown
+
+mediawiki_builtin_groups:
+ - user
+ - autoconfirmed
+ - bot
+ - sysop
+ - interface-admin
+ - bureaucrat
+ - suppress
+
+mediawiki_apache_config: |
+ AllowEncodedSlashes NoDecode
+
+ RewriteEngine On
+
+ RewriteCond %{REQUEST_URI} ^/({{ mediawiki_rewrite_blacklist | map("regex_escape") | join("|") }})$
+ RewriteRule ^(.*)$ %{DOCUMENT_ROOT}/index.php [L]
+
+ RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !\.php/
+ RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
+ RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
+ RewriteRule ^(.*)$ %{DOCUMENT_ROOT}/index.php [L]
+
+ RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !\.php/
+ RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-f
+ RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} !-d
+ RewriteRule ^(.*)/([a-z]*)$ %{DOCUMENT_ROOT}/index.php [L,QSA]
+
+ <Location />
+ AuthName "FreeIPA Single Sign-On"
+ AuthType GSSAPI
+ <If "({% for cidr in kerberized_cidrs %}-R '{{ cidr }}'{% if not loop.last %} || {% endif %}{% endfor %}) && ! -R '{{ ansible_default_ipv4.address }}'">
+ {{ apache_gssapi_session_config }}
+ Require valid-user
+ </If>
+ </Location>
+
+ <Directory "{{ mediawiki_home }}/cache">
+ AllowOverride None
+ Require all denied
+ </Directory>
+
+# Since we're using pretty URLs, page titles can clash with real files in the
+# mediawiki directory. If this ever happens, add the file path to this list.
+mediawiki_rewrite_blacklist:
+ - CODE_OF_CONDUCT.md
+ - COPYING
+ - CREDITS
+ - FAQ
+ - HISTORY
+ - INSTALL
+ - README.md
+ - SECURITY
+ - UPGRADE
+ - composer.json
+ - jsduck.json
+
+mediawiki_archive_shell: >-
+ TIMESTAMP=$(date +%Y%m%d%H%M%S);
+ tar czf "mediawiki-${TIMESTAMP}.tar.gz"
+ --transform "s|^\.|mediawiki-${TIMESTAMP}|"
+ -C "{{ mediawiki_home }}"
+ images