io.stallion.plugins.flatBlog.contacts.ContactsEndpoints.java Source code

Java tutorial

Introduction

Here is the source code for io.stallion.plugins.flatBlog.contacts.ContactsEndpoints.java

Source

/*
 * Stallion Flat-file Blog: A simple blog-engine
 *
 * Copyright (C) 2015 - 2016 Stallion Software LLC
 *
 * This program is free software: you can redistribute it and/or modify it under the terms of the
 * GNU General Public License as published by the Free Software Foundation, either version 2 of
 * the License, or (at your option) any later version. 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.  See the GNU General Public
 * License for more details. You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/gpl-2.0.html>.
 *
 */

package io.stallion.plugins.flatBlog.contacts;

import io.stallion.Context;
import io.stallion.exceptions.*;
import io.stallion.exceptions.NotFoundException;
import io.stallion.reflection.PropertyUtils;

import io.stallion.requests.validators.SafeMerger;
import io.stallion.restfulEndpoints.*;
import io.stallion.services.Log;
import io.stallion.settings.Settings;
import io.stallion.templating.TemplateRenderer;
import io.stallion.users.Role;
import io.stallion.utils.DateUtils;
import io.stallion.utils.Sanitize;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.Cookie;
import javax.ws.rs.*;

import java.io.IOException;
import java.net.URL;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import static io.stallion.utils.Literals.*;

public class ContactsEndpoints implements EndpointResource {

    @GET
    @Path("/contacts/my-subscriptions/:token")
    @Produces("text/html")
    @MinRole(Role.ANON)
    public Object mySubscriptions(@PathParam("token") String token) throws Exception {
        URL url = getClass().getClassLoader().getResource("templates/my-subscriptions.jinja");
        Context.getResponse().getMeta().setTitle("My Subscriptions");
        Contact contact = ContactsController.instance().forUniqueKey("secretToken", token);
        if (empty(contact)) {
            throw new io.stallion.exceptions.NotFoundException("Subscriptions for the contact not found.");
        }
        Map ctx = map();
        List<Subscription> subscriptions = SubscriptionController.instance().filter("contactId", contact.getId())
                .all();
        ctx.put("subscriptionsSafeJson", Sanitize.htmlSafeJson(subscriptions));
        ctx.put("contact", Sanitize.htmlSafeJson(contact, "owner"));
        ctx.put("secretToken", Sanitize.htmlSafeJson(contact.getSecretToken()));
        Log.info("Subscriptions contactEmail={0} contactId={1} subs-count={2}", contact.getEmail(), contact.getId(),
                subscriptions.size());
        return TemplateRenderer.instance().renderTemplate(url.toString(), ctx);
    }

    @POST
    @Path("/contacts/subscribe")
    @Produces("text/html")
    @MinRole(Role.ANON)
    public Object resubscribe(@BodyParam("secretToken") String token,
            @BodyParam("subscriptionId") Long subscriptionId) throws Exception {
        Contact contact = ContactsController.instance().forUniqueKey("secretToken", token);
        Subscription subscription = SubscriptionController.instance().forId(subscriptionId);
        if (contact == null || subscription == null || !subscription.getContactId().equals(contact.getId())) {
            throw new ClientException("Forbidden from updating this resource", 403);
        }
        return SubscriptionController.instance().resubscribe(contact, subscriptionId);
    }

    @POST
    @Path("/contacts/unsubscribe")
    @Produces("text/html")
    @MinRole(Role.ANON)
    public Object unsubscribe(@BodyParam("secretToken") String token,
            @BodyParam("subscriptionId") Long subscriptionId) throws Exception {
        URL url = getClass().getClassLoader().getResource("templates/my-subscriptions.jinja");
        Context.getResponse().getMeta().setTitle("My Subscriptions");
        Contact contact = ContactsController.instance().forUniqueKey("secretToken", token);
        Subscription subscription = SubscriptionController.instance().forId(subscriptionId);
        if (contact == null || subscription == null || !subscription.getContactId().equals(contact.getId())) {
            throw new ClientException("Forbidden from updating this resource", 403);
        }
        return SubscriptionController.instance().unsubscribe(contact, subscriptionId);
    }

    @POST
    @Path("/contacts/resend-verify/:secretToken")
    public Object resendVerify(@PathParam("secretToken") String secret) throws IOException {
        Contact contact = ContactsController.instance().forUniqueKey("secretToken", secret);
        if (contact == null) {
            throw new NotFoundException("Could not find a contact record");
        }
        SubscriptionController.instance().enqueueVerifyOptIn(contact);
        return true;
    }

    @GET
    @Path("/contacts/verify-subscribe/:secretToken")
    @Produces("text/html")
    public String verifySubscribe(@PathParam("secretToken") String secret) throws IOException {
        Contact contact = ContactsController.instance().forUniqueKey("secretToken", secret);
        if (contact == null) {
            throw new NotFoundException("Could not find a contact record");
        }
        contact.setOptInAt(DateUtils.mils());
        contact.setVerifiedOptIn(true);
        contact.setVerifiedEmail(true);
        ContactsController.instance().save(contact);

        URL url = getClass().getClassLoader().getResource("templates/my-subscriptions.jinja");
        Map ctx = map(val("contactId", contact.getId().toString()), val("secretToken", contact.getSecretToken()));
        return TemplateRenderer.instance().renderTemplate(url.toString(), ctx);

    }

    @GET
    @Path("/contacts/decline-subscribe/:secretToken")
    @Produces("text/html")
    public String declineSubscribe(@PathParam("secretToken") String secret) throws IOException {
        Contact contact = ContactsController.instance().forUniqueKey("secretToken", secret);
        if (contact == null) {
            throw new NotFoundException("Could not find a contact record");
        }
        contact.setVerifyRejectedAt(DateUtils.mils());
        contact.setVerifiedOptIn(false);
        ContactsController.instance().save(contact);
        URL url = getClass().getClassLoader().getResource("templates/my-subscriptions.jinja");
        Map ctx = map(val("contactId", contact.getId().toString()), val("secretToken", contact.getSecretToken()));
        return TemplateRenderer.instance().renderTemplate(url.toString(), ctx);
    }

    @POST
    @Path("/contacts/submit-form")
    public Boolean submitForm(@ObjectParam FormSubmission rawSubmission) {
        FormSubmission submission = SafeMerger.with().nonEmpty("data")
                .optional("formName", "pageUrl", "pageTitle", "formId").optionalEmail("email").merge(rawSubmission);
        Cookie everCookie = Context.request().getCookie("st-evercookie");
        Contact contact = null;
        if (!empty(submission.getEmail())) {
            contact = ContactsController.instance().forUniqueKey("email", submission.getEmail());
        } else if (empty(submission.getEmail()) && everCookie != null && !empty(everCookie.getValue())) {
            contact = ContactsController.instance().forUniqueKey("everCookie", everCookie.getValue());
            submission.setEmail(contact.getEmail());
        }
        if (empty(submission.getEmail())) {
            throw new ClientException("A valid email is required to submit a form to the contacts endpoint!", 422);
        }
        if (contact == null) {
            contact = new Contact().setEmail(submission.getEmail());
        }
        if (everCookie == null || empty(everCookie.getValue()) && empty(contact.getEverCookie())) {
            contact.setEverCookie(UUID.randomUUID().toString());
        }
        Context.response().addCookie("st-evercookie", contact.getEverCookie(), 365 * 20 * 86400);

        for (Map.Entry<String, Object> entry : submission.getData().entrySet()) {
            if (PropertyUtils.isWriteable(contact, entry.getKey())) {
                if (Contact.SETTABLE_FIELDS.contains(entry.getKey())) {
                    PropertyUtils.setProperty(contact, entry.getKey(), entry.getValue());
                }
            } else {
                contact.put(entry.getKey(), entry.getValue());
            }

        }

        ContactsController.instance().save(contact);

        submission.setEverCookie(contact.getEverCookie()).setContactId(contact.getId()).setSubmittedAt(mils());
        FormSubmissionController.instance().save(submission);

        FormSubmissionEmailTaskHandler.enqueue(submission);

        return true;
    }
}