Skip to content
This repository was archived by the owner on Jan 23, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion conf/web/WEB-INF/applicationContext.xml
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@
<property name="contestFeeService" ref="contestFeeService"/>
<property name="contestFeePercentageService" ref="contestFeePercentageService"/>
<property name="userGroupsApiEndpoint" value="@userGroupsApiEndpoint@"/>
<property name="jwtTokenUpdater" ref="jwtTokenUpdater" />
</bean>

<bean id="projectAction" class="com.topcoder.direct.services.view.action.contest.launch.ProjectAction"
Expand Down Expand Up @@ -1611,7 +1612,7 @@
<property name="groupApiEndpoint" value="@groupMemberApiUrl@"/>
<property name="jwtTokenUpdater" ref="jwtTokenUpdater"/>
</bean>
<bean id="jwtTokenUpdater" class="com.topcoder.direct.services.view.util.JwtTokenUpdater">
<bean id="jwtTokenUpdater" class="com.topcoder.direct.services.view.util.JwtTokenUpdater" scope="prototype">
<property name="ssoLoginUrl" value="@ssoLoginUrl@"/>
<property name="authorizationURL" value="@authorizationUrl@"/>
</bean>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import com.topcoder.direct.services.view.util.AuthorizationProvider;
import com.topcoder.direct.services.view.util.DataProvider;
import com.topcoder.direct.services.view.util.DirectUtils;
import com.topcoder.direct.services.view.util.JwtTokenUpdater;
import com.topcoder.direct.services.view.util.challenge.CostCalculationService;
import com.topcoder.management.project.ProjectGroup;
import com.topcoder.security.TCSubject;
Expand Down Expand Up @@ -128,6 +129,8 @@ public class CommonAction extends BaseContestFeeAction {
*/
private String userGroupsApiEndpoint;

private JwtTokenUpdater jwtTokenUpdater;

/**
* <p>
* Executes the action.
Expand Down Expand Up @@ -558,7 +561,7 @@ public void setCategoryId(long categoryId) {
public String getGroups() {
try {
TCSubject tcSubject = DirectUtils.getTCSubjectFromSession();
Set<ProjectGroup> projectGroups = DirectUtils.getGroups(tcSubject, userGroupsApiEndpoint);
Set<ProjectGroup> projectGroups = DirectUtils.getGroups(tcSubject, jwtTokenUpdater, userGroupsApiEndpoint);
setResult(projectGroups);
} catch (Throwable e) {
if (getModel() != null) {
Expand All @@ -575,4 +578,12 @@ public String getUserGroupsApiEndpoint() {
public void setUserGroupsApiEndpoint(String userGroupsApiEndpoint) {
this.userGroupsApiEndpoint = userGroupsApiEndpoint;
}

public JwtTokenUpdater getJwtTokenUpdater() {
return jwtTokenUpdater;
}

public void setJwtTokenUpdater(JwtTokenUpdater jwtTokenUpdater) {
this.jwtTokenUpdater = jwtTokenUpdater;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import com.topcoder.direct.services.view.dto.my.Challenge;
import com.topcoder.direct.services.view.dto.my.RestResult;
import com.topcoder.direct.services.view.exception.JwtAuthenticationException;
import com.topcoder.direct.services.view.util.JwtTokenUpdater;
import org.codehaus.jackson.JsonNode;

import java.text.DateFormat;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ public class JwtAuthenticationException extends BaseException {
public JwtAuthenticationException(String message) {
super(message);
}

public JwtAuthenticationException(String message, Throwable cause) {
super(message, cause);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3824,11 +3824,12 @@ public static List<ProjectGroup> getGroupIdAndName(List<ProjectGroup> projectGro
* Get group from group API.
*
* @param tcSubject tcSubject of user
* @param jwtTokenUpdater the jwt token updater
* @param endpoint endpoint url
* @return set of group
* @throws Exception
*/
public static Set<ProjectGroup> getGroupsFromApi(TCSubject tcSubject, String endpoint) throws Exception {
public static Set<ProjectGroup> getGroupsFromApi(TCSubject tcSubject, JwtTokenUpdater jwtTokenUpdater, String endpoint) throws Exception {
URIBuilder uri = new URIBuilder(endpoint);

if (!DirectUtils.isCockpitAdmin(tcSubject) && !DirectUtils.isTcStaff(tcSubject)) {
Expand All @@ -3840,7 +3841,7 @@ public static Set<ProjectGroup> getGroupsFromApi(TCSubject tcSubject, String end
HttpGet getRequest = new HttpGet(uri.build());
logger.info("Getting Group with thi uri: " + uri.build().toString());

String v3Token = new JwtTokenUpdater().check().getToken();
String v3Token = jwtTokenUpdater.check().getToken();

getRequest.setHeader(HttpHeaders.AUTHORIZATION, "Bearer " + v3Token);

Expand All @@ -3867,11 +3868,12 @@ public static Set<ProjectGroup> getGroupsFromApi(TCSubject tcSubject, String end
* Get groups. Get from cache first if none then get from api
*
* @param tcSubject tcSubject of user
* @param jwtTokenUpdater the jwt token updater
* @param endpoint endpoint url
* @return set of groupfor user
* @throws Exception
*/
public static Set<ProjectGroup> getGroups(TCSubject tcSubject, String endpoint) throws Exception {
public static Set<ProjectGroup> getGroups(TCSubject tcSubject, JwtTokenUpdater jwtTokenUpdater, String endpoint) throws Exception {
CacheClient cc = null;
Set<ProjectGroup> projectGroups = null;
SortedCacheAddress cacheAddress = new SortedCacheAddress(tcSubject.getUserId());
Expand All @@ -3882,7 +3884,7 @@ public static Set<ProjectGroup> getGroups(TCSubject tcSubject, String endpoint)
logger.info("Can't get group for user " + tcSubject.getUserId() + " from cache");
}
if (projectGroups == null) {
projectGroups = DirectUtils.getGroupsFromApi(tcSubject, endpoint);
projectGroups = DirectUtils.getGroupsFromApi(tcSubject, jwtTokenUpdater, endpoint);
try {
cc.set(cacheAddress, projectGroups, MaxAge.HOUR);
} catch (Exception e) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@
package com.topcoder.direct.services.view.util;

import com.topcoder.direct.services.configs.ServerConfiguration;
import com.topcoder.direct.services.view.dto.my.SingleRestResult;
import com.topcoder.direct.services.view.dto.my.Token;
import com.topcoder.direct.services.view.exception.JwtAuthenticationException;
import org.apache.commons.codec.binary.Base64;
import org.apache.http.HttpEntity;
Expand All @@ -16,6 +14,7 @@
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.log4j.Logger;
import org.apache.struts2.ServletActionContext;
import org.codehaus.jackson.JsonNode;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.ObjectMapper;
Expand All @@ -26,8 +25,6 @@
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.struts2.ServletActionContext;

import static sun.security.krb5.internal.Krb5.getErrorMessage;

/**
Expand Down Expand Up @@ -93,11 +90,10 @@ public JwtTokenUpdater check() throws Exception {
}


private Token getRefreshTokenFromApi(String oldToken) throws Exception {
private String getRefreshTokenFromApi(String oldToken) throws Exception {
DefaultHttpClient httpClient = new DefaultHttpClient();
SingleRestResult<Token> resultToken = null;
try {
URI authorizationUri = new URI(getAuthorizationURL());
URI authorizationUri = new URI(this.authorizationURL);
HttpPost httpPost = new HttpPost(authorizationUri);
httpPost.addHeader(HttpHeaders.CONTENT_TYPE, "application/json");

Expand All @@ -112,57 +108,54 @@ private Token getRefreshTokenFromApi(String oldToken) throws Exception {
}

JsonNode result = objectMapper.readTree(entity.getContent());
resultToken = objectMapper.readValue(result.get("result"),
objectMapper.getTypeFactory().constructParametricType(SingleRestResult.class, Token.class));

return result.path("result").path("content").path("token").asText();
} finally {
httpClient.getConnectionManager().shutdown();
}
return resultToken.getContent();
}

/**
* Verify token.If token expired: refresh it
* Verify token. If token expired: refresh it
*
* @param tokenV3
* @param tokenV2
* @param v3token the v3 jwt token
* @param v2token the v2 jwt token
* @return
* @throws JwtAuthenticationException
*/
private String getValidJwtToken(String tokenV3, String tokenV2) throws JwtAuthenticationException {
String[] tokenSplit = tokenV3.split("\\.");
boolean valid = true;
if (tokenSplit.length < 2) valid = false;

JsonNode jsonNode = null;
private String getValidJwtToken(String v3token, String v2token) throws JwtAuthenticationException {
String[] tokenSplit = v3token.split("\\.");
boolean valid = tokenSplit.length >= 2;

try {
if (valid) {
StringBuffer payloadStr = new StringBuffer(tokenSplit[1]);
StringBuilder payloadStr = new StringBuilder(tokenSplit[1]);
while (payloadStr.length() % 4 != 0) payloadStr.append('=');
String payload = new String(Base64.decodeBase64(payloadStr.toString().getBytes(StandardCharsets.UTF_8)));

jsonNode = objectMapper.readValue(payload.toString(), JsonNode.class);
JsonNode jsonNode = objectMapper.readValue(payload, JsonNode.class);

long exp = jsonNode.get("exp").getLongValue();
Date expDate = new Date(exp * 1000);
logger.info("token expire at: " + expDate);
if (expDate.before(new Date())) valid = false;
}

if (!valid) {
logger.info("refresh new token for : " + tokenV2);
Token newToken = getRefreshTokenFromApi(tokenV2);
if (newToken == null || newToken.getToken().isEmpty()) {
throw new JwtAuthenticationException("Invalid refresh token");
if (expDate.after(new Date())) {
return v3token;
}
}

return newToken.getToken();
logger.info("refresh v3 token for : " + v2token);
String newToken = getRefreshTokenFromApi(v2token);
if (newToken == null || newToken.isEmpty()) {
throw new JwtAuthenticationException("Invalid refreshed token - " + newToken);
}

return newToken;
} catch (JwtAuthenticationException e) {
throw e;
} catch (Exception e) {
throw new JwtAuthenticationException("Failed to refresh toke through api, Please go to sso login page : " +
getSsoLoginUrl());
this.ssoLoginUrl, e);
}
return tokenV3;
}

/**
Expand All @@ -172,11 +165,11 @@ private String getValidJwtToken(String tokenV3, String tokenV2) throws JwtAuthen
* @param v3 cookie v3
* @throws Exception
*/
private void validateCookieV2V3(Cookie v2, Cookie v3) throws Exception{
private void validateCookieV2V3(Cookie v2, Cookie v3) throws Exception {
String validToken;
String v3Token = null;
if (v3 == null) {
validToken = getRefreshTokenFromApi(v2.getValue()).getToken();
validToken = getRefreshTokenFromApi(v2.getValue());
} else {
validToken = getValidJwtToken(v3.getValue(), v2.getValue());
v3Token = v3.getValue();
Expand Down