OPASynapseRequestGenerator.java
/*
* Copyright (c) 2022, WSO2 Inc. (http://www.wso2.org) All Rights Reserved.
*
* WSO2 Inc. licenses this file to you under the Apache License,
* Version 2.0 (the "License"); you may not use this file except
* in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.synapse.mediators.opa;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.synapse.MessageContext;
import org.apache.synapse.core.axis2.Axis2MessageContext;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Map;
import java.util.TreeMap;
/**
* Default implementation of the {@link OPARequestGenerator}.
*/
public class OPASynapseRequestGenerator implements OPARequestGenerator {
private static final Log log = LogFactory.getLog(OPASynapseRequestGenerator.class);
@Override
public String generateRequest(String policyName, String rule, Map<String, String> additionalParameters,
MessageContext messageContext) throws OPASecurityException {
org.apache.axis2.context.MessageContext axis2MessageContext = ((Axis2MessageContext) messageContext)
.getAxis2MessageContext();
TreeMap<String, String> transportHeadersMap = (TreeMap<String, String>) axis2MessageContext
.getProperty(org.apache.axis2.context.MessageContext.TRANSPORT_HEADERS);
String requestOriginIP = OPAUtils.getRequestIp(axis2MessageContext);
String requestMethod = (String) axis2MessageContext.getProperty(OPAConstants.HTTP_METHOD_STRING);
String requestPath = (String) axis2MessageContext.getProperty(OPAConstants.API_BASEPATH_STRING);
JSONObject inputPayload = new JSONObject();
JSONObject opaPayload = new JSONObject();
opaPayload.put(OPAConstants.REQUEST_ORIGIN_KEY, requestOriginIP);
opaPayload.put(OPAConstants.REQUEST_METHOD_KEY, requestMethod);
opaPayload.put(OPAConstants.REQUEST_PATH_KEY, requestPath);
opaPayload.put(OPAConstants.REQUEST_TRANSPORT_HEADERS_KEY, new JSONObject(transportHeadersMap));
if (additionalParameters.get(OPAConstants.ADDITIONAL_MC_PROPERTY_PARAMETER) != null) {
String additionalMCPropertiesString =
additionalParameters.get(OPAConstants.ADDITIONAL_MC_PROPERTY_PARAMETER);
String[] additionalMCProperties =
additionalMCPropertiesString.split(OPAConstants.ADDITIONAL_MC_PROPERTY_DIVIDER);
for (String mcProperty : additionalMCProperties) {
if (messageContext.getProperty(mcProperty) != null) {
opaPayload.put(mcProperty, messageContext.getProperty(mcProperty));
}
}
}
inputPayload.put(OPAConstants.INPUT_KEY, opaPayload);
return inputPayload.toString();
}
@Override
public boolean handleResponse(String policyName, String rule, String opaResponse,
Map<String, String> additionalParameters, MessageContext messageContext)
throws OPASecurityException {
if (opaResponse.equals(OPAConstants.EMPTY_OPA_RESPONSE)) {
log.error("Empty result received for the OPA policy " + policyName + " for rule " + rule);
throw new OPASecurityException(OPASecurityException.INTERNAL_ERROR,
"Empty result received for the OPA policy " + policyName + " for rule " + rule);
} else {
try {
JSONObject responseObject = new JSONObject(opaResponse);
if (rule != null) {
return responseObject.getBoolean(OPAConstants.OPA_RESPONSE_RESULT_KEY);
} else {
// If a rule is not specified, default allow rule is considered
JSONObject resultObjectFromAllow =
(JSONObject) responseObject.get(OPAConstants.OPA_RESPONSE_DEFAULT_RULE);
return resultObjectFromAllow.getBoolean(OPAConstants.OPA_RESPONSE_RESULT_KEY);
}
} catch (JSONException e) {
log.error("Error parsing OPA JSON response, the field \"result\" not found or not a Boolean", e);
throw new OPASecurityException(OPASecurityException.INTERNAL_ERROR,
OPASecurityException.INTERNAL_ERROR_MESSAGE, e);
}
}
}
}