3
3
*/
4
4
package com .topcoder .direct .services .view .action ;
5
5
6
- import com .topcoder .direct .services .configs .ServerConfiguration ;
7
6
import com .topcoder .direct .services .view .dto .contest .ContestStatus ;
8
- import com .topcoder .direct .services .view .dto .my .SingleRestResult ;
9
- import com .topcoder .direct .services .view .dto .my .Token ;
10
7
import com .topcoder .direct .services .view .dto .project .ProjectBriefDTO ;
11
- import com .topcoder .direct .services .view .exception .JwtAuthenticationException ;
12
8
import com .topcoder .direct .services .view .util .DataProvider ;
13
9
import com .topcoder .direct .services .view .util .DirectUtils ;
10
+ import com .topcoder .direct .services .view .util .JwtTokenUpdater ;
14
11
import com .topcoder .security .TCSubject ;
15
- import org .apache .commons .codec .binary .Base64 ;
16
12
import org .apache .http .HttpEntity ;
17
13
import org .apache .http .HttpHeaders ;
18
14
import org .apache .http .HttpResponse ;
19
15
import org .apache .http .HttpStatus ;
20
16
import org .apache .http .client .methods .HttpGet ;
21
- import org .apache .http .client .methods .HttpPost ;
22
17
import org .apache .http .client .utils .URIBuilder ;
23
- import org .apache .http .entity .StringEntity ;
24
18
import org .apache .http .impl .client .DefaultHttpClient ;
25
19
import org .apache .log4j .Logger ;
26
- import org .apache .struts2 .ServletActionContext ;
27
20
import org .codehaus .jackson .JsonNode ;
28
21
import org .codehaus .jackson .map .DeserializationConfig ;
29
22
import org .codehaus .jackson .map .ObjectMapper ;
30
23
31
- import javax .servlet .http .Cookie ;
32
24
import java .io .UnsupportedEncodingException ;
33
25
import java .net .URI ;
34
26
import java .net .URISyntaxException ;
35
27
import java .net .URLEncoder ;
36
- import java .nio .charset .StandardCharsets ;
37
28
import java .text .SimpleDateFormat ;
38
- import java .util .*;
29
+ import java .util .ArrayList ;
30
+ import java .util .LinkedHashMap ;
31
+ import java .util .List ;
32
+ import java .util .Map ;
39
33
40
34
/**
41
35
* <p>
@@ -108,11 +102,6 @@ public abstract class ServiceBackendDataTablesAction extends AbstractAction {
108
102
*/
109
103
private String serviceURL ;
110
104
111
- /**
112
- * authorization Url
113
- */
114
- private String authorizationURL ;
115
-
116
105
/**
117
106
* The challenge types options in filter panel
118
107
*
@@ -196,11 +185,6 @@ public abstract class ServiceBackendDataTablesAction extends AbstractAction {
196
185
*/
197
186
private String endDateTo ;
198
187
199
- /**
200
- * ssoLogin Url
201
- */
202
- private String ssoLoginUrl ;
203
-
204
188
/**
205
189
* The max pagination size.
206
190
*/
@@ -227,14 +211,14 @@ public abstract class ServiceBackendDataTablesAction extends AbstractAction {
227
211
protected static final String ERROR_MESSAGE_FORMAT = "Service URL:%s, HTTP Status Code:%d, Error Message:%s" ;
228
212
229
213
/**
230
- * URI params for refresh token
214
+ * The jackson object mapping which is used to deserialize json return from API to domain model.
231
215
*/
232
- private final String AUTHORIZATION_PARAMS = "{ \" param \" : { \" externalToken \" : \" %s \" }}" ;
216
+ protected static final ObjectMapper objectMapper ;
233
217
234
218
/**
235
- * The jackson object mapping which is used to deserialize json return from API to domain model.
219
+ * JwtTokenUpdater
236
220
*/
237
- protected static final ObjectMapper objectMapper ;
221
+ private JwtTokenUpdater jwtTokenUpdater ;
238
222
239
223
/**
240
224
* <p>A static <code>Map</code> mapping the existing contest statuses to their textual presentations.</p>
@@ -339,19 +323,10 @@ protected JsonNode getJsonResultFromAPI(URI apiEndPoint) throws Exception {
339
323
// specify the get request
340
324
HttpGet getRequest = new HttpGet (apiEndPoint );
341
325
342
- Cookie jwtCookieV3 = DirectUtils .getCookieFromRequest (ServletActionContext .getRequest (),
343
- ServerConfiguration .JWT_V3_COOKIE_KEY );
344
- Cookie jwtCookieV2 = DirectUtils .getCookieFromRequest (ServletActionContext .getRequest (),
345
- ServerConfiguration .JWT_COOOKIE_KEY );
346
-
347
- if (jwtCookieV2 == null ) {
348
- throw new JwtAuthenticationException ("Please re-login" );
349
- }
350
-
351
- validateCookieV2V3 (jwtCookieV2 ,jwtCookieV3 );
326
+ String token = jwtTokenUpdater .check ().getToken ();
352
327
353
328
getRequest .setHeader (HttpHeaders .AUTHORIZATION ,
354
- "Bearer " + jwtCookieV3 . getValue () );
329
+ "Bearer " + token );
355
330
356
331
getRequest .addHeader (HttpHeaders .ACCEPT , "application/json" );
357
332
@@ -728,143 +703,11 @@ public void setEndDateTo(String endDateTo) {
728
703
this .endDateTo = endDateTo ;
729
704
}
730
705
731
- /**
732
- * Getter for {@link #authorizationURL}
733
- * @return authorizationURL
734
- */
735
- public String getAuthorizationURL () {
736
- return authorizationURL ;
706
+ public JwtTokenUpdater getJwtTokenUpdater () {
707
+ return jwtTokenUpdater ;
737
708
}
738
709
739
- /**
740
- * Setter for {@link #authorizationURL}
741
- * @param authorizationURL
742
- */
743
- public void setAuthorizationURL (String authorizationURL ) {
744
- this .authorizationURL = authorizationURL ;
745
- }
746
-
747
- /**
748
- * Get Full SSO login url
749
- * @return
750
- */
751
- public String getSsoLoginUrl () {
752
- try {
753
- URIBuilder builder = new URIBuilder (ssoLoginUrl );
754
- builder .addParameter ("next" , ServletActionContext .getRequest ().getRequestURL ().toString ());
755
- return builder .build ().toString ();
756
- } catch (Exception e ) {
757
- return ssoLoginUrl ;
758
- }
759
- }
760
-
761
- /**
762
- * Setter {@link #ssoLoginUrl}
763
- *
764
- * @param ssoLoginUrl
765
- */
766
- public void setSsoLoginUrl (String ssoLoginUrl ) {
767
- this .ssoLoginUrl = ssoLoginUrl ;
768
- }
769
-
770
- /**
771
- * Refresh token from API endpoint
772
- *
773
- * @param oldToken
774
- * @return
775
- * @throws Exception
776
- */
777
- private Token getRefreshTokenFromApi (String oldToken ) throws Exception {
778
- DefaultHttpClient httpClient = new DefaultHttpClient ();
779
- SingleRestResult <Token > resultToken = null ;
780
- try {
781
- URI authorizationUri = new URI (getAuthorizationURL ());
782
- HttpPost httpPost = new HttpPost (authorizationUri );
783
- httpPost .addHeader (HttpHeaders .CONTENT_TYPE , "application/json" );
784
-
785
- StringEntity body = new StringEntity (String .format (AUTHORIZATION_PARAMS , oldToken ));
786
- httpPost .setEntity (body );
787
- HttpResponse response = httpClient .execute (httpPost );
788
- HttpEntity entity = response .getEntity ();
789
- if (response .getStatusLine ().getStatusCode () != HttpStatus .SC_OK ) {
790
- throw new JwtAuthenticationException (String .format (ERROR_MESSAGE_FORMAT , authorizationUri ,
791
- response .getStatusLine ().getStatusCode (),
792
- getErrorMessage (response .getStatusLine ().getStatusCode ())));
793
- }
794
-
795
- JsonNode result = objectMapper .readTree (entity .getContent ());
796
- resultToken = objectMapper .readValue (result .get ("result" ),
797
- objectMapper .getTypeFactory ().constructParametricType (SingleRestResult .class , Token .class ));
798
- } finally {
799
- httpClient .getConnectionManager ().shutdown ();
800
- }
801
- return resultToken .getContent ();
802
- }
803
-
804
- /**
805
- * Verify token.If token expired: refresh it
806
- *
807
- * @param tokenV3
808
- * @param tokenV2
809
- * @return
810
- * @throws JwtAuthenticationException
811
- */
812
- private String getValidJwtToken (String tokenV3 , String tokenV2 ) throws JwtAuthenticationException {
813
- String [] tokenSplit = tokenV3 .split ("\\ ." );
814
- boolean valid = true ;
815
- if (tokenSplit .length < 2 ) valid = false ;
816
-
817
- JsonNode jsonNode = null ;
818
-
819
- try {
820
- if (valid ) {
821
- StringBuffer payloadStr = new StringBuffer (tokenSplit [1 ]);
822
- while (payloadStr .length () % 4 != 0 ) payloadStr .append ('=' );
823
- String payload = new String (Base64 .decodeBase64 (payloadStr .toString ().getBytes (StandardCharsets .UTF_8 )));
824
-
825
- jsonNode = objectMapper .readValue (payload .toString (), JsonNode .class );
826
-
827
- long exp = jsonNode .get ("exp" ).getLongValue ();
828
- Date expDate = new Date (exp * 1000 );
829
- logger .info ("token expire: " + expDate );
830
- if (expDate .before (new Date ())) valid = false ;
831
- }
832
-
833
- if (!valid ) {
834
- logger .info ("refresh new token for : " + tokenV2 );
835
- Token newToken = getRefreshTokenFromApi (tokenV2 );
836
- if (newToken == null || newToken .getToken ().isEmpty ()) {
837
- throw new JwtAuthenticationException ("Invalid refresh token" );
838
- }
839
-
840
- return newToken .getToken ();
841
- }
842
- } catch (Exception e ) {
843
- throw new JwtAuthenticationException ("Failed to refresh toke through api, Please go to sso login page : " +
844
- getSsoLoginUrl ());
845
- }
846
- return tokenV3 ;
847
- }
848
-
849
- /**
850
- * Validate cookie v2 and v3
851
- *
852
- * @param v2 cookie v2
853
- * @param v3 cookie v3
854
- * @throws Exception
855
- */
856
- protected void validateCookieV2V3 (Cookie v2 , Cookie v3 ) throws Exception {
857
- String validToken = null ;
858
- String v3Token = null ;
859
- if (v3 == null ) {
860
- validToken = getRefreshTokenFromApi (v2 .getValue ()).getToken ();
861
- } else {
862
- validToken = getValidJwtToken (v3 .getValue (), v2 .getValue ());
863
- v3Token = v3 .getValue ();
864
- }
865
-
866
- if (!validToken .equals (v3Token )) {
867
- DirectUtils .addDirectCookie (ServletActionContext .getResponse (), ServerConfiguration .JWT_V3_COOKIE_KEY , validToken , -1 );
868
- }
710
+ public void setJwtTokenUpdater (JwtTokenUpdater jwtTokenUpdater ) {
711
+ this .jwtTokenUpdater = jwtTokenUpdater ;
869
712
}
870
713
}
0 commit comments