Beispiel #1
0
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,
	})
}
Beispiel #2
0
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)
}
Beispiel #3
0
func ActionLockThread(w http.ResponseWriter, r *http.Request) {
	user := utils.GetCurrentUser(r)
	if !user.CanModerate() {
		http.NotFound(w, r)
		return
	}

	thread_id_str := r.FormValue("post_id")
	thread_id, err := strconv.Atoi(thread_id_str)

	if err != nil {
		http.NotFound(w, r)
		return
	}

	db := models.GetDbSession()
	obj, err := db.Get(&models.Post{}, thread_id)
	thread := obj.(*models.Post)

	if thread == nil || err != nil {
		http.NotFound(w, r)
		return
	}

	thread.Locked = !(thread.Locked)
	db.Update(thread)

	http.Redirect(w, r, fmt.Sprintf("/board/%d/%d", thread.BoardId, thread.Id), http.StatusFound)
}
Beispiel #4
0
func GetMigrationInfo() (latest_db_version int64, migrations []*goose.Migration, err error) {
	goose_conf := generateGooseDbConf()
	db := models.GetDbSession()

	latest_db_version, _ = goose.GetMostRecentDBVersion(goose_conf.MigrationsDir)
	current_db_version, _ := goose.EnsureDBVersion(goose_conf, db.Db)
	migrations, _ = goose.CollectMigrations(goose_conf.MigrationsDir, current_db_version, latest_db_version)

	return latest_db_version, migrations, err
}
Beispiel #5
0
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,
	})
}
Beispiel #6
0
func ActionMarkAllRead(w http.ResponseWriter, r *http.Request) {
	user := utils.GetCurrentUser(r)
	if user == nil {
		http.NotFound(w, r)
		return
	}

	db := models.GetDbSession()
	user.LastUnreadAll = pq.NullTime{Time: time.Now(), Valid: true}
	db.Update(user)

	http.Redirect(w, r, "/", http.StatusFound)
}
Beispiel #7
0
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,
	})
}
Beispiel #8
0
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)
}
Beispiel #9
0
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)
		},
	})
}
Beispiel #10
0
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)
}
Beispiel #11
0
func ActionDeleteThread(w http.ResponseWriter, r *http.Request) {
	user := utils.GetCurrentUser(r)
	thread_id_str := r.FormValue("post_id")
	thread_id, err := strconv.Atoi(thread_id_str)

	if err != nil {
		http.NotFound(w, r)
		return
	}

	db := models.GetDbSession()
	obj, err := db.Get(&models.Post{}, thread_id)
	thread := obj.(*models.Post)

	if thread == nil || err != nil {
		http.NotFound(w, r)
		return
	}

	if (thread.AuthorId != user.Id) && !user.CanModerate() {
		http.NotFound(w, r)
		return
	}

	redirect_board := true
	if thread.ParentId.Valid {
		redirect_board = false
	}

	thread.DeleteAllChildren()
	db.Delete(thread)

	if redirect_board {
		http.Redirect(w, r, fmt.Sprintf("/board/%d", thread.BoardId), http.StatusFound)
	} else {
		http.Redirect(w, r, fmt.Sprintf("/board/%d/%d", thread.BoardId, thread.ParentId.Int64), http.StatusFound)
	}

}
Beispiel #12
0
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)
}
Beispiel #13
0
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,
	})
}
Beispiel #14
0
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,
	})
}
Beispiel #15
0
func main() {
	// Get the config file
	var config_path string
	flag.StringVar(&config_path, "config", "gobb.conf", "Specifies the location of a config file")
	run_migrations := flag.Bool("migrate", false, "Runs database migrations")
	ign_migrations := flag.Bool("ignore-migrations", false, "Ignores an out of date database and runs the server anyways")
	serve := flag.Bool("serve", false, "run server")
	useradd := flag.Bool("add-user", false, "add a user")
	var name, password string
	flag.StringVar(&name, "name", "", "username to add")
	flag.StringVar(&password, "password", "", "password new user")
	group := flag.Int64("group", 0, "group of new user (<0 is special group, 0 is default, 1 is mod, 2 is admin)")
	flag.Parse()
	config.GetConfig(config_path)

	// Do we need to run migrations?
	latest_db_version, migrations, err := utils.GetMigrationInfo()
	if len(migrations) != 0 && *run_migrations {
		fmt.Println("[notice] Running database migrations:\n")
		err = utils.RunMigrations(latest_db_version)
		if err != nil {
			fmt.Printf("[error] Could not run migrations (%s)\n", err.Error())
			return
		}

		fmt.Println("\n[notice] Database migration successful!")
	} else if len(migrations) != 0 && !(*ign_migrations) {
		fmt.Println("Your database appears to be out of date. Please run migrations with --migrate or ignore this message with --ignore-migrations")
		return
	}
	db := models.GetDbSession()

	if *useradd {
		user := models.NewUser(name, password)
		user.GroupId = *group
		err = db.Insert(user)

	}

	if !*serve {
		return
	}
	// URL Routing!
	r := mux.NewRouter()
	r.StrictSlash(true)

	r.HandleFunc("/", controllers.Index)
	r.HandleFunc("/register", controllers.Register)
	r.HandleFunc("/login", controllers.Login)
	r.HandleFunc("/logout", controllers.Logout)
	r.HandleFunc("/admin", controllers.Admin)
	r.HandleFunc("/admin/boards", controllers.AdminBoards)
	r.HandleFunc("/admin/users/{id:[0-9]+}", controllers.AdminUser)
	r.HandleFunc("/admin/users", controllers.AdminUsers)
	r.HandleFunc("/action/stick", controllers.ActionStickThread)
	r.HandleFunc("/action/lock", controllers.ActionLockThread)
	r.HandleFunc("/action/delete", controllers.ActionDeleteThread)
	r.HandleFunc("/action/move", controllers.ActionMoveThread)
	r.HandleFunc("/action/mark_read", controllers.ActionMarkAllRead)
	r.HandleFunc("/action/edit", controllers.PostEditor)
	r.HandleFunc("/board/{id:[0-9]+}", controllers.Board)
	r.HandleFunc("/board/{board_id:[0-9]+}/new", controllers.PostEditor)
	r.HandleFunc("/board/{board_id:[0-9]+}/{post_id:[0-9]+}", controllers.Thread)
	r.HandleFunc("/user/{id:[0-9]+}", controllers.User)
	r.HandleFunc("/user/{id:[0-9]+}/settings", controllers.UserSettings)

	// Handle static files
	selected_template, _ := models.GetStringSetting("template")
	base_path, _ := config.Config.GetString("gobb", "base_path")
	if selected_template == "default" {
		pkg, _ := build.Import("github.com/stevenleeg/gobb/gobb", ".", build.FindOnly)
		static_path := filepath.Join(pkg.SrcRoot, pkg.ImportPath, "../templates")
		r.PathPrefix("/static/").Handler(http.FileServer(http.Dir(static_path)))
	} else {
		static_path := filepath.Join(base_path, "templates", selected_template)
		r.PathPrefix("/static/").Handler(http.FileServer(http.Dir(static_path)))
	}

	// User provided static files
	static_path, err := config.Config.GetString("gobb", "base_path")
	if err == nil {
		r.PathPrefix("/assets/").Handler(http.FileServer(http.Dir(static_path)))
	}

	http.Handle("/", r)

	port, err := config.Config.GetString("gobb", "port")
	fmt.Println("[notice] Starting server on port " + port)
	http.ListenAndServe(":"+port, nil)
}
Beispiel #16
0
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)
}
Beispiel #17
0
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)
}
Beispiel #18
0
func PostEditor(w http.ResponseWriter, r *http.Request) {
	db := models.GetDbSession()

	var err error
	var board *models.Board
	var post *models.Post

	// Attempt to get a board
	board_id_str := mux.Vars(r)["board_id"]
	if board_id_str != "" {
		board_id, _ := strconv.Atoi(board_id_str)
		board, err = models.GetBoard(board_id)
	}

	// Otherwise, a post
	post_id_str := r.FormValue("post_id")
	if post_id_str != "" {
		post_id, _ := strconv.Atoi(post_id_str)
		post_tmp, _ := db.Get(&models.Post{}, post_id)
		post = post_tmp.(*models.Post)
	}

	if err != nil {
		fmt.Println("something went wrong")
		http.NotFound(w, r)
		return
	}

	current_user := utils.GetCurrentUser(r)
	if current_user == nil {
		http.NotFound(w, r)
		return
	}
	if post != nil && (post.AuthorId != current_user.Id && !current_user.CanModerate()) {
		http.NotFound(w, r)
		return
	}

	if r.Method == "POST" {
		title := r.FormValue("title")
		content := r.FormValue("content")

		if post == nil {
			post = models.NewPost(current_user, board, title, content)
			post.LatestReply = time.Now()

			err = post.Validate()
			if err != nil {
				renderPostEditor(w, r, board, post, err)
				return
			}

			err = db.Insert(post)
		} else {
			post.Title = title
			post.Content = content
			post.LastEdit = time.Now()
			post.LatestReply = time.Now()

			err = post.Validate()
			if err != nil {
				renderPostEditor(w, r, board, post, err)
				return
			}

			_, err = db.Update(post)
		}

		if err != nil {
			fmt.Printf("[error] Could not save post (%s)", err.Error())
			return
		}

		http.Redirect(w, r, post.GetLink(), http.StatusFound)
		return
	}

	renderPostEditor(w, r, board, post, err)
}
Beispiel #19
0
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)
}
Beispiel #20
0
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)
}
Beispiel #21
0
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
		},
	})
}