Skip to content

Commit

Permalink
initial commit: get public key endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
Paul Fawkesley committed Dec 4, 2018
1 parent 72c5266 commit f289ca6
Show file tree
Hide file tree
Showing 71 changed files with 10,317 additions and 14 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.vagrant/*
.secrets.sh

*-cloudimg-console.log
21 changes: 21 additions & 0 deletions .realize.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
settings:
legacy:
force: true
interval: 500ms
schema:
- name: /home/vagrant/go/src/github.com/fluidkeys/api
path: /home/vagrant/go/src/github.com/fluidkeys/api
commands:
install:
status: true
run:
status: true
watcher:
extensions:
- go
paths:
- /
ignored_paths:
- .git
- .realize
- vendor
13 changes: 13 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
language: go

go:
- "1.10.x"
- master

before_install:
- go get -u github.com/golang/dep/cmd/dep

script: make test

notifications:
email: false
39 changes: 39 additions & 0 deletions Gopkg.lock

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

38 changes: 38 additions & 0 deletions Gopkg.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Gopkg.toml example
#
# Refer to https://golang.github.io/dep/docs/Gopkg.toml.html
# for detailed Gopkg.toml documentation.
#
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
#
# [[constraint]]
# name = "github.com/user/project"
# version = "1.0.0"
#
# [[constraint]]
# name = "github.com/user/project2"
# branch = "dev"
# source = "github.com/myfork/project2"
#
# [[override]]
# name = "github.com/x/y"
# version = "2.4.0"
#
# [prune]
# non-go = false
# go-tests = true
# unused-packages = true


[prune]
go-tests = true
unused-packages = true

[metadata.heroku]
root-package = "github.com/fluidkeys/api"
go-version = "1.10.5"

[[constraint]]
name = "github.com/lib/pq"
version = "1.0.0"
24 changes: 24 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.PHONY: run
run:
firejail --seccomp.drop=sendfile realize start

.PHONY: run_collectors
run_collectors:
go run main.go collect

.PHONY: migrate
migrate:
./migrations/migrate migrations/*.sql

.PHONY: migrate_heroku
migrate_heroku:
MIGRATE_HEROKU=1 ./migrations/migrate migrations/*.sql

.PHONY: test
test:
go build main.go

.PHONY: jenkins_deploy_to_heroku
jenkins_deploy_to_heroku:
heroku git:remote --app fluidkeys-api
git push heroku HEAD:master
1 change: 1 addition & 0 deletions Procfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
web: api
28 changes: 14 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
Get a verified OpenPGP public key for the email address:

```
GET /directory/email/:email
GET /emails/:email/key
```

### Parameters
Expand All @@ -21,40 +21,40 @@ Status: 200 Found
Content-Type: application/json
{
"publicKey": "<base64 encoded openpgp data>"
"armoredPublicKey": "--- BEGIN PGP PUBLIC KEY ---"
}
```

### Example

```
GET https://api.fluidkeys.com/v1/directory/email/tina%40example.com
curl https://api.fluidkeys.com/v1/email/tina@example.com/key
```

# Secrets

## Send a secret to a public key

```
POST /secrets/
POST /secrets
```

### Parameters

| Name | Type | Description |
|----------------------|--------|-----------------------------------------------------------------------------------------------|
| recipientFingerprint | string | **Required.** The fingerprint of the key to send the secret to, prepended with `OPENPGP4FPR:`
| encryptedSecret | string | **Required.** Base64-encoded PGP secret data.
| Name | Type | Description |
|-------------------------|--------|-------------|
| recipientFingerprint--- | string | **Required.** The fingerprint of the key to send the secret to, prepended with `OPENPGP4FPR:`
| `armoredEncryptedSecret | string | **Required.** Base64-encoded PGP secret data.

### Example

```
POST https://api.fluidkeys.com/v1/secrets/
Content-Type: application/json
curl -v -X POST -H "Content-Type: application/json" https://api.fluidkeys.com/v1/secrets --data @- << EOF
{
"recipientFingerprint": "OPENPGP4FPR:AAAABBBBAAAABBBBAAAABBBBAAAABBBBAAAABBBB",
"encryptedSecret": "hQEMAz2taCwJI2vTAQgAxwpk+pkIQIPgwV8wGTodQbUwXrAu..."
"armoredEncryptedSecret": "---- BEGIN PGP MESSAGE --- ..."
}
EOF
```

### Response
Expand All @@ -68,7 +68,7 @@ Status: 201 Created
List the stored encrypted secrets for the authenticated public key:

```
GET /secrets/
GET /secrets
```

### Authentication
Expand Down Expand Up @@ -125,7 +125,7 @@ The call must be authenticated as the key that is the recipient of the secret.
| uuid | uuid | **Required.** The UUID of the secret to delete


### Response
### Response


```
Expand All @@ -139,4 +139,4 @@ DELETE https://api.fluidkeys.com/v1/secrets/8ef46a96-f735-11e8-a220-7fd225378c68
Authorization: tmpfingerprint: OPENPGP4FPR:AAAABBBBAAAABBBBAAAABBBBAAAABBBBAAAABBBB
---
202 Accepted
```
```
62 changes: 62 additions & 0 deletions Vagrantfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :

# Vagrantfile API/syntax version. Don't touch unless you know what you're doing!
VAGRANTFILE_API_VERSION = "2"

Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
# All Vagrant configuration is done here. The most common configuration
# options are documented and commented below. For a complete reference,
# please see the online documentation at vagrantup.com.

config.vm.hostname = 'fkapi'

# Every Vagrant virtual environment requires a box to build off of.
# config.vm.box = "ubuntu/xenial64"
config.vm.box = "ubuntu/bionic64"
config.vm.synced_folder "~/go", "/home/vagrant/go"
config.vm.synced_folder "~/.cache/vagrant-apt-archives", "/var/cache/apt/archives", create: true
config.vm.synced_folder "~/.cache/tmp_download", "/tmp/download", create: true

# The url from where the 'config.vm.box' box will be fetched if it
# doesn't already exist on the user's system.
# config.vm.box_url = "http://domain.com/path/to/above.box"

# Create a forwarded port mapping which allows access to a specific port
# within the machine from a port on the host machine. In the example below,
# accessing "localhost:8080" will access port 80 on the guest machine.
config.vm.network :forwarded_port, guest: 4747, host: 4747

# Create a private network, which allows host-only access to the machine
# using a specific IP.
# config.vm.network :private_network, ip: "10.9.0.3"

# Create a public network, which generally matched to bridged network.
# Bridged networks make the machine appear as another physical device on
# your network.
# config.vm.network :public_network

# If true, then any SSH connections made will enable agent forwarding.
# Default value: false
config.ssh.forward_agent = false

# Share an additional folder to the guest VM. The first argument is
# the path on the host to the actual folder. The second argument is
# the path on the guest to mount the folder. And the optional third
# argument is a set of non-required options.

# Provider-specific configuration so you can fine-tune various
# backing providers for Vagrant. These expose provider-specific options.
# Example for VirtualBox:
#
config.vm.provider :virtualbox do |vb|
# # Don't boot with headless mode
# vb.gui = true

# Use VBoxManage to customize the VM. For example to change memory:
vb.customize ["modifyvm", :id, "--memory", "1024"]
end

config.vm.provision "shell", path: "vagrant/provision.sh"

end
62 changes: 62 additions & 0 deletions datastore/datastore.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
package datastore

import (
"database/sql"
"fmt"
"os"

_ "github.com/lib/pq"
)

var db *sql.DB

func init() {
databaseUrl, present := os.LookupEnv("DATABASE_URL")

if !present {
panic("Missing DATABASE_URL, it should be e.g. " +
"postgres://vagrant:password@localhost:5432/vagrant")
}

err := Initialize(databaseUrl)
if err != nil {
panic(err)
}
}

// Initialize initialises a postgres database from the given databaseUrl
func Initialize(databaseUrl string) error {
var err error
db, err = sql.Open("postgres", databaseUrl)
if err != nil {
return err
}
if err = db.Ping(); err != nil {
return err
}
return nil
}

func GetArmoredPublicKeyForEmail(email string) (armoredPublicKey string, found bool, err error) {
query := `SELECT email_key_link.email,
keys.armored_public_key
FROM email_key_link
LEFT JOIN keys ON email_key_link.key_id = keys.id
WHERE email_key_link.email=$1`

var gotEmail string

err = db.QueryRow(query, email).Scan(&gotEmail, &armoredPublicKey)
if err == sql.ErrNoRows {
return "", false, nil // return found=false without an error

} else if err != nil {
return "", false, err
}

if email != gotEmail {
panic(fmt.Errorf("queried for '%s', got back '%s'", email, gotEmail))
}

return armoredPublicKey, true, nil
}
11 changes: 11 additions & 0 deletions fixtures/generate
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#!/bin/sh -eu


PAUL_FINGERPRINT="B79F0840DEF12EBBA72FF72D7327A44C2157A758"
PAUL_ARMORED_KEY=$(gpg --armor --export "$PAUL_FINGERPRINT")

echo "DELETE FROM keys WHERE fingerprint='4:${PAUL_FINGERPRINT}';"
echo "INSERT INTO keys(fingerprint, armored_public_key) VALUES('4:${PAUL_FINGERPRINT}', '${PAUL_ARMORED_KEY}') RETURNING id AS inserted_key_id;"

echo "INSERT INTO email_key_link(email, key_id) VALUES('paul@fluidkeys.com', (SELECT keys.id FROM keys WHERE keys.fingerprint='4:${PAUL_FINGERPRINT}'));"

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

import (
"github.com/fluidkeys/api/server"
)

func main() {
err := server.Serve()
if err != nil {
panic(err)
}
}
Loading

0 comments on commit f289ca6

Please sign in to comment.