001    /**
002     * Copyright 2009-2012 The Kuali Foundation
003     *
004     * Licensed under the Educational Community License, Version 2.0 (the "License");
005     * you may not use this file except in compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     * http://www.opensource.org/licenses/ecl2.php
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed under the License is distributed on an "AS IS" BASIS,
012     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013     * See the License for the specific language governing permissions and
014     * limitations under the License.
015     */
016    package org.codehaus.mojo.properties;
017    
018    import java.util.ArrayList;
019    import java.util.Collections;
020    import java.util.List;
021    import java.util.Properties;
022    
023    import org.apache.commons.lang.StringUtils;
024    import org.apache.maven.plugin.AbstractMojo;
025    import org.apache.maven.plugin.MojoExecutionException;
026    import org.apache.maven.project.MavenProject;
027    import org.jasypt.util.text.BasicTextEncryptor;
028    
029    /**
030     * Inspect project and system properties for any keys ending with <code>endsWith</code>. Any matching properties are
031     * assumed to be encrypted. They are decrypted and stored as project properties minus the <code>endsWith</code> suffix.
032     * For example, the value for the property "dba.password.encrypted" will be decrypted and stored as "dba.password"
033     * 
034     * @goal decryptall
035     */
036    public class DecryptAllPropertiesMojo extends AbstractMojo {
037    
038        /**
039         * @parameter default-value="${project}"
040         * @required
041         * @readonly
042         */
043        private MavenProject project;
044    
045        /**
046         * If true, the plugin will include system properties when decrypting properties
047         * 
048         * @parameter default-value="false" expression="${properties.includeSystemProperties}"
049         */
050        private boolean includeSystemProperties;
051    
052        /**
053         * If true, the plugin will include environment variables when decrypting properties.
054         * 
055         * @parameter default-value="false" expression="${properties.includeEnvironmentVariables}"
056         */
057        private boolean includeEnvironmentVariables;
058    
059        /**
060         * If true, the plugin will emit no logging information
061         * 
062         * @parameter expression="${properties.quiet}" default-value="false"
063         * @required
064         */
065        private boolean quiet;
066    
067        /**
068         * The pattern for matching properties in need of decryption
069         * 
070         * @parameter expression="${properties.endsWith}" default-value=".encrypted"
071         * @required
072         */
073        private String endsWith;
074    
075        /**
076         * If true the plain text decrypted values are displayed to the console.
077         * 
078         * @parameter expression="${properties.show}" default-value="false"
079         * @required
080         */
081        private boolean show;
082    
083        /**
084         * The password for decrypting property values. This same password must have been used to encrypt them.
085         * 
086         * @parameter expression="${properties.password}"
087         * @required
088         */
089        private String password;
090    
091        @Override
092        public void execute() throws MojoExecutionException {
093            BasicTextEncryptor encryptor = new BasicTextEncryptor();
094            encryptor.setPassword(password);
095            Properties props = new Properties();
096            props.putAll(project.getProperties());
097            if (includeEnvironmentVariables) {
098                props.putAll(WriteProjectProperties.getEnvironmentVariables());
099            }
100            if (includeSystemProperties) {
101                props.putAll(System.getProperties());
102            }
103            List<String> keys = new ArrayList<String>(props.stringPropertyNames());
104            Collections.sort(keys);
105            for (String key : keys) {
106                boolean decrypt = key.endsWith(endsWith);
107                if (!decrypt) {
108                    continue;
109                }
110                String value = getProperty(key);
111                if (StringUtils.isBlank(value) && !quiet) {
112                    getLog().info("Skipping blank property " + key);
113                    continue;
114                }
115                String newValue = encryptor.decrypt(value);
116                int length = endsWith.length();
117                String newKey = key.substring(0, key.length() - length);
118                project.getProperties().setProperty(newKey, newValue);
119                if (quiet) {
120                    continue;
121                }
122                if (show) {
123                    getLog().info("Setting " + newKey + "=" + newValue + " - " + value);
124                } else {
125                    getLog().info("Setting " + newKey);
126                }
127            }
128        }
129    
130        protected String getProperty(String key) {
131            String sys = System.getProperty(key);
132            String proj = project.getProperties().getProperty(key);
133            if (!StringUtils.isBlank(sys)) {
134                return sys;
135            } else {
136                return proj;
137            }
138        }
139    
140        public boolean isQuiet() {
141            return quiet;
142        }
143    
144        public void setQuiet(boolean quiet) {
145            this.quiet = quiet;
146        }
147    
148        public String getEndsWith() {
149            return endsWith;
150        }
151    
152        public void setEndsWith(String endsWith) {
153            this.endsWith = endsWith;
154        }
155    
156        public boolean isShow() {
157            return show;
158        }
159    
160        public void setShow(boolean show) {
161            this.show = show;
162        }
163    
164        public String getPassword() {
165            return password;
166        }
167    
168        public void setPassword(String password) {
169            this.password = password;
170        }
171    
172        public MavenProject getProject() {
173            return project;
174        }
175    
176        public boolean isIncludeSystemProperties() {
177            return includeSystemProperties;
178        }
179    
180        public void setIncludeSystemProperties(boolean includeSystemProperties) {
181            this.includeSystemProperties = includeSystemProperties;
182        }
183    
184        public boolean isIncludeEnvironmentVariables() {
185            return includeEnvironmentVariables;
186        }
187    
188        public void setIncludeEnvironmentVariables(boolean includeEnvironmentVariables) {
189            this.includeEnvironmentVariables = includeEnvironmentVariables;
190        }
191    }