DEPRECATED - Migrated to https://github.com/mozilla/fxa
Перейти к файлу
Beatriz Rizental eddeb9a97e Release v1.118.0 (#165) 2018-08-09 14:55:55 -04:00
.circleci Setup Circle CI to create docker images (#87) r=@jrgm 2018-06-26 17:50:40 -04:00
config chore(config): change aws region defaults for dev and prod (#154) r=@vladikoff,@philbooth 2018-08-02 16:41:28 -04:00
scripts refactor(settings): drop NODE_ENV and add LOG_LEVEL (#141) r=@vladikoff 2018-07-25 20:50:32 -04:00
src chore(queues): use mozlog and failure in queues process (#161) r=@vladikoff,@philbooth 2018-08-08 20:24:14 -04:00
.gitignore feat(db): check the emailBounces table before sending email 2018-05-16 05:25:08 +01:00
.rustfmt.toml chore(project): inch closer towards the default rustfmt config 2018-05-16 08:34:54 +01:00
.travis.yml chore(deps): update rocket, failure, rusoto and rust versions 2018-08-08 09:43:34 -07:00
CHANGELOG.md Release v1.118.0 (#165) 2018-08-09 14:55:55 -04:00
Cargo.lock Release v1.118.0 (#165) 2018-08-09 14:55:55 -04:00
Cargo.toml Release v1.118.0 (#165) 2018-08-09 14:55:55 -04:00
Dockerfile chore(deps): update rocket, failure, rusoto and rust versions 2018-08-08 09:43:34 -07:00
LICENSE chore(project): add the MPL 2018-05-04 07:14:43 +01:00
README.md chore(docs): automatically publish rustdoc output to github pages 2018-07-04 23:01:46 +01:00
RELEASE.md chore(docs): improve release doc (#144) 2018-07-26 00:35:51 -04:00
r feat(docs): generate developer docs with rustdoc 2018-07-04 20:53:21 +01:00
rq chore(queues): split out a separate process for queue-handling 2018-05-29 09:01:54 +01:00
t chore(queues): split out a separate process for queue-handling 2018-05-29 09:01:54 +01:00
tdb chore(queues): split out a separate process for queue-handling 2018-05-29 09:01:54 +01:00
version.json feat(project): create healthcheck endpoints and make $PORT an env variable (#134) r=@philbooth,@vladikoff 2018-07-18 12:37:30 -04:00

README.md

fxa_email_service

Build status CircleCI License Under construction

What's this?

The FxA team have an OKR for Q2 2018 about decoupling the auth server from SES and making it possible to send email via different providers. You can read more about that OKR in the feature doc.

This repo is our experiment to see what a decoupled email-sending service would look like. It's being written in Rust.

Moving to a new service seems risky. How will that work?

As a first step, we're doing a like-for-like extraction of functionality from the auth server and porting it to Rust behind a very simple, single-endpoint API. The plan is to run it on a closed port on the same box as the auth server, similar to how we run the auth db server.

Included in the code earmarked for extraction is the logic for handling bounce, complaint and delivery notifications. Because this logic is stateful, the initial plan is for the new service to lean on the db server directly and re-use the same table and stored procedures that are already being used. So in that sense, the switchover should be transparent and we can even run the new service side-by-side with the current auth server, if we want to phase it in gradually.

What are the long-term goals?

Ultimately, if everything goes to plan, we'd like to run this as a standalone service that can be used by other trusted reliers from the Firefox/Application Services ecosystem. But getting to that point will require a number of features that are out of scope for the initial release, such as authentication, rate-limiting and a dedicated database.

How will you make sure the new service isn't just as tightly coupled to SES?

The core functionality is going to be exposed behind traits and we will limit the AWS-specific code to AWS-specific trait implementations. To keep ourselves honest about that separation, we will also implement an alternative provider that email can be routed by on a per-request basis.

How can I set up a dev environment?

We're running on the Rust nightly channel, so the easiest way to get set up is with rustup:

curl https://sh.rustup.rs -sSf | sh

If you don't want to use nightly as your default channel, you can use it just for this repo instead by installing nightly and then running rustup override in this directory:

rustup install nightly
rustup override set nightly

You will also need to install Redis. If your Redis instance is not running on the default port (6379), you will need to set the correct port in config/local.json:

{
  "redis": {
    "port": "..."
  }
}

You can also set host in the same way, if your Redis instance is not running locally.

You can find out more about the structure of the code from the developer docs.

How do I run the tests?

A simple cargo t will fail because some of the tests are not threadsafe (they rely on setting environment variables that will conflict with other concurrent tests). To run the tests in a single thread instead, a shell script is provided to save you some keystrokes:

./t

That script assumes you have an instance of fxa-auth-db-mysql running locally on port 8000, which will be the case if you're running fxa-local-dev.

If that's not the case, don't worry. There is another script provided to save you even more keystrokes:

./tdb

That script will clone a local copy of the db repo and start it in the background. At the end of the script, the db process will be left running in the background (but subsequent runs of the script won't start extra db processes, you'll only be left with that one). If you want to kill your db process, you can find it with:

ps -ef | grep "node bin/server"

How can I send an email via SES?

You'll need to set up some config with your AWS credentials. That can be with environment variables:

  • FXA_EMAIL_AWS_KEYS_ACCESS
  • FXA_EMAIL_AWS_KEYS_SECRET

Or in config/local.json:

{
  "aws": {
    "keys": {
      "access": "...",
      "secret": "..."
    }
  }
}

config/local.json is included in .gitignore, so you don't have to worry about your keys being accidentally leaked on GitHub.

Also note that the AWS IAM limits sending to approved from addresses. Again, you can set that via environment variables:

  • FXA_EMAIL_SENDER_ADDRESS
  • FXA_EMAIL_SENDER_NAME

Or in config/local.json:

  "sender": {
    "address": "verification@latest.dev.lcip.org",
    "name": "Firefox Accounts"
  },

Once you have config set, you can start the service with:

cargo r --bin fxa_email_send

Then you can use curl to send requests:

curl \
  -d '{"to":"foo@example.com","subject":"bar","body":{"text":"baz"}}' \
  -H 'Content-Type: application/json' \
  http://localhost:8001/send

If everything is set-up correctly, you should receive email pretty much instantly.

How can I send an email via Sendgrid?

The process is broadly the same as for SES. First set your Sendgrid API key, either using the FXA_EMAIL_SENGRID_KEY environment variable or in config/local.json:

{
  "sendgrid": {
    "key": "..."
  }
}

Then start the service:

cargo r --bin fxa_email_send

Then set provider to sendgrid in your request payload:

curl \
  -d '{"to":"foo@example.com","subject":"bar","body":{"text":"baz"},"provider":"sendgrid"}' \
  -H 'Content-Type: application/json' \
  http://localhost:8001/send

If everything is set-up correctly, you should receive email pretty much instantly.

How do bounce, complaint and delivery notifications work?

For consistency with the implementation in the auth server, three separate SQS queues are monitored for bounce, complaint and delivery notifications. Ultimately we expect to simplify this to a single queue for all three notification types.

Messages on these queues are JSON payloads of the format described in the AWS docs and encoded in src/queues/sqs/notification/mod.rs.

When a message is received, three things happen in sequence:

  1. For bounce and complaint notification types, a bounce record is created in the auth db. Errors are fatal at this point, steps 2 and 3 will not occur if the db returns an error.

  2. The message is forwarded to the auth server via a fourth, outgoing queue. An error here is not fatal.

  3. The message is deleted from the origin queue.

Currently, both the incoming and outgoing queues happen to be SQS queues but, since that's an implementation detail, the code separates them behind more abstract Incoming and Outgoing traits.

The queue URLs and region are set via config, either using environment variables:

  • FXA_EMAIL_AWS_REGION
  • FXA_EMAIL_AWS_SQSURLS_BOUNCE
  • FXA_EMAIL_AWS_SQSURLS_COMPLAINT
  • FXA_EMAIL_AWS_SQSURLS_DELIVERY
  • FXA_EMAIL_AWS_SQSURLS_NOTIFICATION

Or in config/local.json:

{
  "aws": {
    "region": "...",
    "sqsurls": {
      "bounce": "...",
      "complaint": "...",
      "delivery": "...",
      "notification": "..."
    }
  }
}

The queue-handling code runs in a different process to the main email-sending service. You can run it locally like so:

cargo r --bin fxa_email_queues