Adding first round of database migrations using goose

pull/88/head
Jordan Wright 2016-01-18 21:13:32 -06:00
parent 1b5fb638ea
commit 379edf73a3
6 changed files with 66 additions and 19 deletions

View File

@ -16,5 +16,6 @@
"user" : "username", "user" : "username",
"pass" : "password" "pass" : "password"
}, },
"db_path" : "gophish.db" "db_path" : "gophish.db",
"migrations_path" : "db/migrations/"
} }

View File

@ -35,6 +35,7 @@ type Config struct {
PhishConf PhishServer `json:"phish_server"` PhishConf PhishServer `json:"phish_server"`
SMTPConf SMTPServer `json:"smtp"` SMTPConf SMTPServer `json:"smtp"`
DBPath string `json:"db_path"` DBPath string `json:"db_path"`
MigrationsPath string `json:"migrations_path"`
} }
var Conf Config var Conf Config

View File

@ -9,9 +9,9 @@ import (
"os" "os"
"testing" "testing"
"github.com/gorilla/handlers"
"github.com/gophish/gophish/config" "github.com/gophish/gophish/config"
"github.com/gophish/gophish/models" "github.com/gophish/gophish/models"
"github.com/gorilla/handlers"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
) )
@ -26,6 +26,7 @@ var as *httptest.Server = httptest.NewUnstartedServer(handlers.CombinedLoggingHa
func (s *ControllersSuite) SetupSuite() { func (s *ControllersSuite) SetupSuite() {
config.Conf.DBPath = ":memory:" config.Conf.DBPath = ":memory:"
config.Conf.MigrationsPath = "../db/migrations/"
err := models.Setup() err := models.Setup()
if err != nil { if err != nil {
s.T().Fatalf("Failed creating database: %v", err) s.T().Fatalf("Failed creating database: %v", err)

View File

@ -0,0 +1,28 @@
-- +goose Up
-- SQL in section 'Up' is executed when this migration is applied
CREATE TABLE IF NOT EXISTS "users" ("id" integer primary key autoincrement,"username" varchar(255) NOT NULL UNIQUE,"hash" varchar(255),"api_key" varchar(255) NOT NULL UNIQUE );
CREATE TABLE IF NOT EXISTS "templates" ("id" integer primary key autoincrement,"user_id" bigint,"name" varchar(255),"subject" varchar(255),"text" varchar(255),"html" varchar(255),"modified_date" datetime );
CREATE TABLE IF NOT EXISTS "targets" ("id" integer primary key autoincrement,"first_name" varchar(255),"last_name" varchar(255),"email" varchar(255),"position" varchar(255) );
CREATE TABLE IF NOT EXISTS "smtp" ("smtp_id" integer primary key autoincrement,"campaign_id" bigint,"host" varchar(255),"username" varchar(255),"from_address" varchar(255) );
CREATE TABLE IF NOT EXISTS "results" ("id" integer primary key autoincrement,"campaign_id" bigint,"user_id" bigint,"r_id" varchar(255),"email" varchar(255),"first_name" varchar(255),"last_name" varchar(255),"status" varchar(255) NOT NULL ,"ip" varchar(255),"latitude" real,"longitude" real );
CREATE TABLE IF NOT EXISTS "pages" ("id" integer primary key autoincrement,"user_id" bigint,"name" varchar(255),"html" varchar(255),"modified_date" datetime );
CREATE TABLE IF NOT EXISTS "groups" ("id" integer primary key autoincrement,"user_id" bigint,"name" varchar(255),"modified_date" datetime );
CREATE TABLE IF NOT EXISTS "group_targets" ("group_id" bigint,"target_id" bigint );
CREATE TABLE IF NOT EXISTS "events" ("id" integer primary key autoincrement,"campaign_id" bigint,"email" varchar(255),"time" datetime,"message" varchar(255) );
CREATE TABLE IF NOT EXISTS "campaigns" ("id" integer primary key autoincrement,"user_id" bigint,"name" varchar(255) NOT NULL ,"created_date" datetime,"completed_date" datetime,"template_id" bigint,"page_id" bigint,"status" varchar(255),"url" varchar(255) );
CREATE TABLE IF NOT EXISTS "attachments" ("id" integer primary key autoincrement,"template_id" bigint,"content" varchar(255),"type" varchar(255),"name" varchar(255) );
-- +goose Down
-- SQL section 'Down' is executed when this migration is rolled back
DROP TABLE "attachments";
DROP TABLE "campaigns";
DROP TABLE "events";
DROP TABLE "group_targets";
DROP TABLE "groups";
DROP TABLE "pages";
DROP TABLE "results";
DROP TABLE "smtp";
DROP TABLE "targets";
DROP TABLE "templates";
DROP TABLE "users";

View File

@ -8,6 +8,8 @@ import (
"log" "log"
"os" "os"
"bitbucket.org/liamstask/goose/lib/goose"
"github.com/gophish/gophish/config" "github.com/gophish/gophish/config"
"github.com/jinzhu/gorm" "github.com/jinzhu/gorm"
_ "github.com/mattn/go-sqlite3" // Blank import needed to import sqlite3 _ "github.com/mattn/go-sqlite3" // Blank import needed to import sqlite3
@ -62,6 +64,24 @@ func Setup() error {
if _, err = os.Stat(config.Conf.DBPath); err != nil || config.Conf.DBPath == ":memory:" { if _, err = os.Stat(config.Conf.DBPath); err != nil || config.Conf.DBPath == ":memory:" {
create_db = true create_db = true
} }
// Setup the goose configuration
migrateConf := &goose.DBConf{
MigrationsDir: config.Conf.MigrationsPath,
Env: "production",
Driver: goose.DBDriver{
Name: "sqlite3",
OpenStr: config.Conf.DBPath,
Import: "github.com/mattn/go-sqlite3",
Dialect: &goose.Sqlite3Dialect{},
},
}
// Get the latest possible migration
latest, err := goose.GetMostRecentDBVersion(migrateConf.MigrationsDir)
if err != nil {
Logger.Println(err)
return err
}
// Open our database connection
db, err = gorm.Open("sqlite3", config.Conf.DBPath) db, err = gorm.Open("sqlite3", config.Conf.DBPath)
db.LogMode(false) db.LogMode(false)
db.SetLogger(Logger) db.SetLogger(Logger)
@ -69,20 +89,14 @@ func Setup() error {
Logger.Println(err) Logger.Println(err)
return err return err
} }
//If the file already exists, delete it and recreate it // Migrate up to the latest version
err = goose.RunMigrationsOnDb(migrateConf, migrateConf.MigrationsDir, latest, db.DB())
if err != nil {
Logger.Println(err)
return err
}
//If the database didn't exist, we need to create the admin user
if create_db { if create_db {
Logger.Printf("Database not found... creating db at %s\n", config.Conf.DBPath)
db.CreateTable(User{})
db.CreateTable(Target{})
db.CreateTable(Result{})
db.CreateTable(Group{})
db.CreateTable(GroupTarget{})
db.CreateTable(Template{})
db.CreateTable(Attachment{})
db.CreateTable(Page{})
db.CreateTable(SMTP{})
db.CreateTable(Event{})
db.CreateTable(Campaign{})
//Create the default user //Create the default user
initUser := User{ initUser := User{
Username: "admin", Username: "admin",
@ -92,6 +106,7 @@ func Setup() error {
err = db.Save(&initUser).Error err = db.Save(&initUser).Error
if err != nil { if err != nil {
Logger.Println(err) Logger.Println(err)
return err
} }
} }
return nil return nil

View File

@ -16,6 +16,7 @@ var _ = check.Suite(&ModelsSuite{})
func (s *ModelsSuite) SetUpSuite(c *check.C) { func (s *ModelsSuite) SetUpSuite(c *check.C) {
config.Conf.DBPath = ":memory:" config.Conf.DBPath = ":memory:"
config.Conf.MigrationsPath = "../db/migrations/"
err := Setup() err := Setup()
if err != nil { if err != nil {
c.Fatalf("Failed creating database: %v", err) c.Fatalf("Failed creating database: %v", err)