diff --git a/controllers/api.go b/controllers/api.go index f9dfb142..346aafe7 100644 --- a/controllers/api.go +++ b/controllers/api.go @@ -238,7 +238,36 @@ func API_Groups_Id(w http.ResponseWriter, r *http.Request) { } func API_Templates(w http.ResponseWriter, r *http.Request) { - http.Redirect(w, r, "/", 302) + switch { + case r.Method == "GET": + ts, err := db.GetTemplates(ctx.Get(r, "user_id").(int64)) + if checkError(err, w, "Templates not found", http.StatusNotFound) { + return + } + tj, err := json.MarshalIndent(ts, "", " ") + if checkError(err, w, "Error marshaling template information", http.StatusInternalServerError) { + return + } + writeJSON(w, tj) + //POST: Create a new group and return it as JSON + case r.Method == "POST": + t := models.Template{} + // Put the request into a group + err := json.NewDecoder(r.Body).Decode(&t) + if checkError(err, w, "Invalid Request", http.StatusBadRequest) { + return + } + t.ModifiedDate = time.Now() + err = db.PostTemplate(&t, ctx.Get(r, "user_id").(int64)) + if checkError(err, w, "Error inserting template", http.StatusInternalServerError) { + return + } + tj, err := json.MarshalIndent(t, "", " ") + if checkError(err, w, "Error creating JSON response", http.StatusInternalServerError) { + return + } + writeJSON(w, tj) + } } func API_Templates_Id(w http.ResponseWriter, r *http.Request) { diff --git a/controllers/route.go b/controllers/route.go index b0fbae7c..12019804 100644 --- a/controllers/route.go +++ b/controllers/route.go @@ -36,7 +36,7 @@ func CreateRouter() *nosurf.CSRFHandler { api.HandleFunc("/campaigns/{id:[0-9]+}", Use(API_Campaigns_Id, mid.RequireAPIKey)) api.HandleFunc("/groups/", Use(API_Groups, mid.RequireAPIKey)) api.HandleFunc("/groups/{id:[0-9]+}", Use(API_Groups_Id, mid.RequireAPIKey)) - api.HandleFunc("/templates", Use(API_Templates, mid.RequireAPIKey)) + api.HandleFunc("/templates/", Use(API_Templates, mid.RequireAPIKey)) api.HandleFunc("/templates/{id:[0-9]+}", Use(API_Templates_Id, mid.RequireAPIKey)) // Setup static file serving diff --git a/db/db.go b/db/db.go index c7885629..c7b920a5 100644 --- a/db/db.go +++ b/db/db.go @@ -30,6 +30,7 @@ func Setup() error { Conn.AddTableWithName(models.User{}, "users").SetKeys(true, "Id") Conn.AddTableWithName(models.Campaign{}, "campaigns").SetKeys(true, "Id") Conn.AddTableWithName(models.Group{}, "groups").SetKeys(true, "Id") + Conn.AddTableWithName(models.Template{}, "templates").SetKeys(true, "Id") if err != nil { Logger.Println("Database not found, recreating...") createTablesSQL := []string{ @@ -42,7 +43,7 @@ func Setup() error { `CREATE TABLE user_campaigns (uid INTEGER NOT NULL, cid INTEGER NOT NULL, FOREIGN KEY (uid) REFERENCES users(id), FOREIGN KEY (cid) REFERENCES campaigns(id), UNIQUE(uid, cid))`, `CREATE TABLE user_groups (uid INTEGER NOT NULL, gid INTEGER NOT NULL, FOREIGN KEY (uid) REFERENCES users(id), FOREIGN KEY (gid) REFERENCES groups(id), UNIQUE(uid, gid))`, `CREATE TABLE group_targets (gid INTEGER NOT NULL, tid INTEGER NOT NULL, FOREIGN KEY (gid) REFERENCES groups(id), FOREIGN KEY (tid) REFERENCES targets(id), UNIQUE(gid, tid));`, - `CREATE TABLE templates (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, modified_date TIMESTAMP NOT NULL, html TEXT NOT NULL, plaintext TEXT NOT NULL;`, + `CREATE TABLE templates (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, modified_date TIMESTAMP NOT NULL, html TEXT NOT NULL, text TEXT NOT NULL);`, `CREATE TABLE user_templates (uid INTEGER NOT NULL, tid INTEGER NOT NULL, FOREIGN KEY (uid) REFERENCES users(id), FOREIGN KEY (tid) REFERENCES templates(id), UNIQUE(uid, tid));`, } Logger.Printf("Creating db at %s\n", config.Conf.DBPath) @@ -304,14 +305,14 @@ func PutGroup(g *models.Group, uid int64) error { return nil } -// GetCampaigns returns the campaigns owned by the given user. +// GetTemplates returns the templates owned by the given user. func GetTemplates(uid int64) ([]models.Template, error) { ts := []models.Template{} - _, err := Conn.Select(&ts, "SELECT t.id, t.name, t.modified_date, t.text, t.html FROM templates t, user_templates ut, users u WHERE ut.uid=u.id AND ut.tid=c.id AND u.id=?", uid) + _, err := Conn.Select(&ts, "SELECT t.id, t.name, t.modified_date, t.text, t.html FROM templates t, user_templates ut, users u WHERE ut.uid=u.id AND ut.tid=t.id AND u.id=?", uid) return ts, err } -// GetCampaign returns the campaign, if it exists, specified by the given id and user_id. +// GetTemplate returns the template, if it exists, specified by the given id and user_id. func GetTemplate(id int64, uid int64) (models.Template, error) { t := models.Template{} err := Conn.SelectOne(&t, "SELECT t.id, t.name, t.modified_date, t.text, t.html FROM templates t, user_templates ut, users u WHERE ut.uid=u.id AND ut.tid=t.id AND t.id=? AND u.id=?", id, uid) @@ -321,6 +322,22 @@ func GetTemplate(id int64, uid int64) (models.Template, error) { return t, err } +// PostTemplate creates a new template in the database. +func PostTemplate(t *models.Template, uid int64) error { + // Insert into the DB + err = Conn.Insert(t) + if err != nil { + Logger.Println(err) + return err + } + // Now, let's add the user->user_templates->template mapping + _, err = Conn.Exec("INSERT OR IGNORE INTO user_templates VALUES (?,?)", uid, t.Id) + if err != nil { + Logger.Printf("Error adding many-many mapping for template %s\n", t.Name) + } + return nil +} + func insertTargetIntoGroup(t models.Target, gid int64) error { if _, err = mail.ParseAddress(t.Email); err != nil { Logger.Printf("Invalid email %s\n", t.Email) diff --git a/models/models.go b/models/models.go index ca4abaa3..c4c60ddc 100644 --- a/models/models.go +++ b/models/models.go @@ -62,9 +62,9 @@ type Target struct { } type Template struct { - Id int64 `json:"-"` - Name string `json:"name"` - Text string `json:"text"` - Html string `json:"html"` + Id int64 `json:"id"` + Name string `json:"name" db:"name"` + Text string `json:"text" db:"text"` + Html string `json:"html" db:"html"` ModifiedDate time.Time `json:"modified_date" db:"modified_date"` }