Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
thisaltennakoon committed Sep 14, 2023
1 parent 4ca0bd2 commit b92b58d
Show file tree
Hide file tree
Showing 30 changed files with 1,613 additions and 317 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public class API implements CacheableEntity<String> {
private String status;
private String revision;
private String organization;
private String securityScheme;

public String getRevision() {

Expand Down Expand Up @@ -199,4 +200,12 @@ public String getOrganization() {
public void setOrganization(String organization) {
this.organization = organization;
}

public String getSecurityScheme() {
return securityScheme;
}

public void setSecurityScheme(String securityScheme) {
this.securityScheme = securityScheme;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ public class APIMgtGatewayConstants {
* Web socket header for jwt assertion.
*/
public static final String WS_JWT_TOKEN_HEADER = "websocket.custom.header.X-JWT-Assertion";
public static final String WEBSOCKET_HANDSHAKE = "handshake";
public static final String WEBSOCKET_FRAME = "frame";

public static final String WS_CUSTOM_HEADER = "ws.custom.header";
public static final String WS_NOT_SECURED = "ws";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,18 @@ public static TreeMap<String, org.wso2.carbon.apimgt.keymgt.model.entity.API> ge

return selectedAPIMap;
}

public static List<String> getSecuritySchemeOfWebSocketAPI(String context, String version, String tenantDomain) {

List<String> securitySchemeList = new ArrayList<>();
SubscriptionDataStore tenantSubscriptionStore =
SubscriptionDataHolder.getInstance().getTenantSubscriptionStore(tenantDomain);
if (tenantSubscriptionStore != null) {
securitySchemeList = Arrays.asList(tenantSubscriptionStore.getApiByContextAndVersion(context, version).getSecurityScheme().split(","));
}
return securitySchemeList;
}

private static class ContextLengthSorter implements Comparator<String> {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public class InboundMessageContext {
private String matchingResource; //invoking API resource
private ChannelHandlerContext ctx;
private boolean isJWTToken;
private String apiKeyFromQueryParams;

//Graphql Subscription specific connection context information
private GraphQLSchemaDTO graphQLSchemaDTO;
Expand Down Expand Up @@ -252,4 +253,12 @@ public boolean isJWTToken() {
public void setJWTToken(boolean JWTToken) {
isJWTToken = JWTToken;
}

public String getApiKeyFromQueryParams() {
return apiKeyFromQueryParams;
}

public void setApiKeyFromQueryParams(String apiKeyFromQueryParams) {
this.apiKeyFromQueryParams = apiKeyFromQueryParams;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public InboundProcessorResponseDTO handleHandshake(FullHttpRequest req, ChannelH
PrivilegedCarbonContext.startTenantFlow();
PrivilegedCarbonContext.getThreadLocalCarbonContext().setTenantDomain(
inboundMessageContext.getTenantDomain(), true);
if (validateOAuthHeader(req, inboundMessageContext)) {
if (validateOAuthHeader(req, inboundMessageContext) || validateAPIKeyHeaderOrQueryParameter(inboundMessageContext)) {
setRequestHeaders(req, inboundMessageContext);
inboundMessageContext.getRequestHeaders().put(WebsocketUtil.authorizationHeader, req.headers()
.get(WebsocketUtil.authorizationHeader));
Expand Down Expand Up @@ -158,7 +158,7 @@ public InboundProcessorResponseDTO handleHandshake(FullHttpRequest req, ChannelH
* @param inboundMessageContext InboundMessageContext
* @return InboundProcessorResponseDTO with handshake processing response
*/
public InboundProcessorResponseDTO handleRequest(WebSocketFrame msg, InboundMessageContext inboundMessageContext) {
public InboundProcessorResponseDTO handleRequest(WebSocketFrame msg, InboundMessageContext inboundMessageContext) throws APISecurityException {

RequestProcessor requestProcessor;
String msgText = null;
Expand Down Expand Up @@ -431,4 +431,19 @@ private void setRequestHeaders(FullHttpRequest request, InboundMessageContext in
inboundMessageContext.setHeadersToRemove(new ArrayList<>());
}

private boolean validateAPIKeyHeaderOrQueryParameter(InboundMessageContext inboundMessageContext) {

if (inboundMessageContext.getRequestHeaders().containsKey(APIConstants.API_KEY_HEADER_QUERY_PARAM)) {
return true;
} else {
QueryStringDecoder decoder = new QueryStringDecoder(inboundMessageContext.getFullRequestPath());
Map<String, List<String>> requestMap = decoder.parameters();
if (requestMap.containsKey(APIConstants.API_KEY_HEADER_QUERY_PARAM)) {
inboundMessageContext.setApiKeyFromQueryParams(requestMap.get(APIConstants.API_KEY_HEADER_QUERY_PARAM).get(0));
return true;
}
}
return false;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ public InboundProcessorResponseDTO processHandshake(InboundMessageContext inboun
+ inboundMessageContext.getApiContext());
}
InboundProcessorResponseDTO inboundProcessorResponseDTO = new InboundProcessorResponseDTO();
boolean isOAuthHeaderValid;
boolean isTokenValid;
try {
isOAuthHeaderValid = InboundWebsocketProcessorUtil.isAuthenticated(inboundMessageContext);
isTokenValid = InboundWebsocketProcessorUtil.isAuthenticated(inboundMessageContext);
} catch (APIManagementException e) {
log.error(WebSocketApiConstants.HandshakeErrorConstants.API_AUTH_GENERAL_MESSAGE, e);
return InboundWebsocketProcessorUtil.getHandshakeErrorDTO(
Expand All @@ -68,7 +68,7 @@ public InboundProcessorResponseDTO processHandshake(InboundMessageContext inboun
WebSocketApiConstants.HandshakeErrorConstants.API_AUTH_ERROR,
e.getMessage());
}
if (isOAuthHeaderValid) {
if (isTokenValid) {
if (log.isDebugEnabled()) {
log.debug("Handshake authentication success for inbound websocket context: "
+ inboundMessageContext.getApiContext() + " Setting ResourceInfoDTOs of elected API "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.wso2.carbon.apimgt.gateway.dto.GraphQLOperationDTO;
import org.wso2.carbon.apimgt.common.gateway.graphql.GraphQLProcessorUtil;
import org.wso2.carbon.apimgt.gateway.handlers.WebsocketUtil;
import org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityException;
import org.wso2.carbon.apimgt.gateway.handlers.streaming.websocket.WebSocketApiConstants;
import org.wso2.carbon.apimgt.gateway.handlers.streaming.websocket.WebSocketUtils;
import org.wso2.carbon.apimgt.gateway.inbound.InboundMessageContext;
Expand Down Expand Up @@ -71,7 +72,7 @@ public class GraphQLRequestProcessor extends RequestProcessor {
*/
@Override
public InboundProcessorResponseDTO handleRequest(int msgSize, String msgText,
InboundMessageContext inboundMessageContext) {
InboundMessageContext inboundMessageContext) throws APISecurityException {
InboundProcessorResponseDTO responseDTO;
JSONObject graphQLMsg = new JSONObject(msgText);
// removing the existing resource already set in the channel so that new resource can be extracted and set,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.wso2.carbon.apimgt.gateway.handlers.WebsocketUtil;
import org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityException;
import org.wso2.carbon.apimgt.gateway.inbound.InboundMessageContext;
import org.wso2.carbon.apimgt.gateway.inbound.websocket.InboundProcessorResponseDTO;
import org.wso2.carbon.apimgt.gateway.inbound.websocket.utils.InboundWebsocketProcessorUtil;
Expand All @@ -42,7 +43,7 @@ public class RequestProcessor {
* @return InboundProcessorResponseDTO
*/
public InboundProcessorResponseDTO handleRequest(int msgSize, String msgText,
InboundMessageContext inboundMessageContext) {
InboundMessageContext inboundMessageContext) throws APISecurityException {
InboundProcessorResponseDTO responseDTO;
responseDTO = InboundWebsocketProcessorUtil.authenticateToken(inboundMessageContext);
if (!responseDTO.isError()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import org.json.JSONObject;
import org.wso2.carbon.apimgt.common.gateway.constants.GraphQLConstants;
import org.wso2.carbon.apimgt.gateway.handlers.WebsocketUtil;
import org.wso2.carbon.apimgt.gateway.handlers.security.APISecurityException;
import org.wso2.carbon.apimgt.gateway.handlers.streaming.websocket.WebSocketUtils;
import org.wso2.carbon.apimgt.gateway.inbound.InboundMessageContext;
import org.wso2.carbon.apimgt.gateway.dto.GraphQLOperationDTO;
Expand All @@ -45,7 +46,7 @@ public class GraphQLResponseProcessor extends ResponseProcessor {
*/
@Override
public InboundProcessorResponseDTO handleResponse(int msgSize, String msgText,
InboundMessageContext inboundMessageContext) {
InboundMessageContext inboundMessageContext) throws APISecurityException {
InboundProcessorResponseDTO responseDTO =
InboundWebsocketProcessorUtil.authenticateToken(inboundMessageContext);
JSONObject graphQLMsg = new JSONObject(msgText);
Expand Down
Loading

0 comments on commit b92b58d

Please sign in to comment.