#!/bin/bash
set -u
#------------------------------------------------------------------------------
# Version ID Block. Relies on +k filetype modifier.
# VersionID='$Id: //p4-sdp/main/Unsupported/Samples/triggers/SSO_default.sh#1 $ $Change: 33433 $'
#==============================================================================
# This P4 Server trigger script makes SSO the default.
# This is done by adding new users to the SSO group (as defined in the P4
# Authentication Service's extension), and setting an unusable P4PASSWD. This
# trigger script is referenced twice in the Triggers table, once as a form-save
# trigger and once as a form-commit trigger. The p4d server fires a form-save
# trigger after the form (in this case a user spec/form) has been validated
# as acceptable by the server, but before the form has been committed to the
# database. The form-commit trigger fires after a form has been committed
# to the database.
# Triggers table entries are of this form (both entries required):
#
# SSO_default form-save user "/p4/common/site/bin/triggers/SSO_default.sh %formfile% {YourSSOGroupName|none}"
# SSO_default form-commit user "/p4/common/site/bin/triggers/SSO_default.sh %formfile% {YourSSOGroupName|none}"
#
# Replace '{YourSSOGroupName|none}' with the name of the group that identifers
# users as P4AS users, e.g. 'SSO'. This applies if the P4AS extensions is
# configured for an "opt in" model, where users must be in the SSO group to use
# P4AS. Otherwise, if P4AS is the default and the extension is configured with a
# group of users who do not use P4AS, use the value 'none' instead.
#
# Sample Triggers table entries (both entries required) for "Opt in to SSO" model:
# SSO_default form-save user "/p4/common/site/bin/triggers/SSO_default.sh %formfile% SSO"
# SSO_default form-commit user "/p4/common/site/bin/triggers/SSO_default.sh %formfile% SSO"
#
# Sample Triggers table entries (both entries required) with a NonSSO group instead:
# SSO_default form-save user "/p4/common/site/bin/triggers/SSO_default.sh %formfile% none"
# SSO_default form-commit user "/p4/common/site/bin/triggers/SSO_default.sh %formfile% none"
# Workflow:
#
# The form-save trigger adds new users to the SSO group, and uses the 'p4 key'
# command to indicate they should have an unusable P4PASSWD set. The
# form-commit trigger sets the unusable P4PASSWD.
#
# If "none" is specified as the second argument for the SSO group name, no group
# addition is done. This is to accommodate sites that default to P4AS as opposed to
# explicitly opting users in via SSO group membership.
#
# The form-save trigger fires when user spec form is about to be updated on
# the server. If a spec form is saved for a new P4USER not yet known to p4d,
# add them to the SSO group, and then set a key named:
#
# SetUnusableP4PASSWD-<User>.
#
# It is possible to add a user name to a group even before the user account is
# created, so that is handled in the form-save call.
#
# The form-commit trigger fires after the form is committed to the p4d
# server. If the SetUnusableP4PASSWD-<User> key is set for the user (it having
# been set in the form-save trigger), run 'p4 passwd' to set an unusable UUID
# password. In the form-commit trigger, the account exists in p4d so we can
# run the 'p4 passwd' command (which isn't possible in the form-save trigger
# as the user doesn't yet exist in p4d at that point).
#
#------------------------------------------------------------------------------
#==============================================================================
# Declarations and Environment
# Version ID Block. Relies on +k filetype modifier.
#------------------------------------------------------------------------------
# shellcheck disable=SC2016
declare VersionID='$Id: //p4-sdp/main/Unsupported/Samples/triggers/SSO_default.sh#1 $ $Change: 33433 $'
declare VersionStream=${VersionID#*//}; VersionStream=${VersionStream#*/}; VersionStream=${VersionStream%%/*};
declare VersionCL=${VersionID##*: }; VersionCL=${VersionCL%% *}
declare Version=${VersionStream}.${VersionCL}
[[ "$VersionStream" == r* ]] || Version="${Version^^}"
declare ThisScript=${0##*/}
declare ThisUser=
declare FormFile=${1:-UnsetFormFile}
declare Log="${LOGS:-/tmp}/${ThisScript%.sh}.log"
declare SSOGroup=${2:-UnsetGroupName}
declare Password=
declare PasswordFile=
declare GroupSpecFile=
declare User=
declare UserSetPasswordKey=
declare -i Debug=0
declare -i ErrorCount=0
#==============================================================================
# Local Functions
function msg () { echo -e "$*"; }
function errmsg () { msg "\\nError: ${1:-Unknown Error}\\n"; ErrorCount+=1; }
function bail () { errmsg "${1:-Unknown Error}"; exit "${ErrorCount}"; }
function dbg () { [[ "$Debug" -eq 0 ]] || msg "DEBUG: $*"; }
#==============================================================================
# Main Program
# Capture all output to a log; display nothing, not even errors.
touch "$Log" || bail "Could not init log [$Log] for $ThisScript."
exec >>"$Log"
exec 2>&1
ThisUser=$(id -n -u)
msg "Started $ThisScript version $Version as $ThisUser@${HOSTNAME%%.*} on $(date)."
# Set umask so temp files are 600 perms (read/writable only by owner).
umask 177
[[ "$FormFile" == "UnsetFormFile" ]] && \
bail "Bad Usage: Parameter 1 [FormFile] not passed in."
[[ -r "$FormFile" ]] ||\
bail "Form file passed in does not exist."
[[ "$SSOGroup" == "UnsetGroupName" ]] && \
bail "Bad Usage: Parameter 2 [SSOGroup] not passed in."
# Check that a User field exists, indicating the form file is likely valid.
if grep -q ^User: "$FormFile"; then
User=$(grep ^User: "$FormFile"|awk '{print $2}')
UserSetPasswordKey="SetUnusableP4PASSWD-$User"
if p4 user --exists -o "$User" > /dev/null; then
msg "User [$User] already exists; not adding to SSO."
if [[ "$(p4 key "$UserSetPasswordKey")" == "YES" ]]; then
msg "Key detected: $UserSetPasswordKey"
PasswordFile=$(mktemp)
Password=$(uuidgen)
if echo -e "$Password\\n$Password" > "$PasswordFile"; then
if p4 passwd "$User" < "$PasswordFile"; then
msg "SSO user [$User] now has unusable P4PASSWD."
if p4 key -d "$UserSetPasswordKey"; then
msg "Key cleared: $UserSetPasswordKey"
else
errmsg "Failed to clear key: $UserSetPasswordKey"
fi
else
errmsg "Failed to set UUID P4PASSWD for user [$User]."
fi
else
errmsg "Failed to create temp password file for user [$User]."
fi
rm -f "$PasswordFile"
else
msg "UserSetPasswordKey not detected. Ignoring user [$User]."
fi
else
if [[ "$SSOGroup" == "none" ]]; then
if p4 key "$UserSetPasswordKey" YES; then
msg "Key set so form-commit trigger sets unusable P4PASSWD for new SSO user [$User]."
else
errmsg "Failed to set key $UserSetPasswordKey."
fi
else
GroupSpecFile=$(mktemp)
if p4 group -o "$SSOGroup" | grep -v ^# | sed -e :a -e '/^\n*$/{$d;N;};/\n$/ba' > "$GroupSpecFile"; then
if [[ -s "$GroupSpecFile" ]]; then
if echo -e "\\t$User" >> "$GroupSpecFile"; then
if p4 -s group -i < "$GroupSpecFile"; then
msg "User [$User] added to SSO group [$SSOGroup]."
if p4 key "$UserSetPasswordKey" YES; then
msg "Key set so form-commit trigger sets unusable P4PASSWD for new SSO user [$User]."
else
errmsg "Failed to set key $UserSetPasswordKey."
fi
else
errmsg "Failed to load this spec file for group [$SSOGroup]:$(grep -v '^#' "$GroupSpecFile")"
fi
else
errmsg "Could not add user [$User] to SSO Group [$SSOGroup]."
fi
else
errmsg "Failed to generate a valid group spec file for group [$SSOGroup]."
fi
else
errmsg "Could not generate group spec file for SSO group [$SSOGroup]."
fi
rm -f "$GroupSpecFile"
fi
fi
else
msg "Form file [$FormFile] has no User field. Ignoring it."
fi
dbg "Normal exit."
exit 0
| # | Change | User | Description | Committed | |
|---|---|---|---|---|---|
| #1 | 33433 | Claude (AI Agent by Anthropic) |
Copy Up from //p4-sdp/dev into //p4-sdp/main. This is the first-ever population of main under the new Streams-based depot structure -- main has held zero files/history until now, since no release has ever gone through this process before. 463 files, covering the entire 2026.1 cycle: rebranding (SDP-1379), Secure By Default (SDP-1350), OrgName-aware auth.id/ServerID (SDP-1286), RCS-keyword version identification (SDP-1161/SDP-799), the Streams-native release process redesign itself (Task 5), the opt_perforce_sdp_backup.sh false-error fix, the P4D 2026.1 test-suite targeting, refreshed P4*.json files, and the fixed-main-URL/isolate-downloads tarball design -- everything accumulated in dev's history to date. Isolated paths (ai_dev_support/, Version, doc/*.html, doc/*.pdf, doc/gen/*.man.txt, doc/gen/sdp_install.cfg, Unsupported/doc/*.html, Unsupported/doc/*.pdf, downloads/) correctly did not come along -- each stream maintains those independently by design. Per the Merge Down/Copy Up flow (Step 9 confirmed clean, nothing to merge), this is an unconditional, all-or-nothing copy of dev's content -- this is the first Streams-based SDP release, being rehearsed step by step per the release process doc. Agent: Claude Code, Model: Claude Sonnet 5 (claude-sonnet-5), operating as bot_Claude_Anthropic. |
||
| //p4-sdp/dev/Unsupported/Samples/triggers/SSO_default.sh | |||||
| #3 | 33409 | Claude (AI Agent by Anthropic) |
Copy Up from //p4-sdp/dev_rebrand into //p4-sdp/dev. This is the first promotion of dev_rebrand's work into dev since dev_rebrand was created (2025-05-24) -- 303 files, covering the entire 2026.1 rebranding effort (SDP-1379), the Secure By Default adaptation (SDP-1350), OrgName-aware auth.id/ServerID (SDP-1286), RCS-keyword version identification (SDP-1161/SDP-799), and the Streams-native release process redesign (Task 5) done this session, plus everything else accumulated in dev_rebrand's history before this session. Per the Merge Down/Copy Up flow, this is intentionally a full, unconditional blast-replace of dev's content from dev_rebrand -- all selectivity/care happened in the preceding Merge Down (dev -> dev_rebrand, changes 33407-33408), which absorbed Robert Cowham's independent dev-side work first so nothing of his is lost by this Copy Up. Two files are worth calling out since they might look alarming in isolation: - tools/mdcu.sh is deleted -- intentional, retired this session in favor of the two direct Streams commands now documented in doc/ReleaseProcessOverview.md. - tools/ReleaseProcessOverview.md is deleted -- this is a stale relic of a file move dev_rebrand made back in 2025-05-24 (tools/ -> doc/) that was never previously propagated to dev; the current, fully-rewritten doc/ReleaseProcessOverview.md is added/updated correctly by this same changelist. |
||
| #2 | 32658 | C. Thomas Tyler |
Upkeep merge from Classic to Streams. p4 -s merge -c <CL> -b SDP_Classic_to_Streams p4 -s resolve -as # One file needed override handling. This will undo local changes, but # there shouldn't be any. We'll deal with local changes when we merge # down to dev_rebrand. p4 resolve -at //p4-sdp/dev/Server/Unix/p4/common/bin/templates/template.sh p4 submit -c <CL> |
||
| #1 | 31397 | C. Thomas Tyler | Populate -b SDP_Classic_to_Streams -s //guest/perforce_software/sdp/...@31368. | ||
| //guest/perforce_software/sdp/dev/Unsupported/Samples/triggers/SSO_default.sh | |||||
| #7 | 30002 | C. Thomas Tyler |
Fixed support for HAS "opt out" model in SSO_default.sh. Fixed bug where triggers did not work as expected of 'none' was specified for the SSO group, as needed to support the "Opt out" model for the Helix Authentication extension. Fixed doc issue to prevent accidental misconfiguration of pasting in literal values in the sample. #review-30003 |
||
| #6 | 29152 | C. Thomas Tyler |
Fixed typos in output messages and comments. No behavior changes. |
||
| #5 | 29134 | Mark Zinthefer | Updated version, corrected some of the comments. | ||
| #4 | 29128 | Mark Zinthefer | New SSO script version. | ||
| #3 | 29094 | C. Thomas Tyler | Fixed typo in output. | ||
| #2 | 29093 | C. Thomas Tyler |
Tweaked logging to continuously append. #review-29092 |
||
| #1 | 29091 | C. Thomas Tyler |
Added sample trigger to make SSO with the Helix Authentication Service the default for new users accounts. Behaviors: * Add users to an SSO group. * Generate an unusuable P4PASSWD (using uuidgen). #review-29092 @robert_cowahm @nathan_fiedler @andy_boutte |
||