1 package org.apache.maven.it;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.it.util.ResourceExtractor;
23 import org.apache.maven.it.utils.DeployedResource;
24 import org.codehaus.plexus.util.StringUtils;
25 import org.eclipse.jetty.security.ConstraintMapping;
26 import org.eclipse.jetty.security.ConstraintSecurityHandler;
27 import org.eclipse.jetty.security.HashLoginService;
28 import org.eclipse.jetty.server.Handler;
29 import org.eclipse.jetty.server.NetworkConnector;
30 import org.eclipse.jetty.server.Request;
31 import org.eclipse.jetty.server.Server;
32 import org.eclipse.jetty.server.handler.AbstractHandler;
33 import org.eclipse.jetty.server.handler.HandlerList;
34 import org.eclipse.jetty.servlet.ServletContextHandler;
35 import org.eclipse.jetty.util.B64Code;
36 import org.eclipse.jetty.util.security.Constraint;
37 import org.eclipse.jetty.util.security.Password;
38
39 import javax.servlet.http.HttpServletRequest;
40 import javax.servlet.http.HttpServletResponse;
41 import java.io.File;
42 import java.nio.charset.StandardCharsets;
43 import java.util.Collections;
44 import java.util.Deque;
45 import java.util.concurrent.ConcurrentLinkedDeque;
46
47 import static org.eclipse.jetty.servlet.ServletContextHandler.SECURITY;
48 import static org.eclipse.jetty.servlet.ServletContextHandler.SESSIONS;
49 import static org.eclipse.jetty.util.security.Constraint.__BASIC_AUTH;
50
51
52
53
54
55
56
57 public class MavenITmng4470AuthenticatedDeploymentToProxyTest
58 extends AbstractMavenIntegrationTestCase
59 {
60 private Server server;
61
62 private int port;
63
64 private volatile boolean deployed;
65
66 private final Deque<DeployedResource> deployedResources = new ConcurrentLinkedDeque<>();
67
68 public MavenITmng4470AuthenticatedDeploymentToProxyTest()
69 {
70 super( "[2.0.3,3.0-alpha-1),[3.0-alpha-6,)" );
71 }
72
73 @Override
74 protected void setUp()
75 throws Exception
76 {
77 Handler proxyHandler = new AbstractHandler()
78 {
79 @Override
80 public void handle( String target, Request baseRequest, HttpServletRequest request,
81 HttpServletResponse response )
82 {
83 System.out.println( "Handling " + request.getMethod() + " " + request.getRequestURL() );
84
85 String auth = request.getHeader( "Proxy-Authorization" );
86 if ( auth != null )
87 {
88 auth = auth.substring( auth.indexOf( ' ' ) + 1 ).trim();
89 auth = B64Code.decode( auth, StandardCharsets.US_ASCII.name() );
90 }
91 System.out.println( "Proxy-Authorization: " + auth );
92
93 if ( !"proxyuser:proxypass".equals( auth ) )
94 {
95 response.setStatus( HttpServletResponse.SC_PROXY_AUTHENTICATION_REQUIRED );
96 response.addHeader( "Proxy-Authenticate", "Basic realm=\"Squid proxy-caching web server\"" );
97 ( (Request) request ).setHandled( true );
98 }
99
100 DeployedResource deployedResource = new DeployedResource();
101
102 deployedResource.httpMethod = request.getMethod();
103 deployedResource.requestUri = request.getRequestURI();
104 deployedResource.transferEncoding = request.getHeader( "Transfer-Encoding" );
105 deployedResource.contentLength = request.getHeader( "Content-Length" );
106
107 deployedResources.add( deployedResource );
108 }
109 };
110
111 Handler repoHandler = new AbstractHandler()
112 {
113 @Override
114 public void handle( String target, Request baseRequest, HttpServletRequest request,
115 HttpServletResponse response )
116 {
117 System.out.println( "Handling " + request.getMethod() + " " + request.getRequestURL() );
118
119 if ( "PUT".equalsIgnoreCase( request.getMethod() ) )
120 {
121 response.setStatus( HttpServletResponse.SC_OK );
122 deployed = true;
123 }
124 else
125 {
126 response.setStatus( HttpServletResponse.SC_NOT_FOUND );
127 }
128
129 ( (Request) request ).setHandled( true );
130
131 DeployedResource deployedResource = new DeployedResource();
132
133 deployedResource.httpMethod = request.getMethod();
134 deployedResource.requestUri = request.getRequestURI();
135 deployedResource.transferEncoding = request.getHeader( "Transfer-Encoding" );
136 deployedResource.contentLength = request.getHeader( "Content-Length" );
137
138 deployedResources.add( deployedResource );
139 }
140 };
141
142 Constraint constraint = new Constraint();
143 constraint.setName( Constraint.__BASIC_AUTH );
144 constraint.setRoles( new String[]{ "deployer" } );
145 constraint.setAuthenticate( true );
146
147 ConstraintMapping constraintMapping = new ConstraintMapping();
148 constraintMapping.setConstraint( constraint );
149 constraintMapping.setPathSpec( "/*" );
150
151 HashLoginService userRealm = new HashLoginService( "TestRealm" );
152 userRealm.putUser( "testuser", new Password( "testtest" ), new String[] { "deployer" } );
153
154 server = new Server( 0 );
155 ServletContextHandler ctx = new ServletContextHandler( server, "/", SESSIONS | SECURITY );
156 ConstraintSecurityHandler securityHandler = (ConstraintSecurityHandler) ctx.getSecurityHandler();
157 securityHandler.setLoginService( userRealm );
158 securityHandler.setAuthMethod( __BASIC_AUTH );
159 securityHandler.setConstraintMappings( new ConstraintMapping[] { constraintMapping } );
160
161 HandlerList handlerList = new HandlerList();
162 handlerList.addHandler( proxyHandler );
163 handlerList.addHandler( securityHandler );
164 handlerList.addHandler( repoHandler );
165
166 server.setHandler( handlerList );
167 server.start();
168 if ( server.isFailed() )
169 {
170 fail( "Couldn't bind the server socket to a free port!" );
171 }
172 port = ( (NetworkConnector) server.getConnectors()[0] ).getLocalPort();
173 System.out.println( "Bound server socket to the port " + port );
174 deployed = false;
175 }
176
177 @Override
178 protected void tearDown()
179 throws Exception
180 {
181 if ( server != null )
182 {
183 server.stop();
184 server.join();
185 }
186 }
187
188
189
190
191
192
193 public void testitRelease()
194 throws Exception
195 {
196 testit( "release" );
197 }
198
199
200
201
202
203
204 public void testitSnapshot()
205 throws Exception
206 {
207 testit( "snapshot" );
208 }
209
210 private void testit( String project )
211 throws Exception
212 {
213 File testDir = ResourceExtractor.simpleExtractResources( getClass(), "/mng-4470/" + project );
214
215 Verifier verifier = newVerifier( testDir.getAbsolutePath() );
216 verifier.setAutoclean( false );
217 verifier.filterFile( "settings-template.xml", "settings.xml", "UTF-8",
218 Collections.singletonMap( "@port@", Integer.toString( port ) ) );
219 verifier.addCliOption( "--settings" );
220 verifier.addCliOption( "settings.xml" );
221 verifier.executeGoal( "validate" );
222 verifier.verifyErrorFreeLog();
223 verifier.resetStreams();
224
225 for ( DeployedResource deployedResource : deployedResources )
226 {
227 if ( StringUtils.equalsIgnoreCase( "chunked", deployedResource.transferEncoding ) )
228 {
229 fail( "deployedResource " + deployedResource
230 + " use chuncked transfert encoding some http server doesn't support that" );
231 }
232 }
233
234 assertTrue( deployed );
235 }
236 }