@Override public Details newInstance(StaplerRequest req, JSONObject formData)throws FormException { if (req == null) { // Should never happen, see newInstance() Javadoc thrownewFormException("Stapler request is missing in the call", "staplerRequest"); } Stringpwd= Util.fixEmpty(req.getParameter("user.password")); Stringpwd2= Util.fixEmpty(req.getParameter("user.password2"));
if (pwd == null || pwd2 == null) { // one of the fields is empty thrownewFormException("Please confirm the password by typing it twice", "user.password2"); }
// will be null if it wasn't encrypted Stringdata= Protector.unprotect(pwd); Stringdata2= Protector.unprotect(pwd2);
if (data == null != (data2 == null)) { // Require that both values are protected or unprotected; do not allow user to change just one text field thrownewFormException("Please confirm the password by typing it twice", "user.password2"); }
if (data != null/* && data2 != null */ && !MessageDigest.isEqual(data.getBytes(StandardCharsets.UTF_8), data2.getBytes(StandardCharsets.UTF_8))) { // passwords are different encrypted values thrownewFormException("Please confirm the password by typing it twice", "user.password2"); }
if (data == null/* && data2 == null */ && !pwd.equals(pwd2)) { // passwords are different plain values thrownewFormException("Please confirm the password by typing it twice", "user.password2"); }
/********** 新增密码复杂度 start **********/ // Validate password complexity if (pwd.length() < 8) { thrownewFormException("Password must be at least 8 characters long", "user.password"); }
// Check if it contains at least one lowercase letter if (!pwd.matches(".*[a-z].*")) { thrownewFormException("Password must contain at least one lowercase letter", "user.password"); }
// Check if it contains at least one uppercase letter if (!pwd.matches(".*[A-Z].*")) { thrownewFormException("Password must contain at least one uppercase letter", "user.password"); }
// Check if it contains at least one digit if (!pwd.matches(".*[0-9].*")) { thrownewFormException("Password must contain at least one digit", "user.password"); }
// Check if it contains at least one special character (common set) if (!pwd.matches(".*[!@#$%^&*(),.?\":{}|<>].*")) { thrownewFormException("Password must contain at least one special character (e.g., !@#$%^&*()-_=+[]{}|;:'\",.<>?/)", "user.password"); }
/********** 新增密码复杂度 end **********/
if (data != null) { Stringprefix= Stapler.getCurrentRequest().getSession().getId() + ':'; if (data.startsWith(prefix)) { return Details.fromHashedPassword(data.substring(prefix.length())); } }
Useruser= Util.getNearestAncestorOfTypeOrThrow(req, User.class); // the UserSeedProperty is not touched by the configure page UserSeedPropertyuserSeedProperty= user.getProperty(UserSeedProperty.class); if (userSeedProperty != null) { userSeedProperty.renewSeed(); }
@Override publicbooleanisEnabled() { // this feature is only when HudsonPrivateSecurityRealm is enabled return Jenkins.get().getSecurityRealm() instanceof HudsonPrivateSecurityRealm; }
<!-- 新增密码复杂度校验 --> <scripttype="text/javascript"> // <![CDATA[ document.getElementById('password').addEventListener('input', function() { var password = this.value; var hintElement = document.getElementById('passwordHint'); var result = checkPasswordStrength(password); if (result) { hintElement.textContent = result; hintElement.style.display = 'inline'; } else { hintElement.textContent = ''; hintElement.style.display = 'none'; } }); functioncheckPasswordStrength(password) { // Check password length if (password.length < 8) { return"Password must be at least 8 characters long"; } // Check for at least one uppercase letter if (!/[A-Z]/.test(password)) { return"Password must contain at least one uppercase letter"; } // Check for at least one lowercase letter if (!/[a-z]/.test(password)) { return"Password must contain at least one lowercase letter"; } // Check for at least one digit if (!/\d/.test(password)) { return"Password must contain at least one digit"; } // Check for at least one special character (common set) if (!/[!@#$%^&*()\-_=+$${}|;:',.<>?/\\]/.test(password)) { return"Password must contain at least one special character (e.g., !@#$%^&*()-_=+[]{}|;:'\",.<>?/)"; } // Password meets all criteria returnnull; // Password is valid } document.getElementById('password2').addEventListener('input', function() { var password = document.getElementById('password').value; var confirmPassword = this.value; var hintElement = document.getElementById('confirmPasswordHint'); if (password !== confirmPassword) { hintElement.textContent = "Please confirm the password by typing it twice"; hintElement.style.display = 'inline'; } else { hintElement.textContent = ''; hintElement.style.display = 'none'; } }); // ]]> </script> </j:jelly>
FROM eclipse-temurin:11.0.19_7-jdk-centos7 as jre-build
# Generate smaller java runtime without unneeded files # for now we include the full module path to maintain compatibility # while still saving space (approx 200mb from the full distribution) RUN jlink \ --add-modules ALL-MODULE-PATH \ --no-man-pages \ --compress=2 \ --output /javaruntime
FROM centos:centos7.9.2009
RUN sed -e 's|^mirrorlist=|#mirrorlist=|g' \ -e 's|^#baseurl=http://mirror.centos.org|baseurl=https://mirrors.aliyun.com|g' \ -i.bak /etc/yum.repos.d/CentOS-Base.repo
RUN yum install -y \ curl \ fontconfig \ freetype \ git \ unzip \ which \ && yum clean all
# Jenkins is run with user `jenkins`, uid = 1000 # If you bind mount a volume from the host or a data container, # ensure you use the same uid RUNmkdir -p $JENKINS_HOME \ && chown${uid}:${gid}$JENKINS_HOME \ && groupadd -g ${gid}${group} \ && useradd -N -d "$JENKINS_HOME" -u ${uid} -g ${gid} -l -m -s /bin/bash ${user}
# Jenkins home directory is a volume, so configuration and build history # can be persisted and survive image upgrades VOLUME$JENKINS_HOME
# $REF (defaults to `/usr/share/jenkins/ref/`) contains all reference configuration we want # to set on a fresh new installation. Use it to bundle additional plugins # or config file with your custom jenkins Docker image. RUNmkdir -p ${REF}/init.groovy.d
# Use tini as subreaper in Docker container to adopt zombie processes ARG TINI_VERSION=v0.19.0 COPY ../tini_pub.gpg "${JENKINS_HOME}/tini_pub.gpg" RUN curl -fsSL "https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-static-${TARGETARCH}" -o /sbin/tini \ && curl -fsSL "https://github.com/krallin/tini/releases/download/${TINI_VERSION}/tini-static-${TARGETARCH}.asc" -o /sbin/tini.asc \ && gpg --no-tty --import "${JENKINS_HOME}/tini_pub.gpg" \ && gpg --verify /sbin/tini.asc \ && rm -rf /sbin/tini.asc /root/.gnupg \ && chmod +x /sbin/tini
# jenkins version being bundled in this docker image ARG JENKINS_VERSION ENV JENKINS_VERSION ${JENKINS_VERSION:-2.356}
# jenkins.war checksum, download will be validated using it #ARG JENKINS_SHA=1163c4554dc93439c5eef02b06a8d74f98ca920bbc012c2b8a089d414cfa8075
# Can be used to customize where jenkins.war get downloaded from #ARG JENKINS_URL=https://repo.jenkins-ci.org/public/org/jenkins-ci/main/jenkins-war/${JENKINS_VERSION}/jenkins-war-${JENKINS_VERSION}.war
# could use ADD but this one does not check Last-Modified header neither does it allow to control checksum # see https://github.com/docker/docker/issues/8331 #RUN curl -fsSL ${JENKINS_URL} -o /usr/share/jenkins/jenkins.war \ # && echo "${JENKINS_SHA} /usr/share/jenkins/jenkins.war" >/tmp/jenkins_sha \ # && sha256sum -c --strict /tmp/jenkins_sha \ # && rm -f /tmp/jenkins_sha COPY war/target/jenkins.war /usr/share/jenkins/jenkins.war