View Javadoc
1   package org.apache.maven.it;
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 org.apache.maven.it.util.ResourceExtractor;
23  
24  import java.io.File;
25  import java.util.Collections;
26  import java.util.List;
27  import java.util.Properties;
28  
29  import org.eclipse.jetty.security.ConstraintSecurityHandler;
30  import org.eclipse.jetty.security.HashLoginService;
31  import org.eclipse.jetty.server.NetworkConnector;
32  import org.eclipse.jetty.server.Server;
33  import org.eclipse.jetty.server.handler.DefaultHandler;
34  import org.eclipse.jetty.server.handler.HandlerList;
35  import org.eclipse.jetty.server.handler.ResourceHandler;
36  import org.eclipse.jetty.util.security.Constraint;
37  import org.eclipse.jetty.security.ConstraintMapping;
38  import org.eclipse.jetty.util.security.Password;
39  import org.eclipse.jetty.servlet.ServletContextHandler;
40  
41  import static org.eclipse.jetty.servlet.ServletContextHandler.SECURITY;
42  import static org.eclipse.jetty.servlet.ServletContextHandler.SESSIONS;
43  import static org.eclipse.jetty.util.security.Constraint.__BASIC_AUTH;
44  
45  /**
46   * This is a test set for <a href="https://issues.apache.org/jira/browse/MNG-553">MNG-553</a>.
47   *
48   * @author Benjamin Bentmann
49   */
50  public class MavenITmng0553SettingsAuthzEncryptionTest
51      extends AbstractMavenIntegrationTestCase
52  {
53  
54      private File testDir;
55  
56      private Server server;
57  
58      private int port;
59  
60      public MavenITmng0553SettingsAuthzEncryptionTest()
61      {
62          super( "[2.1.0,3.0-alpha-1),[3.0-alpha-3,)" );
63      }
64  
65      @Override
66      protected void setUp()
67          throws Exception
68      {
69          testDir = ResourceExtractor.simpleExtractResources( getClass(), "/mng-0553" );
70  
71          Constraint constraint = new Constraint( __BASIC_AUTH, "user" );
72          constraint.setAuthenticate( true );
73  
74          ConstraintMapping constraintMapping = new ConstraintMapping();
75          constraintMapping.setConstraint( constraint );
76          constraintMapping.setPathSpec( "/*" );
77  
78          HashLoginService userRealm = new HashLoginService( "TestRealm" );
79          userRealm.putUser( "testuser", new Password( "testtest" ), new String[] { "user" } );
80  
81          server = new Server( 0 );
82          ServletContextHandler ctx = new ServletContextHandler( server, "/", SESSIONS | SECURITY );
83          ConstraintSecurityHandler securityHandler = (ConstraintSecurityHandler) ctx.getSecurityHandler();
84          securityHandler.setLoginService( userRealm );
85          securityHandler.setAuthMethod( __BASIC_AUTH );
86          securityHandler.setConstraintMappings( new ConstraintMapping[] { constraintMapping } );
87  
88          ResourceHandler repoHandler = new ResourceHandler();
89          repoHandler.setResourceBase( new File( testDir, "repo" ).getAbsolutePath() );
90  
91          HandlerList handlerList = new HandlerList();
92          handlerList.addHandler( securityHandler );
93          handlerList.addHandler( repoHandler );
94          handlerList.addHandler( new DefaultHandler() );
95  
96          server.setHandler( handlerList );
97          server.start();
98          if ( server.isFailed() )
99          {
100             fail( "Couldn't bind the server socket to a free port!" );
101         }
102         port = ( (NetworkConnector) server.getConnectors()[0] ).getLocalPort();
103         System.out.println( "Bound server socket to the port " + port );
104     }
105 
106     @Override
107     protected void tearDown()
108         throws Exception
109     {
110         if ( server != null )
111         {
112             server.stop();
113             server.join();
114         }
115     }
116 
117     /**
118      * Test that the encrypted auth infos given in the settings.xml are decrypted.
119      *
120      * @throws Exception in case of failure
121      */
122     public void testitBasic()
123         throws Exception
124     {
125         testDir = new File( testDir, "test-1" );
126 
127         Properties filterProps = new Properties();
128         filterProps.setProperty( "@port@", Integer.toString( port ) );
129 
130         Verifier verifier = newVerifier( testDir.getAbsolutePath() );
131         verifier.setAutoclean( false );
132         verifier.deleteArtifacts( "org.apache.maven.its.mng0553" );
133         verifier.assertArtifactNotPresent( "org.apache.maven.its.mng0553", "a", "0.1-SNAPSHOT", "jar" );
134         verifier.filterFile( "settings-template.xml", "settings.xml", "UTF-8", filterProps );
135         setUserHome( verifier, new File( testDir, "userhome" ) );
136         verifier.addCliOption( "--settings" );
137         verifier.addCliOption( "settings.xml" );
138         verifier.executeGoal( "validate" );
139         verifier.verifyErrorFreeLog();
140         verifier.resetStreams();
141 
142         verifier.assertArtifactPresent( "org.apache.maven.its.mng0553", "a", "0.1-SNAPSHOT", "jar" );
143     }
144 
145     /**
146      * Test that the encrypted auth infos given in the settings.xml are decrypted when the master password resides
147      * in an external file.
148      *
149      * @throws Exception in case of failure
150      */
151     public void testitRelocation()
152         throws Exception
153     {
154         testDir = new File( testDir, "test-2" );
155 
156         Properties filterProps = new Properties();
157         filterProps.setProperty( "@port@", Integer.toString( port ) );
158         // NOTE: The upper-case scheme name is essential part of the test
159         String secUrl = "FILE://" + new File( testDir, "relocated-settings-security.xml" ).toURI().getRawPath();
160         filterProps.setProperty( "@relocation@", secUrl );
161 
162         Verifier verifier = newVerifier( testDir.getAbsolutePath() );
163         verifier.setAutoclean( false );
164         verifier.deleteArtifacts( "org.apache.maven.its.mng0553" );
165         verifier.assertArtifactNotPresent( "org.apache.maven.its.mng0553", "a", "0.1-SNAPSHOT", "jar" );
166 
167         // NOTE: The tilde ~ in the file name is essential part of the test
168         verifier.filterFile( "security-template.xml", "settings~security.xml", "UTF-8", filterProps );
169         verifier.filterFile( "settings-template.xml", "settings.xml", "UTF-8", filterProps );
170 
171         verifier.getSystemProperties().setProperty( "settings.security",
172             new File( testDir, "settings~security.xml" ).getAbsolutePath() );
173         verifier.addCliOption( "--settings" );
174         verifier.addCliOption( "settings.xml" );
175         // NOTE: The selection of the Turkish language for the JVM locale is essential part of the test
176         verifier.executeGoal( "validate", Collections.singletonMap( "MAVEN_OPTS", "-Duser.language=tr" ) );
177         verifier.verifyErrorFreeLog();
178         verifier.resetStreams();
179 
180         verifier.assertArtifactPresent( "org.apache.maven.its.mng0553", "a", "0.1-SNAPSHOT", "jar" );
181     }
182 
183     /**
184      * Test that the CLI supports generation of encrypted (master) passwords.
185      *
186      * @throws Exception in case of failure
187      */
188     public void testitEncryption()
189         throws Exception
190     {
191         requiresMavenVersion( "[2.1.0,3.0-alpha-1),[3.0-alpha-7,)" );
192 
193         testDir = new File( testDir, "test-3" );
194 
195         Verifier verifier = newVerifier( testDir.getAbsolutePath() );
196         verifier.setAutoclean( false );
197         setUserHome( verifier, new File( testDir, "userhome" ) );
198         verifier.addCliOption( "--encrypt-master-password" );
199         verifier.addCliOption( "test" );
200         verifier.setLogFileName( "log-emp.txt" );
201         verifier.executeGoal( "-e" );
202         verifier.verifyErrorFreeLog();
203         verifier.resetStreams();
204 
205         List<String> log = verifier.loadLines( verifier.getLogFileName(), null );
206         assertNotNull( findPassword( log ) );
207 
208         verifier = newVerifier( testDir.getAbsolutePath() );
209         verifier.setAutoclean( false );
210         setUserHome( verifier, new File( testDir, "userhome" ) );
211         verifier.addCliOption( "--encrypt-password" );
212         verifier.addCliOption( "testpass" );
213         verifier.setLogFileName( "log-ep.txt" );
214         verifier.executeGoal( "-e" );
215         verifier.verifyErrorFreeLog();
216         verifier.resetStreams();
217 
218         log = verifier.loadLines( verifier.getLogFileName(), null );
219         assertNotNull( findPassword( log ) );
220     }
221 
222     private String findPassword( List<String> log )
223     {
224         for ( String line : log )
225         {
226             if ( line.matches( ".*\\{[A-Za-z0-9+/=]+\\}.*" ) )
227             {
228                 return line;
229             }
230         }
231 
232         return null;
233     }
234 
235     private void setUserHome( Verifier verifier, File home )
236     {
237         // NOTE: We set the user.home directory instead of say settings.security to reflect Maven's normal behavior
238         String path = home.getAbsolutePath();
239         if ( path.indexOf( ' ' ) < 0 )
240         {
241             verifier.setEnvironmentVariable( "MAVEN_OPTS", "-Duser.home=" + path );
242         }
243         else
244         {
245             verifier.setEnvironmentVariable( "MAVEN_OPTS", "\"-Duser.home=" + path + "\"" );
246         }
247     }
248 }