View Javadoc
1   package org.apache.maven.shared.release.exec;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.util.ArrayList;
24  import java.util.List;
25  
26  import org.apache.maven.settings.Proxy;
27  import org.apache.maven.settings.Server;
28  import org.apache.maven.settings.Settings;
29  import org.apache.maven.settings.SettingsUtils;
30  import org.apache.maven.settings.io.xpp3.SettingsXpp3Writer;
31  import org.apache.maven.shared.release.ReleaseResult;
32  import org.apache.maven.shared.release.env.ReleaseEnvironment;
33  import org.codehaus.plexus.component.annotations.Requirement;
34  import org.codehaus.plexus.logging.LogEnabled;
35  import org.codehaus.plexus.logging.Logger;
36  import org.codehaus.plexus.util.StringUtils;
37  import org.sonatype.plexus.components.cipher.DefaultPlexusCipher;
38  import org.sonatype.plexus.components.cipher.PlexusCipher;
39  import org.sonatype.plexus.components.cipher.PlexusCipherException;
40  import org.sonatype.plexus.components.sec.dispatcher.DefaultSecDispatcher;
41  import org.sonatype.plexus.components.sec.dispatcher.SecDispatcher;
42  import org.sonatype.plexus.components.sec.dispatcher.SecDispatcherException;
43  import org.sonatype.plexus.components.sec.dispatcher.SecUtil;
44  import org.sonatype.plexus.components.sec.dispatcher.model.SettingsSecurity;
45  
46  /**
47   * <p>Abstract AbstractMavenExecutor class.</p>
48   *
49   */
50  public abstract class AbstractMavenExecutor
51      implements MavenExecutor, LogEnabled
52  {
53  
54      private Logger logger;
55  
56      /**
57       * When this plugin requires Maven 3.0 as minimum, this component can be removed and o.a.m.s.c.SettingsDecrypter be
58       * used instead.
59       */
60      @Requirement( role = SecDispatcher.class, hint = "mng-4384" )
61      private DefaultSecDispatcher secDispatcher;
62  
63      /**
64       *
65       */
66      @Requirement
67      private PlexusCipher cipher;
68  
69      /**
70       * <p>Constructor for AbstractMavenExecutor.</p>
71       */
72      protected AbstractMavenExecutor()
73      {
74      }
75  
76      @Override
77      public void executeGoals( File workingDirectory, String goals, ReleaseEnvironment releaseEnvironment,
78                                boolean interactive, String additionalArguments, String pomFileName,
79                                ReleaseResult result )
80          throws MavenExecutorException
81      {
82          List<String> goalsList = new ArrayList<>();
83          if ( goals != null )
84          {
85              // accept both space and comma, so the old way still work
86              // also accept line separators, so that goal lists can be spread
87              // across multiple lines in the POM.
88              for ( String token : StringUtils.split( goals, ", \n\r\t" ) )
89              {
90                  goalsList.add( token );
91              }
92          }
93          executeGoals( workingDirectory, goalsList, releaseEnvironment, interactive, additionalArguments, pomFileName,
94                        result );
95      }
96  
97      protected abstract void executeGoals( File workingDirectory, List<String> goals,
98                                            ReleaseEnvironment releaseEnvironment, boolean interactive,
99                                            String additionalArguments, String pomFileName, ReleaseResult result )
100         throws MavenExecutorException;
101 
102     /**
103      * <p>Getter for the field <code>logger</code>.</p>
104      *
105      * @return a {@link org.codehaus.plexus.logging.Logger} object
106      */
107     protected final Logger getLogger()
108     {
109         return logger;
110     }
111 
112     @Override
113     public void enableLogging( Logger logger )
114     {
115         this.logger = logger;
116     }
117 
118 
119     /**
120      * <p>encryptSettings.</p>
121      *
122      * @param settings a {@link org.apache.maven.settings.Settings} object
123      * @return a {@link org.apache.maven.settings.Settings} object
124      */
125     protected Settings encryptSettings( Settings settings )
126     {
127         Settings encryptedSettings = SettingsUtils.copySettings( settings );
128 
129         for ( Server server : encryptedSettings.getServers() )
130         {
131             String password = server.getPassword();
132             if ( password != null && !isEncryptedString( password ) )
133             {
134                 try
135                 {
136                     server.setPassword( encryptAndDecorate( password ) );
137                 }
138                 catch ( IllegalStateException | SecDispatcherException | PlexusCipherException e )
139                 {
140                     // ignore
141                 }
142             }
143 
144             String passphrase = server.getPassphrase();
145             if ( passphrase != null && !isEncryptedString( passphrase ) )
146             {
147                 try
148                 {
149                     server.setPassphrase( encryptAndDecorate( passphrase ) );
150                 }
151                 catch ( IllegalStateException | SecDispatcherException | PlexusCipherException e )
152                 {
153                     // ignore
154                 }
155             }
156         }
157 
158         for ( Proxy proxy : encryptedSettings.getProxies() )
159         {
160             String password = proxy.getPassword();
161             if ( password != null && !isEncryptedString( password ) )
162             {
163                 try
164                 {
165                     proxy.setPassword( encryptAndDecorate( password ) );
166                 }
167                 catch ( IllegalStateException | SecDispatcherException | PlexusCipherException e )
168                 {
169                     // ignore
170                 }
171             }
172         }
173 
174         return encryptedSettings;
175     }
176 
177     // From org.apache.maven.cli.MavenCli.encryption(CliRequest)
178     private String encryptAndDecorate( String passwd )
179         throws IllegalStateException, SecDispatcherException, PlexusCipherException
180     {
181         String configurationFile = secDispatcher.getConfigurationFile();
182 
183         if ( configurationFile.startsWith( "~" ) )
184         {
185             configurationFile = System.getProperty( "user.home" ) + configurationFile.substring( 1 );
186         }
187 
188         String file = System.getProperty( DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION, configurationFile );
189 
190         String master = null;
191 
192         SettingsSecurity sec = SecUtil.read( file, true );
193         if ( sec != null )
194         {
195             master = sec.getMaster();
196         }
197 
198         if ( master == null )
199         {
200             throw new IllegalStateException( "Master password is not set in the setting security file: " + file );
201         }
202 
203         DefaultPlexusCipher cipher = new DefaultPlexusCipher();
204         String masterPasswd = cipher.decryptDecorated( master, DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION );
205         return cipher.encryptAndDecorate( passwd, masterPasswd );
206     }
207 
208     private boolean isEncryptedString( String str )
209     {
210         return cipher.isEncryptedString( str );
211     }
212 
213     /**
214      * <p>getSettingsWriter.</p>
215      *
216      * @return a {@link org.apache.maven.settings.io.xpp3.SettingsXpp3Writer} object
217      */
218     protected SettingsXpp3Writer getSettingsWriter()
219     {
220         return new SettingsXpp3Writer();
221     }
222 }