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

com.icegreen.greenmail.standalone.GreenMailApiResource Maven / Gradle / Ivy

There is a newer version: 2.1.0-rc-1
Show newest version
package com.icegreen.greenmail.standalone;

import com.icegreen.greenmail.configuration.GreenMailConfiguration;
import com.icegreen.greenmail.store.FolderException;
import com.icegreen.greenmail.store.MailFolder;
import com.icegreen.greenmail.user.GreenMailUser;
import com.icegreen.greenmail.user.UserException;
import com.icegreen.greenmail.user.UserManager;
import com.icegreen.greenmail.util.GreenMail;
import com.icegreen.greenmail.util.ServerSetup;
import jakarta.ws.rs.*;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Response;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Scanner;

/**
 * Exposes GreenMail API and openapi.
 */
@Path("/")
public class GreenMailApiResource {
    private static final Logger LOG = LoggerFactory.getLogger(GreenMailApiResource.class);
    private final GreenMail greenMail;
    private final ServerSetup[] serverSetups;
    private final GreenMailConfiguration configuration;

    public GreenMailApiResource(GreenMail greenMail, ServerSetup[] serverSetups, GreenMailConfiguration configuration) {
        this.greenMail = greenMail;
        this.serverSetups = serverSetups;
        this.configuration = configuration;
    }

    // UI
    private static final String INDEX_CONTENT = loadResource("index.html");
    private static final String OPENAPI_CONTENT = loadResource("greenmail-openapi.yml");

    private static String loadResource(String name) {
        try (InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(name)) {
            return new Scanner(is, StandardCharsets.UTF_8.name()).useDelimiter("\\A").next();
        } catch (IOException | NullPointerException e) {
            throw new IllegalArgumentException("Can not load resource " + name + " from classpath", e);
        }
    }

    @GET
    @Produces("text/html")
    public String index() {
        return INDEX_CONTENT;
    }

    @Path("/greenmail-openapi.yml")
    @GET
    @Produces("application/yaml")
    public String openapi() {
        return OPENAPI_CONTENT;
    }

    // General
    abstract static class AbstractMessage {
        private final String message;

        protected AbstractMessage(String message) {
            this.message = message;
        }

        public String getMessage() {
            return message;
        }
    }

    static class SuccessMessage extends AbstractMessage {
        protected SuccessMessage(String message) {
            super(message);
        }
    }

    static class ErrorMessage extends AbstractMessage {
        protected ErrorMessage(String message) {
            super(message);
        }
    }

    // Configuration
    static class Configuration {
        public ServerSetup[] serverSetups;
        public boolean authenticationDisabled;
        public boolean sieveIgnoreDetail;
        public String preloadDirectory;
    }

    @GET
    @Path("/api/configuration")
    @Produces("application/json")
    public Response configuration() {
        final Configuration config = new Configuration();
        config.serverSetups = serverSetups;
        config.authenticationDisabled = configuration.isAuthenticationDisabled();
        config.sieveIgnoreDetail = configuration.isSieveIgnoreDetailEnabled();
        config.preloadDirectory = configuration.getPreloadDir();
        return Response.status(Response.Status.OK)
            .entity(config)
            .build();
    }

    // User
    public static class User {
        public String email;
        public String login;
        public String password;
    }

    /**
     * Custom mapped, see {@link JacksonObjectMapperProvider.GreenMailUserSerializer}
     */
    @GET
    @Path("/api/user")
    @Produces("application/json")
    public Collection listUsers() {
        return greenMail.getUserManager().listUser();
    }

    @POST
    @Path("/api/user")
    @Consumes({MediaType.APPLICATION_JSON})
    @Produces("application/json")
    public Response createUsers(User newUser) {
        try {
            final GreenMailUser user = greenMail.getUserManager().createUser(newUser.email, newUser.login, newUser.password);
            LOG.debug("Created user {}", user);
            return Response.status(Response.Status.OK)
                .entity(user)
                .build();
        } catch (UserException e) {
            return Response.status(Response.Status.BAD_REQUEST)
                .entity(new ErrorMessage("Can not create user : " + e.getMessage()))
                .build();
        }
    }

    @DELETE
    @Path("/api/user/{emailOrLogin}")
    @Produces("application/json")
    public Response deleteUserById(@PathParam("emailOrLogin") String emailOrLogin) {
        final UserManager userManager = greenMail.getUserManager();
        final GreenMailUser user = getUserByLoginOrEmail(emailOrLogin, userManager);
        if (null == user) {
            return Response.status(Response.Status.BAD_REQUEST)
                .entity(new ErrorMessage("User '" + emailOrLogin + "' not found")).build();
        }
        LOG.debug("Deleting user {}", user);
        userManager.deleteUser(user);
        return Response.status(Response.Status.OK)
            .entity(new SuccessMessage("User '" + emailOrLogin + "' deleted")).build();
    }

    /**
     * Gets emails for existing user and INBOX folder.
     *
     * @param emailOrLogin the user email or login.
     *                     Custom mapped, see {@link JacksonObjectMapperProvider.StoredMessageSerializer}
     */
    @GET
    @Path("/api/user/{emailOrLogin}/messages/")
    @Produces("application/json")
    public Response listMessages(@PathParam("emailOrLogin") String emailOrLogin) {
        return listMessages(emailOrLogin, null);
    }

    /**
     * Gets emails for existing user and given folder.
     *
     * @param emailOrLogin the user email or login.
     * @param folderName   the name of the folder. Defaults to INBOX.
     *                     Custom mapped, see {@link JacksonObjectMapperProvider.StoredMessageSerializer}
     */
    @GET
    @Path("/api/user/{emailOrLogin}/messages/{folderName}/")
    @Produces("application/json")
    public Response listMessages(@PathParam("emailOrLogin") String emailOrLogin, @PathParam("folderName") String folderName) {
        final UserManager userManager = greenMail.getUserManager();
        final GreenMailUser user = getUserByLoginOrEmail(emailOrLogin, userManager);
        if (null == user) {
            return Response.status(Response.Status.BAD_REQUEST)
                .entity(new ErrorMessage("User '" + emailOrLogin + "' not found")).build();
        }
        MailFolder folder = getFolderOrDefault(user, folderName);
        if (null == folder) {
            return Response.status(Response.Status.BAD_REQUEST)
                .entity(new ErrorMessage("User '" + emailOrLogin + "' does not have mailbox folder '" + folderName + "'")).build();
        }

        return Response.status(Response.Status.OK)
            .entity(folder.getMessages()).build();
    }

    private static GreenMailUser getUserByLoginOrEmail(String emailOrLogin, UserManager userManager) {
        LOG.debug("Searching user using '{}'", emailOrLogin);
        GreenMailUser user = userManager.getUser(emailOrLogin);
        if (null == user) {
            user = userManager.getUserByEmail(emailOrLogin);
        }
        return user;
    }

    private MailFolder getFolderOrDefault(GreenMailUser user, String folderName) {
        LOG.debug("Getting for user '{}' folder '{}'", user.getEmail(), folderName);
        if (null == folderName || folderName.isEmpty()) {
            try {
                return greenMail.getManagers().getImapHostManager().getInbox(user);
            } catch (FolderException e) {
                return null;
            }
        } else {
            return greenMail.getManagers().getImapHostManager().getFolder(user, folderName);
        }
    }

    // Operations
    @POST
    @Path("/api/mail/purge")
    @Produces("application/json")
    public AbstractMessage purge() {
        try {
            greenMail.purgeEmailFromAllMailboxes();
            return new SuccessMessage("Purged mails");
        } catch (FolderException e) {
            return new ErrorMessage("Can not purge mails : " + e.getMessage());
        }
    }

    @POST
    @Path("/api/service/reset")
    @Produces("application/json")
    public AbstractMessage reset() {
        greenMail.reset();
        return new SuccessMessage("Performed reset");
    }


    @GET
    @Path("/api/service/readiness")
    @Produces("application/json")
    public Response ready() {
        if (greenMail.isRunning()) {
            return Response.status(Response.Status.OK)
                .entity(new SuccessMessage("Service running")).build();
        } else {
            return Response.status(Response.Status.SERVICE_UNAVAILABLE)
                .entity(new SuccessMessage("Service not running")).build();
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy