Files
Qortal-Nextcloud-Integration/scripts/patch-user-oidc-invite-flow.sh

130 lines
3.5 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
repo_root="$(cd "${script_dir}/.." && pwd)"
custom_apps_root="${NEXTCLOUD_CUSTOM_APPS_PATH:-${repo_root}/nextcloud/custom_apps}"
app_path="${USER_OIDC_APP_PATH:-}"
dry_run="0"
usage() {
cat <<USAGE
Usage: ./scripts/patch-user-oidc-invite-flow.sh [options]
Apply the NuQloud invite-token bridge to an installed upstream user_oidc app.
Options:
--app-path <path> Path to user_oidc app directory
--custom-apps-path <path> Nextcloud custom_apps path
--dry-run Check whether patch is needed without writing
-h, --help Show this help
USAGE
}
resolve_path() {
local raw="${1:-}"
if [[ -z "${raw}" ]]; then
printf '%s' ""
elif [[ "${raw}" == /* ]]; then
printf '%s' "${raw}"
else
printf '%s' "${repo_root}/${raw}"
fi
}
while [[ $# -gt 0 ]]; do
case "$1" in
--app-path)
app_path="${2:-}"
shift 2
;;
--app-path=*)
app_path="${1#*=}"
shift
;;
--custom-apps-path)
custom_apps_root="${2:-}"
shift 2
;;
--custom-apps-path=*)
custom_apps_root="${1#*=}"
shift
;;
--dry-run)
dry_run="1"
shift
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown option: $1" >&2
usage
exit 1
;;
esac
done
custom_apps_root="$(resolve_path "${custom_apps_root}")"
if [[ -z "${app_path}" ]]; then
app_path="${custom_apps_root}/user_oidc"
else
app_path="$(resolve_path "${app_path}")"
fi
login_controller="${app_path}/lib/Controller/LoginController.php"
if [[ ! -f "${login_controller}" ]]; then
echo "Missing user_oidc LoginController: ${login_controller}" >&2
exit 1
fi
if grep -q "getParam('invite_token'" "${login_controller}" 2>/dev/null; then
echo "user_oidc invite bridge already present: ${login_controller}"
exit 0
fi
if [[ "${dry_run}" == "1" ]]; then
echo "user_oidc invite bridge would be applied: ${login_controller}"
exit 0
fi
tmp_file="$(mktemp)"
cleanup() {
rm -f "${tmp_file}"
}
trap cleanup EXIT
if ! perl -0pe '
our $patched;
my $pattern = qr{
\n([ \t]*)try[ \t]*\{\n
([ \t]*)\$discovery[ \t]*=[ \t]*\$this->discoveryService->obtainDiscovery\(\$provider\);
}x;
if ($_ =~ $pattern) {
my ($indent, $inner) = ($1, $2);
my $insert = "\n${indent}\$inviteToken = trim((string)\$this->request->getParam(\"invite_token\", \"\"));\n"
. "${indent}if (\$inviteToken !== \"\" && preg_match(\"/^[A-Za-z0-9_-]{16,256}$/\", \$inviteToken) === 1) {\n"
. "${inner}\$data[\"invite_token\"] = \$inviteToken;\n"
. "${indent}}\n"
. "${indent}\$inviteEmail = trim((string)\$this->request->getParam(\"invite_email\", \"\"));\n"
. "${indent}if (\$inviteEmail !== \"\" && filter_var(\$inviteEmail, FILTER_VALIDATE_EMAIL) !== false) {\n"
. "${inner}\$data[\"invite_email\"] = \$inviteEmail;\n"
. "${indent}}\n";
my $replacement = $insert . "\n${indent}try {\n${inner}\$discovery = \$this->discoveryService->obtainDiscovery(\$provider);";
$_ =~ s/$pattern/$replacement/;
$patched = 1;
}
END { exit($patched ? 0 : 3); }
' "${login_controller}" > "${tmp_file}"; then
echo "Unable to patch user_oidc invite bridge; LoginController layout changed." >&2
exit 1
fi
backup_path="${login_controller}.nuqloud-pre-invite-patch.$(date +%Y%m%d%H%M%S)"
cp "${login_controller}" "${backup_path}"
cat "${tmp_file}" > "${login_controller}"
echo "Applied user_oidc invite bridge: ${login_controller}"
echo "Backup written: ${backup_path}"