Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -51,3 +51,6 @@ Temporary Items
GoDeps/Readme

*.swp
docker_db/pgdata/

vendor
19 changes: 19 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
FROM golang:1.11.0 AS builder
WORKDIR /go/src/github.com/atmiguel/cerealnotes
COPY . .
RUN go get github.com/golang/dep/cmd/dep
RUN dep ensure

# Cross compile cerealnotes to work in a minimal alpine image. CGO must be
# disabled for cross compilation. See https://github.com/golang/go/issues/5104
RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o cerealnotes


# Use alpine docker image for production for the small image size (5MB)
FROM alpine:3.8
WORKDIR /root/
COPY --from=builder /go/src/github.com/atmiguel/cerealnotes/cerealnotes .
COPY --from=builder /go/src/github.com/atmiguel/cerealnotes/templates ./templates
COPY --from=builder /go/src/github.com/atmiguel/cerealnotes/static ./static
CMD ["./cerealnotes"]
EXPOSE 8080
5 changes: 5 additions & 0 deletions Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM golang:1.11.0 AS builder
WORKDIR /go/src/github.com/atmiguel/cerealnotes
RUN go get github.com/golang/dep/cmd/dep
RUN apt-get update
RUN apt-get install -y postgresql-client
30 changes: 0 additions & 30 deletions Godeps/Godeps.json

This file was deleted.

42 changes: 42 additions & 0 deletions Gopkg.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions Gopkg.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
# for detailed Gopkg.toml documentation.

[[constraint]]
name = "github.com/dgrijalva/jwt-go"
version = "3.2.0"

[[constraint]]
name = "github.com/lib/pq"
version = "1.0.0"

[prune]
go-tests = true
unused-packages = true
34 changes: 14 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
# Installation
## Locally
* postgres server installed and running: please refer to `migrations/README.md` for more info
* heroku cli installed
* `brew install heroku`
* golang installed
* `brew install go`
* godep installed:
* `go get github.com/tools/godep`

## Heroku
* heroku instance
* instance connected to postgres db

# Running CerealNotes

Assuming your local environment is setup correctly with Golang standards, you can start your local server with the following commands

1. `cd to this repo`
2. `go install && heroku local`
3. Visit `localhost:8080/`
## Local prod like build
* install docker
* cd this repo
* `docker-compose up`
* Visit `localhost:8080/`

## Local Dev instance
1. make sure all go depenecies are ready
* run `./beam_me_up_scotty.sh bash`
* run `dep ensure`
* exit bash
2. run `./beam_me_up_scotty.sh` and everything should work

Please note step 1 is only necessary the first time you connect set up your test environment, or whenever a new package is added
29 changes: 29 additions & 0 deletions beam_me_up_scotty.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#! /bin/bash

GREEN='\033[0;32m'
RED='\033[0;31m'
NC='\033[0m' # No Color

exit_script() {
echo -e "${GREEN}As you command, sir!${NC}"
}

trap exit_script SIGINT SIGTERM

docker-compose --file docker-compose.dev.yml up -d;

if [ "$1" = "db" ]; then
echo -e "${GREEN}Beaming you into the system mechanics, sir!${NC}"
docker exec -it cerealnotes_db_1 /bin/bash;
# docker exec -it cerealnotes_db_1 psql -U docker -W docker
elif [ "$1" = "bash" ]; then
echo -e "${GREEN}Beaming you straight into quantum space, sir!${NC}"
docker exec -it cerealnotes_backend_1 /bin/bash;
else
echo -e "${GREEN}Engaging wormhole stabalizers. Beam will start shortyly, sir!${NC}"
echo "Running tests then staring the service"
docker exec cerealnotes_backend_1 bash -c 'go test ./... && go run main.go';
fi

echo -e "${GREEN}Quantum disentangling reactor subfluid, for next beam, sir!${NC}"
docker-compose --file docker-compose.dev.yml down;
29 changes: 29 additions & 0 deletions docker-compose.dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
version: '3'
services:
db:
image: postgres:9.6
volumes:
- ./docker_db/pgdata:/pgdata
- ./docker_db/migrations:/docker-entrypoint-initdb.d/
ports:
- "5432"
environment:
- POSTGRES_USER=docker
- POSTGRES_PASSWORD=docker
- PGDATA=/pgdata
backend:
build:
context: ./
dockerfile: Dockerfile.dev
volumes:
- .:/go/src/github.com/atmiguel/cerealnotes/
ports:
- "8080:8080"
environment:
- DATABASE_URL=postgresql://docker:docker@db:5432/cerealnotes?sslmode=disable
- DATABASE_URL_TEST=postgresql://docker:docker@db:5432/cerealnotes_test?sslmode=disable
- PORT=8080
- TOKEN_SIGNING_KEY=AllYourBase
depends_on:
- db
tty: true
26 changes: 26 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
version: '3'
services:
db:
image: postgres:9.6
volumes:
- ./docker_db/pgdata:/pgdata
- ./docker_db/migrations:/docker-entrypoint-initdb.d/
ports:
- "5432"
environment:
- POSTGRES_USER=docker
- POSTGRES_PASSWORD=docker
- PGDATA=/pgdata
backend_prod:
build:
context: ./
volumes:
- .:/go/src/github.com/atmiguel/cerealnotes/
ports:
- "8080:8080"
environment:
- DATABASE_URL=postgresql://docker:docker@db:5432?sslmode=disable
- PORT=8080
- TOKEN_SIGNING_KEY=AllYourBase
depends_on:
- db
File renamed without changes.
37 changes: 37 additions & 0 deletions docker_db/migrations/0002_createTables_test.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
\c cerealnotes_test;

-- Types
CREATE TYPE category_type AS ENUM ('predictions', 'marginalia', 'meta', 'questions');

-- Tables
CREATE TABLE IF NOT EXISTS app_user (
id bigserial PRIMARY KEY,
display_name text NOT NULL,
email_address text UNIQUE NOT NULL,
password bytea NOT NULL,
creation_time timestamp NOT NULL
);

CREATE TABLE IF NOT EXISTS publication (
id bigserial PRIMARY KEY,
-- we need to have some sort of foreign key assurance that all note to publication relationships refer to the same author
author_id bigint references app_user(id) NOT NULL,
creation_time timestamp NOT NULL
);

CREATE TABLE IF NOT EXISTS note (
id bigserial PRIMARY KEY,
author_id bigint references app_user(id) ON DELETE CASCADE NOT NULL,
content text NOT NULL,
creation_time timestamp NOT NULL
);

CREATE TABLE IF NOT EXISTS note_to_publication_relationship (
note_id bigint PRIMARY KEY references note(id) ON DELETE CASCADE,
publication_id bigint references publication(id) ON DELETE CASCADE NOT NULL
);

CREATE TABLE IF NOT EXISTS note_to_category_relationship (
note_id bigint PRIMARY KEY references note(id) ON DELETE CASCADE,
category category_type NOT NULL
);
File renamed without changes.
28 changes: 25 additions & 3 deletions handlers/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"html/template"
"log"
"net/http"
"strconv"
"strings"
Expand Down Expand Up @@ -72,6 +73,9 @@ func AuthenticateOrRedirect(
}
} else {
if err, errCode := authenticatedHandlerFunc(env, responseWriter, request, userId); err != nil {
if errCode >= 500 {
log.Print(err)
}
http.Error(responseWriter, err.Error(), errCode)
return
}
Expand All @@ -88,8 +92,12 @@ func AuthenticateOrReturnUnauthorized(
if userId, err := getUserIdFromJwtToken(env, request); err != nil {
responseWriter.Header().Set("WWW-Authenticate", `Bearer realm="`+request.URL.Path+`"`)
http.Error(responseWriter, err.Error(), http.StatusUnauthorized)
return
} else {
if err, errCode := authenticatedHandlerFunc(env, responseWriter, request, userId); err != nil {
if errCode >= 500 {
log.Print(err)
}
http.Error(responseWriter, err.Error(), errCode)
return
}
Expand All @@ -100,6 +108,9 @@ func AuthenticateOrReturnUnauthorized(
func WrapUnauthenticatedEndpoint(env *Environment, handler UnauthenticatedEndpointHandlerType) http.HandlerFunc {
return func(responseWriter http.ResponseWriter, request *http.Request) {
if err, errCode := handler(env, responseWriter, request); err != nil {
if errCode >= 500 {
log.Print(err)
}
http.Error(responseWriter, err.Error(), errCode)
return
}
Expand Down Expand Up @@ -547,6 +558,14 @@ func HandleCategoryApiRequest(
id, err := strconv.ParseInt(request.URL.Query().Get("id"), 10, 64)
noteId := models.NoteId(id)

_, err = env.Db.GetNoteById(noteId)
if err != nil {
if err == models.NoNoteFoundError {
return err, http.StatusBadRequest
}
return err, http.StatusInternalServerError
}

type CategoryForm struct {
Category string `json:"category"`
}
Expand All @@ -558,7 +577,6 @@ func HandleCategoryApiRequest(
}

category, err := models.DeserializeCategory(strings.ToLower(noteForm.Category))

if err != nil {
return err, http.StatusBadRequest
}
Expand Down Expand Up @@ -607,8 +625,12 @@ func RedirectToPathHandler(
http.StatusTemporaryRedirect)
return
default:
err, errcode := respondWithMethodNotAllowed(responseWriter, http.MethodGet)
http.Error(responseWriter, err.Error(), errcode)
err, errCode := respondWithMethodNotAllowed(responseWriter, http.MethodGet)
if errCode >= 500 {
log.Print(err)
}
http.Error(responseWriter, err.Error(), errCode)
return
}
}
}
Expand Down
Loading