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

network.oxalis.as2.util.MimeMessageHelper Maven / Gradle / Ivy

/*
 * Copyright 2010-2018 Norwegian Agency for Public Management and eGovernment (Difi)
 *
 * Licensed under the EUPL, Version 1.1 or – as soon they
 * will be approved by the European Commission - subsequent
 * versions of the EUPL (the "Licence");
 *
 * You may not use this work except in compliance with the Licence.
 *
 * You may obtain a copy of the Licence at:
 *
 * https://joinup.ec.europa.eu/community/eupl/og_page/eupl
 *
 * Unless required by applicable law or agreed to in
 * writing, software distributed under the Licence is
 * distributed on an "AS IS" basis,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied.
 * See the Licence for the specific language governing
 * permissions and limitations under the Licence.
 */

package network.oxalis.as2.util;

import com.google.common.io.ByteStreams;
import network.oxalis.commons.bouncycastle.BCHelper;
import network.oxalis.vefa.peppol.common.model.Digest;

import javax.activation.DataHandler;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.InternetHeaders;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.util.ByteArrayDataSource;
import java.io.*;
import java.security.DigestOutputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Collections;
import java.util.Enumeration;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Collection of useful methods for manipulating MIME messages.
 *
 * @author Steinar Overbeck Cook
 * @author Thore Johnsen
 * @author Arun Kumar
 */
public class MimeMessageHelper {

    private static final Session SESSION = Session.getDefaultInstance(System.getProperties(), null);

    /**
     * Creates a MIME message from the supplied stream, which must contain headers,
     * especially the header "Content-Type:"
     */
    public static MimeMessage parse(InputStream inputStream) throws MessagingException {
        return new MimeMessage(SESSION, inputStream);
    }

    /**
     * Creates a MIME message from the supplied InputStream, using values from the HTTP headers to
     * do a successful MIME decoding.
     */
    public static MimeMessage parse(InputStream inputStream, InternetHeaders headers)
            throws MessagingException {

        return parse(inputStream,
                Collections.list((Enumeration) headers.getAllHeaderLines())
                        .stream()
                        .map(String.class::cast));
    }

    /**
     * Parses a complete MIME message with provided headers.
     *
     * @param inputStream Content part of MIME message.
     * @param headers     Headers provided as a stream of Strings.
     * @return Parsed MIME message.
     * @throws MessagingException Thrown when content is successfully parsed.
     * @since 4.0.2
     */
    public static MimeMessage parse(InputStream inputStream, Stream headers)
            throws MessagingException {

        // Read headers to a string
        String headerString = headers.collect(Collectors.joining("\r\n")) + "\r\n\r\n";

        // Parse content
        return parse(new SequenceInputStream(
                new ByteArrayInputStream(headerString.getBytes()),
                inputStream
        ));
    }

    public static MimeBodyPart createMimeBodyPart(InputStream inputStream, String mimeType) {
        MimeBodyPart mimeBodyPart = new MimeBodyPart();
        ByteArrayDataSource byteArrayDataSource;

        try {
            byteArrayDataSource = new ByteArrayDataSource(inputStream, mimeType);
        } catch (IOException e) {
            throw new IllegalStateException("Unable to create ByteArrayDataSource from inputStream." + e.getMessage(), e);
        }

        try {
            DataHandler dh = new DataHandler(byteArrayDataSource);
            mimeBodyPart.setDataHandler(dh);
        } catch (MessagingException e) {
            throw new IllegalStateException("Unable to set data handler on mime body part." + e.getMessage(), e);
        }

        try {
            mimeBodyPart.setHeader("Content-Type", mimeType);
            mimeBodyPart.setHeader("Content-Transfer-Encoding", "binary");   // No content-transfer-encoding needed for http
        } catch (MessagingException e) {
            throw new IllegalStateException("Unable to set headers." + e.getMessage(), e);
        }

        return mimeBodyPart;
    }

    /**
     * Calculates sha1 mic based on the MIME body part.
     */
    public static Digest calculateMic(MimeBodyPart bodyPart, SMimeDigestMethod digestMethod) {
        try {
            MessageDigest md = BCHelper.getMessageDigest(digestMethod.getIdentifier());
            bodyPart.writeTo(new DigestOutputStream(ByteStreams.nullOutputStream(), md));
            return Digest.of(digestMethod.getDigestMethod(), md.digest());
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalStateException(digestMethod.getIdentifier() + " not found", e);
        } catch (IOException e) {
            throw new IllegalStateException("Unable to read data from digest input. " + e.getMessage(), e);
        } catch (MessagingException e) {
            throw new IllegalStateException("Unable to handle mime body part. " + e.getMessage(), e);
        }
    }

    public static byte[] toBytes(MimeMessage mimeMessage) {
        ByteArrayOutputStream evidenceBytes = new ByteArrayOutputStream();
        try {
            mimeMessage.writeTo(evidenceBytes);
        } catch (IOException | MessagingException e) {
            throw new IllegalStateException("Unable to convert MDN mime message into bytes()", e);
        }

        return evidenceBytes.toByteArray();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy