Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 20-improve-apache-configuration
  • add-authz-endpoint
  • add-matomo
  • add-matomo-plugin
  • advanced-query-plugin
  • bump-theme-3.10.0
  • careers-custom-branch
  • cern-theme-3.1.0
  • cleanup-rebase
  • crdeoliv-mvp-patch-65006
  • database-garbage-collection
  • dbod-compatible
  • disable-extra-plugins
  • disable-json-api
  • file-permissions
  • fix-crash-error
  • fix-custom-themes
  • fix-oidc-logout-url
  • fix-openssl-version-mismatch
  • fluentformpro
  • image-testing
  • import-plugin-wp
  • int-tests
  • lite-plugins
  • master
  • multimedia-and-svg-support
  • mvp
  • new-apache-logs
  • new-wp-lite-image
  • nginx-share
  • oidc-configuration
  • plugin-test
  • polylang
  • polylang-enable
  • private-folder
  • renovate-composer
  • renovate-config
  • renovate-docker-compose
  • renovate-dockerfile
  • renovate-major-4-composer
  • rudy-forks-testing
  • rudy/chore/ci
  • salts_vars
  • test-image
  • test-no-lang
  • theme-update-3.9
  • theme-update-v3.12.0
  • update-cern-theme-legacy
  • update-theme-version
  • 1.0.0
  • 1.0.0a1
  • 1.0.0a2
  • 1.0.1
  • 1.0.2
  • 1.0.3
  • 1.0.4
  • 1.0.5
57 results

Target

Select target project
  • alossent/wordpress-image
  • wordpress/wordpress-image
2 results
Select Git revision
  • master
  • test-no-lang
  • wordpress-basic-security
3 results
Show changes
Commits on Source (191)
Showing
with 867 additions and 46 deletions
# editor and IDE paraphernalia
.idea
# vsc
.gitignore
COMPOSER_AUTH={"gitlab-token":{"gitlab.cern.ch":"<TOKEN>"}}
OIDC_CLIENT_ID=client-id
OIDC_CLIENT_SECRET=client-secret
APPLICATION_NAME=localhost
WP_DEBUG=TRUE
FORCE_SSL_ADMIN=FALSE
# editor and IDE paraphernalia
.idea
.DS_Store
# Env file
.env
# Lock files
*.lock
include:
- project: 'paas-tools/infrastructure-ci'
file: 'docker-images-ci-templates/DockerImages.gitlab-ci.yml'
variables:
GIT_SUBMODULE_STRATEGY: recursive
### Disable cache in Docker builds, as this has occasionally resulted in images not containing what was
### expected multiple MRs where being built/retried.
NO_CACHE: 'true'
stages:
- build
.build_common_variables: &build_common_variables
# As of GitLab 12.5, privileged runners at CERN mount a /certs/client docker volume that enables use of TLS to
# communicate with the docker daemon. This avoids a warning about the docker service possibly not starting
# successfully.
# See https://docs.gitlab.com/ee/ci/docker/using_docker_build.html#tls-enabled
DOCKER_TLS_CERTDIR: "/certs"
# Gitlab Token for composer auth to pull from CERN Theme API
COMPOSER_AUTH: "{\"gitlab-token\":{\"gitlab.cern.ch\":\"$CI_GITLAB_TOKEN\"}}"
.build_command: &base
tags:
- docker-privileged-xl
variables:
<<: *build_common_variables
stage: build
services:
- name: registry.cern.ch/docker.io/docker:27.4.0-dind
alias: docker
image: registry.cern.ch/docker.io/library/docker:27.4.0
before_script:
- apk update && apk add openssh-client # Install SSH client if needed
- echo "$SSH_PRIVATE_KEY" | base64 -d > id_rsa # Create the private key file
- chmod 600 id_rsa # Set correct permissions for file
- mkdir -p -m 0700 ~/.ssh
- eval `ssh-agent -s`
- ssh-keyscan -p 7999 -H gitlab.cern.ch >> ~/.ssh/known_hosts # Add server's hostkey (important!)
- ssh-add id_rsa # Add the key to the SSH agent and then you can run ssh whenever you need
script:
- export DATE=`date -u +%Y.%m.%dT%H-%M-%SZ`
# TAG will have a different value depending on what branch the docker image is built
# If the branch is master TAG will be composed by the word "RELEASE" and the current date in UTC
# If the branch is a feature branch TAG will be the name of that branch
- export TAG=${TAG:-$CI_COMMIT_REF_NAME."RELEASE".$DATE}
- docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" $CI_REGISTRY
# Build and push the image from the Dockerfile at the root of the project.
- docker build --secret id=COMPOSER_AUTH --ssh default -t "$CI_REGISTRY_IMAGE:$TAG" .
- docker push "$CI_REGISTRY_IMAGE:$TAG"
- echo "Image pushed to "$CI_REGISTRY_IMAGE:$TAG
- docker build --build-arg CI_REGISTRY_IMAGE="${CI_REGISTRY_IMAGE}" --build-arg TAG="${TAG}" -t "${CI_REGISTRY_IMAGE}/nginx:$TAG" -f Dockerfile-nginx .
- docker push "${CI_REGISTRY_IMAGE}/nginx:$TAG"
- echo "Nginx image pushed to "${CI_REGISTRY_IMAGE}/nginx:$TAG
build:
<<: *base
variables:
<<: *build_common_variables
rules:
- if: '$CI_COMMIT_TAG'
when: always
variables:
TAG: ${CI_COMMIT_TAG}
- if: '$CI_COMMIT_REF_NAME == "master" || $CI_COMMIT_REF_NAME == "mvp"'
when: always
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: always
variables:
TAG: $CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
when: manual
variables:
TAG: $CI_COMMIT_REF_SLUG-$CI_COMMIT_SHORT_SHA
FROM registry.access.redhat.com/ubi8/php-74
# Add application sources
ADD . .
USER root
RUN mv --force ./bin/* /usr/local/bin/ && \
# Create a tmp folder where to put temporarily custom plugins, themes, etc.
mkdir -p /opt/app-root/downloads/{plugins,themes} && \
# Move plugins, themes, etc to a temp folder
mv ./plugins/* /opt/app-root/downloads/plugins/ && \
mv ./themes/* /opt/app-root/downloads/themes/ && \
# Install WP-CLI command line tool
# Will allow to create users:
# wp user create admin email@cern.ch --role=administrator
# will create admin user with random password
# Must run from the WP installation directory (/opt/app-root/src)
# https://make.wordpress.org/cli/handbook/installing/
curl -Ls https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar > /opt/app-root/downloads/wp-cli.phar && \
# Verify it's ok
php /opt/app-root/downloads/wp-cli.phar --info && \
mv --force /opt/app-root/downloads/wp-cli.phar /usr/local/bin/wp && \
# Make all scripts under /usr/local/bin/ executables
chmod +x /usr/local/bin/* && \
# Fix permissions
fix-permissions /opt/app-root/ && \
# Remove leftovers
rm -rf .git/
USER default
# Run script uses standard ways to configure the PHP application
# and execs httpd -D FOREGROUND at the end
# See more in <version>/s2i/bin/run in this repository.
# Shortly what the run script does: The httpd daemon and php needs to be
# configured, so this script prepares the configuration based on the container
# parameters (e.g. available memory) and puts the configuration files into
# the approriate places.
# This can obviously be done differently, and in that case, the final CMD
# should be set to "CMD httpd -D FOREGROUND" instead.
CMD ["/usr/local/bin/run.sh"]
\ No newline at end of file
# syntax=docker/dockerfile:1
FROM php:8.1-fpm
# Set php.ini configs
RUN mv "${PHP_INI_DIR}/php.ini-production" "${PHP_INI_DIR}/php.ini"
COPY app/php/ ${PHP_INI_DIR}/conf.d
# Set php.conf final configuration
COPY app/php-fpm-conf/zzzz-php-fpm-final.conf /usr/local/etc/php-fpm.d/
# Install system dependencies
RUN apt-get update && apt-get install -y \
openssh-client \
git \
mariadb-client \
jq \
unzip \
curl \
&& docker-php-ext-install mysqli pdo pdo_mysql
# Install system dependencies needed for plugins and image handling (https://make.wordpress.org/hosting/handbook/handbook/server-environment/#php-extensions)
RUN apt-get update && apt-get install -y --no-install-recommends \
libavif-dev \
libfreetype6-dev \
libicu-dev \
libjpeg62-turbo-dev \
libmagickwand-dev \
libpng-dev \
libwebp-dev \
libzip-dev \
ghostscript \
&& docker-php-ext-configure gd \
--with-avif \
--with-freetype \
--with-jpeg \
--with-webp \
&& docker-php-ext-install exif gd intl zip bcmath
# Provides better image quality for media uploads
RUN pecl install imagick-3.7.0
# SSH Key setup
RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan -p 7999 -H gitlab.cern.ch >> ~/.ssh/known_hosts
# Install Composer globally
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer && \
composer --version
ENV SCRIPTS_DIR=/usr/share/container-scripts
# Copy custom scripts and app content to the image
COPY app/scripts/ ${SCRIPTS_DIR}
# Set working directory
ENV WORKING_DIR=/var/www/html
WORKDIR ${WORKING_DIR}
# Set Directories
ENV WORDPRESS_DIR=wordpress
ENV UPLOADS_DIR=${WORDPRESS_DIR}/wp-content/uploads
# Set flag file directory
ENV FLAG_DIR=/var/opt/build
RUN mkdir ${FLAG_DIR}
# Install dependencies at build time
COPY app/composer.json ./composer.json
COPY app/wp-cli.yml ./wp-cli.yml
# Do not run Composer as root/super user! See https://getcomposer.org/root for details
# Set up drupal minimum stack
ENV COMPOSER_MEMORY_LIMIT=-1
ENV COMPOSER_ALLOW_SUPERUSER=1
# supports SSH keys and API TOkEN
RUN --mount=type=ssh --mount=type=secret,id=COMPOSER_AUTH,env=COMPOSER_AUTH composer install --optimize-autoloader -v
# Create uploads dir
RUN mkdir -p ${UPLOADS_DIR}
# Remove default themes and plugins shipped with WordPress
RUN rm -rf wordpress/wp-content/themes/twenty* && \
rm -rf wordpress/wp-content/plugins/hello.php
# Copy mu plugins & wp-config
COPY app/wordpress-content/mu-plugins/* wordpress/wp-content/mu-plugins/
COPY app/wordpress-content/wp-config.php wordpress/wp-config.php
# Setup Maintenance flag file. See more: https://developer.wordpress.org/reference/functions/wp_is_maintenance_mode/
ENV MAINTENANCE_PATH=${WORDPRESS_DIR}/.maintenance
RUN touch ${MAINTENANCE_PATH}
# Symlink WP CLI
ENV WP_CLI_PATH=vendor/wp-cli/wp-cli/bin/wp
RUN ln -s ${WORKING_DIR}/${WP_CLI_PATH} /usr/bin/wp
# Set folder permissions
ENV WPUSER_USER_ID=1000
# Set restrictive permissions.
# No files are executable in general. All directories need executable permission for ls, etc.
# Details:
# - working/wordpress dir: readonly
# - maintenance mode dir: read/write
# - uploads dir: read/write
# - install flag dir: read/write
# - scripts dir binaries: read/execute files
# - WP CLI binary: read/execute
RUN chmod -R -x,+u=rX,go= ${WORKING_DIR} \
&& chmod +u=rw,go= ${MAINTENANCE_PATH} \
&& chmod -R -x,+u=rwX,go= ${UPLOADS_DIR} \
&& chmod -R -x,+u=rwX,go= ${FLAG_DIR} \
&& chmod -R +u=rx,go= ${SCRIPTS_DIR} \
&& chmod -R u=rx,go= ${WP_CLI_PATH}
# Give same permissions to group as user: In CERN Openshift pods run with a random user of group 0
# https://paas.docs.cern.ch/2._Deploy_Applications/Deploy_Docker_Image/3-requirements-docker-images/#application-binaries-or-other-source-files
RUN chgrp -R 0 ${WORKING_DIR} \
&& chgrp -R 0 ${FLAG_DIR} \
&& chgrp -R 0 ${SCRIPTS_DIR} \
&& chmod -R g=u ${WORKING_DIR} \
&& chmod -R g=u ${FLAG_DIR} \
&& chmod -R g=u ${SCRIPTS_DIR}
# Add wpuser
RUN useradd wpuser --uid ${WPUSER_USER_ID} --gid 0 \
&& chown -R wpuser ${WORKING_DIR} \
&& chown -R wpuser ${FLAG_DIR} \
&& chown -R wpuser ${SCRIPTS_DIR}
USER wpuser
ENTRYPOINT ["/usr/share/container-scripts/entrypoint.sh"]
ARG CI_REGISTRY_IMAGE="gitlab-registry.cern.ch/wordpress/wordpress-image"
ARG TAG="mvp"
FROM ${CI_REGISTRY_IMAGE}:${TAG} AS builder
FROM registry.cern.ch/docker.io/library/nginx:1.28.0
WORKDIR /var/www/html
COPY --from=builder /var/www/html .
# Set folder permissions
ENV WPUSER_USER_ID=1000
ENV CACHE_DIR=/var/cache/nginx/
ENV RUN_DIR=/run/
RUN chgrp -R 0 ${CACHE_DIR} \
&& chmod -R g=u ${CACHE_DIR} \
&& chgrp -R 0 ${RUN_DIR} \
&& chmod -R g=u ${RUN_DIR}
# Add wpuser
RUN useradd wpuser --uid ${WPUSER_USER_ID} --gid 0 \
&& chown -R wpuser ${CACHE_DIR} \
&& chown -R wpuser ${RUN_DIR}
USER wpuser
################### Docker development helpful directives ####################
#
# Usage:
# make logs # displays log outputs from running services
# make build # build images
# make up # create and start containers
# make destroy # stop and remove containers, networks, images, and volume
# make reload # destroy and restart containers, networks, images, and volume
# make shell # start bash inside service
# make down # stop services
# env # build + shell
up:
docker compose up -d --build --remove-orphans
.PHONY: up
build:
docker compose build --no-cache --parallel
.PHONY: build
logs:
docker compose logs -f
.PHONY: logs
destroy: down
docker compose rm -f
.PHONY: destroy
down:
docker compose down --volumes
.PHONY: down
reload: destroy build up shell
.PHONY: reload
restart: down up shell
.PHONY: restart
shell:
docker compose exec wordpress /bin/bash
.PHONY: shell
env: up shell
.PHONY: env
# WordPress image
This project is the WordPress skeleton that will be consumed by the [https://gitlab.cern.ch/wordpress/wordpress-operator](https://gitlab.cern.ch/wordpress/wordpress-operator).
This project is the WordPress skeleton that will be consumed by the [https://gitlab.cern.ch/wordpress/paas/wordpress-operator](https://gitlab.cern.ch/wordpress/wordpress-operator).
//TODO
\ No newline at end of file
# WordPress CERN Theme
The WordPress CERN Theme is contained in the image created from this [https://gitlab.cern.ch/wordpress/wordpress-image](https://gitlab.cern.ch/wordpress/wordpress-image) repo.
## Design
This repository provides a Dockerized setup for running WordPress with PHP-FPM. The Dockerfile installs necessary tools like MariaDB client, Composer, and WP-CLI, and includes custom scripts to handle tasks such as setting up WordPress, configuring plugins (e.g., OpenID Connect Generic), and managing file permissions. The `docker-compose.yml` file links WordPress with MySQL and NGINX, creating a fully functional local environment. All custom scripts, themes, and configurations are organized under `root/usr/share/container-scripts/php` for easy management. This design makes it straightforward to customize, extend, and deploy WordPress efficiently.
### WP CLi extensions
#### Maintenance Mode
- `wp cern maintenance-mode activate`
- `wp cern maintenance-mode deactivate`
### Limitations
WordPress bultin maintenance mode is supported but only lasts 10 minutes, by design.
Read more: https://github.com/WordPress/WordPress/blob/4e3cca4095d2335a04a2c00fed54889109c7177c/wp-includes/load.php#L444
## Development
### Build
- We depend on CERN private repositories at build time, therefore make sure you have a gitlab.cern.ch ssh key configured locally and then run
```bash
eval $(ssh-agent)
ssh-add ~/.ssh/id_rsa # needs to match your key name
```
before running docker compose.
- We need to setup a Gitlab API TOKEN at build time, with read permissions on the CERN theme.
You can use a token from your own account or obtain the token from the CI.
Once you have a token please create a .env file with the following content:
```bash
COMPOSER_AUTH={"gitlab-token":{"gitlab.cern.ch":"<API_TOKEN>"}}
```
### Run
To start the project
```
make reload
```
In order to run locally https can be disabled, update your .env file with the following content:
```
FORCE_SSL_ADMIN=false
APPLICATION_NAME=http://localhost:80
```
To run locally with OIDC we need to:
1. Create an app-portal registration
Use http; and save the client id and client secret
![1.png](docs%2F1.png)
![2.png](docs%2F2.png)
Configure role administrator at least.
2. Configure /etc/hosts in our local machines
To do that simply add:
```
127.0.0.1 carina-dev-wordpress.web.cern.ch
```
3. Configure wp CLI missing options. For example for website `carina-dev-wordpress.web.cern.ch`, update your .env file with the following content:
```
OIDC_CLIENT_ID=<client-id>
OIDC_CLIENT_SECRET=<client-secret>
APPLICATION_NAME='http://carina-dev-wordpress.web.cern.ch'
FORCE_SSL_ADMIN=false
# recommended
WP_DEBUG=true
```
Finally, go to on your preferred browser http://carina-dev-wordpress.web.cern.ch/wp-login.php
## Known Issues
- `wordpress-cron The requested image's platform (linux/amd64) does not match the detected host platform (linux/arm64/v8) and no specific platform was requested`
Workaround: run `export DOCKER_DEFAULT_PLATFORM=linux/amd64` and rerun.
{
"name": "wordpress/wordpress-image",
"description": "CERN WordPress distribution installation profile.",
"type": "project",
"minimum-stability": "dev",
"prefer-stable": true,
"repositories": [
{
"type": "composer",
"url": "https://wpackagist.org"
},
{
"type": "composer",
"url": "https://wp-languages.github.io",
"only": [
"koodimonni-language/*",
"koodimonni-plugin-language/*",
"koodimonni-theme-language/*"
]
},
{
"type": "package",
"package": {
"name": "wordpress/cern",
"description": "Defines a set of re-usable patterns for the CERN WordPress infrastructure",
"version": "v3.4.1",
"type": "wordpress-theme",
"dist": {
"url": "https://gitlab.cern.ch/api/v4/projects/wordpress%2Ftheme-lite/packages/generic/cern-theme/3.4.1/cern-theme.zip",
"type": "zip"
}
}
}
],
"require": {
"johnpbloch/wordpress-core": "6.8.1",
"wp-cli/wp-cli-bundle": "2.12.0",
"koodimonni-language/fr_fr": "6.8.1",
"koodimonni-language/en_gb": "6.8.1",
"koodimonni/composer-dropin-installer": "1.4",
"wpackagist-plugin/disable-json-api": "1.8",
"wpackagist-plugin/jetpack-boost": "3.13.1",
"wpackagist-plugin/fluentform": "6.0.3",
"wpackagist-plugin/fluentforms-pdf": "1.1.9",
"wpackagist-plugin/wp-piwik": "1.0.30",
"wpackagist-plugin/fluent-smtp": "2.2.90",
"wpackagist-plugin/filebird": "6.4.7",
"wpackagist-plugin/daggerhart-openid-connect-generic": "3.10.0",
"wpackagist-plugin/polylang": "3.7.1",
"wordpress/cern": "v3.4.1"
},
"require-dev": {
"boxuk/wp-muplugin-loader": "2.2.0",
"johnpbloch/wordpress-core-installer": "2.0"
},
"extra": {
"force-mu": [
"disable-json-api",
"daggerhart-openid-connect-generic",
"jetpack-boost",
"filebird",
"polylang"
],
"installer-paths": {
"wordpress-install-dir": "",
"wordpress/wp-content/mu-plugins/{$name}": [
"type:wordpress-muplugin"
],
"wordpress/wp-content/themes/{$name}": [
"type:wordpress-theme"
],
"wordpress/wp-content/plugins/{$name}": [
"type:wordpress-plugin"
]
},
"dropin-paths": {
"wordpress/wp-content/languages/": [
"vendor:koodimonni-language"
],
"wordpress/wp-content/languages/plugins/": [
"vendor:koodimonni-plugin-language"
],
"wordpress/wp-content/languages/themes/": [
"vendor:koodimonni-theme-language"
]
}
},
"config": {
"allow-plugins": {
"composer/installers": true,
"johnpbloch/wordpress-core-installer": true,
"boxuk/wp-muplugin-loader": true,
"koodimonni/composer-dropin-installer": true
}
}
}
[www]
pm.status_path = /status
ping.path = /ping
; PHP_MEMORY_LIMIT is taken from environment
memory_limit = ${PHP_MEMORY_LIMIT}
; as of PHP 8.3 we can set default values
;memory_limit = ${PHP_MEMORY_LIMIT:-128M}
; PHP_MEMORY_LIMIT is taken from environment
upload_max_filesize = ${UPLOAD_MAX_FILESIZE}
; as of PHP 8.3 we can set default values
;upload_max_filesize = ${UPLOAD_MAX_FILESIZE:-50M}
extension=imagick.so
#!/bin/bash
# Wait for the installation flag file
echo "Waiting for WordPress installation to complete..."
while [ ! -f "$FLAG_FILE" ]; do
sleep 2
done
echo "Installation detected. Checking for updates..."
# Activate maintenance mode
wp cern maintenance-mode activate
wp core update-db --allow-root
# Set or update options
source /usr/share/container-scripts/set-options.sh
wp cern maintenance-mode deactivate
echo "Starting PHP-FPM..."
# Start PHP-FPM
php-fpm
#!/bin/bash
wait_for_db() {
echo "Waiting for database at $MYSQL_HOST..."
until wp db check; do
sleep 3
done
echo "Database is ready!"
}
# Ensure the database is ready
wait_for_db
wp core is-installed --allow-root
wp_install_status=$?
if [ $wp_install_status -eq 1 ]; then
echo "WordPress not installed. Installing..."
wp core install --url=http://$APPLICATION_NAME --title="$APPLICATION_NAME" --admin_user=admin --admin_email=$ADMIN_EMAIL --skip-email --quiet
wp cern configure-polylang
echo "WordPress configuration completed."
fi
# Create flag file to indicate installation completion
touch "$FLAG_FILE"
echo "Installation complete. Flag file created."
#!/bin/bash
set -e
# Wait for the installation flag file
echo "Waiting for WordPress installation to complete..."
while [ ! -f "$FLAG_FILE" ]; do
sleep 2
done
# Onetime run:
exec wp cron event run --due-now
# Configure OpenID Connect Generic Plugin settings
configure_oidc_plugin() {
echo "--> Configuring OIDC Connect Generic Plugin..."
# Initialize settings if not already present
wp option get openid_connect_generic_settings --allow-root > /dev/null 2>&1
if [ $? -ne 0 ]; then
# Initialize settings as an empty JSON object if they don't exist
wp option add openid_connect_generic_settings '{}' --format=json --allow-root
fi
# passing args through pipe due to misfire of has_stdin in wp option patch when running in s2i scripts
# see more https://github.com/wp-cli/entity-command/issues/164
# piping can be removed if s2i in dropped
# Configure plugin settings
wp option patch insert openid_connect_generic_settings client_id "${OIDC_CLIENT_ID}" --allow-root
wp option patch insert openid_connect_generic_settings client_secret "${OIDC_CLIENT_SECRET}" --allow-root
wp option patch insert openid_connect_generic_settings login_type 'auto' --allow-root
wp option patch insert openid_connect_generic_settings scope 'openid' --allow-root
wp option patch insert openid_connect_generic_settings endpoint_login "${AUTHZ_API_ENDPOINT}/protocol/openid-connect/auth" --allow-root
wp option patch insert openid_connect_generic_settings endpoint_userinfo "${AUTHZ_API_ENDPOINT}/protocol/openid-connect/userinfo" --allow-root
wp option patch insert openid_connect_generic_settings endpoint_token "${AUTHZ_API_ENDPOINT}/protocol/openid-connect/token" --allow-root
wp option patch insert openid_connect_generic_settings endpoint_end_session "${AUTHZ_API_ENDPOINT}/protocol/openid-connect/logout" --allow-root
wp option patch insert openid_connect_generic_settings link_existing_users 1 --allow-root
wp option patch insert openid_connect_generic_settings create_if_does_not_exist 1 --allow-root
echo "--> OIDC Connect Generic Plugin configured."
}
# Configure options
configure_oidc_plugin
wp option set blogname $APPLICATION_NAME
wp option set title $APPLICATION_NAME
wp option set admin_email $ADMIN_EMAIL
\ No newline at end of file
<?php
/*
Plugin Name: CERN Roles
Description: Maps OpenID Connect roles to WordPress roles. Once enabled, this role mapper will enforce permissions configured at the Application-Portal. By end of November this plugin will be enforced for all websites. Action user is required, please see instructions at our https://wordpress.docs.cern.ch
Version: 1.0.0
Plugin URI: https://wordpress.docs.cern.ch/
Author: CERN Infrastructure
*/
function oidc_cern_role_assignment($user = null) {
if (!$user) {
$user = wp_get_current_user();
}
if (!$user || !isset($user->user_login)) {
error_log("Unable to determine username.");
return;
}
write_log_debug("User object: " . print_r($user, true));
// Get ID Token Claim from user meta
$id_token_claim = get_user_meta($user->ID, "openid-connect-generic-last-id-token-claim", true);
// Check if cern_roles exists in the claim
if (!isset($id_token_claim["cern_roles"])) {
error_log("cern_roles not found in ID Token Claim");
return;
}
$cern_roles = $id_token_claim["cern_roles"];
write_log_debug("Claim object: " . print_r($cern_roles, true));
// Define a mapping between CERN roles and WordPress roles
$role_mapping = [
"administrator" => "administrator",
"editor" => "editor",
"author" => "author",
"contributor" => "contributor",
];
// Assign WordPress roles based on CERN roles
foreach ($cern_roles as $cern_role) {
if (isset($role_mapping[$cern_role])) {
$wp_role = $role_mapping[$cern_role];
if (!in_array( $wp_role, (array) $user->roles )) {
$user->add_role($wp_role);
write_log_debug("Assigned WordPress role '$wp_role' based on CERN role '$cern_role'");
}
}
}
# Remove roles not in claim
foreach($user->roles as $role) {
if(!in_array($role, (array) $cern_roles)){
$user->remove_role($role);
write_log_debug("Removed role '$role'");
}
}
if (empty($user->roles)) {
error_log("No roles found.");
return;
}
write_log_debug("Assigned WordPress roles: " . implode(", ", $user->roles));
# update name and username
$new_name = isset($id_token_claim["name"]) ? $id_token_claim["name"] : $user->display_name;
$new_upn = isset($id_token_claim["cern_upn"]) ? $id_token_claim["cern_upn"] : $user->user_login;
$user_data = wp_update_user( array( 'ID' => $user->ID, 'nickname' => $new_upn, 'display_name' => $new_name ) );
if ( is_wp_error( $user_data ) ) {
// There was an error; possibly this user doesn't exist.
error_log("Unable to update user data.");
}
}
// Hook into the OpenID Connect Generic plugin's user logged-in event
add_action("openid-connect-generic-user-logged-in", "oidc_cern_role_assignment");
<?php
/*
Plugin Name: CERN
Author: CERN Infrastructure
Description: This plugin adds necessary CERN Infrastructure dependencies.
Version: 1.0.0
Plugin URI: https://wordpress.docs.cern.ch/
*/
/**
* Adds a WordPress Notice
*/
function wpb_admin_notice_info() {
echo '<div class="notice notice-info ">
<p><b>CERN WordPress is fully managed!</b></p>
<p><b>In this centrally managed WordPress Service at CERN, installing additional plugins is not possible.</b>
</br> All upgrades and updates are pushed centrally and timely for you! We got you covered. :)</p>
<p>See more details at <a href="https://wordpress.docs.cern.ch">https://wordpress.docs.cern.ch</a>.</p>
</div>';
}
add_action( 'admin_notices', 'wpb_admin_notice_info' );
/**
* Debug logs via error_log
*/
function write_log_debug($data) {
if (WP_DEBUG === true) {
if (is_array($data) || is_object($data)) {
$data_str = print_r($data, true);
error_log("DEBUG: $data_str \n");
return;
}
error_log("DEBUG: $data \n");
}
}
if ( defined( 'WP_CLI' ) && WP_CLI ) {
require_once dirname( __FILE__ ) . '/wp-cli-command-extensions.php';
}
<?php
/*
Plugin Name: CERN CLI Extensions
Author: CERN Infrastructure
Description: This plugin adds necessary CERN Infrastructure dependencies.
Version: 1.0.0
Plugin URI: https://wordpress.docs.cern.ch/
*/
/**
* Implements CERN Maintenance mode commands.
*/
class CERN_Maintenance_mode {
/**
* Enables maintenance mode.
*
* ## OPTIONS
*
* ---
* default: success
* options:
* - success
* - error
* ---
*
* ## EXAMPLES
*
* wp cern maintenance-mode activate
*
* @when after_wp_load
*/
function activate($args, $assoc_args) {
return WP_CLI::runcommand( 'maintenance-mode activate' );
}
/**
* Disables maintenance mode.
*
* ## OPTIONS
*
* ---
* default: success
* options:
* - success
* - error
* ---
*
* ## EXAMPLES
*
* wp cern maintenance-mode deactivate
*
* @when after_wp_load
*/
function deactivate($args, $assoc_args) {
global $wp_filesystem;
if ( ! $wp_filesystem ) {
if ( ! function_exists( 'WP_Filesystem' ) ) {
require_once ABSPATH . 'wp-admin/includes/file.php';
}
ob_start();
$credentials = request_filesystem_credentials( '' );
ob_end_clean();
if ( false === $credentials || ! WP_Filesystem( $credentials ) ) {
WP_CLI::error( __FUNCTION__, __( 'Could not access filesystem.' ) );
return;
}
}
$file = $wp_filesystem->abspath() . '.maintenance';
# Disable maintenance mode
# we don't use `wp maintenance-mode deactivate` because it deletes the .maintenance file entirely, and we restrict
# write/delete permissions on wordpress root folder
# Read more: https://github.com/WordPress/WordPress/blob/master/wp-admin/includes/class-wp-upgrader.php#L1007C18-L1007C34
$maintenance_string = '<?php $upgrading = 0; ?>';
$wp_filesystem->put_contents( $file, $maintenance_string, FS_CHMOD_FILE );
WP_CLI::success( "Maintenance mode disabled" );
}
}
/**
* Implements CERN commands.
*/
class CERN_commands {}
if ( defined('WP_CLI') && true === constant('WP_CLI') ) {
WP_CLI::add_command( 'cern', 'CERN_commands');
WP_CLI::add_command( 'cern maintenance-mode', 'CERN_Maintenance_mode' );
}
<?php
/**
* Plugin Name: Update OpenID Connect Settings
* Description: Automatically updates the openid_connect_generic_settings option based on environment variables.
* Author: CERN Infrastructure
* Version: 1.0
* Plugin URI: https://wordpress.org/plugins/openid-connect-server/
*/
/**
* OpenID Connect Generic Plugin Settings.
* Updates settings on every page load via an init hook.
*/
function update_openid_connect_settings() {
// Build the new settings array from environment variables
$new_settings = array(
'client_id' => getenv('OIDC_CLIENT_ID') ?: '',
'client_secret' => getenv('OIDC_CLIENT_SECRET') ?: '',
'login_type' => 'auto',
'scope' => 'openid',
'endpoint_login' => getenv('AUTHZ_API_ENDPOINT') . '/protocol/openid-connect/auth',
'endpoint_userinfo' => getenv('AUTHZ_API_ENDPOINT') . '/protocol/openid-connect/userinfo',
'endpoint_token' => getenv('AUTHZ_API_ENDPOINT') . '/protocol/openid-connect/token',
'endpoint_end_session' => getenv('AUTHZ_API_ENDPOINT') . '/protocol/openid-connect/logout',
'link_existing_users' => 1,
'create_if_does_not_exist' => 1,
);
// Merge with current settings and update option
$current_settings = get_option('openid_connect_generic_settings');
if($current_settings){
$merged_settings = array_merge($current_settings, $new_settings);
update_option('openid_connect_generic_settings', $merged_settings);
write_log_debug('updated oidc settings');
} else {
add_option('openid_connect_generic_settings', $new_settings);
write_log_debug('created oidc settings');
}
}
// Hook update function into WordPress's initialization
add_action('init', 'update_openid_connect_settings');
/**
* Update other generic options.
*/
function generic_options() {
update_option('blogname', getenv('APPLICATION_NAME'));
update_option('admin_emai', getenv('ADMIN_EMAIL'));
}
add_action('init', 'generic_options');