mailspree

package module
v0.0.0-...-fb80ee1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 7, 2016 License: MIT Imports: 5 Imported by: 0

README

Build Status Coverage Status GoDoc Dockerhub

Mailspree

Mailspree is a mailing service which delegates mailsending to different mail service providers. It aims to be fault tolerant, failing over to another mail service provider if there was a problem with the one that tried to send the email.

Architecture

Mailspree is written in go which is great for writing services. Mailspree is exposed as a http api, with token authentication. It currently supports mailgun and sendgrid. It has a simple circuit breaker, which prevents a mail service from being used for some time, if it has been having problems.

HTTP API Reference

The http api is documented in the api reference

Installation

The easiest way to run the mailspree service is using docker. You can either grab the latest image from dockerhub blacksails/mailspree, or build the image from source using the following instructions:

git clone git@github.com:blacksails/mailspree.git
cd mailspree-ui
npm install
npm run build
docker build -t blacksails/mailspree .

Instead of using docker run you can save a create an environment varibale file in the directory, called mailspree-vars.env, which contains the environment variable. See the mailspree-vars.env.example file for an example. Then run the mailspree container with docker compose.

docker-compose up

Caveats

Currently the api allows that the consumer supplies the from email, which can be problematic due to SPF checks.

Say a user wants to send an eamil from test@test.com to someone, when we send the email, the mail service that we used for sending the email will be checked against the SPF record of test.com, and it might very well get bounced.

Therefore you should be sure that the mailing services you have configured with mailspree, are allowed to send mails from the domain that you want as the sender.

Future ideas

I was making this project with a set time, and there are certainly areas in the application that would be nice to improve. To read more about these, checkout the issues.

Demo

To see a demo of the project go to the mailspree-ui project and follow the instructions.

Acknowledgements

I am new to the go eco system. I started looking into go during my summer holidays 2016. There might and most likely are pieces of the code that could be written more go idiomatic.

Credits

Author: Benjamin Nørgaard (blacksails)

Documentation

Overview

Package mailspree contains all of the mailspree domain models and interfaces. Implementation of interfaces is generally put into subpackages named by the main dependency which that particular implementaion is based upon.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type AuthService

type AuthService interface {
	Authenticate(User, string) (string, error)
	Validate(string, UserService) (User, error)
}

AuthService is a common interface to token authentication. Authenticate takes a User and a password, and returns a token if they match. Validate takes a token and returns a user if it is valid

type CircuitBreakerTimer

type CircuitBreakerTimer interface {
	// Run starts a timer which returns an int when it runs out
	Run() <-chan int
}

CircuitBreakerTimer is an interface to the timer used when the channel is open. This is defined as an interface so that we can make a mock implementation

func NewCircuitBreakerTimer

func NewCircuitBreakerTimer() CircuitBreakerTimer

NewCircuitBreakerTimer returns a CircuitBreakerTimer which runs out after 30 seconds.

type Email

type Email struct {
	Name    string `json:"name"`
	Address string `json:"address" valid:"email,required"`
}

Email is simply a real name together with the address

func (Email) String

func (e Email) String() string

String returns a string representation of an Email

type MailingProvider

type MailingProvider interface {
	SendEmail(Message) error
}

MailingProvider abstacts different mailing providers.

func NewCircuitBreaker

func NewCircuitBreaker(mp MailingProvider, t CircuitBreakerTimer) MailingProvider

NewCircuitBreaker wraps a mailing provider with a circuit breaker.

type MailingProviders

type MailingProviders []MailingProvider

MailingProviders is a list of MailingProvider implementations

func (MailingProviders) SendEmail

func (mps MailingProviders) SendEmail(m Message) error

SendEmail runs through the mailing providers and tries to send the email. Returns on first successful try. This also makes MailingProviders be a MailingProvider, which is a bit fun.

type Message

type Message struct {
	From    Email   `json:"from" valid:"required"`
	To      []Email `json:"to" valid:"required"`
	Subject string  `json:"subject" valid:"required"`
	Body    string  `json:"body" valid:"required"`
}

Message represents an email with all the related information.

type NewSession

type NewSession struct {
	Username string `json:"username" valid:"required"`
	Password string `json:"password" valid:"required"`
}

NewSession is what the api receives in order to login a user

type Session

type Session struct {
	Username string `json:"username"`
	Token    string `json:"token"`
}

Session is returned on a successful login

type SimpleUserService

type SimpleUserService struct {
	User User
}

SimpleUserService only has a single user. A lookup for any other user will return an error.

func (SimpleUserService) Find

func (us SimpleUserService) Find(username string) (User, error)

Find checks if the given username matches the one of the User set in the SimpleUserService. If it does, the user is returned otherwise we get a not found error.

type User

type User struct {
	Username     string
	PasswordHash []byte
}

User represents a user of the mailspree system

func NewUser

func NewUser(username, password string) User

NewUser creates a new user from a username and a password.

func (User) CheckPassword

func (u User) CheckPassword(p string) bool

CheckPassword checks if the given password is correct

func (*User) SetPassword

func (u *User) SetPassword(p string)

SetPassword takes a cleartext password and sets the user password.

type UserService

type UserService interface {
	Find(string) (User, error)
}

UserService is a common interface for retrieving Users from usernames. This will make it easy to swap out with a database.

Directories

Path Synopsis
cmd
mailspree
The command mailspree starts a mailspree server.
The command mailspree starts a mailspree server.
Package http contains all the http api logic which serves as the interface to the mailspree service.
Package http contains all the http api logic which serves as the interface to the mailspree service.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL