diff options
Diffstat (limited to 'id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/sl20/SL20JSONExtractorUtils.java')
-rw-r--r-- | id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/sl20/SL20JSONExtractorUtils.java | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/sl20/SL20JSONExtractorUtils.java b/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/sl20/SL20JSONExtractorUtils.java new file mode 100644 index 000000000..e1444c95f --- /dev/null +++ b/id/server/modules/moa-id-module-sl20_authentication/src/main/java/at/gv/egovernment/moa/id/auth/modules/sl20_auth/sl20/SL20JSONExtractorUtils.java @@ -0,0 +1,259 @@ +package at.gv.egovernment.moa.id.auth.modules.sl20_auth.sl20; + +import java.io.InputStreamReader; +import java.net.URLDecoder; +import java.util.Base64; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.Map.Entry; + +import org.apache.http.Header; +import org.apache.http.HttpResponse; +import org.apache.http.client.utils.URIBuilder; +import org.apache.log4j.Logger; + +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonParser; + +import at.gv.egovernment.moa.id.auth.modules.sl20_auth.data.VerificationResult; +import at.gv.egovernment.moa.id.auth.modules.sl20_auth.exceptions.SL20Exception; +import at.gv.egovernment.moa.id.auth.modules.sl20_auth.exceptions.SLCommandoParserException; + +public class SL20JSONExtractorUtils { + private static final Logger log = Logger.getLogger(SL20JSONExtractorUtils.class); + + /** + * Extract String value from JSON + * + * @param input + * @param keyID + * @param isRequired + * @return + * @throws SLCommandoParserException + */ + public static String getStringValue(JsonObject input, String keyID, boolean isRequired) throws SLCommandoParserException { + try { + JsonElement internal = getAndCheck(input, keyID, isRequired); + + if (internal != null) + return internal.getAsString(); + else + return null; + + } catch (SLCommandoParserException e) { + throw e; + + } catch (Exception e) { + throw new SLCommandoParserException("Can not extract String value with keyId: " + keyID, e); + + } + } + + /** + * Extract Boolean value from JSON + * + * @param input + * @param keyID + * @param isRequired + * @return + * @throws SLCommandoParserException + */ + public static boolean getBooleanValue(JsonObject input, String keyID, boolean isRequired, boolean defaultValue) throws SLCommandoParserException { + try { + JsonElement internal = getAndCheck(input, keyID, isRequired); + + if (internal != null) + return internal.getAsBoolean(); + else + return defaultValue; + + } catch (SLCommandoParserException e) { + throw e; + + } catch (Exception e) { + throw new SLCommandoParserException("Can not extract Boolean value with keyId: " + keyID, e); + + } + } + + /** + * Extract JSONObject value from JSON + * + * @param input + * @param keyID + * @param isRequired + * @return + * @throws SLCommandoParserException + */ + public static JsonObject getJSONObjectValue(JsonObject input, String keyID, boolean isRequired) throws SLCommandoParserException { + try { + JsonElement internal = getAndCheck(input, keyID, isRequired); + + if (internal != null) + return internal.getAsJsonObject(); + else + return null; + + } catch (SLCommandoParserException e) { + throw e; + + } catch (Exception e) { + throw new SLCommandoParserException("Can not extract Boolean value with keyId: " + keyID, e); + + } + } + + /** + * Extract Map of Key/Value pairs from a JSON Array + * + * @param input + * @param keyID + * @param isRequired + * @return + * @throws SLCommandoParserException + */ + public static Map<String, String> getMapOfStringElements(JsonObject input, String keyID, boolean isRequired) throws SLCommandoParserException { + JsonElement internal = getAndCheck(input, keyID, isRequired); + + Map<String, String> result = new HashMap<String, String>(); + + if (internal != null) { + if (!internal.isJsonArray()) + throw new SLCommandoParserException("JSON Element IS NOT a JSON array"); + + Iterator<JsonElement> arrayIterator = internal.getAsJsonArray().iterator(); + while(arrayIterator.hasNext()) { + //JsonObject next = arrayIterator.next().getAsJsonObject(); + //result.put( + // next.get(SL20Constants.SL20_COMMAND_PARAM_GENERAL_REQPARAMETER_KEY).getAsString(), + // next.get(SL20Constants.SL20_COMMAND_PARAM_GENERAL_REQPARAMETER_VALUE).getAsString()); + JsonElement next = arrayIterator.next(); + Iterator<Entry<String, JsonElement>> entry = next.getAsJsonObject().entrySet().iterator(); + while (entry.hasNext()) { + Entry<String, JsonElement> el = entry.next(); + if (result.containsKey(el.getKey())) + log.info("Attr. Map already contains Element with Key: " + el.getKey() + ". Overwrite element ... "); + + result.put(el.getKey(), el.getValue().getAsString()); + + } + } + } + + return result; + } + + + public static JsonElement extractSL20Result(JsonObject command, JsonSecurityUtils encrypter, boolean mustBeEncrypted) throws SLCommandoParserException { + JsonElement result = command.get(SL20Constants.SL20_COMMAND_CONTAINER_RESULT); + JsonElement encryptedResult = command.get(SL20Constants.SL20_COMMAND_CONTAINER_ENCRYPTEDRESULT); + + if (result == null && encryptedResult == null) + throw new SLCommandoParserException("NO result OR encryptedResult FOUND."); + + else if (result == null && encryptedResult == null) + throw new SLCommandoParserException("result AND encryptedResultFOUND. Can not used twice"); + + else if (encryptedResult == null && mustBeEncrypted) + throw new SLCommandoParserException("result MUST be signed."); + + else if (result != null) + return result; + + else if (encryptedResult != null) { + //TODO: Add correct signature validation + String[] signedPayload = encryptedResult.toString().split("\\."); + JsonElement payLoad = new JsonParser().parse(new String(Base64.getUrlDecoder().decode(signedPayload[1]))); + return payLoad; + + } else + throw new SLCommandoParserException("Internal build error"); + + + } + + /** + * Extract payLoad from generic transport container + * + * @param container + * @param joseTools + * @return + * @throws SLCommandoParserException + */ + public static VerificationResult extractSL20PayLoad(JsonObject container, IJOSETools joseTools, boolean mustBeSigned) throws SL20Exception { + + JsonElement sl20Payload = container.get(SL20Constants.SL20_PAYLOAD); + JsonElement sl20SignedPayload = container.get(SL20Constants.SL20_SIGNEDPAYLOAD); + + if (mustBeSigned && joseTools == null) + throw new SLCommandoParserException("'joseTools' MUST be set if 'mustBeSigned' is 'true'"); + + if (sl20Payload == null && sl20SignedPayload == null) + throw new SLCommandoParserException("NO payLoad OR signedPayload FOUND."); + + else if (sl20Payload == null && sl20SignedPayload == null) + throw new SLCommandoParserException("payLoad AND signedPayload FOUND. Can not used twice"); + + else if (sl20SignedPayload == null && mustBeSigned) + throw new SLCommandoParserException("payLoad MUST be signed."); + + else if (sl20Payload != null) + return new VerificationResult(sl20Payload.getAsJsonObject()); + + else if (sl20SignedPayload != null && sl20SignedPayload.isJsonPrimitive()) + return joseTools.validateSignature(sl20SignedPayload.getAsString()); + + else + throw new SLCommandoParserException("Internal build error"); + + + } + + + /** + * Extract generic transport container from httpResponse + * + * @param httpResp + * @return + * @throws SLCommandoParserException + */ + public static JsonObject getSL20ContainerFromResponse(HttpResponse httpResp) throws SLCommandoParserException { + try { + JsonObject sl20Resp = null; + if (httpResp.getStatusLine().getStatusCode() == 307) { + Header[] locationHeader = httpResp.getHeaders("Location"); + if (locationHeader == null) + throw new SLCommandoParserException("Find Redirect statuscode but not Location header"); + + String sl20RespString = new URIBuilder(locationHeader[0].getValue()).getQueryParams().get(0).getValue(); + sl20Resp = new JsonParser().parse(URLDecoder.decode(sl20RespString)).getAsJsonObject(); + + } else if (httpResp.getStatusLine().getStatusCode() == 200) { + if (!httpResp.getEntity().getContentType().getValue().equals("application/json;charset=UTF-8")) + throw new SLCommandoParserException("SL20 response with a wrong ContentType: " + httpResp.getEntity().getContentType().getValue()); + + sl20Resp = new JsonParser().parse(new InputStreamReader(httpResp.getEntity().getContent())).getAsJsonObject(); + + } else + throw new SLCommandoParserException("SL20 response with http-code: " + httpResp.getStatusLine().getStatusCode()); + + return sl20Resp; + + } catch (Exception e) { + throw new SLCommandoParserException("SL20 response parsing FAILED! Reason: " + e.getMessage(), e); + + } + } + + private static JsonElement getAndCheck(JsonObject input, String keyID, boolean isRequired) throws SLCommandoParserException { + JsonElement internal = input.get(keyID); + + if (internal == null && isRequired) + throw new SLCommandoParserException("REQUIRED Element with keyId: " + keyID + " does not exist"); + + return internal; + + } +} |