11package com .denimgroup .threadfix .cli .endpoints ;
22
3+ import com .denimgroup .threadfix .data .entities .RouteParameter ;
4+ import com .denimgroup .threadfix .data .entities .RouteParameterType ;
35import com .denimgroup .threadfix .data .interfaces .Endpoint ;
46import com .denimgroup .threadfix .framework .util .PathUtil ;
57
68import java .io .IOException ;
7- import java .net .HttpURLConnection ;
8- import java .net .MalformedURLException ;
9- import java .net .URL ;
10- import java .net .URLConnection ;
9+ import java .io .OutputStream ;
10+ import java .io .UnsupportedEncodingException ;
11+ import java .net .*;
12+ import java .nio .charset .StandardCharsets ;
13+ import java .util .List ;
14+ import java .util .Map ;
15+ import java .util .StringJoiner ;
16+
17+ import static com .denimgroup .threadfix .CollectionUtils .list ;
18+ import static com .denimgroup .threadfix .CollectionUtils .map ;
1119
1220public class EndpointTester {
1321 String basePath ;
@@ -16,12 +24,171 @@ public EndpointTester(String basePath) {
1624 this .basePath = basePath ;
1725 }
1826
19- public int test (Endpoint endpoint ) throws IOException {
27+ public int test (Endpoint endpoint , Credentials credentials ) throws IOException {
2028 URL url = new URL (PathUtil .combine (this .basePath , endpoint .getUrlPath ()));
2129 HttpURLConnection conn = (HttpURLConnection )url .openConnection ();
2230 conn .setRequestMethod (endpoint .getHttpMethod ());
2331
32+ if (credentials != null && credentials .authenticatedParameters != null ) {
33+ for (Map .Entry <String , String > header : credentials .authenticatedParameters .entrySet ()) {
34+ conn .setRequestProperty (header .getKey (), header .getValue ());
35+ }
36+ }
37+
2438 conn .getInputStream ().close ();
2539 return conn .getResponseCode ();
2640 }
41+
42+ public int authorize (Credentials credentials , Endpoint endpoint ) throws IOException {
43+ // Get query settings
44+ String httpMethod = endpoint != null ? endpoint .getHttpMethod () : "POST" ;
45+
46+ HttpURLConnection .setFollowRedirects (false );
47+
48+ // Try auth by best-match
49+
50+ if (endpoint != null ) {
51+ try {
52+ String urlParams = configureRequestWithBestMatchParameters (endpoint .getParameters (), credentials , null );
53+ String finalizedPath = credentials .authenticationEndpoint ;
54+ if (!urlParams .isEmpty ()) {
55+ finalizedPath += "?" + urlParams ;
56+ }
57+
58+ URL url = new URL (PathUtil .combine (this .basePath , finalizedPath ));
59+ // Configure connection
60+ HttpURLConnection conn = (HttpURLConnection )url .openConnection ();
61+ conn .setRequestMethod (httpMethod );
62+ configureRequestWithBestMatchParameters (endpoint .getParameters (), credentials , conn );
63+
64+ conn .getInputStream ().close ();
65+ if (conn .getResponseCode () < 400 && saveCredentialsResponse (conn , credentials )) {
66+ return conn .getResponseCode ();
67+ }
68+ } catch (IOException e ) {
69+ System .out .println ("Unable to authorize using best-match parameters:" );
70+ e .printStackTrace ();
71+ }
72+ }
73+
74+ try {
75+ URL url = new URL (PathUtil .combine (this .basePath , credentials .authenticationEndpoint ));
76+ HttpURLConnection conn = (HttpURLConnection )url .openConnection ();
77+ conn .setRequestMethod (httpMethod );
78+ configureRequestWithFormParameters (credentials , conn );
79+
80+ conn .getInputStream ().close ();
81+ if (conn .getResponseCode () < 400 && saveCredentialsResponse (conn , credentials )) {
82+ return conn .getResponseCode ();
83+ }
84+ } catch (IOException e ) {
85+ System .out .println ("Unable to authorize using all-forms parameters:" );
86+ e .printStackTrace ();
87+ }
88+
89+ return -1 ;
90+ }
91+
92+ private boolean saveCredentialsResponse (HttpURLConnection conn , Credentials creds ) {
93+ if (conn .getHeaderField ("Set-Cookie" ) != null ) {
94+ List <String > cookies = conn .getHeaderFields ().get ("Set-Cookie" );
95+ List <String > sanitizeCookies = list ();
96+
97+ for (String cookie : cookies ) {
98+ String mainPart = cookie ;
99+ if (mainPart .contains (";" )) {
100+ mainPart = mainPart .substring (0 , mainPart .indexOf (';' ));
101+ }
102+ sanitizeCookies .add (mainPart );
103+ }
104+
105+ creds .authenticatedParameters = map ();
106+ creds .authenticatedParameters .put ("Cookie" , String .join ("; " , sanitizeCookies ));
107+
108+ return true ;
109+ }
110+ return false ;
111+ }
112+
113+ private String configureRequestWithBestMatchParameters (Map <String , RouteParameter > parsedParameters , Credentials credentials , HttpURLConnection conn ) throws IOException {
114+ StringJoiner queryString = new StringJoiner ("&" );
115+ StringJoiner formParams = new StringJoiner ("&" );
116+
117+ for (Map .Entry <String , String > credParam : credentials .parameters .entrySet ()) {
118+ RouteParameter paramSpec = null ;
119+ if (parsedParameters != null ) {
120+ if (parsedParameters .containsKey (credParam .getKey ())) {
121+ paramSpec = parsedParameters .get (credParam .getKey ());
122+ }
123+ }
124+
125+ if (paramSpec == null ) {
126+ paramSpec = RouteParameter .fromDataType (credParam .getKey (), "String" );
127+ paramSpec .setParamType (RouteParameterType .FORM_DATA );
128+ }
129+
130+ String encodedKey , encodedValue ;
131+ try {
132+ encodedKey = URLEncoder .encode (credParam .getKey (), "UTF-8" );
133+ encodedValue = URLEncoder .encode (credParam .getValue (), "UTF-8" );
134+ } catch (UnsupportedEncodingException e ) {
135+ e .printStackTrace ();
136+ continue ;
137+ }
138+
139+ String encodedPair = encodedKey + "=" + encodedValue ;
140+
141+ switch (paramSpec .getParamType ()) {
142+ case QUERY_STRING :
143+ queryString .add (encodedPair );
144+ break ;
145+
146+ default :
147+ // Assume form data for anything else
148+ formParams .add (encodedPair );
149+ }
150+ }
151+
152+ if (formParams .length () > 0 && conn != null ) {
153+
154+ byte [] out = formParams .toString ().getBytes (StandardCharsets .UTF_8 );
155+
156+ conn .setDoOutput (true );
157+ conn .setFixedLengthStreamingMode (out .length );
158+ conn .setRequestProperty ("Content-Type" , "application/x-www-form-urlencoded; charset=UTF-8" );
159+
160+ conn .connect ();
161+ try (OutputStream os = conn .getOutputStream ()) {
162+ os .write (out );
163+ }
164+ }
165+
166+ if (queryString .length () == 0 ) {
167+ return "" ;
168+ } else {
169+ return "?" + queryString .toString ();
170+ }
171+ }
172+
173+ private void configureRequestWithFormParameters (Credentials credentials , HttpURLConnection conn ) throws IOException {
174+ StringJoiner joiner = new StringJoiner ("&" );
175+ for (Map .Entry <String , String > param : credentials .parameters .entrySet ()) {
176+ try {
177+ joiner .add (URLEncoder .encode (param .getKey (), "UTF-8" ) + "=" + URLEncoder .encode (param .getValue (), "UTF-8" ));
178+ } catch (UnsupportedEncodingException e ) {
179+ e .printStackTrace ();
180+ }
181+ }
182+
183+ byte [] out = joiner .toString ().getBytes (StandardCharsets .UTF_8 );
184+
185+ conn .setDoOutput (true );
186+ conn .setFixedLengthStreamingMode (out .length );
187+ conn .setRequestProperty ("Content-Type" , "application/x-www-form-urlencoded; charset=UTF-8" );
188+
189+ conn .connect ();
190+ try (OutputStream os = conn .getOutputStream ()) {
191+ os .write (out );
192+ }
193+ }
27194}
0 commit comments