View Javadoc

1   /*
2    * Copyright 2012 smartics, Kronseder & Reiner GmbH
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package de.smartics.ci.comm.hudson.command;
17  
18  import org.apache.commons.httpclient.HttpClient;
19  import org.apache.commons.httpclient.HttpState;
20  import org.apache.commons.httpclient.NTCredentials;
21  import org.apache.commons.httpclient.auth.AuthScope;
22  import org.apache.commons.httpclient.methods.GetMethod;
23  import org.apache.commons.httpclient.methods.PostMethod;
24  
25  import de.smartics.ci.comm.CiSystem;
26  import de.smartics.ci.comm.Credentials;
27  import de.smartics.ci.comm.ProxyCredentials;
28  import de.smartics.ci.comm.ProxyInformation;
29  import de.smartics.ci.comm.command.CommandException;
30  import de.smartics.ci.comm.command.AbstractLoginCommand;
31  import de.smartics.ci.comm.command.LoginCommandException;
32  
33  /**
34   * Implements the login command for a hudson ci server.
35   */
36  public final class HudsonLoginCommand extends
37      AbstractLoginCommand<HudsonLoginCommand>
38  {
39    // ********************************* Fields *********************************
40  
41    // --- constants ------------------------------------------------------------
42  
43    /**
44     * The credentials used to login.
45     */
46    private Credentials loginCredentials;
47  
48    /**
49     * The information needed for a proxy.
50     */
51    private ProxyInformation proxyInformation;
52  
53    // --- members --------------------------------------------------------------
54  
55    // ****************************** Initializer *******************************
56  
57    // ****************************** Constructors ******************************
58  
59    /**
60     * Default constructor.
61     *
62     * @param loginCredentials the credentials used to login.
63     * @param proxyInformation the information needed for a proxy.
64     */
65    public HudsonLoginCommand(final Credentials loginCredentials,
66        final ProxyInformation proxyInformation)
67    {
68      this.loginCredentials = loginCredentials;
69      this.proxyInformation = proxyInformation;
70    }
71  
72    /**
73     * Default constructor. Sets credentials and proxyinfo to null;
74     */
75    public HudsonLoginCommand()
76    {
77      this(null, null);
78    }
79  
80    // ****************************** Inner Classes *****************************
81  
82    // ********************************* Methods ********************************
83  
84    // --- init -----------------------------------------------------------------
85  
86    // --- get&set --------------------------------------------------------------
87  
88    /**
89     * Sets the information needed for a proxy.
90     *
91     * @param proxyInformation the information needed for a proxy.
92     */
93    public void setProxyInformation(final ProxyInformation proxyInformation)
94    {
95      this.proxyInformation = proxyInformation;
96    }
97  
98    /**
99     * Sets the credentials used to login.
100    *
101    * @param loginCredentials the credentials used to login.
102    */
103   public void setLoginCredentials(final Credentials loginCredentials)
104   {
105     this.loginCredentials = loginCredentials;
106   }
107 
108   // --- business -------------------------------------------------------------
109 
110   @Override
111   public void execute(final CiSystem target) throws LoginCommandException
112   {
113     handleProxy(target.getClient());
114     handleLogin(target);
115   }
116 
117   private void handleProxy(final HttpClient client)
118   {
119     if (checkIfProxyIsConfigured())
120     {
121       configureProxybaseInformation(client);
122       configureProxyCredentials(client);
123     }
124   }
125 
126   private void handleLogin(final CiSystem target) throws LoginCommandException
127   {
128     final String hostName = target.getUrl();
129     final GetMethod method = new GetMethod(buildLoginUrl(hostName));
130 
131     try
132     {
133       int statusCode = target.execute(method);
134       checkResult(statusCode);
135       String location = hostName + "/j_acegi_security_check";
136       while (true)
137       {
138         final PostMethod loginMethod = new PostMethod(location);
139         final String userName = loginCredentials.getUserName();
140         final String password = loginCredentials.getPassword();
141 
142         loginMethod.addParameter("j_username", userName);
143         loginMethod.addParameter("j_password", password);
144 
145         loginMethod.addParameter("action", "login");
146 
147         statusCode = target.execute(loginMethod);
148         if (statusCode / ERROR_CATEGORY_DESTINGUISHER == 3)
149         {
150           location = loginMethod.getResponseHeader("Location").getValue();
151           continue;
152         }
153         checkResult(statusCode);
154         break;
155       }
156     }
157     catch (final CommandException e)
158     {
159       throw new LoginCommandException(
160           "Login failed, due to a Hudson failure response. Connecting to': "
161               + buildLoginUrl(hostName), e);
162     }
163   }
164 
165   private String buildLoginUrl(final String hostName)
166   {
167     return hostName + "/loginEntry";
168   }
169 
170   private boolean checkIfProxyIsConfigured()
171   {
172     return proxyInformation != null;
173   }
174 
175   private void configureProxyCredentials(final HttpClient client)
176   {
177     final HttpState state = new HttpState();
178     final AuthScope authScope = new AuthScope(null, -1, AuthScope.ANY_REALM);
179     final ProxyCredentials credentials = proxyInformation.getCredentials();
180     final String userName = credentials.getUserName();
181     final String password = credentials.getPassword();
182     final String clientName = credentials.getClientName();
183     final String domain = credentials.getDomain();
184 
185     state.setProxyCredentials(authScope, new NTCredentials(userName, password,
186         clientName, domain));
187     client.setState(state);
188   }
189 
190   private void configureProxybaseInformation(final HttpClient client)
191   {
192     final String host = proxyInformation.getHost();
193     final int port = proxyInformation.getPort();
194     client.getHostConfiguration().setProxy(host, port);
195   }
196 
197   // --- object basics --------------------------------------------------------
198 
199 }