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
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
config.toml
.idea/
*.json
gin-bin
gapps.json
*-bin
api/swagger
pkg/api
10 changes: 10 additions & 0 deletions .golangci.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[linters]
enable = [
"gofmt",
"goimports",
"whitespace",
"wsl"
]

[linters-settings.goimports]
local-prefixes = "github.com/cthit/gotify"
17 changes: 3 additions & 14 deletions DESIGN.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,11 @@
# Design rationale for gotify

## Project structure
The root package/directory only contains the domain types and logic. This will probably be limited to notification service interfaces and notification types. This package may not depend on any other package in this repo.

cmd contains the main package and takes care of meta sutch as configuration and binding all other packages together, This package may depend on any other package

All other packages represent a functionality or dependency and may only depend on the root package as well as external packages.

See [Project structure in go](https://medium.com/@benbjohnson/structuring-applications-in-go-3b04be4ff091) for further explanation.
See [Project structure in go](https://github.com/golang-standards/project-layout) for further explanation.

## API Structure
One api endpoint for every notification type.
See readme for existing api endpoints

A post request to an endpoint with the matching jason notification type should send a notification and on success return the sent notification in json.

## Dependency injection

The web package has some weird dependency injection.

For now, take a look at it until you understand it. It looks like it does for a good reason.
A post request to an endpoint with the matching json notification type should send a notification and on
success return the sent notification in json.
41 changes: 34 additions & 7 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,31 @@
# Dockerfile for protobuf generation
FROM znly/protoc:0.4.0 AS protocGenerator
MAINTAINER digIT <[email protected]>

RUN apk update
RUN apk upgrade
RUN apk add --update git

# Add standard certificates
RUN apk add ca-certificates && rm -rf /var/cache/apk/*

# Add proto imports
RUN mkdir -p /src/github.com/grpc-ecosystem
WORKDIR /src/github.com/grpc-ecosystem
RUN git clone https://github.com/grpc-ecosystem/grpc-gateway.git

# create dir
RUN mkdir /app
WORKDIR /app

ENTRYPOINT ["/bin/sh"]

FROM protocGenerator AS protocGen

COPY . /app

RUN ./scripts/protoc-gen.sh

# Dockerfile for gotify production
FROM golang:alpine AS buildStage
MAINTAINER digIT <[email protected]>
Expand All @@ -8,16 +36,15 @@ RUN apk upgrade
RUN apk add --update git

# Copy sources
RUN mkdir -p $GOPATH/src/github.com/cthit/gotify
COPY . $GOPATH/src/github.com/cthit/gotify
WORKDIR $GOPATH/src/github.com/cthit/gotify/cmd
RUN mkdir /app
COPY --from=protocGen /app /app
WORKDIR /app/cmd/gotify

# Grab dependencies
RUN go get -d -v ./...
RUN go mod download

# build binary
RUN go install -v
RUN mkdir /app && mv $GOPATH/bin/cmd /app/gotify
RUN go build

##########################
# PRODUCTION STAGE #
Expand All @@ -34,7 +61,7 @@ RUN adduser -S -G app -s /bin/bash app
USER app:app

# Copy binary
COPY --from=buildStage /app/gotify /app/gotify
COPY --from=buildStage /app/cmd/gotify/gotify /app/gotify

# Set good defaults
WORKDIR /app
Expand Down
44 changes: 44 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
.PHONY: setup
setup: gen-setup gen
go mod download

.PHONY: gen-setup
gen-setup:
docker build --target protocGenerator -t gotify-protoc-generator .

.PHONY: gen
gen:
docker run -v `pwd`:/app gotify-protoc-generator ./scripts/protoc-gen.sh

.PHONY: build
build: gen
go build -o gotify-bin ./cmd/gotify

.PHONY: run
run: gen
go run ./cmd/gotify

.PHONY: dev
dev:
docker-compose up

.PHONY: clean
clean:
rm -rf pkg/api
git restore api/swagger

.PHONY: lint
lint:
golangci-lint run

.PHONY: lint-fix
lint-fix:
golangci-lint run --fix

.PHONY: lint-docker
lint-docker:
docker run --rm -v `pwd`:/app -w /app golangci/golangci-lint:v1.31.0-alpine golangci-lint run

.PHONY: test
test:
go test ./...
98 changes: 30 additions & 68 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,18 @@ Currently supports the following notification types:
## Usage
How to use the running application

All request must inclue a header with the preshared key.

`Authorization`: `pre-shared: your...key`

### Mail
POST `/mail`

Json Request:
```
```json5
{
"to": "....",
"from": "....",
"subject": "....",
"body": "...."
"to": "...",
"from": "...", // (optional)
"reply_to": "...", // (optional)
"content_type": "...", // (optional)
"subject": "...",
"body": "..."
}
```

Expand All @@ -30,29 +28,19 @@ Steps to run the application.
this include configuration and key files at the moment

### Config
The application can be configured through a config file or environment variables. Environment variables take precedence.

#### config.toml
config.toml can reside in your working directory, `/etc/gotify/` or `$HOME/.gotify/`

```
port = "8080"
pre-shared-key = "......"
debug-mode = false
mock-mode = false

[google-mail]
keyfile = "gapps.json"
admin-mail = "[email protected]"
```
See [Environment Variables](#environment-variables) for config explanation
The application is configured through environment variables.

#### Environment Variables
* `GOTIFY_PORT`: Port for the web service, defaults to `8080` (string)
* `GOTIFY_PRE-SHARED-KEY`*: Random string used by other apps to authenticate
* `GOTIFY_DEBUG-MODE`: Bool indicating debug mode defaults to `false`
* `GOTIFY_GOOGLE-MAIL.KEYFILE`: the file described in [Google config file](#google-config-file) defaults to `gapps.json`
* `GOTIFY_GOOGLE-MAIL.ADMIN-MAIL`*: The google administrator email.
* `GOTIFY_WEB_PORT`: Port for the web service, defaults to `8080` (string)
* `GOTIFY_RPC_PORT`: Port for the rpc service, defaults to `8090` (string)
* `GOTIFY_DEBUG_MODE`: Bool indicating debug mode defaults to `false`
* `GOTIFY_GOOGLE_MAIL_KEYFILE`: the file described in [Google config file](#google-config-file) defaults
to `gapps.json`
* `GOTIFY_MAIL_DEFAULT_FROM`: Default `from` address in the mail, defaults to `[email protected]`
* `GOTIFY_MAIL_DEFAULT_REPLY_TO`: Default `reply_to` address in the mail, defaults to `[email protected]`
* `GOTIFY_MAIL_DEFAULT_CONTENT_TYPE`: Default `content_type` in mail, default so `text/html; charset=ISO-8859-1`
* `GOTIFY_MOCK_MODE`: Enable mock mode, defaults to `false`
* `GOTIFY_ENVIRONMENT`: (`test` | `production` | `development`), defaults to `development`

### Google config file
This file (gapps.json by default config) should be placed in the working directory
Expand All @@ -63,6 +51,7 @@ This file (gapps.json by default config) should be placed in the working directo
Go to [Google developer console](https://console.developers.google.com) to retrieve this file

* go to credentials
* create a project for this app if you don't already have one
* create new service account för this app
* use the downloaded file

Expand All @@ -74,45 +63,18 @@ You must also allow mail api calls:
* use api scope `https://www.googleapis.com/auth/gmail.send`

## Development
You can either set this project up manually or with a simple docker compose setup. The manual setup is recommended if you'll be doing extensive development.

Please referer to the software design document before starting development: `DESIGN.md`

See issues for suggested features.
### Manual
Make sure you have golang installed and you `$GOPATH` setup.
1. Follow the steps in [Setup](#setup) and enable debug mode.
2. Grab all dependencies by standing in the project root and run `go get -d ./...`
3. You find the main file in `cmd/main.go`
4. Go to http://localhost:8080

Use gin for hot reloading.
1. Grab it with `go get github.com/codegangsta/gin`
2. Run gotify with `gin -d cmd -a 8080 run main.go`
3. Go to http://localhost:3000

### Docker Compose
1. Get a [Google key file](#google-config-file).
2. Run `docker-compose up --build`
3. Go to http://localhost:8080

You can install additional dependencies without restarting the container by running `docker exec gotify_web_1 go get ...`, gotify_web_1 is the name of the container and ... is the dependency.

### As mock
1. Set the `pre-shared-key` config/environment variable.
2. Set the `mock-mode` config/environment variable to true
3. Enjoy

Example docker-compose entry for mock service:
To start a dockerized development environment with hot-reloading:
```bash
$ make dev
```
services:
...
gotify:
image: cthit/gotify:latest
environment:
GOTIFY_PRE-SHARED-KEY: "123abc"
GOTIFY_MOCK-MODE: "true"

To start a non-dockerized development environment:
```bash
$ make run
```

Other services would then be able to reach this service on `http://gotify:8080/...` with `123abc` as the preshared key
Please referer to the software design document before starting development: `DESIGN.md`

### As mock
1. Set the `mock-mode` config/environment variable to true
2. Enjoy
29 changes: 29 additions & 0 deletions api/proto/v1/mail.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
syntax = "proto3";

package gotify;

import "google/api/annotations.proto";
import "protoc-gen-swagger/options/annotations.proto";

option (grpc.gateway.protoc_gen_swagger.options.openapiv2_swagger) = {
host: "localhost:8080"
schemes: HTTP;
};

service Mailer {
rpc SendMail(Mail) returns (Mail) {
option(google.api.http) = {
post: "/mail"
body: "*"
};
}
}

message Mail {
string to = 1;
string from = 2;
string reply_to = 3;
string subject = 4;
string content_type = 5;
string body = 6;
}
1 change: 1 addition & 0 deletions api/swagger/v1/apidocs.swagger.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
PLACEHOLDER FILE
24 changes: 0 additions & 24 deletions cmd/config.go

This file was deleted.

18 changes: 18 additions & 0 deletions cmd/gotify/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package main

import (
"fmt"
"os"

"github.com/cthit/gotify/internal/app"
)

func main() {
err := app.Start()
if err != nil {
fmt.Printf("Crash: %v\n", err)
os.Exit(1)
}

os.Exit(0)
}
Loading