# Square OAuth Serverless Example

## Overview

This example demonstrates a Python implementation of the Square OAuth flow with all the good practices.
The example is writen with [**Chalice**](https://github.com/aws/chalice) serverless microframework, and
use [Dynamodb](https://aws.amazon.com/dynamodb/) to store Square OAuth tokens.

For more information, see [Square OAuth Overview](https://developer.squareup.com/docs/auth), along with the
comments included in this project.

## Getting started

### Add OAuth Credentials and encryption key

Open `.chalice/config.json`:

- Add a new environment variable `application_id`, and fill value with your sandbox application's ID, which is available on your
  [Square Developer Dashboard](https://developer.squareup.com/apps).

- Add a new environment variable `application_secret`, and fill value with your sandbox application's secret, also available on your
  [Square Developer Dashboard](https://developer.squareup.com/apps).

- Add a new environment variable `token_encrypt_secret` with the key value which is generated by following python script:

  ```Python
  >>> from cryptography.fernet import Fernet
  >>> key = Fernet.generate_key()
  >>> print(key.decode())
  ```

> **NOTE**: Changing the encryption key can be a broken change after service is in use, so make sure you've migrated all the OAuth tokens in the database before replace the key completely, otherwise you'll lose the valid OAuth tokens.

```json
"environment_variables": {
  ...
  "application_id": "REPLACE_WITH_SANDBOX_APPLICATION_ID",
  "application_secret": "REPLACE_WITH_SANDBOX_APPLICATION_SECRET",
  "token_encrypt_secret": "REPLACE_WITH_TOKEN_ENCRYPT_SECRET",
  ...
}
```

> **NOTE**: **DO NOT** check in your _application_secret_ to git repo.

### Setup and deploy

1. install [**Chalice**](https://github.com/aws/chalice) and all the project dependencies, **Chalice** is a
   microframework for writing serverless apps in Python. We use this microframework to manage all the elasticsearch management tasks.

   ```bash
   pip install -r requirements.txt
   ```

1. Follow [**this Credentials section**](https://github.com/aws/chalice#credentials) to setup aws credentials.

1. Deploy to lambda:
   ```bash
   chalice deploy
   ```

## Test

1. After deploy, find the API gateway host domain from the lambda dev console, Add `https://{host_domain}/api/authorize-callback`
   to the **Sandbox Redirect URL** on the application dashboard.

1. Open this link to create the OAuthTable in DynamoDB `https://{host_domain}/api/createOAuthTable`, you should see **Table Created** if the table created successfully, then you can find the table `oauth_users` from your Dynamodb console.

1. Sign in [Square Developer Dashboard](https://developer.squareup.com/apps), launch the sandbox dashboard from the dashboard.

1. Open authorize endpoint `https://{host_domain}/api/authorize`, click "Click here" to finish the OAuth step.

   > Note: make sure you use the same **host_domain** for both `authorize` and `authorize-callback` endpoints.

## All endpoints in the example

Once setup the example, you can play with these endpoints.

- `https://{host_domain}/api/authorize` - entry point to start authorization with Square merchant.

- `https://{host_domain}/api/authorize-callback` - The endpoint that handles Square authorization callback, you don't visit this url directly.

- `https://{host_domain}/api/revokeOAuthToken/{merchant_id}` - The endpoint that revoke all the access token from the specified merchant for this application. You can find the merchant_id from dynamodb table `oauth_users`.

- `https://{host_domain}/api/checkAccessTokenStatus/{merchant_id}` - The endpoint that check access token status of a merchant. You can find the merchant_id from dynamodb table `oauth_users`.

- `https://{host_domain}/api/createOAuthTable` - The endpoint that create a OAuth table in db if not exists.

## Token encryption thoughts

In this example, we use **cryptography** to encrypt and decrypt OAuth tokens and you have to save your encryption
key muanually as the environment variable.

You can use [AWS Key Management Service (KMS)](https://docs.aws.amazon.com/kms/latest/developerguide/overview.html)
or other similar services to protect your key.

## Feedback

Rate this sample app [here](https://delighted.com/t/Z1xmKSqy)!
