Package ninja.template

Source Code of ninja.template.TemplateEngineJsonP

/**
* Copyright (C) 2012-2014 the original author or authors.
*
* Licensed 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 ninja.template;

import java.io.IOException;
import java.io.OutputStream;
import java.util.regex.Pattern;

import ninja.Context;
import ninja.Result;
import ninja.utils.NinjaConstant;
import ninja.utils.NinjaProperties;
import ninja.utils.ResponseStreams;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.util.JSONPObject;
import com.google.common.base.Strings;
import com.google.inject.Inject;
import com.google.inject.Singleton;

/**
* JSONP engine. Outputs the given result as JSONP output: Javascript callback
* with data as a parameter. Contains JSONP validation regular expression to
* test the validness of the JSONP callback. The valid callbacks are simple
* functions like myJsFunction or simple object path looking like:
* something1.something2.something3 .
* See {@linkplain ninja.template.TemplateEngineJsonPValidatorTest} for supported cases tests.
* This is a subset of rules from the
* following article:
*
* @see <a href="http://tav.espians.com/sanitising-jsonp-callback-identifiers-for-security.html">Sanitizing JSONP callbacks</a>
*/
@Singleton
public class TemplateEngineJsonP implements TemplateEngine {

    private final Logger logger = LoggerFactory.getLogger(TemplateEngineJsonP.class);

    static final String DEFAULT_CALLBACK_PARAMETER_NAME = "callback";

    static final String DEFAULT_CALLBACK_PARAMETER_VALUE = "onResponse";

    static final Pattern CALLBACK_SECURITY_VALIDATION_REGEXP
            = Pattern.compile("^([a-zA-Z$_]{1}[a-zA-Z0-9$_.]*[a-zA-Z0-9$_]{1}){1,}$");

    private final ObjectMapper objectMapper;

    private final String callbackParameterName;

    @Inject
    public TemplateEngineJsonP(ObjectMapper objectMapper, NinjaProperties properties) {

        this.objectMapper = objectMapper;
        this.callbackParameterName = properties.getWithDefault(
                NinjaConstant.NINJA_JSONP_CALLBACK_PARAMETER,
                DEFAULT_CALLBACK_PARAMETER_NAME);
    }

    @Override
    public void invoke(Context context, Result result) {
        ResponseStreams responseStreams = context.finalizeHeaders(result);
        String callback = getCallbackName(context);
        try (OutputStream outputStream = responseStreams.getOutputStream()) {
            objectMapper.writeValue(outputStream, new JSONPObject(callback, result.getRenderable()));
        } catch (IOException e) {
            logger.error("Error while rendering jsonp.", e);
        }
    }

    @Override
    public String getContentType() {
        return Result.APPLICATON_JSONP;
    }

    @Override
    public String getSuffixOfTemplatingEngine() {
        // intentionally returns null...
        return null;
    }

    private String getCallbackName(Context context) {
        String callback = context.getParameter(this.callbackParameterName, DEFAULT_CALLBACK_PARAMETER_VALUE);
        return isThisASecureCallbackName(callback) ? callback : DEFAULT_CALLBACK_PARAMETER_VALUE;
    }

    /**
     * Tests whether the given function name is a valid JSONP function
     * name/path.
     *
     * @param callback Callback value to test.
     * @return Whether the given function name is a valid JSONP function
     * name/path.
     */
    public static boolean isThisASecureCallbackName(String callback) {
        return !Strings.isNullOrEmpty(callback)
                && !callback.contains("..")
                && CALLBACK_SECURITY_VALIDATION_REGEXP.matcher(callback).matches();
    }
}
TOP

Related Classes of ninja.template.TemplateEngineJsonP

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.