func Index(w http.ResponseWriter, request *http.Request) { current_user := utils.GetCurrentUser(request) boards, err := models.GetBoardsUnread(current_user) if err != nil { fmt.Printf("[error] Could not get boards (%s)\n", err.Error()) } user_count, _ := models.GetUserCount() latest_user, _ := models.GetLatestUser() total_posts, _ := models.GetPostCount() utils.RenderTemplate(w, request, "index.html", map[string]interface{}{ "boards": boards, "user_count": user_count, "online_users": models.GetOnlineUsers(), "latest_user": latest_user, "total_posts": total_posts, }, map[string]interface{}{ "IsUnread": func(join *models.JoinBoardView) bool { latest_post := join.Board.GetLatestPost() if current_user != nil && !current_user.LastUnreadAll.Time.Before(latest_post.Op.LatestReply) { return false } return !join.ViewedOn.Valid || join.ViewedOn.Time.Before(latest_post.Op.LatestReply) }, }) }
func AdminUsers(w http.ResponseWriter, r *http.Request) { current_user := utils.GetCurrentUser(r) if current_user == nil || !current_user.IsAdmin() { http.NotFound(w, r) return } err := "" success := false starts_with := r.FormValue("starts_with") last_seen := r.FormValue("last_seen") db := models.GetDbSession() var users []*models.User if len(starts_with) == 1 { db.Select(&users, "SELECT * FROM users WHERE username LIKE $1", starts_with+"%") } else if last_seen == "1" { db.Select(&users, "SELECT * FROM users ORDER BY last_seen DESC") } else { db.Select(&users, "SELECT * FROM users ORDER BY id DESC") } utils.RenderTemplate(w, r, "admin_users.html", map[string]interface{}{ "error": err, "success": success, "users": users, }, nil) }
func NewThread(w http.ResponseWriter, r *http.Request) { db := models.GetDbSession() board_id_str := mux.Vars(r)["id"] board_id, _ := strconv.Atoi(board_id_str) err, board := models.GetBoard(board_id) if err != nil { http.NotFound(w, r) return } current_user := utils.GetCurrentUser(r) if current_user == nil { http.NotFound(w, r) return } if r.Method == "POST" { title := r.FormValue("title") content := r.FormValue("content") post := models.NewPost(current_user, board, title, content) post.LatestReply = time.Now() db.Insert(post) http.Redirect(w, r, fmt.Sprintf("/board/%d/%d", board.Id, post.Id), http.StatusFound) return } utils.RenderTemplate(w, r, "new_thread.html", map[string]interface{}{ "board": board, }) }
func Index(w http.ResponseWriter, request *http.Request) { db := models.GetDbSession() var boards []models.Board _, err := db.Select(&boards, "SELECT * FROM boards") if err != nil { fmt.Printf("[error] Could not get boards (%s)\n", err.Error()) } utils.RenderTemplate(w, request, "index.html", map[string]interface{}{ "boards": boards, }) }
func Login(w http.ResponseWriter, r *http.Request) { if utils.GetCurrentUser(r) != nil { http.Redirect(w, r, "/", http.StatusFound) return } if r.Method == "POST" { username := r.FormValue("username") password := r.FormValue("password") var error string err, _ := models.AuthenticateUser(username, password) if err != nil { error = "Invalid username or password" } if error != "" { utils.RenderTemplate(w, r, "login.html", map[string]interface{}{ "error": error, }) return } session, _ := utils.Store.Get(r, "sirsid") session.Values["username"] = username session.Values["password"] = password fmt.Println("[notice] Auth success!") err = session.Save(r, w) if err != nil { fmt.Printf("[error] Could not save session (%s)\n", err.Error()) } http.Redirect(w, r, "/", http.StatusFound) return } utils.RenderTemplate(w, r, "login.html", nil) }
func Thread(w http.ResponseWriter, r *http.Request) { page_id_str := r.FormValue("page") page_id, err := strconv.Atoi(page_id_str) if err != nil { page_id = 0 } board_id_str := mux.Vars(r)["board_id"] board_id, _ := strconv.Atoi(board_id_str) err, board := models.GetBoard(board_id) post_id_str := mux.Vars(r)["post_id"] post_id, _ := strconv.Atoi(post_id_str) err, op, posts := models.GetThread(post_id, page_id) if r.Method == "POST" { db := models.GetDbSession() title := r.FormValue("title") content := r.FormValue("content") current_user := utils.GetCurrentUser(r) if current_user == nil { http.NotFound(w, r) return } post := models.NewPost(current_user, board, title, content) post.ParentId = sql.NullInt64{int64(post_id), true} op.LatestReply = time.Now() db.Insert(post) db.Update(op) err, op, posts = models.GetThread(post_id, page_id) } if err != nil { http.NotFound(w, r) return } num_pages := op.GetPagesInThread() utils.RenderTemplate(w, r, "thread.html", map[string]interface{}{ "board": board, "op": op, "posts": posts, "prev_page": (page_id != 0), "next_page": (page_id < num_pages), "page_id": page_id, }) }
func Register(w http.ResponseWriter, r *http.Request) { if utils.GetCurrentUser(r) != nil { http.Redirect(w, r, "/", http.StatusFound) return } if r.Method == "POST" { username := r.FormValue("username") password := r.FormValue("password") confirm := r.FormValue("password2") var error string if password != confirm { error = "Passwords don't match" } if error != "" { utils.RenderTemplate(w, r, "register.html", map[string]interface{}{ "error": error, }) return } // We're good, let's make it db_map := models.GetDbSession() user := models.NewUser(username, password) err := db_map.Insert(user) if err != nil { fmt.Printf("[error] Could not insert user (%s)\n", err.Error()) } else { http.Redirect(w, r, "/login", http.StatusFound) return } } utils.RenderTemplate(w, r, "register.html", nil) }
func ActionMoveThread(w http.ResponseWriter, r *http.Request) { current_user := utils.GetCurrentUser(r) if current_user == nil || !current_user.CanModerate() { http.NotFound(w, r) return } thread_id_str := r.FormValue("post_id") thread_id, err := strconv.Atoi(thread_id_str) board_id_str := r.FormValue("to") board_id, err := strconv.Atoi(board_id_str) op, err := models.GetPost(thread_id) // boards, _ := models.GetBoardsfor(current_user.GroupId) boards, _ := models.GetBoards() if op == nil || err != nil { http.NotFound(w, r) return } if board_id_str != "" { db := models.GetDbSession() new_board, _ := models.GetBoard(board_id) if new_board == nil { http.NotFound(w, r) return } _, err := db.Exec("UPDATE posts SET board_id=$1 WHERE parent_id=$2", new_board.Id, op.Id) op.BoardId = new_board.Id db.Update(op) if err != nil { http.NotFound(w, r) fmt.Printf("Error moving post: %s\n", err.Error()) return } http.Redirect(w, r, fmt.Sprintf("/board/%d/%d", op.BoardId, op.Id), http.StatusFound) } board, err := models.GetBoard(int(op.BoardId)) utils.RenderTemplate(w, r, "action_move_thread.html", map[string]interface{}{ "board": board, "thread": op, "boards": boards, }, nil) }
func Board(w http.ResponseWriter, r *http.Request) { db := models.GetDbSession() page_id_str := r.FormValue("page") page_id, err := strconv.Atoi(page_id_str) if err != nil { page_id = 0 } board_id_str := mux.Vars(r)["id"] board_id, _ := strconv.Atoi(board_id_str) obj, err := db.Get(&models.Board{}, board_id) if err != nil || obj == nil { http.NotFound(w, r) return } board := obj.(*models.Board) if err != nil { http.NotFound(w, r) return } current_user := utils.GetCurrentUser(r) threads, err := board.GetThreads(page_id, current_user) if err != nil { fmt.Printf("[error] Could not get posts (%s)\n", err.Error()) } num_pages := board.GetPagesInBoard() utils.RenderTemplate(w, r, "board.html", map[string]interface{}{ "board": board, "threads": threads, "page_id": page_id, "prev_page": (page_id != 0), "next_page": (page_id < num_pages), }, map[string]interface{}{ "IsUnread": func(join *models.JoinThreadView) bool { if current_user != nil && !current_user.LastUnreadAll.Time.Before(join.LatestReply) { return false } return !join.ViewedOn.Valid || join.ViewedOn.Time.Before(join.LatestReply) }, }) }
func User(w http.ResponseWriter, r *http.Request) { db := models.GetDbSession() user_id_str := mux.Vars(r)["id"] user_id, err := strconv.Atoi(user_id_str) if err != nil { http.NotFound(w, r) return } user, err := db.Get(&models.User{}, user_id) if err != nil { http.NotFound(w, r) return } utils.RenderTemplate(w, r, "user.html", map[string]interface{}{ "user": user, }, nil) }
func renderPostEditor( w http.ResponseWriter, r *http.Request, board *models.Board, post *models.Post, err error) { utils.RenderTemplate(w, r, "post_editor.html", map[string]interface{}{ "board": board, "post": post, "error": err, }, map[string]interface{}{ "ShowTitleField": func() bool { if post == nil { return true } return !post.ParentId.Valid }, }) }
func Board(w http.ResponseWriter, r *http.Request) { db := models.GetDbSession() board_id_str := mux.Vars(r)["id"] board_id, _ := strconv.Atoi(board_id_str) board, err := db.Get(models.Board{}, board_id) if err != nil { http.NotFound(w, r) return } var threads []*models.Post _, err = db.Select(&threads, "SELECT * FROM posts WHERE board_id=$1 AND parent_id IS NULL ORDER BY latest_reply DESC", board_id) if err != nil { fmt.Printf("[error] Could not get posts (%s)\n", err.Error()) } utils.RenderTemplate(w, r, "board.html", map[string]interface{}{ "board": board, "threads": threads, }) }
func UserSettings(w http.ResponseWriter, r *http.Request) { user_id_str := mux.Vars(r)["id"] user_id, _ := strconv.Atoi(user_id_str) current_user := utils.GetCurrentUser(r) if int64(user_id) != current_user.Id { http.NotFound(w, r) return } success := false if r.Method == "POST" { db := models.GetDbSession() current_user.Avatar = r.FormValue("avatar_url") db.Update(current_user) success = true } utils.RenderTemplate(w, r, "user_settings.html", map[string]interface{}{ "success": success, }) }
func Admin(w http.ResponseWriter, r *http.Request) { current_user := utils.GetCurrentUser(r) if current_user == nil || !current_user.IsAdmin() { http.NotFound(w, r) return } var err error success := false stylesheet, _ := models.GetStringSetting("theme_stylesheet") favicon, _ := models.GetStringSetting("favicon_url") current_template, _ := models.GetStringSetting("template") if r.Method == "POST" { stylesheet = r.FormValue("theme_stylesheet") favicon = r.FormValue("favicon_url") current_template = r.FormValue("template") models.SetStringSetting("theme_stylesheet", stylesheet) models.SetStringSetting("favicon_url", favicon) models.SetStringSetting("template", current_template) success = true } utils.RenderTemplate(w, r, "admin.html", map[string]interface{}{ "error": err, "success": success, "theme_stylesheet": stylesheet, "favicon_url": favicon, "current_template": current_template, "templates": utils.ListTemplates(), }, map[string]interface{}{ "IsCurrentTemplate": func(name string) bool { return name == current_template }, }) }
func AdminBoards(w http.ResponseWriter, r *http.Request) { current_user := utils.GetCurrentUser(r) if current_user == nil || !current_user.IsAdmin() { http.NotFound(w, r) return } db := models.GetDbSession() // Creating a board if r.Method == "POST" && r.FormValue("create_board") != "" { name := r.FormValue("title") desc := r.FormValue("description") form_order := r.FormValue("order") var order int if form_order != "" { if len(form_order) == 0 { order = 1 } else { order, _ = strconv.Atoi(form_order) } } else { order = 1 } board := models.NewBoard(name, desc, order) db.Insert(board) } // Update the boards if r.Method == "POST" && r.FormValue("update_boards") != "" { err := r.ParseForm() // loop through the post data, entries correspond via index in the map for i := 0; i < len(r.Form["board_id"]); i++ { // basically repeat the process for inserting a board form_id, _ := strconv.Atoi(r.Form["board_id"][i]) id := int64(form_id) name := r.Form["name"][i] desc := r.Form["description"][i] form_order := r.Form["order"][i] groupidst := r.Form["groupid"][i] var order int var groupid int64 if form_order != "" { if len(form_order) == 0 { order = 1 } else { order, _ = strconv.Atoi(form_order) } } else { order = 1 } if len(groupidst) < 1 { groupid = 0 } else { groupid, _ = strconv.ParseInt(groupidst, 10, 64) } board := models.UpdateBoard(name, desc, order, id, groupid) db.Update(board) } if err != nil { http.NotFound(w, r) return } } // Delete a board if id := r.FormValue("delete"); id != "" { obj, _ := db.Get(&models.Board{}, id) if obj == nil { http.NotFound(w, r) return } board := obj.(*models.Board) board.Delete() } boards, _ := models.GetBoards() utils.RenderTemplate(w, r, "admin_boards.html", map[string]interface{}{ "boards": boards, }, nil) }
func Admin(w http.ResponseWriter, request *http.Request) { utils.RenderTemplate(w, request, "admin.html", nil) }
func AdminUser(w http.ResponseWriter, r *http.Request) { current_user := utils.GetCurrentUser(r) if current_user == nil || !current_user.IsAdmin() { http.NotFound(w, r) return } id_str := mux.Vars(r)["id"] id, _ := strconv.Atoi(id_str) user, err := models.GetUser(id) if err != nil || user == nil { http.NotFound(w, r) return } var form_error string success := false if r.Method == "POST" { db := models.GetDbSession() user.Username = r.FormValue("username") user.Avatar = r.FormValue("avatar_url") user.UserTitle = r.FormValue("user_title") user.StylesheetUrl = sql.NullString{ Valid: true, String: r.FormValue("stylesheet_url"), } if r.FormValue("signature") == "" { user.Signature = sql.NullString{ Valid: false, String: r.FormValue("signature"), } } else { user.Signature = sql.NullString{ Valid: true, String: r.FormValue("signature"), } } // Change hiding settings user.HideOnline = false if r.FormValue("hide_online") == "1" { user.HideOnline = true } // Update the username? if len(user.Username) < 3 { form_error = "Username must at least 3 characters" } // Update password? new_pass := r.FormValue("password_new") new_pass2 := r.FormValue("password_new2") if len(new_pass) > 0 { if len(new_pass) < 5 { form_error = "Password must be greater than 4 characters" } else if new_pass != new_pass2 { form_error = "Passwords didn't match" } else { user.SetPassword(new_pass) } } group_id, _ := strconv.Atoi(r.FormValue("group_id")) user.GroupId = int64(group_id) if form_error == "" { db.Update(user) success = true } } utils.RenderTemplate(w, r, "admin_user.html", map[string]interface{}{ "error": form_error, "success": success, "user": user, }, nil) }
func UserSettings(w http.ResponseWriter, r *http.Request) { enable_signatures, _ := config.Config.GetBool("gobb", "enable_signatures") user_id_str := mux.Vars(r)["id"] user_id, _ := strconv.Atoi(user_id_str) current_user := utils.GetCurrentUser(r) if current_user == nil || int64(user_id) != current_user.Id { http.NotFound(w, r) return } success := false var form_error string if r.Method == "POST" { db := models.GetDbSession() current_user.Avatar = r.FormValue("avatar_url") current_user.UserTitle = r.FormValue("user_title") current_user.StylesheetUrl = sql.NullString{ Valid: true, String: r.FormValue("stylesheet_url"), } if r.FormValue("signature") == "" { current_user.Signature = sql.NullString{ Valid: false, String: r.FormValue("signature"), } } else { current_user.Signature = sql.NullString{ Valid: true, String: r.FormValue("signature"), } } // Change hiding settings current_user.HideOnline = false if r.FormValue("hide_online") == "1" { current_user.HideOnline = true } // Update password? old_pass := r.FormValue("password_old") new_pass := r.FormValue("password_new") new_pass2 := r.FormValue("password_new2") if old_pass != "" { err, user := models.AuthenticateUser(current_user.Username, old_pass) if user == nil || err != nil { form_error = "Invalid password" } else if len(new_pass) < 5 { form_error = "Password must be greater than 4 characters" } else if new_pass != new_pass2 { form_error = "Passwords didn't match" } else { current_user.SetPassword(new_pass) session, _ := utils.GetCookieStore(r).Get(r, "sirsid") session.Values["password"] = new_pass session.Save(r, w) } } if form_error == "" { db.Update(current_user) success = true } } stylesheet := "" if current_user.StylesheetUrl.Valid { stylesheet = current_user.StylesheetUrl.String } signature := "" if current_user.Signature.Valid { signature = current_user.Signature.String } utils.RenderTemplate(w, r, "user_settings.html", map[string]interface{}{ "error": form_error, "success": success, "user_stylesheet": stylesheet, "user_signature": signature, "enable_signatures": enable_signatures, }, nil) }
func Register(w http.ResponseWriter, r *http.Request) { if utils.GetCurrentUser(r) != nil { http.Redirect(w, r, "/", http.StatusFound) return } if r.Method == "POST" { username := r.FormValue("username") password := r.FormValue("password") confirm := r.FormValue("password2") var error string if password != confirm { error = "Passwords don't match" } // See if a user with this name already exists db := models.GetDbSession() count, err := db.SelectInt("SELECT COUNT(*) FROM users WHERE username=$1", username) if count > 0 || err != nil { error = "This username is already taken." } if len(username) < 3 { error = "Username must be greater than 3 characters." } if error != "" { utils.RenderTemplate(w, r, "register.html", map[string]interface{}{ "error": error, }, nil) return } // We're good, let's make it user := models.NewUser(username, password) err = db.Insert(user) if err != nil { fmt.Printf("[error] Could not insert user (%s)\n", err.Error()) return; } // Adminify the first user id, err := db.SelectInt("SELECT lastval()") if err == nil && id == 1 { user.GroupId = 2 count, err = db.Update(user) if err != nil { fmt.Printf("[error] Could not adminify user (%s)\n", err.Error()) return; } } http.Redirect(w, r, "/login", http.StatusFound) return } utils.RenderTemplate(w, r, "register.html", nil, nil) }
func Thread(w http.ResponseWriter, r *http.Request) { page_id_str := r.FormValue("page") page_id, err := strconv.Atoi(page_id_str) if err != nil { page_id = 0 } board_id_str := mux.Vars(r)["board_id"] board_id, _ := strconv.Atoi(board_id_str) board, err := models.GetBoard(board_id) post_id_str := mux.Vars(r)["post_id"] post_id, _ := strconv.Atoi(post_id_str) err, op, posts := models.GetThread(post_id, page_id) var posting_error error current_user := utils.GetCurrentUser(r) if r.Method == "POST" { db := models.GetDbSession() title := r.FormValue("title") content := r.FormValue("content") if current_user == nil { http.NotFound(w, r) return } if op.Locked && !current_user.CanModerate() { http.NotFound(w, r) return } post := models.NewPost(current_user, board, title, content) post.ParentId = sql.NullInt64{int64(post_id), true} op.LatestReply = time.Now() posting_error = post.Validate() if posting_error == nil { db.Insert(post) db.Update(op) if page := post.GetPageInThread(); page != page_id { http.Redirect(w, r, fmt.Sprintf("/board/%d/%d?page=%d#post_%d", post.BoardId, op.Id, page, post.Id), http.StatusFound) } err, op, posts = models.GetThread(post_id, page_id) } } if err != nil { http.NotFound(w, r) fmt.Printf("[error] Something went wrong in posts (%s)\n", err.Error()) return } num_pages := op.GetPagesInThread() if page_id > num_pages { http.NotFound(w, r) return } var previous_text string if posting_error != nil { previous_text = r.FormValue("content") } // Mark the thread as read if current_user != nil { models.AddView(current_user, op) } utils.RenderTemplate(w, r, "thread.html", map[string]interface{}{ "board": board, "op": op, "posts": posts, "first_page": (page_id > 0), "prev_page": (page_id > 1), "next_page": (page_id < num_pages-1), "last_page": (page_id < num_pages), "page_id": page_id, "posting_error": posting_error, "previous_text": previous_text, }, map[string]interface{}{ "CurrentUserCanModerateThread": func(thread *models.Post) bool { current_user := utils.GetCurrentUser(r) if current_user == nil { return false } return (current_user.CanModerate() && thread.ParentId.Valid == false) }, "CurrentUserCanDeletePost": func(thread *models.Post) bool { current_user := utils.GetCurrentUser(r) if current_user == nil { return false } return (current_user.Id == thread.AuthorId) || current_user.CanModerate() }, "CurrentUserCanEditPost": func(post *models.Post) bool { current_user := utils.GetCurrentUser(r) if current_user == nil { return false } return (current_user.Id == post.AuthorId || current_user.CanModerate()) }, "CurrentUserCanModerate": func() bool { current_user := utils.GetCurrentUser(r) if current_user == nil { return false } return current_user.CanModerate() }, "SignaturesEnabled": func() bool { enable_signatures, _ := config.Config.GetBool("gobb", "enable_signatures") return enable_signatures }, "ShowReplyBox": func(post *models.Post) bool { current_user := utils.GetCurrentUser(r) if current_user != nil && (!post.Locked || current_user.CanModerate()) { return true } return false }, }) }