<commit_before>/*
 * The MIT License
 *
 * Copyright (c) 2010-2011, <NAME>,
 * <NAME>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package com.michelin.cio.hudson.plugins.maskpasswords;

import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import hudson.Extension;
import hudson.Launcher;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.BuildListener;
import hudson.model.ParameterValue;
import hudson.model.ParametersAction;
import hudson.tasks.BuildWrapper;
import hudson.tasks.BuildWrapperDescriptor;
import hudson.util.Secret;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.jvnet.localizer.Localizable;
import org.jvnet.localizer.ResourceBundleHolder;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;

/**
 * Build wrapper that alters the console so that passwords don't get displayed.
 * 
 * @author <NAME> (http://openromain.blogspot.com)
 */
public final class MaskPasswordsBuildWrapper extends BuildWrapper {

    /**
     * {@code allPasswords} contains all the passwords that have to be masked.
     */
    private transient List<String> allPasswords = new ArrayList<String>();
    private final List<VarPasswordPair> varPasswordPairs;

    @DataBoundConstructor
    public MaskPasswordsBuildWrapper(List<VarPasswordPair> varPasswordPairs) {
        this.varPasswordPairs = varPasswordPairs;

        // global passwords
        List<VarPasswordPair> globalVarPasswordPairs = MaskPasswordsConfig.getInstance().getGlobalVarPasswordPairs();
        for(VarPasswordPair globalVarPasswordPair: globalVarPasswordPairs) {
            allPasswords.add(globalVarPasswordPair.getPassword());
        }

        if(varPasswordPairs != null) {
            for(VarPasswordPair varPasswordPair: varPasswordPairs) {
                String password = varPasswordPair.getPassword();
                if(StringUtils.isNotBlank(password)) {
                    allPasswords.add(password);
                }
            }
        }
    }

    /**
     * This method is invoked before {@link #makeBuildVariables()} and {@link
     * #setUp()}.
     */
    @Override
    public OutputStream decorateLogger(AbstractBuild build, OutputStream logger) {
        MaskPasswordsConfig config = MaskPasswordsConfig.getInstance();

        // find build parameters which are passwords (PasswordParameterValue)
        ParametersAction params = build.getAction(ParametersAction.class);
        if(params != null) {
            for(ParameterValue param : params) {
                if(config.isMasked(param.getClass().getName())) {
                    String password = param.createVariableResolver(build).resolve(param.getName());
                    if(StringUtils.isNotBlank(password)) {
                        allPasswords.add(password);<commit_msg>[FIXED JENKINS-11934] Once a job config has been submitted, new/updated global passwords are not masked<commit_after>/*
 * The MIT License
 *
 * Copyright (c) 2010-2011, <NAME>,
 * <NAME>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package com.michelin.cio.hudson.plugins.maskpasswords;

import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import hudson.Extension;
import hudson.Launcher;
import hudson.model.AbstractBuild;
import hudson.model.AbstractProject;
import hudson.model.BuildListener;
import hudson.model.ParameterValue;
import hudson.model.ParametersAction;
import hudson.tasks.BuildWrapper;
import hudson.tasks.BuildWrapperDescriptor;
import hudson.util.Secret;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.jvnet.localizer.Localizable;
import org.jvnet.localizer.ResourceBundleHolder;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.StaplerRequest;

/**
 * Build wrapper that alters the console so that passwords don't get displayed.
 * 
 * @author <NAME> (http://openromain.blogspot.com)
 */
public final class MaskPasswordsBuildWrapper extends BuildWrapper {

    private final List<VarPasswordPair> varPasswordPairs;

    @DataBoundConstructor
    public MaskPasswordsBuildWrapper(List<VarPasswordPair> varPasswordPairs) {
        this.varPasswordPairs = varPasswordPairs;
    }

    /**
     * This method is invoked before {@link #makeBuildVariables()} and {@link
     * #setUp()}.
     */
    @Override
    public OutputStream decorateLogger(AbstractBuild build, OutputStream logger) {
        List<String> allPasswords = new ArrayList<String>();  // all passwords to be masked
        MaskPasswordsConfig config = MaskPasswordsConfig.getInstance();

        // global passwords
        List<VarPasswordPair> globalVarPasswordPairs = config.getGlobalVarPasswordPairs();
        for(VarPasswordPair globalVarPasswordPair: globalVarPasswordPairs) {
            allPasswords.add(globalVarPasswordPair.getPassword());
        }

        // job's passwords
        if(varPasswordPairs != null) {
            for(VarPasswordPair varPasswordPair: varPasswordPairs) {
                String password = varPasswordPair.getPassword();
                if(StringUtils.isNotBlank(password)) {
                    allPasswords.add(password);
                }
            }
        }

        // find build parameters which are passwords (PasswordParameterValue)
        ParametersAction params = build.getAction(ParametersAction.class);
        if(params != null) {
            for(ParameterValue param : params) {
                if(config.isMasked(param.getClass().getName())) {
                    String password = param.createVariableResolver(build).resolve(param.getName());
                    if(StringUtils.isNotBlank(password)) {
                        allPasswords.add(password);
{'fraction_non_alphanumeric': 0.08356195701874715, 'fraction_numerical': 0.0024005486968449933, 'mean_word_length': 3.793972602739726, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4446214', 'n_tokens_mistral': 2384, 'n_tokens_neox': 2252, 'n_words': 685}