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

org.shredzone.acme4j.smime.wrapper.SimpleMail Maven / Gradle / Ivy

The newest version!
/*
 * acme4j - Java ACME client
 *
 * Copyright (C) 2023 Richard "Shred" Körber
 *   http://acme4j.shredzone.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 */
package org.shredzone.acme4j.smime.wrapper;

import static java.util.Objects.requireNonNull;
import static java.util.stream.Collectors.toUnmodifiableList;

import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Locale;
import java.util.Optional;

import jakarta.mail.Message;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.InternetAddress;
import org.shredzone.acme4j.smime.exception.AcmeInvalidMessageException;

/**
 * Represents a simple, unsigned {@link Message}.
 * 

* There is no signature validation at all. Use this class only for testing purposes, * or if a validation has already been performed in a separate step. * * @since 2.16 */ public class SimpleMail implements Mail { private static final String HEADER_MESSAGE_ID = "Message-ID"; private static final String HEADER_AUTO_SUBMITTED = "Auto-Submitted"; private final Message message; public SimpleMail(Message message) { this.message = requireNonNull(message, "message"); } @Override public InternetAddress getFrom() throws AcmeInvalidMessageException { try { var from = message.getFrom(); if (from == null) { throw new AcmeInvalidMessageException("Missing required 'From' header"); } if (from.length != 1) { throw new AcmeInvalidMessageException("Message must have exactly one sender, but has " + from.length); } if (!(from[0] instanceof InternetAddress)) { throw new AcmeInvalidMessageException("Invalid sender message type: " + from[0].getClass().getName()); } return (InternetAddress) from[0]; } catch (MessagingException ex) { throw new AcmeInvalidMessageException("Could not read 'From' header", ex); } } @Override public InternetAddress getTo() throws AcmeInvalidMessageException { try { var to = message.getRecipients(Message.RecipientType.TO); if (to == null) { throw new AcmeInvalidMessageException("Missing required 'To' header"); } if (to.length != 1) { throw new AcmeInvalidMessageException("Message must have exactly one recipient, but has " + to.length); } if (!(to[0] instanceof InternetAddress)) { throw new AcmeInvalidMessageException("Invalid recipient message type: " + to[0].getClass().getName()); } return (InternetAddress) to[0]; } catch (MessagingException ex) { throw new AcmeInvalidMessageException("Could not read 'To' header", ex); } } @Override public String getSubject() throws AcmeInvalidMessageException { try { var subject = message.getSubject(); if (subject == null) { throw new AcmeInvalidMessageException("Message must have a subject"); } return subject; } catch (MessagingException ex) { throw new AcmeInvalidMessageException("Could not read 'Subject' header", ex); } } @Override public Collection getReplyTo() throws AcmeInvalidMessageException { try { var rto = message.getReplyTo(); if (rto == null) { return Collections.emptyList(); } return Arrays.stream(rto) .filter(InternetAddress.class::isInstance) .map(InternetAddress.class::cast) .collect(toUnmodifiableList()); } catch (MessagingException ex) { throw new AcmeInvalidMessageException("Could not read 'Reply-To' header", ex); } } @Override public Optional getMessageId() throws AcmeInvalidMessageException { try { var mid = message.getHeader(HEADER_MESSAGE_ID); if (mid == null || mid.length == 0) { return Optional.empty(); } if (mid.length > 1) { throw new AcmeInvalidMessageException("Expected one Message-ID, but found " + mid.length); } return Optional.of(mid[0]); } catch (MessagingException ex) { throw new AcmeInvalidMessageException("Could not read '" + HEADER_MESSAGE_ID + "' header", ex); } } @Override public boolean isAutoSubmitted() throws AcmeInvalidMessageException { try { var autoSubmitted = message.getHeader(HEADER_AUTO_SUBMITTED); if (autoSubmitted == null) { return false; } return Arrays.stream(autoSubmitted) .map(String::trim) .map(as -> as.toLowerCase(Locale.ENGLISH)) .anyMatch(h -> h.equals("auto-generated") || h.startsWith("auto-generated;")); } catch (MessagingException ex) { throw new AcmeInvalidMessageException("Could not read '" + HEADER_AUTO_SUBMITTED + "' header", ex); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy