This repository contains an implementation of the CheckMyMole API. All the endpoints have been described in the Swagger definition.
In order to deploy this project to AWS Lambda, simply commit the changes to this repo and the CI process will take care of everything.
In order to deploy the project manually, run the following:
ENV="dev" # or any stage of your choice
make migrate-$ENV # run the database migrations
make deploy-$ENV # deploy to AWS Lambda
This project uses dep
for dependency management
and migrate
for running database
migrations. Additionally swagger-codegen
is required for swagger.yaml
compilation,
statik
is required for resource embedding
and node
, npm
and serverless
are required for
deployment to AWS Lambda.
In order to run the tests, you will also need a PostgreSQL database. In order to
make setting it up easier, there's a docker-compose.yml
file, which lets you
start a fully configured database using a single command:
docker-compose up -d
After the database is running, you can either run the tests:
# Using ginkgo (more features)
ginkgo -r --randomizeAllSpecs --randomizeSuites --failOnPending --trace --progress
# Or using the standard go test
go test -v ./...
Or start the API using the local database:
export POSTGRES="user=molepatrol password=molepatrol host=localhost dbname=molepatrol sslmode=disable"
migrate -source file://./migrations -database postgres://molepatrol:molepatrol@localhost/molepatrol up
go build -v && ./ml-check-mole-api
.circleci
contains all files related to the CI process,docs
contains all the documentation packages used for resource embedding,migrations
contains all the SQL migrations,pkg
:auth
has all the authentication helpers,models
contains all the data model declarations and a basic CRUD layer,rest
contains an implementation of the REST API,types
contains custom SQL/JSON types,
vendor
is the Go vendor directory,- the root directory contains mostly configuration files
All the CORS configuration is available in serverless.yaml
. The OPTIONS route
is configured by the Serverless software during the deployment.
- Ensure that you have dependencies:
swagger-codegen
statik
sed
- fetched node modules (
npm install
).
- Update
swaggger.yaml
. - Run
make update-docs
.
The API expects an access token from the ap-southeast-2_gfSuuHw6e
AWS Cognito
User Pool to be passed with every single request that requires authentication
in form of an Authorization: Bearer <token>
header. This token must be acquired
as a result of an OAuth2 flow (ie. it must be an OIDC token). It seems that the
serverside username + password configuration does NOT work with the OIDC endpoints.
For JavaScript, AWS recommends using Amplify.js.
In order to test the access token, query the GET /users/me
endpoint.
Please note that there are no "image upload" endpoints, as an AWS Identity Pool has been configured. The credentials are as following:
// Initialize the Amazon Cognito credentials provider
CognitoCachingCredentialsProvider credentialsProvider = new CognitoCachingCredentialsProvider(
getApplicationContext(),
"ap-southeast-2:cd3aaf88-b529-4260-9408-5597eeeea034", // Identity pool ID
Regions.AP_SOUTHEAST_2 // Region
);
The permissions system is set up as following:
- Users who aren't in any group, can only access the public endpoints
(read
/questions
,/body-parts
etc.) and read and write their own data (/users/me/*
). - Doctors can access the "unrestricted" endpoints on top of that (
/reports
,/requests
,/lesions
and so on). - Administrators can access the write endpoints of
/body-parts
and/questions
.
- User authenticates with AWS Cognito, sets up their acount over there etc. Ends up with an access token.
- They load up body parts and questions from /body-parts and /questions respectively.
- User loads up all their requests - GET /users/me/requests
- User creates a new request and marks it as a draft - POST /users/me/requests.
- User loads up all their lesions - GET /users/me/lesions
- User creates a new lesion, selects the location on the body part - POST /users/me/lesions.
- User loads up all their lesions again - GET /users/me/lesions
- User selects a lesion, creates a new report for it - POST /users/me/lesions/:id/reports
- User updates the request to submit it - PUT /users/me/requests/:id
- User waits for the doctor.
- Doctor authenticates using AWS Cognito.
- They access all the requests - GET /requests?status=submitted&order_by=updated_date DESC
- They browse all the information about the request - GET /reports, GET /lesions etc.
- They write up an answer and update the request - PUT /requests/:id