Skip to content
This repository was archived by the owner on Jan 23, 2025. It is now read-only.

Commit 27e0376

Browse files
authored
Merge pull request #317 from appirio-tech/dev
Limit assignees to group members
2 parents faf7aed + d778817 commit 27e0376

16 files changed

+806
-246
lines changed

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,5 @@ Build/Compile
5151
Deploy:
5252
* simply run 'ant deploy' to build all the components and the direct and deploy the direct to jboss
5353

54+
55+

conf/web/WEB-INF/applicationContext.xml

+12-4
Original file line numberDiff line numberDiff line change
@@ -1555,16 +1555,14 @@
15551555
<bean id="myCreatedChallengesAction"
15561556
class="com.topcoder.direct.services.view.action.my.MyCreatedChallengesAction" scope="prototype">
15571557
<property name="serviceURL" value="@directChallengeServicesApiUrl@"/>
1558-
<property name="ssoLoginUrl" value="@ssoLoginUrl@"/>
1559-
<property name="authorizationURL" value="@authorizationUrl@"/>
15601558
<property name="userService" ref="userService"/>
1559+
<property name="jwtTokenUpdater" ref="jwtTokenUpdater"/>
15611560
</bean>
15621561

15631562
<bean id="myChallengesAction"
15641563
class="com.topcoder.direct.services.view.action.my.MyChallengesAction" scope="prototype">
15651564
<property name="serviceURL" value="@directChallengeServicesApiUrl@"/>
1566-
<property name="ssoLoginUrl" value="@ssoLoginUrl@"/>
1567-
<property name="authorizationURL" value="@authorizationUrl@"/>
1565+
<property name="jwtTokenUpdater" ref="jwtTokenUpdater"/>
15681566
</bean>
15691567

15701568
<bean id="xmlPhaseTemplatePersistence"
@@ -1605,4 +1603,14 @@
16051603
<constructor-arg ref="startDateGenerator"/>
16061604
<constructor-arg ref="workdays"/>
16071605
</bean>
1606+
1607+
<bean id="getGroupMemberAction" class="com.topcoder.direct.services.view.action.contest.launch.GetGroupMemberAction"
1608+
scope="prototype" parent="baseDirectStrutsAction">
1609+
<property name="groupApiEndpoint" value="@groupMemberApiUrl@"/>
1610+
<property name="jwtTokenUpdater" ref="jwtTokenUpdater"/>
1611+
</bean>
1612+
<bean id="jwtTokenUpdater" class="com.topcoder.direct.services.view.util.JwtTokenUpdater">
1613+
<property name="ssoLoginUrl" value="@ssoLoginUrl@"/>
1614+
<property name="authorizationURL" value="@authorizationUrl@"/>
1615+
</bean>
16081616
</beans>

conf/web/WEB-INF/struts.xml

+7
Original file line numberDiff line numberDiff line change
@@ -2511,6 +2511,13 @@
25112511
<result name="success" type="json"/>
25122512
<result name="error" type="json"/>
25132513
</action>
2514+
<action name="member" class="getGroupMemberAction">
2515+
<interceptor-ref name="token"/>
2516+
<interceptor-ref name="baseStack"/>
2517+
<result name="success" type="json"/>
2518+
<result name="error" type="json"/>
2519+
<result name="invalid.token" type="json"/>
2520+
</action>
25142521
</package>
25152522

25162523
<package name="payments" namespace="/payments" extends="base">

src/java/main/com/topcoder/direct/services/view/action/ServiceBackendDataTablesAction.java

+15-172
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,33 @@
33
*/
44
package com.topcoder.direct.services.view.action;
55

6-
import com.topcoder.direct.services.configs.ServerConfiguration;
76
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;
107
import com.topcoder.direct.services.view.dto.project.ProjectBriefDTO;
11-
import com.topcoder.direct.services.view.exception.JwtAuthenticationException;
128
import com.topcoder.direct.services.view.util.DataProvider;
139
import com.topcoder.direct.services.view.util.DirectUtils;
10+
import com.topcoder.direct.services.view.util.JwtTokenUpdater;
1411
import com.topcoder.security.TCSubject;
15-
import org.apache.commons.codec.binary.Base64;
1612
import org.apache.http.HttpEntity;
1713
import org.apache.http.HttpHeaders;
1814
import org.apache.http.HttpResponse;
1915
import org.apache.http.HttpStatus;
2016
import org.apache.http.client.methods.HttpGet;
21-
import org.apache.http.client.methods.HttpPost;
2217
import org.apache.http.client.utils.URIBuilder;
23-
import org.apache.http.entity.StringEntity;
2418
import org.apache.http.impl.client.DefaultHttpClient;
2519
import org.apache.log4j.Logger;
26-
import org.apache.struts2.ServletActionContext;
2720
import org.codehaus.jackson.JsonNode;
2821
import org.codehaus.jackson.map.DeserializationConfig;
2922
import org.codehaus.jackson.map.ObjectMapper;
3023

31-
import javax.servlet.http.Cookie;
3224
import java.io.UnsupportedEncodingException;
3325
import java.net.URI;
3426
import java.net.URISyntaxException;
3527
import java.net.URLEncoder;
36-
import java.nio.charset.StandardCharsets;
3728
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;
3933

4034
/**
4135
* <p>
@@ -108,11 +102,6 @@ public abstract class ServiceBackendDataTablesAction extends AbstractAction {
108102
*/
109103
private String serviceURL;
110104

111-
/**
112-
* authorization Url
113-
*/
114-
private String authorizationURL;
115-
116105
/**
117106
* The challenge types options in filter panel
118107
*
@@ -196,11 +185,6 @@ public abstract class ServiceBackendDataTablesAction extends AbstractAction {
196185
*/
197186
private String endDateTo;
198187

199-
/**
200-
* ssoLogin Url
201-
*/
202-
private String ssoLoginUrl;
203-
204188
/**
205189
* The max pagination size.
206190
*/
@@ -227,14 +211,14 @@ public abstract class ServiceBackendDataTablesAction extends AbstractAction {
227211
protected static final String ERROR_MESSAGE_FORMAT = "Service URL:%s, HTTP Status Code:%d, Error Message:%s";
228212

229213
/**
230-
* URI params for refresh token
214+
* The jackson object mapping which is used to deserialize json return from API to domain model.
231215
*/
232-
private final String AUTHORIZATION_PARAMS = "{\"param\": {\"externalToken\": \"%s\"}}";
216+
protected static final ObjectMapper objectMapper;
233217

234218
/**
235-
* The jackson object mapping which is used to deserialize json return from API to domain model.
219+
* JwtTokenUpdater
236220
*/
237-
protected static final ObjectMapper objectMapper;
221+
private JwtTokenUpdater jwtTokenUpdater;
238222

239223
/**
240224
* <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 {
339323
// specify the get request
340324
HttpGet getRequest = new HttpGet(apiEndPoint);
341325

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();
352327

353328
getRequest.setHeader(HttpHeaders.AUTHORIZATION,
354-
"Bearer " + jwtCookieV3.getValue());
329+
"Bearer " + token);
355330

356331
getRequest.addHeader(HttpHeaders.ACCEPT, "application/json");
357332

@@ -728,143 +703,11 @@ public void setEndDateTo(String endDateTo) {
728703
this.endDateTo = endDateTo;
729704
}
730705

731-
/**
732-
* Getter for {@link #authorizationURL}
733-
* @return authorizationURL
734-
*/
735-
public String getAuthorizationURL() {
736-
return authorizationURL;
706+
public JwtTokenUpdater getJwtTokenUpdater() {
707+
return jwtTokenUpdater;
737708
}
738709

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;
869712
}
870713
}

0 commit comments

Comments
 (0)