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.DefaultReleaseEnvironment;
33  import org.apache.maven.shared.release.env.ReleaseEnvironment;
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.SecDispatcherException;
42  import org.sonatype.plexus.components.sec.dispatcher.SecUtil;
43  import org.sonatype.plexus.components.sec.dispatcher.model.SettingsSecurity;
44  
45  public abstract class AbstractMavenExecutor
46      implements MavenExecutor, LogEnabled
47  {
48  
49      private Logger logger;
50  
51      /**
52       * When this plugin requires Maven 3.0 as minimum, this component can be removed and o.a.m.s.c.SettingsDecrypter be
53       * used instead.
54       * 
55       * @plexus.requirement role="org.sonatype.plexus.components.sec.dispatcher.SecDispatcher" role-hint="mng-4384"
56       */
57      private DefaultSecDispatcher secDispatcher;
58  
59      /**
60       * @plexus.requirement
61       */
62      private PlexusCipher cipher;
63      
64      protected AbstractMavenExecutor()
65      {
66      }
67  
68      /** {@inheritDoc} */
69      public void executeGoals( File workingDirectory, String goals, boolean interactive, String additionalArguments,
70                                String pomFileName, ReleaseResult result )
71          throws MavenExecutorException
72      {
73          executeGoals( workingDirectory, goals, new DefaultReleaseEnvironment(), interactive, additionalArguments, pomFileName, result );
74      }
75  
76      /** {@inheritDoc} */
77      public void executeGoals( File workingDirectory, String goals, boolean interactive, String additionalArguments,
78                                ReleaseResult result )
79          throws MavenExecutorException
80      {
81          executeGoals( workingDirectory, goals, new DefaultReleaseEnvironment(), interactive, additionalArguments, result );
82      }
83  
84      /** {@inheritDoc} */
85      public void executeGoals( File workingDirectory, String goals, ReleaseEnvironment releaseEnvironment,
86                                boolean interactive, String arguments, ReleaseResult result )
87          throws MavenExecutorException
88      {
89          executeGoals( workingDirectory, goals, releaseEnvironment, interactive, arguments, null, result );
90      }
91  
92      /** {@inheritDoc} */
93      public void executeGoals( File workingDirectory, String goals, ReleaseEnvironment releaseEnvironment,
94                                boolean interactive, String additionalArguments, String pomFileName, ReleaseResult result )
95          throws MavenExecutorException
96      {
97          List<String> goalsList = new ArrayList<String>();
98          if ( goals != null )
99          {
100             // accept both space and comma, so the old way still work
101             // also accept line separators, so that goal lists can be spread
102             // across multiple lines in the POM.
103             String[] tokens = StringUtils.split( goals, ", \n\r\t" );
104 
105             for ( int i = 0; i < tokens.length; ++i )
106             {
107                 goalsList.add( tokens[i] );
108             }
109         }
110         executeGoals( workingDirectory, goalsList, releaseEnvironment, interactive, additionalArguments, pomFileName, result );
111     }
112 
113     protected abstract void executeGoals( File workingDirectory, List<String> goals, ReleaseEnvironment releaseEnvironment,
114                               boolean interactive, String additionalArguments, String pomFileName, ReleaseResult result )
115         throws MavenExecutorException;
116 
117 
118     protected final Logger getLogger()
119     {
120         return logger;
121     }
122 
123     /** {@inheritDoc} */
124     public void enableLogging( Logger logger )
125     {
126         this.logger = logger;
127     }
128 
129     
130     protected Settings encryptSettings( Settings settings )
131     {
132         Settings encryptedSettings = SettingsUtils.copySettings( settings );
133         
134         for ( Server server : encryptedSettings.getServers() )
135         {
136             String password = server.getPassword(); 
137             if ( password != null && !isEncryptedString( password ) )
138             {
139                 try
140                 {
141                     server.setPassword( encryptAndDecorate( password ) );
142                 }
143                 catch ( IllegalStateException e )
144                 {
145                     // ignore
146                 }
147                 catch ( SecDispatcherException e )
148                 {
149                     // ignore
150                 }
151                 catch ( PlexusCipherException e )
152                 {
153                     // ignore
154                 }
155             }
156 
157             String passphrase = server.getPassphrase(); 
158             if ( passphrase != null && !isEncryptedString( passphrase ) )
159             {
160                 try
161                 {
162                     server.setPassphrase( encryptAndDecorate( passphrase ) );
163                 }
164                 catch ( IllegalStateException e )
165                 {
166                     // ignore
167                 }
168                 catch ( SecDispatcherException e )
169                 {
170                     // ignore
171                 }
172                 catch ( PlexusCipherException e )
173                 {
174                     // ignore
175                 }
176             }
177         }
178         
179         for ( Proxy proxy : encryptedSettings.getProxies() )
180         {
181             String password = proxy.getPassword();
182             if ( password != null && !isEncryptedString( password ) )
183             {
184                 try
185                 {
186                     proxy.setPassword( encryptAndDecorate( password ) );
187                 }
188                 catch ( IllegalStateException e )
189                 {
190                     // ignore
191                 }
192                 catch ( SecDispatcherException e )
193                 {
194                     // ignore
195                 }
196                 catch ( PlexusCipherException e )
197                 {
198                     // ignore
199                 }
200             }
201         }
202         
203         return encryptedSettings;
204     }
205     
206     // From org.apache.maven.cli.MavenCli.encryption(CliRequest)
207     private final String encryptAndDecorate( String passwd ) throws IllegalStateException, SecDispatcherException, PlexusCipherException
208     {
209         String configurationFile = secDispatcher.getConfigurationFile();
210 
211         if ( configurationFile.startsWith( "~" ) )
212         {
213             configurationFile = System.getProperty( "user.home" ) + configurationFile.substring( 1 );
214         }
215 
216         String file = System.getProperty( DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION, configurationFile );
217 
218         String master = null;
219 
220         SettingsSecurity sec = SecUtil.read( file, true );
221         if ( sec != null )
222         {
223             master = sec.getMaster();
224         }
225 
226         if ( master == null )
227         {
228             throw new IllegalStateException( "Master password is not set in the setting security file: " + file );
229         }
230 
231         DefaultPlexusCipher cipher = new DefaultPlexusCipher();
232         String masterPasswd = cipher.decryptDecorated( master, DefaultSecDispatcher.SYSTEM_PROPERTY_SEC_LOCATION );
233         return cipher.encryptAndDecorate( passwd, masterPasswd );
234     }
235     
236     private boolean isEncryptedString( String str )
237     {
238         return cipher.isEncryptedString( str );
239     }
240 
241     protected SettingsXpp3Writer getSettingsWriter()
242     {
243         return new SettingsXpp3Writer();
244     }
245 }