diff --git a/build.bat b/build.bat index 363fa9f1..6df7d4da 100644 --- a/build.bat +++ b/build.bat @@ -1 +1,2 @@ -go build \ No newline at end of file +go build +pause \ No newline at end of file diff --git a/config.go b/config.go index aedda908..1f4f3ad6 100644 --- a/config.go +++ b/config.go @@ -12,4 +12,5 @@ var max_request_size = 5 * megabyte // Misc var default_route = route_topics -var staff_css = "background-color: #ffeaff;background-position: left;" \ No newline at end of file +var staff_css = "background-color: #ffeaff;background-position: left;" +var uncategorised_forum_visible = true \ No newline at end of file diff --git a/errors.go b/errors.go index a66c7082..797d414d 100644 --- a/errors.go +++ b/errors.go @@ -120,6 +120,26 @@ func LoginRequiredJSQ(w http.ResponseWriter, r *http.Request, user User, is_js s } } +func SecurityError(w http.ResponseWriter, r *http.Request, user User) { + errmsg := "There was a security issue with your request." + pi := Page{"Security Error","error",user,tList,errmsg} + var b bytes.Buffer + templates.ExecuteTemplate(&b,"error.html", pi) + errpage := b.String() + w.WriteHeader(403) + fmt.Fprintln(w,errpage) +} + +func NotFound(w http.ResponseWriter, r *http.Request, user User) { + errmsg := "The requested page doesn't exist." + pi := Page{"Not Found","error",user,tList,errmsg} + var b bytes.Buffer + templates.ExecuteTemplate(&b,"error.html", pi) + errpage := b.String() + w.WriteHeader(404) + fmt.Fprintln(w,errpage) +} + func CustomErrorJSQ(errmsg string, errcode int, errtitle string, w http.ResponseWriter, r *http.Request, user User, is_js string) { if is_js == "0" { pi := Page{errtitle,"error",user,tList,errmsg} diff --git a/forum.go b/forum.go index b08cf501..e100ca9b 100644 --- a/forum.go +++ b/forum.go @@ -4,6 +4,7 @@ type Forum struct { ID int Name string + Active bool LastTopic string LastTopicID int LastReplyer string diff --git a/grosolo-linux b/grosolo-linux new file mode 100644 index 00000000..a1cc146d --- /dev/null +++ b/grosolo-linux @@ -0,0 +1,2 @@ +go build +./Grosolo \ No newline at end of file diff --git a/grosolo.exe b/grosolo.exe index 216a9b3f..25dcd8a4 100644 Binary files a/grosolo.exe and b/grosolo.exe differ diff --git a/grosolo.exe~ b/grosolo.exe~ new file mode 100644 index 00000000..f9ba9b81 Binary files /dev/null and b/grosolo.exe~ differ diff --git a/main.go b/main.go index 3ec3dca6..f2b2bdad 100644 --- a/main.go +++ b/main.go @@ -42,12 +42,15 @@ var register_stmt *sql.Stmt var username_exists_stmt *sql.Stmt var create_forum_stmt *sql.Stmt +var delete_forum_stmt *sql.Stmt +var update_forum_stmt *sql.Stmt var custom_pages map[string]string = make(map[string]string) var templates = template.Must(template.ParseGlob("templates/*")) var no_css_tmpl = template.CSS("") var staff_css_tmpl = template.CSS(staff_css) var groups map[int]Group = make(map[int]Group) +var forums map[int]Forum = make(map[int]Forum) var static_files map[string]SFile = make(map[string]SFile) func init_database(err error) { @@ -188,8 +191,20 @@ func init_database(err error) { log.Fatal(err) } + log.Print("Preparing delete_forum statement.") + delete_forum_stmt, err = db.Prepare("DELETE FROM forums WHERE fid = ?") + if err != nil { + log.Fatal(err) + } + + log.Print("Preparing update_forum statement.") + update_forum_stmt, err = db.Prepare("UPDATE forums SET name = ? WHERE fid = ?") + if err != nil { + log.Fatal(err) + } + log.Print("Loading the usergroups.") - rows, err := db.Query("select gid,name,permissions,is_admin,is_banned from users_groups") + rows, err := db.Query("SELECT gid,name,permissions,is_admin,is_banned FROM users_groups") if err != nil { log.Fatal(err) } @@ -207,6 +222,42 @@ func init_database(err error) { if err != nil { log.Fatal(err) } + + log.Print("Loading the forums.") + rows, err = db.Query("SELECT fid, name, lastTopic, lastTopicID, lastReplyer, lastReplyerID, lastTopicTime FROM forums") + if err != nil { + log.Fatal(err) + } + defer rows.Close() + + for rows.Next() { + forum := Forum{0,"",true,"",0,"",0,""} + err := rows.Scan(&forum.ID, &forum.Name, &forum.LastTopic, &forum.LastTopicID, &forum.LastReplyer, &forum.LastReplyerID, &forum.LastTopicTime) + if err != nil { + log.Fatal(err) + } + + if forum.LastTopicID != 0 { + forum.LastTopicTime, err = relative_time(forum.LastTopicTime) + if err != nil { + log.Fatal(err) + } + } else { + forum.LastTopic = "None" + forum.LastTopicTime = "" + } + + forums[forum.ID] = forum + } + err = rows.Err() + if err != nil { + log.Fatal(err) + } + + log.Print("Adding the uncategorised forum") + forums[0] = Forum{0,"Uncategorised",uncategorised_forum_visible,"",0,"",0,""} + log.Print("Adding the reports forum") + forums[-1] = Forum{-1,"Reports",false,"",0,"",0,""} } func main(){ @@ -288,6 +339,9 @@ func main(){ // Admin http.HandleFunc("/panel/forums/", route_panel_forums) http.HandleFunc("/panel/forums/create/", route_panel_forums_create_submit) + http.HandleFunc("/panel/forums/delete/", route_panel_forums_delete) + http.HandleFunc("/panel/forums/delete/submit/", route_panel_forums_delete_submit) + http.HandleFunc("/panel/forums/edit/submit/", route_panel_forums_edit_submit) http.HandleFunc("/", default_route) diff --git a/pages.go b/pages.go index 365ca4d9..efdff4ec 100644 --- a/pages.go +++ b/pages.go @@ -21,6 +21,12 @@ type PageSimple struct Something interface{} } +type AreYouSure struct +{ + URL string + Message string +} + func add_custom_page(path string, f os.FileInfo, err error) error { if err != nil { return err diff --git a/public/global.js b/public/global.js index 255d127b..c8a9d234 100644 --- a/public/global.js +++ b/public/global.js @@ -83,4 +83,30 @@ $(document).ready(function(){ }); }); }); + + $(".edit_field").click(function(event) + { + event.preventDefault(); + var block_parent = $(this).closest('.editable_parent'); + var block = block_parent.find('.editable_block').eq(0); + block.html(""); + + $(".submit_edit").click(function(event) + { + event.preventDefault(); + var block_parent = $(this).closest('.editable_parent'); + var block = block_parent.find('.editable_block').eq(0); + var newContent = block.find('input').eq(0).val(); + block.html(newContent); + + var form_action = $(this).closest('a').attr("href"); + console.log("Form Action: " + form_action); + $.ajax({ + url: form_action + "?session=" + session, + type: "POST", + dataType: "json", + data: {is_js: "1",edit_item: newContent} + }); + }); + }); }); \ No newline at end of file diff --git a/routes.go b/routes.go index 99c27d35..8d794de8 100644 --- a/routes.go +++ b/routes.go @@ -1,5 +1,6 @@ package main +import "errors" import "log" import "fmt" import "strconv" @@ -58,14 +59,7 @@ func route_custom_page(w http.ResponseWriter, r *http.Request){ pi := Page{"Page","page",user,tList,val} templates.ExecuteTemplate(w,"custom_page.html", pi) } else { - errmsg := "The requested page doesn't exist." - pi := Page{"Error","error",user,tList,errmsg} - - var b bytes.Buffer - templates.ExecuteTemplate(&b,"error.html", pi) - errpage := b.String() - w.WriteHeader(404) - fmt.Fprintln(w,errpage) + NotFound(w,r,user) } } @@ -133,7 +127,6 @@ func route_forum(w http.ResponseWriter, r *http.Request){ var( topicList map[int]interface{} currentID int - fname string tid int title string @@ -156,18 +149,9 @@ func route_forum(w http.ResponseWriter, r *http.Request){ return } - err = db.QueryRow("select name from forums where fid = ?", fid).Scan(&fname) - if err == sql.ErrNoRows { - pi := Page{"Error","error",user,tList,"The requested forum doesn't exist."} - - var b bytes.Buffer - templates.ExecuteTemplate(&b,"error.html", pi) - errpage := b.String() - w.WriteHeader(404) - fmt.Fprintln(w,errpage) - return - } else if err != nil { - InternalError(err,w,r,user) + _, ok := forums[fid] + if !ok { + NotFound(w,r,user) return } @@ -202,7 +186,7 @@ func route_forum(w http.ResponseWriter, r *http.Request){ InternalError(err,w,r,user) return } - pi := Page{fname,"forum",user,topicList,0} + pi := Page{forums[fid].Name,"forum",user,topicList,0} err = templates.ExecuteTemplate(w,"forum.html", pi) if err != nil { InternalError(err, w, r, user) @@ -211,46 +195,23 @@ func route_forum(w http.ResponseWriter, r *http.Request){ func route_forums(w http.ResponseWriter, r *http.Request){ user := SessionCheck(w,r) - var forumList map[int]interface{} - forumList = make(map[int]interface{}) + var forumList map[int]interface{} = make(map[int]interface{}) currentID := 0 - rows, err := db.Query("select fid, name, lastTopic, lastTopicID, lastReplyer, lastReplyerID, lastTopicTime from forums") - if err != nil { - InternalError(err,w,r,user) - return + for _, forum := range forums { + if forum.Active { + forumList[currentID] = forum + currentID++ + } } - defer rows.Close() - for rows.Next() { - forum := Forum{0,"","",0,"",0,""} - err := rows.Scan(&forum.ID, &forum.Name, &forum.LastTopic,&forum.LastTopicID,&forum.LastReplyer,&forum.LastReplyerID,&forum.LastTopicTime) - if err != nil { - InternalError(err,w,r,user) - return - } - - if forum.LastTopicID != 0 { - forum.LastTopicTime, err = relative_time(forum.LastTopicTime) - if err != nil { - InternalError(err,w,r,user) - return - } - } else { - forum.LastTopic = "None" - forum.LastTopicTime = "" - } - - forumList[currentID] = forum - currentID++ - } - err = rows.Err() - if err != nil { - InternalError(err,w,r,user) + if len(forums) == 0 { + InternalError(errors.New("No forums"),w,r,user) return } + pi := Page{"Forum List","forums",user,forumList,0} - err = templates.ExecuteTemplate(w,"forums.html", pi) + err := templates.ExecuteTemplate(w,"forums.html", pi) if err != nil { InternalError(err, w, r, user) } @@ -290,14 +251,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){ //err = db.QueryRow("select title, content, createdBy, status, is_closed from topics where tid = ?", tid).Scan(&title, &content, &createdBy, &status, &is_closed) err = db.QueryRow("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, users.name, users.avatar, users.is_super_admin, users.group from topics left join users ON topics.createdBy = users.uid where tid = ?", topic.ID).Scan(&topic.Title, &content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.CreatedByName, &topic.Avatar, &is_super_admin, &group) if err == sql.ErrNoRows { - errmsg := "The requested topic doesn't exist." - pi := Page{"Error","error",user,tList,errmsg} - - var b bytes.Buffer - templates.ExecuteTemplate(&b,"error.html", pi) - errpage := b.String() - w.WriteHeader(404) - fmt.Fprintln(w,errpage) + NotFound(w,r,user) return } else if err != nil { InternalError(err,w,r,user) @@ -1036,9 +990,9 @@ func route_login_submit(w http.ResponseWriter, r *http.Request) { var salt string var session string username := html.EscapeString(r.PostFormValue("username")) - log.Print("Username: " + username) + //log.Print("Username: " + username) password := r.PostFormValue("password") - log.Print("Password: " + password) + //log.Print("Password: " + password) err = login_stmt.QueryRow(username).Scan(&uid, &username, &real_password, &salt) if err == sql.ErrNoRows { @@ -1112,8 +1066,8 @@ func route_login_submit(w http.ResponseWriter, r *http.Request) { return } - log.Print("Successful Login") - log.Print("Session: " + session) + //log.Print("Successful Login") + //log.Print("Session: " + session) cookie := http.Cookie{Name: "uid",Value: strconv.Itoa(uid),Path: "/",MaxAge: year} http.SetCookie(w,&cookie) cookie = http.Cookie{Name: "session",Value: session,Path: "/",MaxAge: year} @@ -1230,28 +1184,11 @@ func route_panel_forums(w http.ResponseWriter, r *http.Request){ var forumList map[int]interface{} = make(map[int]interface{}) currentID := 0 - rows, err := db.Query("select fid, name from forums") - if err != nil { - InternalError(err,w,r,user) - return - } - defer rows.Close() - - for rows.Next() { - forum := ForumSimple{0,""} - err := rows.Scan(&forum.ID, &forum.Name) - if err != nil { - InternalError(err,w,r,user) - return + for _, forum := range forums { + if forum.ID > -1 { + forumList[currentID] = forum + currentID++ } - - forumList[currentID] = forum - currentID++ - } - err = rows.Err() - if err != nil { - InternalError(err,w,r,user) - return } pi := Page{"Forum Manager","panel-forums",user,forumList,0} @@ -1264,17 +1201,135 @@ func route_panel_forums_create_submit(w http.ResponseWriter, r *http.Request){ NoPermissions(w,r,user) return } + err := r.ParseForm() if err != nil { LocalError("Bad Form", w, r, user) return } + if r.FormValue("session") != user.Session { + SecurityError(w,r,user) + return + } - _, err = create_forum_stmt.Exec(r.PostFormValue("forum-name")) + fname := r.PostFormValue("forum-name") + res, err := create_forum_stmt.Exec(fname) if err != nil { InternalError(err,w,r,user) return } - http.Redirect(w,r, "/panel/forums/", http.StatusSeeOther) + lastId, err := res.LastInsertId() + if err != nil { + InternalError(err,w,r,user) + return + } + + forums[int(lastId)] = Forum{int(lastId),fname,true,"",0,"",0,""} + http.Redirect(w,r,"/panel/forums/",http.StatusSeeOther) +} + +func route_panel_forums_delete(w http.ResponseWriter, r *http.Request){ + user := SessionCheck(w,r) + if !user.Is_Admin { + NoPermissions(w,r,user) + return + } + if r.FormValue("session") != user.Session { + SecurityError(w,r,user) + return + } + fid, err := strconv.Atoi(r.URL.Path[len("/panel/forums/delete/"):]) + if err != nil { + LocalError("The provided Forum ID is not a valid number.",w,r,user) + return + } + + _, ok := forums[fid]; + if !ok { + LocalError("The forum you're trying to delete doesn't exist.",w,r,user) + return + } + + confirm_msg := "Are you sure you want to delete the '" + forums[fid].Name + "' forum?" + yousure := AreYouSure{"/panel/forums/delete/submit/" + strconv.Itoa(fid),confirm_msg} + + pi := Page{"Delete Forum","panel-forums-delete",user,tList,yousure} + templates.ExecuteTemplate(w,"areyousure.html", pi) +} + +func route_panel_forums_delete_submit(w http.ResponseWriter, r *http.Request) { + user := SessionCheck(w,r) + if !user.Is_Admin { + NoPermissions(w,r,user) + return + } + if r.FormValue("session") != user.Session { + SecurityError(w,r,user) + return + } + + fid, err := strconv.Atoi(r.URL.Path[len("/panel/forums/delete/submit/"):]) + if err != nil { + LocalError("The provided Forum ID is not a valid number.",w,r,user) + return + } + + _, ok := forums[fid]; + if !ok { + LocalError("The forum you're trying to delete doesn't exist.",w,r,user) + return + } + + _, err = delete_forum_stmt.Exec(fid) + if err != nil { + InternalError(err,w,r,user) + return + } + + // Remove this forum from the forum cache + delete(forums,fid); + http.Redirect(w,r,"/panel/forums/",http.StatusSeeOther) +} + +func route_panel_forums_edit_submit(w http.ResponseWriter, r *http.Request) { + user := SessionCheck(w,r) + if !user.Is_Admin { + NoPermissions(w,r,user) + return + } + + err := r.ParseForm() + if err != nil { + LocalError("Bad Form", w, r, user) + return + } + if r.FormValue("session") != user.Session { + SecurityError(w,r,user) + return + } + + fid, err := strconv.Atoi(r.URL.Path[len("/panel/forums/edit/submit/"):]) + if err != nil { + LocalError("The provided Forum ID is not a valid number.",w,r,user) + return + } + + forum_name := r.PostFormValue("edit_item") + + forum, ok := forums[fid]; + if !ok { + LocalError("The forum you're trying to edit doesn't exist.",w,r,user) + return + } + + _, err = update_forum_stmt.Exec(forum_name, fid) + if err != nil { + InternalError(err,w,r,user) + return + } + forum.Name = forum_name + forums[fid] = forum + + http.Redirect(w,r,"/panel/forums/",http.StatusSeeOther) } \ No newline at end of file diff --git a/templates/areyousure.html b/templates/areyousure.html new file mode 100644 index 00000000..e0dae8a8 --- /dev/null +++ b/templates/areyousure.html @@ -0,0 +1,10 @@ +{{template "header.html" . }} +
+
Are you sure?
+
+
+
{{.Something.Message}}

+ Continue +
+
+{{template "footer.html" . }} \ No newline at end of file diff --git a/templates/header.html b/templates/header.html index 11f5cdd8..9a027289 100644 --- a/templates/header.html +++ b/templates/header.html @@ -4,6 +4,9 @@ {{.Title}} + diff --git a/templates/panel-forums.html b/templates/panel-forums.html index ee6d1d10..060e223b 100644 --- a/templates/panel-forums.html +++ b/templates/panel-forums.html @@ -5,18 +5,24 @@
Coming Soon
Coming Soon
Coming Soon
-
Coming Soon
+
Reports
{{range .ItemList}} -
{{.Name}}
+
+ {{.Name}} + + Edit + Delete + +
{{end}}

Add Forum
-
+