Verified Commit f4a60786 authored by Jakob Tigerström's avatar Jakob Tigerström 🦊
Browse files

Removed typhon install

parent bc591027
typhon_install: sql.go main.go typhon.sql
go build
sql.go: typhon.sql
go generate
.PHONY: clean
clean:
rm -f typhon_install sql.go
package main
import (
"database/sql"
"fmt"
mysql "github.com/go-sql-driver/mysql"
"os"
"testing"
"time"
)
var db *sql.DB
func initDB(addr string) (*sql.DB, error) {
db, err := sql.Open("mysql", addr)
if err != nil {
return nil, err
}
err = db.Ping()
if err != nil {
return nil, err
}
return db, err
}
func TestMain(m *testing.M) {
var err error
db, err = initDB("typhond:localdbpass@tcp(127.0.0.1)/typhond")
if err != nil {
fmt.Println(err)
}
err = db.Ping()
if err != nil {
fmt.Println(err)
}
os.Exit(m.Run())
}
func TestAddUserRemoveUserGetUserId(t *testing.T) {
var id int
var err error
//Tests to add a user-
row := db.QueryRow("CALL addUser(?,?)", "testName", "testPass")
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id == 0 {
t.Errorf("Should return id larger then 0 instead it returned id = %d", id)
}
//Tests to add duplicate of a user and this should return 0 casue that means that the user already exsists.
row = db.QueryRow("CALL addUser(?,?)", "testName", "testPass")
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id != 0 {
t.Errorf("Should return id = 0 Adding a user with a username that exists should return 0. Returned id = %d", id)
}
//Test to get userId from user testName
row = db.QueryRow("SELECT getUserId(?)", "testName")
err = row.Scan(&id)
checkId := id
if err != nil {
t.Errorf("%s", err)
} else if id == 0 {
t.Errorf("Should return a id. The user exists so id should be larger then 0")
}
//Test to get userId from a user that does not exist
row = db.QueryRow("SELECT getUserId(?)", "testNameDoesNotExsist")
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id != 0 {
t.Errorf("Should return a id = 0 but returned id = %d", id)
}
//Test remove user testName
row = db.QueryRow("CALL removeUser(?)", "testName")
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if checkId != id {
t.Errorf("Should have returned id = %d but instead returned id = %d", checkId, id)
}
}
func TestAddSecretRemoveSecretGetSecretId(t *testing.T) {
var id int
var err error
testData := "Secret Data"
//Add user to add the secret to
row := db.QueryRow("CALL addUser(?,?)", "testName", "testPass")
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id == 0 {
t.Errorf("Should return id larger then 0 instead it returned id = %d", id)
}
//Tests to add a secret.
row = db.QueryRow("CALL addSecret(?,?,?,?)", "Secret", "testName", testData, 0)
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id == 0 {
t.Errorf("Should return id larger then 0 instead it returned id = %d", id)
}
//Tests to add a duplicate and should return a error in err which is good cause then it works.
row = db.QueryRow("CALL addSecret(?,?,?,?)", "Secret", "testName", testData, 0)
err = row.Scan(&id)
if err == nil {
t.Errorf("%s", err)
}
//Test to get secretId
row = db.QueryRow("SELECT getSecretId(?,getUserId(?))", "Secret", "testName")
err = row.Scan(&id)
checkSecretId := id
if err != nil {
t.Errorf("%s", err)
} else if id == 0 {
t.Errorf("Should return id larger then 0 instead it returned id = %d", id)
}
//Test to get a secretId that does not exists
row = db.QueryRow("SELECT getSecretId(?,getUserId(?))", "SecretDoesNotExist", "testName")
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id != 0 {
t.Errorf("Should return id = 0 instead it returned id = %d", id)
}
//Test remove a secret that does not exists
row = db.QueryRow("CALL removeSecret(?,?)", "SecretDoesNotExist", "testName")
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id != 0 {
t.Errorf("Should return id = 0 instead it returned id = %d", id)
}
//Test remove a secret that exists
row = db.QueryRow("CALL removeSecret(?,?)", "Secret", "testName")
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id != checkSecretId {
t.Errorf("Should return id = %d instead it returned id = %d", checkSecretId, id)
}
//Cleanup
row = db.QueryRow("CALL removeUser(?)", "testName")
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id == 0 {
t.Errorf("Should have returned larger then 0 instead returned id = %d", id)
}
}
func TestGetSecret(t *testing.T) {
var id int
var data string
var dateCreated mysql.NullTime
var dateToDie mysql.NullTime
var err error
//Setup
testData := "Secret Data"
row := db.QueryRow("CALL addUser(?,?)", "testName", "testPass")
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id == 0 {
t.Errorf("Should return id larger then 0 instead it returned id = %d", id)
}
row = db.QueryRow("CALL addSecret(?,?,?,?)", "Secret", "testName", testData, 0)
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id == 0 {
t.Errorf("Should return id larger then 0 instead it returned id = %d", id)
}
//Test to get a secret.
err = db.QueryRow("CALL getSecret(?,?)", "Secret", "testName").Scan(&id, &data, &dateCreated, &dateToDie)
if err != nil {
if err == sql.ErrNoRows {
t.Errorf("Should have returned a set instead returned a empty one")
} else {
t.Errorf("%s", err)
}
}
//Test to get a secret where that secret does not exsist.
err = db.QueryRow("CALL getSecret(?,?)", "Secret1", "testName").Scan(&id, &data, &dateCreated, &dateToDie)
if err != nil {
if err != sql.ErrNoRows {
t.Errorf("Should have returned a empty set instead returned id = %d", id)
}
}
//Test to get a secret where that user does not exsist.
err = db.QueryRow("CALL getSecret(?,?)", "Secret", "testName1").Scan(&id, &data, &dateCreated, &dateToDie)
if err != nil {
if err != sql.ErrNoRows {
t.Errorf("Should have returned a empty set instead returned id = %d", id)
}
}
//Test to add a secret with Time To Live 1 hour
testData = "TTL test"
expectMin := time.Now().UTC()
expectMax := time.Now().UTC().Add(time.Second * time.Duration(30))
row = db.QueryRow("CALL addSecret(?,?,?,?)", "SecretTTL", "testName", testData, 2)
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id == 0 {
t.Errorf("Should return id larger then 0 instead it returned id = %d", id)
}
err = db.QueryRow("CALL getSecret(?,?)", "SecretTTL", "testName").Scan(&id, &data, &dateCreated, &dateToDie)
if err != nil {
if err != sql.ErrNoRows {
t.Errorf("Should have returned a empty set instead returned id = %d", id)
} else {
t.Errorf("%s", err)
}
}
if dateToDie.Valid == false {
t.Errorf("Got invalid dateToDie value from database")
}
if expectMin.After(dateToDie.Time) || expectMax.Before(dateToDie.Time) {
t.Errorf("Got incorrect time: %v", dateToDie.Time)
t.Errorf("Expected range: %v - %v", expectMin, expectMax)
}
//Cleanup
row = db.QueryRow("CALL removeSecret(?,?)", "Secret", "testName")
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
}
row = db.QueryRow("CALL removeSecret(?,?)", "SecretTTL", "testName")
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
}
row = db.QueryRow("CALL removeUser(?)", "testName")
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id == 0 {
t.Errorf("Should have returned larger then 0 instead returned id = %d", id)
}
}
func TestBlockUserUnBlockUser(t *testing.T) {
var blocked int
var id int
var username string
var err error
//Setup
row := db.QueryRow("CALL addUser(?,?)", "testName", "testPass")
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id == 0 {
t.Errorf("Should return id larger then 0 instead it returned id = %d", id)
}
//Test Blockuser
row = db.QueryRow("CALL blockUser(?)", "testName")
err = row.Scan(&username, &blocked)
if err != nil {
t.Errorf("%s", err)
} else if username != "testName" && blocked != 1 {
t.Errorf("Should have blocked user testName\nusername = %s\nblocked = %d", username, blocked)
}
//Test to see if blocked user get's allowed to do things.
row = db.QueryRow("SELECT validRpc(?,?)", "testName", "getSecret")
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id != 0 {
t.Errorf("Should have returned 0 instead returned %d", id)
}
//Test unblockuser
row = db.QueryRow("CALL unblockUser(?)", "testName")
err = row.Scan(&username, &blocked)
if err != nil {
t.Errorf("%s", err)
} else if username != "testName" && blocked != 0 {
t.Errorf("Should have blocked user testName\nusername = %s\nblocked = %d", username, blocked)
}
//Test to see if unblocked user get's allowed to do things.
row = db.QueryRow("SELECT validRpc(?,?)", "testName", "getSecret")
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id != 1 {
t.Errorf("Should have returned 1 instead returned %d", id)
}
//Cleanup
row = db.QueryRow("CALL removeUser(?)", "testName")
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id == 0 {
t.Errorf("Should have returned larger then 0 instead returned id = %d", id)
}
}
func TestListUserListSecretAndListUser(t *testing.T) {
var id int
var blocked int
var name string
var secondsToUpdate int64
var dateCreated mysql.NullTime
var dateToDie mysql.NullTime
var err error
testData := "Secret Data"
secretNames := [4]string{"Secret1", "Secret2", "Secret3", "Secret4"}
userNames := [2]string{"testname1", "testname2"}
//Setup
for i := 0; i < 2; i++ {
row := db.QueryRow("CALL addUser(?,?)", userNames[i], "testPass")
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id == 0 {
t.Errorf("Should return id larger then 0 instead it returned id = %d", id)
}
}
x := 0
for i := 0; i < 4; i++ {
row := db.QueryRow("CALL addSecret(?,?,?,?)", secretNames[i], userNames[x], testData, 0)
err = row.Scan(&id)
if i == 2 {
x++
}
if err != nil {
t.Errorf("%s", err)
} else if id == 0 {
t.Errorf("Should return id larger then 0 instead it returned id = %d", id)
}
}
//Test to see if testName only sees secret1,secret2
rows, err := db.Query("CALL listSecrets(?)", "testName1")
x = 0
for rows.Next() {
err = rows.Scan(&id, &name, &secondsToUpdate, &dateCreated, &dateToDie)
if err != nil {
t.Errorf("%s", err)
} else if secretNames[x] != name {
t.Errorf("Failed to list all secrets. secretname = %s should be %s", name, secretNames[x])
}
x++
}
rows, err = db.Query("CALL listUsers()")
x = 0
for rows.Next() {
err = rows.Scan(&id, &name, &dateCreated, &blocked)
if err != nil {
t.Errorf("%s", err)
} else if userNames[x] != name {
t.Errorf("Failed to list all users. username = %s should be %s", name, userNames[x])
}
x++
}
//Cleanup
for i := 0; i < 2; i++ {
row := db.QueryRow("CALL removeUser(?)", userNames[i])
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id == 0 {
t.Errorf("Should have returned larger then 0 instead returned id = %d", id)
}
}
}
func TestCheckEventDeletesSecret(t *testing.T) {
var id int
var data string
var dateCreated mysql.NullTime
var dateToDie mysql.NullTime
var err error
//Setup
row := db.QueryRow("CALL addUser(?,?)", "testName", "testPass")
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id == 0 {
t.Errorf("Should return id larger then 0 instead it returned id = %d", id)
}
row = db.QueryRow("CALL addSecret(?,?,?,?)", "Secret", "testName", "secretData", 1)
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id == 0 {
t.Errorf("Should return id larger then 0 instead it returned id = %d", id)
}
time.Sleep(2 * time.Second)
//Should have deleted the secret with the name Secret
db.QueryRow("CALL deleteOutdatedSecret()")
err = db.QueryRow("CALL getSecret(?,?)", "Secret", "testName").Scan(&id, &data, &dateCreated, &dateToDie)
if err != sql.ErrNoRows {
t.Errorf("Should have returned a empty set instead returned id = %d", id)
}
row = db.QueryRow("CALL removeUser(?)", "testName")
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id == 0 {
t.Errorf("Should have returned larger then 0 instead returned id = %d", id)
}
}
func TestSetSecretNameAndTTL(t *testing.T) {
var id int
var secretName string
var date mysql.NullTime
var useTTL int
var err error
expectMin := time.Now().UTC().Add(time.Second * time.Duration(59))
shouldBeDate := time.Now().UTC().Add(time.Second * time.Duration(60))
//Setup
row := db.QueryRow("CALL addUser(?,?)", "testName", "testPass")
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id == 0 {
t.Errorf("Should return id larger then 0 instead it returned id = %d", id)
}
row = db.QueryRow("CALL addSecret(?,?,?,?)", "Secret", "testName", "secretData", 0)
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id == 0 {
t.Errorf("Should return id larger then 0 instead it returned id = %d", id)
}
//Change name of secret
row = db.QueryRow("CALL setSecretName(?,?,?)", "SecretNewName", "Secret", "testName")
err = row.Scan(&id, &secretName)
if err != nil {
t.Errorf("%s", err)
} else if secretName != "SecretNewName" {
t.Errorf("It did not change the name of the secret correctly. The secret name returned is %s", secretName)
}
//Change TTL of secret
row = db.QueryRow("CALL setSecretTTL(?,?,?)", 60, "SecretNewName", "testName")
err = row.Scan(&id, &secretName, &useTTL, &date)
if err != nil {
t.Errorf("%s", err)
} else if useTTL != 1 {
t.Errorf("It did not change the TTL of the secret correctly. The secret TTL returned is %d", useTTL)
} else if expectMin.After(date.Time) {
t.Errorf("Changed the time to incorrect value. Returnet %v should be %v", date, shouldBeDate)
}
//Cleanup
row = db.QueryRow("CALL removeUser(?)", "testName")
err = row.Scan(&id)
if err != nil {
t.Errorf("%s", err)
} else if id == 0 {
t.Errorf("Should have returned larger then 0 instead returned id = %d", id)
}
}
package main
import (
"database/sql"
"errors"
"flag"
"fmt"
"io"
"os"
"os/exec"
"strconv"
"time"
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"math/big"
"git.blesstherains.africa/typhon/gocry"
_ "github.com/go-sql-driver/mysql"
)
// https://stackoverflow.com/a/29500100
//go:generate go run scripts/makesql.go
var (
dbUser *string
dbPass *string
dbName *string
dbHost *string
checkSetup *bool
forceSetup *bool
serverAddr = "localhost"
serverPort = 8080
tlsVerify = false
configFile *string
genCert *bool
keyOut *string
certOut *string
keySize *int
certExpiry *int
)
func performStep(info string, step func() error) {
fmt.Print("[WAIT]")
fmt.Print(" " + info + " ...")
err := step()
fmt.Print("\r")
if err != nil {
fmt.Print("[FAIL]\n")
fmt.Println(err)
os.Exit(1)
} else {
fmt.Print("[ OK ]\n")
}
}
func setupDB() error {
var cmd *exec.Cmd
if *dbHost == "" {
cmd = exec.Command("mysql", "-u", *dbUser, "-p"+*dbPass, *dbName)
} else {
cmd = exec.Command("mysql", "-u", *dbUser, "-p"+*dbPass, "-h", *dbHost, *dbName)
}
stdin, _ := cmd.StdinPipe()
go func() {
defer stdin.Close()
io.WriteString(stdin, SQL)
}()
out, err := cmd.CombinedOutput()
if err != nil {
return errors.New(string(out))
}
return nil
}
func createDefaultAdmin() error {
*dbHost = "tcp(" + *dbHost + ")"
db, err := sql.Open("mysql", *dbUser+":"+*dbPass+"@"+*dbHost+"/"+*dbName)
if err != nil {
return err
}
err = db.Ping()
if err != nil {
return err
}
_, err = db.Exec("CALL initiateDatabase(?, ?)", "admin", gocry.GenerateHash("typhon"))
if err != nil {
return err
}
return nil
}
func generateKeys() error {
key, err := rsa.GenerateKey(rand.Reader, *keySize)
if err != nil {
return err
}
keyPem := pem.EncodeToMemory(&pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(key),
})
randInt, err := rand.Int(rand.Reader, big.NewInt(1000000))
if err != nil {
return err
}
tml := x509.Certificate{
NotBefore: time.Now(),
NotAfter: time.Now().Add(time.Hour * time.Duration(24) * time.Duration(*certExpiry)),
SerialNumber: randInt,
Subject: pkix.Name{
CommonName: "Typhon",
Organization: []string{"Typhon"},
},