1 package com.atlassian.sal.core.net;
2
3 import com.atlassian.sal.api.net.Request;
4 import com.atlassian.sal.api.net.ResponseException;
5 import com.atlassian.sal.api.user.UserManager;
6 import com.atlassian.sal.core.trusted.CertificateFactory;
7 import com.atlassian.security.auth.trustedapps.EncryptedCertificate;
8 import com.atlassian.security.auth.trustedapps.TrustedApplicationUtils;
9 import org.apache.http.Header;
10 import org.apache.http.HttpClientConnection;
11 import org.apache.http.HttpException;
12 import org.apache.http.HttpRequest;
13 import org.apache.http.HttpResponse;
14 import org.apache.http.HttpStatus;
15 import org.apache.http.ProtocolVersion;
16 import org.apache.http.conn.ConnectionRequest;
17 import org.apache.http.conn.HttpClientConnectionManager;
18 import org.apache.http.conn.routing.HttpRoute;
19 import org.apache.http.entity.StringEntity;
20 import org.apache.http.message.BasicHttpResponse;
21 import org.apache.http.protocol.HttpContext;
22 import org.apache.http.protocol.HttpRequestExecutor;
23 import org.hamcrest.FeatureMatcher;
24 import org.hamcrest.Matcher;
25 import org.junit.Before;
26 import org.junit.Ignore;
27 import org.junit.Rule;
28 import org.junit.Test;
29 import org.junit.rules.ExpectedException;
30 import org.junit.runner.RunWith;
31 import org.mockito.ArgumentCaptor;
32 import org.mockito.Captor;
33 import org.mockito.Mock;
34 import org.mockito.runners.MockitoJUnitRunner;
35
36
37 import java.io.IOException;
38 import java.nio.charset.StandardCharsets;
39 import java.text.MessageFormat;
40 import java.util.concurrent.ExecutionException;
41 import java.util.concurrent.TimeUnit;
42
43 import static org.hamcrest.MatcherAssert.assertThat;
44 import static org.hamcrest.Matchers.arrayContaining;
45 import static org.hamcrest.Matchers.equalTo;
46 import static org.mockito.Matchers.any;
47 import static org.mockito.Matchers.anyInt;
48 import static org.mockito.Matchers.anyObject;
49 import static org.mockito.Matchers.anyString;
50 import static org.mockito.Matchers.eq;
51 import static org.mockito.Mockito.mock;
52 import static org.mockito.Mockito.verify;
53 import static org.mockito.Mockito.when;
54
55 @RunWith (MockitoJUnitRunner.class)
56 public class TestHttpClientTrustedRequest
57 {
58
59 private static final String DUMMY_HOST = "dummy.atlassian.test";
60 private static final String DUMMY_HTTP_URL = MessageFormat.format("http://{0}/", DUMMY_HOST);
61
62 private static final String DUMMY_USERNAME = "dummy";
63 private static final String DUMMY_TRUSTED_TOKEN_ID = "dummy-id";
64
65 @Rule
66 public ExpectedException thrown = ExpectedException.none();
67
68 @Mock
69 private HttpRequestExecutor mockRequestExecutor;
70
71 @Mock
72 private HttpClientConnectionManager mockConnectionManager;
73
74 @Mock
75 private CertificateFactory certificateFactory;
76
77 @Mock
78 private EncryptedCertificate encryptedCertificate;
79
80 @Mock
81 private UserManager userManager;
82
83 private HttpClientTrustedRequestFactory requestFactory;
84
85 @Captor
86 private ArgumentCaptor<HttpRequest> requestCaptor;
87
88 @Before
89 public void setup() throws InterruptedException, ExecutionException, IOException, HttpException
90 {
91 requestFactory = new HttpClientWithMockConnectionTrustedRequestFactory(userManager, certificateFactory, mockConnectionManager, mockRequestExecutor);
92
93
94 when(mockRequestExecutor.execute(any(HttpRequest.class), any(HttpClientConnection.class),
95 any(HttpContext.class))).thenReturn(createOkResponse());
96
97
98 final HttpClientConnection conn = mock(HttpClientConnection.class);
99 final ConnectionRequest connRequest = mock(ConnectionRequest.class);
100 when(connRequest.get(anyInt(), any(TimeUnit.class))).thenReturn(conn);
101 when(mockConnectionManager.requestConnection(any(HttpRoute.class), anyObject())).thenReturn(connRequest);
102
103
104 when(userManager.getRemoteUsername()).thenReturn(DUMMY_USERNAME);
105 when(encryptedCertificate.getID()).thenReturn(DUMMY_TRUSTED_TOKEN_ID);
106 when(certificateFactory.createCertificate(eq(DUMMY_USERNAME), eq(DUMMY_HTTP_URL))).thenReturn(encryptedCertificate);
107 }
108
109 private static HttpResponse createOkResponse()
110 {
111 final BasicHttpResponse response = new BasicHttpResponse(new ProtocolVersion("HTTP", 1, 1), HttpStatus.SC_OK, "OK");
112 response.setEntity(new StringEntity("test body", StandardCharsets.UTF_8));
113 return response;
114 }
115
116
117 @Ignore
118 @Test
119 public void assertThatTrustedTokenHeadersAdded() throws ResponseException, IOException, HttpException
120 {
121 final HttpClientTrustedRequest request = requestFactory.createTrustedRequest(Request.MethodType.GET, DUMMY_HTTP_URL);
122
123 request.addTrustedTokenAuthentication(DUMMY_HOST);
124 request.execute();
125
126 verify(mockRequestExecutor).execute(requestCaptor.capture(), any(HttpClientConnection.class), any(HttpContext.class));
127 final HttpRequest lastRequest = requestCaptor.getValue();
128 final Header[] headers = lastRequest.getHeaders(TrustedApplicationUtils.Header.Request.ID);
129
130
131 assertThat(headers, arrayContaining(headerWithValue(equalTo(DUMMY_TRUSTED_TOKEN_ID))));
132
133 }
134
135 private static Matcher<Header> headerWithValue(final Matcher<String> valueMatcher)
136 {
137 return new FeatureMatcher<Header, String>(valueMatcher, "header with value", "header value")
138 {
139 @Override
140 protected String featureValueOf(final Header header)
141 {
142 return header.getValue();
143 }
144 };
145 }
146 }