Disable Basic Authentication in JIRA connector once JSESSIONID cookie was received to maintain session

This commit is contained in:
Mikhail Golubev
2014-04-10 13:30:47 +04:00
parent 33da443b53
commit 36825935ed
4 changed files with 49 additions and 28 deletions
@@ -76,6 +76,9 @@ public abstract class BaseRepositoryImpl extends BaseRepository {
client.getParams().setCredentialCharset("UTF-8");
client.getParams().setAuthenticationPreemptive(true);
client.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(getUsername(), getPassword()));
} else {
client.getState().clearCredentials();
client.getParams().setAuthenticationPreemptive(false);
}
}
@@ -18,10 +18,7 @@ import com.intellij.tasks.jira.rest.JiraRestApi;
import com.intellij.tasks.jira.soap.JiraSoapApi;
import com.intellij.util.ArrayUtil;
import com.intellij.util.xmlb.annotations.Tag;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.cookie.CookiePolicy;
import org.apache.commons.httpclient.methods.GetMethod;
import org.jetbrains.annotations.NotNull;
@@ -54,10 +51,13 @@ public class JiraRepository extends BaseRepositoryImpl {
*/
@SuppressWarnings({"UnusedDeclaration"})
public JiraRepository() {
myUseHttpAuthentication = true;
}
public JiraRepository(JiraRepositoryType type) {
super(type);
// Use Basic authentication at the beginning of new session and disable then if needed
myUseHttpAuthentication = true;
}
private JiraRepository(JiraRepository other) {
@@ -131,7 +131,7 @@ public class JiraRepository extends BaseRepositoryImpl {
@NotNull
public JiraRemoteApi discoverApiVersion() throws Exception {
if (LEGACY_API_ONLY) {
LOG.warn("Intentionally using only legacy JIRA API");
LOG.info("Intentionally using only legacy JIRA API");
return new JiraSoapApi(this);
}
@@ -166,22 +166,32 @@ public class JiraRepository extends BaseRepositoryImpl {
}
}
// Used primarily for XML_RPC API
@NotNull
public String executeMethod(@NotNull HttpMethod method) throws Exception {
return executeMethod(getHttpClient(), method);
}
@NotNull
public String executeMethod(@NotNull HttpClient client, @NotNull HttpMethod method) throws Exception {
LOG.debug("URI: " + method.getURI());
int statusCode;
String entityContent;
statusCode = client.executeMethod(method);
HttpClient client = getHttpClient();
// Fix for https://jetbrains.zendesk.com/agent/#/tickets/24566
// See https://confluence.atlassian.com/display/ONDEMANDKB/Getting+randomly+logged+out+of+OnDemand for details
boolean cookieAuthenticated = false;
for (Cookie cookie : client.getState().getCookies()) {
if (cookie.getName().equals("JSESSIONID") && !cookie.isExpired()) {
cookieAuthenticated = true;
break;
}
}
// disable subsequent basic authorization attempts if user already was authenticated
boolean enableBasicAuthentication = !(isRestApiSupported() && cookieAuthenticated);
if (enableBasicAuthentication != isUseHttpAuthentication()) {
LOG.info("Basic authentication for subsequent requests was " + (enableBasicAuthentication ? "enabled" : "disabled"));
}
setUseHttpAuthentication(enableBasicAuthentication);
int statusCode = client.executeMethod(method);
LOG.debug("Status code: " + statusCode);
// may be null if 204 No Content received
final InputStream stream = method.getResponseBodyAsStream();
entityContent = stream == null ? "" : StreamUtil.readText(stream, CharsetToolkit.UTF8);
String entityContent = stream == null ? "" : StreamUtil.readText(stream, CharsetToolkit.UTF8);
TaskUtil.prettyFormatJsonToLog(LOG, entityContent);
// besides SC_OK, can also be SC_NO_CONTENT in issue transition requests
// see: JiraRestApi#setTaskStatus
@@ -221,14 +231,6 @@ public class JiraRepository extends BaseRepositoryImpl {
return super.getHttpClient();
}
/**
* Always use Basic HTTP authentication for JIRA REST interface
*/
@Override
public boolean isUseHttpAuthentication() {
return true;
}
@Override
protected void configureHttpClient(HttpClient client) {
super.configureHttpClient(client);
@@ -238,17 +240,22 @@ public class JiraRepository extends BaseRepositoryImpl {
@Override
protected int getFeatures() {
int features = super.getFeatures();
if (myApiVersion == null || myApiVersion.getType() == JiraRemoteApi.ApiType.SOAP) {
return features & ~NATIVE_SEARCH & ~STATE_UPDATING & ~TIME_MANAGEMENT;
} else {
if (isRestApiSupported()) {
return features | TIME_MANAGEMENT | STATE_UPDATING;
}
else {
return features & ~NATIVE_SEARCH & ~STATE_UPDATING & ~TIME_MANAGEMENT;
}
}
public boolean isJqlSupported() {
private boolean isRestApiSupported() {
return myApiVersion != null && myApiVersion.getType() != JiraRemoteApi.ApiType.SOAP;
}
public boolean isJqlSupported() {
return isRestApiSupported();
}
public String getSearchQuery() {
return mySearchQuery;
}
@@ -30,7 +30,7 @@ public abstract class JiraRestApi extends JiraRemoteApi {
private static final Logger LOG = Logger.getInstance(JiraRestApi.class);
public static JiraRestApi fromJiraVersion(@NotNull JiraVersion jiraVersion, @NotNull JiraRepository repository) {
LOG.debug("JIRA version is " + jiraVersion);
LOG.info("JIRA version is " + jiraVersion);
if (jiraVersion.getMajorNumber() == 4 && jiraVersion.getMinorNumber() >= 2) {
return new JiraRestApi20Alpha1(repository);
}
@@ -28,6 +28,8 @@ import com.intellij.tasks.impl.TaskUtil;
import com.intellij.tasks.jira.JiraRepository;
import com.intellij.tasks.jira.JiraRepositoryType;
import com.intellij.tasks.jira.JiraVersion;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.jetbrains.annotations.NonNls;
@@ -101,6 +103,15 @@ public class JiraIntegrationTest extends TaskManagerTestCase {
}
}
public void testBasicAuthenticationDisabling() throws Exception {
assertTrue("Basic authentication should be enabled at first", myRepository.isUseHttpAuthentication());
myRepository.findTask("PRJONE-1");
assertFalse("Basic authentication should be disabled once JSESSIONID cookie was received", myRepository.isUseHttpAuthentication());
HttpClient client = myRepository.getHttpClient();
assertFalse(client.getParams().isAuthenticationPreemptive());
assertNull(client.getState().getCredentials(AuthScope.ANY));
}
public void testSetTaskState() throws Exception {
changeStateAndCheck(JIRA_4_TEST_SERVER_URL, "PRJONE-8");
changeStateAndCheck(JIRA_5_TEST_SERVER_URL, "UT-8");