From df5dca3a52b6f98e5ecced62c2263ba37298748c Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Wed, 11 Nov 2015 09:28:07 -0800 Subject: [PATCH] work on porting routers to more gorilla/mux style and making all actions POST and csrf trackable --- .gitignore | 2 ++ js/funcs.js | 23 +++++++++-------- main.go | 11 ++++---- news/news.go | 9 +++---- route_handlers.go | 50 ++++++++++++++++++++----------------- templates/layout.html | 6 ++--- templates/pages/export.html | 5 +++- templates/pages/news.html | 4 +-- templates/pages/post.html | 3 +-- 9 files changed, 60 insertions(+), 53 deletions(-) diff --git a/.gitignore b/.gitignore index 1ed2868..7e101c5 100644 --- a/.gitignore +++ b/.gitignore @@ -29,3 +29,5 @@ _testmain.go *.exe *.test *.prof + +.*.swp diff --git a/js/funcs.js b/js/funcs.js index fc56b0b..09943a0 100644 --- a/js/funcs.js +++ b/js/funcs.js @@ -3,42 +3,43 @@ $(document).ready( function () { $(".confirm-export").confirm({ "text": "Mark current batch exported?", - "title": "Export confrimation", - confirm: function() { - window.location = "/export-commit"; + "title": "Export confirmation", + "confirm": function(form) { + form.submit(); }, }); - - - + if( $('.addedLink').length > 0) { setTimeout(function (){ window.close(); }, 500); } - + $("form.form-add").submit( function(e) { if ( $(".add-category").val() == -1) { e.preventDefault(); $(".add-category-col").addClass("has-error"); } }); - + $(".category-change-parent").change(function (e) { e.target.parentElement.submit(); }); - + $('.cat-delete').confirm({ text: "Are you sure you want to delete this category?", title: "Confirmation required", confirmButton: "Yes", cancelButton: "No", }); - - $(".confirm-delete").confirm({ + + $(".confirm-news-delete").confirm({ "text": "Delete news item?", "title": "Delete confirmation", confirmButton: "Yes", cancelButton: "No", + "confirm": function(form) { + form.submit(); + } }); }); diff --git a/main.go b/main.go index 2a69256..1b8213f 100644 --- a/main.go +++ b/main.go @@ -102,14 +102,15 @@ func main() { loadConfig(*envFlag) dbConnect() initTemplates() - //CSRF := csrf.Protect([]byte(csrfSecret())); - r := init_route_handlers() - errHandle := csrf.ErrorHandler( CSRFErrorHandler{} ) - sec := csrf.Secure(false) + muxRouter := init_route_handlers() + //errHandler := csrf.ErrorHandler( CSRFErrorHandler{} ) + + // Terrible. TODO: Get SSL for prod, and then wrap in if(dev) { { + csrfSecurityOption := csrf.Secure(false) fmt.Println("Listening on", config.Port, "...") - err := http.ListenAndServe(":"+config.Port, csrf.Protect([]byte("12345678901234567890123456789012"), errHandle, sec)(r)) //csrfSecret()))(r)) + err := http.ListenAndServe(":"+config.Port, csrf.Protect([]byte(csrfSecret()), /*errHandler,*/ csrfSecurityOption)(muxRouter)) if err != nil { fmt.Println("Fatal Error: ", err) } diff --git a/news/news.go b/news/news.go index 9802b87..c861c85 100644 --- a/news/news.go +++ b/news/news.go @@ -17,11 +17,10 @@ type News struct { Category_id int Date time.Time Notes string - Expoerted bool } const ( - SQL_NEWS_FIELDS = "id, url, title, category_id, timestamp, notes, exported" + SQL_NEWS_FIELDS = "id, url, title, category_id, timestamp, notes" ) /* Storage Node containing: @@ -95,7 +94,7 @@ func Get(db *sql.DB, id int) (*News, error) { func LoadPage(db *sql.DB, offset, amount int) ([]*News, int, error) { categories.LoadCategories(db) // required by addContainer - rows, err := db.Query("SELECT "+SQL_NEWS_FIELDS+" FROM news WHERE exported is null order by timestamp DESC") + rows, err := db.Query("SELECT "+SQL_NEWS_FIELDS+" FROM news order by timestamp DESC") if err != nil { fmt.Println("DB errpr reading LoadPage news: ", err) return nil, 0, err @@ -174,8 +173,7 @@ func scanNews(rows *sql.Rows) (*News, error) { news := &News{} var url, title, notes sql.NullString var category_id sql.NullInt64 - var exported sql.NullBool - err := rows.Scan(&news.id, &url, &title, &category_id, &news.Date, ¬es, &exported) + err := rows.Scan(&news.id, &url, &title, &category_id, &news.Date, ¬es) if err != nil { fmt.Println("Error reading news from DB: " + err.Error()) return nil, err @@ -184,7 +182,6 @@ func scanNews(rows *sql.Rows) (*News, error) { news.Url = nullStringToString(&url) news.Title = nullStringToString(&title) news.Notes = nullStringToString(¬es) - news.Expoerted = nullBoolToBool(&exported) if category_id.Valid { news.Category_id = int(category_id.Int64) diff --git a/route_handlers.go b/route_handlers.go index 7e2e9be..393847b 100644 --- a/route_handlers.go +++ b/route_handlers.go @@ -176,7 +176,7 @@ func addPostHandler(w http.ResponseWriter, r *http.Request, user *user.User, ses session.AddFlash("Added news \""+news.Title+"\"", flash_info) session.Save(r, w) if popup == "1" { - http.Redirect(w, r, "/added", http.StatusFound) + http.Redirect(w, r, "/news/added", http.StatusFound) } else { http.Redirect(w, r, "/", http.StatusFound) } @@ -284,7 +284,7 @@ func exportHandler(w http.ResponseWriter, r *http.Request, user *user.User, sess session.AddFlash("Last batch of news marked exported", flash_info) } session.Save(r, w) - http.Redirect(w, r, "/", http.StatusFound) + http.Redirect(w, r, "/export", http.StatusFound) } func addedHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) { @@ -294,7 +294,7 @@ func addedHandler(w http.ResponseWriter, r *http.Request, user *user.User, sessi } func deleteHandler(w http.ResponseWriter, r *http.Request, user *user.User, session *sessions.Session) { - id, idErr := strconv.Atoi(r.FormValue("id")) + id, idErr := strconv.Atoi(mux.Vars(r)["id"]) if idErr != nil { session.AddFlash("Invalid news to delete", flash_err) @@ -412,7 +412,6 @@ func newsFormHandler(w http.ResponseWriter, r *http.Request, user *user.User, se } ShowTemplate("news", w, r, map[string]interface{}{"user": user, "flashes": flashes, "news": news, "count": count, "categories": categories.CategoriesFlat}) - } func ServeFileHandler(res http.ResponseWriter, req *http.Request) { @@ -421,41 +420,46 @@ func ServeFileHandler(res http.ResponseWriter, req *http.Request) { } func init_route_handlers() *mux.Router { - - // Mux + CSRF r := mux.NewRouter() - // Basic Handle - static files - no CSRF wrapper r.PathPrefix("/js/").Handler(http.StripPrefix("/js/", http.FileServer(http.Dir("js/")))) r.PathPrefix("/css/").Handler(http.StripPrefix("/css/", http.FileServer(http.Dir("css/")))) r.PathPrefix("/fonts/").Handler(http.StripPrefix("/fonts", http.FileServer(http.Dir("fonts/")))) r.HandleFunc("/favicon.ico", ServeFileHandler) - rGet := r.Methods("GET").Subrouter() rPost := r.Methods("POST").Subrouter() rGet.HandleFunc("/login", LoginFormHandler) rPost.HandleFunc("/login", LoginPostHandler) - r.HandleFunc("/logout", userHandler(LogoutHandler)) + rPost.HandleFunc("/logout", userHandler(LogoutHandler)) - r.HandleFunc("/add", getPostHandler(userHandler(addFormHandler), userHandler(addPostHandler))) - r.HandleFunc("/", userHandler(newsFormHandler)) - r.HandleFunc("/news", userHandler(newsFormHandler)) - r.HandleFunc("/export", userHandler(templateFormHandler)) - r.HandleFunc("/export-commit", userHandler(exportHandler)) - r.HandleFunc("/added", userHandler(addedHandler)) - r.HandleFunc("/delete", userHandler(deleteHandler)) - r.HandleFunc("/edit", getPostHandler(userHandler(editFormHandler), userHandler(editPostHandler))) + rGet.HandleFunc("/news/add", userHandler(addFormHandler)) + rPost.HandleFunc("/news/add", userHandler(addPostHandler)) + + rGet.HandleFunc("/", userHandler(newsFormHandler)) + rGet.HandleFunc("/news", userHandler(newsFormHandler)) + + rGet.HandleFunc("/news/export", userHandler(templateFormHandler)) + rPost.HandleFunc("/news/export", userHandler(exportHandler)) + + rGet.HandleFunc("/news/added", userHandler(addedHandler)) + + // TODO to post and {id} + rPost.HandleFunc("/news/{id:[0-9]+}/delete", userHandler(deleteHandler)) + // TODO post {id} ? + rGet.HandleFunc("/news/{id:[0-9]+}/edit", userHandler(editFormHandler)) + rPost.HandleFunc("/news/{id:[0-9]+}/edit", userHandler(editPostHandler)) - r.HandleFunc("/categories", getPostHandler(userHandler(categoriesFormHandler), userHandler(categoriesPostHandler))) - r.HandleFunc("/categories/change-parent", userHandler(categoryChangeParentHandler)) - r.HandleFunc("/categories/add", userHandler(categoryAddHandler)) - r.HandleFunc("/categories/delete", userHandler(categoryDeleteHandler)) - - //http.Handle("/", r) + rGet.HandleFunc("/categories", userHandler(categoriesFormHandler)) + rPost.HandleFunc("/caegories", userHandler(categoriesPostHandler)) + + // TODO post, add {id} + rPost.HandleFunc("/categories/change-parent", userHandler(categoryChangeParentHandler)) + rPost.HandleFunc("/categories/add", userHandler(categoryAddHandler)) + rPost.HandleFunc("/categories/delete", userHandler(categoryDeleteHandler)) return r } diff --git a/templates/layout.html b/templates/layout.html index 6130f22..68b74e2 100644 --- a/templates/layout.html +++ b/templates/layout.html @@ -32,15 +32,15 @@