Email Confirmation Example: Grails

Email confirmation example on Grails application.

User registration is the common part of any web application. And so email confirmation. In this user guide we will walk through how to email confirmation url and validate the email address when the user clicks it.

We will use Grails mail plugin.

compile ":mail:1.0.1"

Next we configure mail on Config.grovvy file.

grails {
    mail {
        host = "smtp.mailgun.org"
        port = 465
        username = "postmaster@user.mailgun.org"
        password = "yourpassword"
        props = ["mail.smtp.auth":"true",
                "mail.smtp.socketFactory.port":"465",
                "mail.smtp.socketFactory.class":"javax.net.ssl.SSLSocketFactory",
                "mail.smtp.socketFactory.fallback":"false"]
    }
}

Also add from email address on the configuration file.

grails.mail.default.from="noreply@yourdomain.com"

Now lets create a User domain object where we store user registration information. You can have any fields you can. For this article email, confirmCode, enabled fields are important.

class User {
    String username
    String password
        String email
    boolean enabled = true
    String confirmCode
}

Lets create a signupController to handle some http requests.

def mailService; at the top the controller, the service will be used to send email.

index method renders the registration page.

def index() {
        [userInstance: new User(params)]
    }

signup method handles the form post after user submits registration information. It create random unique id string and stores along with user information on the database. And then confirmation email is sent. The body of the email is generated using mailtemplate and confirmCode.

def signup() {
    def userInstance = new User(params)
    userInstance.enabled=false;
    userInstance.confirmCode= UUID.randomUUID().toString()
    if (!userInstance.save(flush: true)) {

        return
    }

    mailService.sendMail {
        to userInstance.email
        subject "New User Confirmation"
        html g.render(template:"mailtemplate",model:[code:userInstance.confirmCode])
    }

    render(view: "index", model: [userInstance: userInstance])
    redirect(action: "success")
}

A small helper function to render some common information pages.

def success(){
        render(view:'success', model: [message: 'Your account has been creeated. Please confirm your email address. Confirmation link has been sent to your account']);
    }

Now lets create a confirm handler when user clicks the confirmation link. It check the user with the unique confirmation code and enables the user which completes the registration process.

def confirm(String id)
    {

        User userInstance= User.findByConfirmCode(id)
        if(!userInstance)
        {
            return;
        }

        //userInstance.confirmCode= '';

        userInstance.enabled=true;
        if (!userInstance.save(flush: true)) {
            render(view: "success", model: [message: 'Problem activating account.'])
            return
        }
        render(view: "success", model: [message: 'You account is successfully activated.'])
    }

View used through out the article.

index.gsp
<h1>
    Register yourself!
</h1>
<g:form role="form" class="form-horizontal" method="post" id="form" action="signup">

        <div class="form-group">
            <label class="col-sm-2 control-label" for="username">User name</label>

            <div class="col-sm-10">
                <g:textField class="form-control"  name="username" required="" value="${userInstance?.username}"/>
            </div>

        </div>

        <div class="form-group">
            <label class="col-sm-2 control-label" for="email">Email</label>

            <div class="col-sm-10">
                <g:textField class="col-sm-10 form-control" name="email" required="Email"
                             value="${userInstance?.email}"/>
            </div>
        </div>

        <div class="form-group">
            <label class="col-sm-2 control-label" for="password">Password</label>

            <div class="col-sm-10">
                <g:passwordField class="form-control" name="password" required="" value="${userInstance?.password}"/>
            </div>

        </div>

        <div class="form-group">
            <label class="col-sm-2 control-label" for="confirmPassword">Confirm Password</label>

            <div class="col-sm-10">
                <g:passwordField class="form-control" name="confirmPassword" required="" value=""/>
            </div>

        </div>

        <div class="form-group">
            <label class="col-sm-2 control-label" ></label>
            <div class="col-sm-10">

                <g:submitButton name="create" class="btn btn-primary"
                                value="${message(code: 'default.button.create.label', default: 'Register')}"/>

            </div>
        </div>
</g:form>
_mailtemplate.gsp
<div>
    <h1> Email Confirmation</h1>

    <g:link absolute="true" controller="signUp" action="confirm" id="${code}">Click this link to confirm your account</g:link>

    <g:createLink absolute="true" controller="signUp" action="confirm" id="${code}"></g:createLink>
</div>
success.gsp

view header and footer are excluded.

<div class="container">
    <h1>Registration</h1>
     <div class="alert alert-success">
        ${message}
     </div>
    </div>