All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.amazonaws.auth.policy.internal.JsonPolicyWriter Maven / Gradle / Ivy

Go to download

The AWS SDK for Java with support for OSGi. The AWS SDK for Java provides Java APIs for building software on AWS' cost-effective, scalable, and reliable infrastructure products. The AWS Java SDK allows developers to code against APIs for all of Amazon's infrastructure web services (Amazon S3, Amazon EC2, Amazon SQS, Amazon Relational Database Service, Amazon AutoScaling, etc).

There is a newer version: 1.11.60
Show newest version
/*
 * Copyright 2010-2016 Amazon.com, Inc. or its affiliates. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file 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 com.amazonaws.auth.policy.internal;

import java.io.IOException;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.amazonaws.AmazonClientException;
import com.amazonaws.auth.policy.Action;
import com.amazonaws.auth.policy.Condition;
import com.amazonaws.auth.policy.Policy;
import com.amazonaws.auth.policy.Principal;
import com.amazonaws.auth.policy.Resource;
import com.amazonaws.auth.policy.Statement;
import com.amazonaws.util.json.Jackson;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonGenerator;

/**
 * Serializes an AWS policy object to a JSON string, suitable for sending to an
 * AWS service.
 */
public class JsonPolicyWriter {

    /** The JSON Generator to generator a JSON string.*/
    private JsonGenerator generator = null;

    /** The output writer to which the JSON String is written.*/
    private Writer writer;

    /** Logger used to log exceptions that occurs while writing the Json policy.*/
    private static final Log log = LogFactory.getLog("com.amazonaws.auth.policy");

    /**
     * Constructs a new instance of JSONPolicyWriter.
     */
    public JsonPolicyWriter() {
        writer = new StringWriter();
        try {
            generator = Jackson.jsonGeneratorOf(writer);
        } catch (IOException ioe) {
            throw new AmazonClientException(
                    "Unable to instantiate JsonGenerator.", ioe);
        }

    }

    /**
     * Converts the specified AWS policy object to a JSON string, suitable for
     * passing to an AWS service.
     *
     * @param policy
     *            The AWS policy object to convert to a JSON string.
     *
     * @return The JSON string representation of the specified policy object.
     *
     * @throws IllegalArgumentException
     *             If the specified policy is null or invalid and cannot be
     *             serialized to a JSON string.
     */
    public String writePolicyToString(Policy policy) {

        if(!isNotNull(policy))
            throw new IllegalArgumentException("Policy cannot be null");

        try {
            return jsonStringOf(policy);
        } catch (Exception e) {
            String message = "Unable to serialize policy to JSON string: "
                    + e.getMessage();
            throw new IllegalArgumentException(message, e);
        } finally {
            try { writer.close(); } catch (Exception e) { }
        }
    }

    /**
     * Converts the given Policy into a JSON String.
     *
     * @param policy
     *            the policy to be converted.
     * @return a JSON String of the specified policy object.
     */
    private String jsonStringOf(Policy policy) throws JsonGenerationException,
            IOException {
        generator.writeStartObject();

        writeJsonKeyValue(JsonDocumentFields.VERSION, policy.getVersion());

        if (isNotNull(policy.getId()))
            writeJsonKeyValue(JsonDocumentFields.POLICY_ID, policy.getId());

        writeJsonArrayStart(JsonDocumentFields.STATEMENT);

        for (Statement statement : policy.getStatements()) {
            generator.writeStartObject();

            if (isNotNull(statement.getId())) {
                writeJsonKeyValue(JsonDocumentFields.STATEMENT_ID, statement.getId());
            }
            writeJsonKeyValue(JsonDocumentFields.STATEMENT_EFFECT, statement
                    .getEffect().toString());

            List principals = statement.getPrincipals();
            if (isNotNull(principals) && !principals.isEmpty())
                writePrincipals(principals);

            List actions = statement.getActions();
            if (isNotNull(actions) && !actions.isEmpty())
                writeActions(actions);

            List resources = statement.getResources();
            if (isNotNull(resources) && !resources.isEmpty())
                writeResources(resources);

            List conditions = statement.getConditions();
            if (isNotNull(conditions) && !conditions.isEmpty())
                writeConditions(conditions);

            generator.writeEndObject();
        }

        writeJsonArrayEnd();

        generator.writeEndObject();

        generator.flush();

        return writer.toString();

    }

    /**
     * Writes the list of conditions to the JSONGenerator.
     *
     * @param conditions
     *            the conditions to be written.
     */
    private void writeConditions(List conditions)
            throws JsonGenerationException, IOException {
        Map conditionsByType = groupConditionsByTypeAndKey(conditions);

        writeJsonObjectStart(JsonDocumentFields.CONDITION);

        ConditionsByKey conditionsByKey;
        for (Map.Entry entry : conditionsByType
                .entrySet()) {
            conditionsByKey = conditionsByType.get(entry.getKey());

            writeJsonObjectStart(entry.getKey());
            for (String key : conditionsByKey.keySet()) {
                writeJsonArray(key, conditionsByKey.getConditionsByKey(key));
            }
            writeJsonObjectEnd();
        }
        writeJsonObjectEnd();
    }

    /**
     * Writes the list of Resources to the JSONGenerator.
     *
     * @param resources
     *            the list of resources to be written.
     */
    private void writeResources(List resources)
            throws JsonGenerationException, IOException {

        List resourceStrings = new ArrayList();

        for (Resource resource : resources) {
            resourceStrings.add(resource.getId());
        }
        writeJsonArray(JsonDocumentFields.RESOURCE, resourceStrings);
    }

    /**
     * Writes the list of Actions to the JSONGenerator.
     *
     * @param actions
     *            the list of the actions to be written.
     */
    private void writeActions(List actions)
            throws JsonGenerationException, IOException {
        List actionStrings = new ArrayList();

        for (Action action : actions) {
            actionStrings.add(action.getActionName());
        }
        writeJsonArray(JsonDocumentFields.ACTION, actionStrings);
    }

    /**
     * Writes the list of Principals to the JSONGenerator.
     *
     * @param principals
     *            the list of principals to be written.
     */
    private void writePrincipals(List principals)
            throws JsonGenerationException, IOException {
        if (principals.size() == 1 && principals.get(0).equals(Principal.All)) {
            writeJsonKeyValue(JsonDocumentFields.PRINCIPAL, Principal.All.getId());
        } else {
            writeJsonObjectStart(JsonDocumentFields.PRINCIPAL);

            Map> principalsByScheme = groupPrincipalByScheme(principals);

            List principalValues;
            for (Map.Entry> entry : principalsByScheme.entrySet()) {
                principalValues = principalsByScheme.get(entry.getKey());

                if (principalValues.size() == 1) {
                    writeJsonKeyValue(entry.getKey(), principalValues.get(0));
                } else {
                    writeJsonArray(entry.getKey(), principalValues);
                }

            }
            writeJsonObjectEnd();
        }
    }

    /**
     * Groups the list of Principals by the Scheme.
     *
     * @param principals
     *            the list of Principals
     * @return a map grouped by scheme of the principal.
     */
    private Map> groupPrincipalByScheme(
            List principals) {
        Map> principalsByScheme = new LinkedHashMap>();

        String provider;
        List principalValues;
        for (Principal principal : principals) {
            provider = principal.getProvider();
            if (!principalsByScheme.containsKey(provider)) {
                principalsByScheme.put(provider, new ArrayList());
            }
            principalValues = principalsByScheme.get(provider);
            principalValues.add(principal.getId());
        }

        return principalsByScheme;
    }

    /**
     * Inner class to hold condition values for each key under a condition type.
     */
    static class ConditionsByKey {
        private Map> conditionsByKey;

        public ConditionsByKey(){
            conditionsByKey = new LinkedHashMap>();
        }

        public Map> getConditionsByKey() {
            return conditionsByKey;
        }

        public void setConditionsByKey(Map> conditionsByKey) {
            this.conditionsByKey = conditionsByKey;
        }

        public boolean containsKey(String key){
            return conditionsByKey.containsKey(key);
        }

        public List getConditionsByKey(String key){
            return conditionsByKey.get(key);
        }

        public Set keySet(){
            return conditionsByKey.keySet();
        }

        public void addValuesToKey(String key, List values) {

            List conditionValues = getConditionsByKey(key);
            if (conditionValues == null)
                conditionsByKey.put(key, new ArrayList(values));
            else
                conditionValues.addAll(values);
        }
    }

    /**
     * Groups the list of Conditions by the condition type and
     * condition key.
     *
     * @param conditions
     *            the list of conditions to be grouped
     * @return a map of conditions grouped by type and then key.
     */
    private Map groupConditionsByTypeAndKey(
            List conditions) {
        Map conditionsByType = new LinkedHashMap();

        String type;
        String key;
        ConditionsByKey conditionsByKey;
        for (Condition condition : conditions) {
            type = condition.getType();
            key = condition.getConditionKey();

            if (!(conditionsByType.containsKey(type))) {
                conditionsByType.put(type, new ConditionsByKey());
            }

            conditionsByKey = conditionsByType.get(type);
            conditionsByKey.addValuesToKey(key, condition.getValues());
        }
        return conditionsByType;
    }

    /**
     * Writes an array along with its values to the JSONGenerator.
     *
     * @param arrayName
     *            name of the JSON array.
     * @param values
     *            values of the JSON array.
     */
    private void writeJsonArray(String arrayName, List values)
            throws JsonGenerationException, IOException {
        writeJsonArrayStart(arrayName);
        for (String value : values)
            generator.writeString(value);
        writeJsonArrayEnd();
    }

    /**
     * Writes the Start of Object String to the JSONGenerator along with Object
     * Name.
     *
     * @param fieldName
     *            name of the JSON Object.
     */
    private void writeJsonObjectStart(String fieldName)
            throws JsonGenerationException, IOException {
        generator.writeObjectFieldStart(fieldName);
    }

    /**
     * Writes the End of Object String to the JSONGenerator.
     */
    private void writeJsonObjectEnd() throws JsonGenerationException, IOException {
        generator.writeEndObject();
    }

    /**
     * Writes the Start of Array String to the JSONGenerator along with Array
     * Name.
     *
     * @param fieldName
     *            name of the JSON array
     */
    private void writeJsonArrayStart(String fieldName)
            throws JsonGenerationException, IOException {
        generator.writeArrayFieldStart(fieldName);
    }

    /**
     * Writes the End of Array String to the JSONGenerator.
     */
    private void writeJsonArrayEnd() throws JsonGenerationException, IOException {
        generator.writeEndArray();
    }

    /**
     * Writes the given field and the value to the JsonGenerator
     *
     * @param fieldName
     *            the JSON field name
     * @param value
     *            value for the field
     */
    private void writeJsonKeyValue(String fieldName, String value)
            throws JsonGenerationException, IOException {
        generator.writeStringField(fieldName, value);
    }

    /**
     * Checks if the given object is not null.
     *
     * @param object
     *            the object compared to null.
     * @return true if the object is not null else false
     */
    private boolean isNotNull(Object object) {
        return null != object;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy