diff --git a/data.sql b/data.sql index 662e01f2..e4e17b44 100644 --- a/data.sql +++ b/data.sql @@ -4,14 +4,14 @@ CREATE TABLE `users`( `uid` int not null AUTO_INCREMENT, `name` varchar(100) not null, `password` varchar(100) not null, - `salt` varchar(80) DEFAULT '', + `salt` varchar(80) DEFAULT '' not null, `group` int not null, `is_super_admin` tinyint(1) not null, `createdAt` datetime not null, `lastActiveAt` datetime not null, - `session` varchar(200) DEFAULT '', - `email` varchar(200) DEFAULT '', - `avatar` varchar(20) DEFAULT '', + `session` varchar(200) DEFAULT '' not null, + `email` varchar(200) DEFAULT '' not null, + `avatar` varchar(20) DEFAULT '' not null, primary key(`uid`) ); @@ -19,6 +19,7 @@ CREATE TABLE `users_groups`( `gid` int not null AUTO_INCREMENT, `name` varchar(100) not null, `permissions` text not null, + `is_mod` tinyint DEFAULT 0 not null, `is_admin` tinyint DEFAULT 0 not null, `is_banned` tinyint DEFAULT 0 not null, `tag` varchar(50) DEFAULT '' not null, @@ -85,8 +86,9 @@ CREATE TABLE `users_replies`( INSERT INTO users(`name`,`group`,`is_super_admin`,`createdAt`,`lastActiveAt`) VALUES ('Admin',1,1,NOW(),NOW()); -INSERT INTO users_groups(`name`,`permissions`,`is_admin`,`tag`) VALUES ('Admin','{}',1,"Admin"); +INSERT INTO users_groups(`name`,`permissions`,`is_mod`,`is_admin`,`tag`) VALUES ('Administrator','{}',1,1,"Admin"); INSERT INTO users_groups(`name`,`permissions`) VALUES ('Member','{}'); +INSERT INTO users_groups(`name`,`permissions`,`is_mod`,`tag`) VALUES ('Moderator','{}',1,"Mod"); INSERT INTO forums(`name`,`lastTopicTime`) VALUES ('General',NOW()); INSERT INTO topics(`title`,`content`,`createdAt`,`lastReplyAt`,`createdBy`,`parentID`) VALUES ('Test Topic','A topic automatically generated by the software.',NOW(),NOW(),1,1); diff --git a/grosolo.exe b/grosolo.exe index 3739202c..e20f1d6c 100644 Binary files a/grosolo.exe and b/grosolo.exe differ diff --git a/grosolo.exe~ b/grosolo.exe~ index 884a6c47..2254edd8 100644 Binary files a/grosolo.exe~ and b/grosolo.exe~ differ diff --git a/group.go b/group.go index 63ff708c..97ab14ed 100644 --- a/group.go +++ b/group.go @@ -5,6 +5,7 @@ type Group struct ID int Name string Permissions string + Is_Mod bool Is_Admin bool Is_Banned bool Tag string diff --git a/main.go b/main.go index 7a7b726b..8ed78fc1 100644 --- a/main.go +++ b/main.go @@ -225,15 +225,15 @@ func init_database(err error) { } log.Print("Loading the usergroups.") - rows, err := db.Query("SELECT gid,name,permissions,is_admin,is_banned,tag FROM users_groups") + rows, err := db.Query("SELECT gid,name,permissions,is_mod,is_admin,is_banned,tag FROM users_groups") if err != nil { log.Fatal(err) } defer rows.Close() for rows.Next() { - group := Group{0,"","",false,false,""} - err := rows.Scan(&group.ID, &group.Name, &group.Permissions, &group.Is_Admin, &group.Is_Banned, &group.Tag) + group := Group{0,"","",false,false,false,""} + err := rows.Scan(&group.ID, &group.Name, &group.Permissions, &group.Is_Mod, &group.Is_Admin, &group.Is_Banned, &group.Tag) if err != nil { log.Fatal(err) } diff --git a/mod_routes.go b/mod_routes.go index 5a7c3753..74fbd876 100644 --- a/mod_routes.go +++ b/mod_routes.go @@ -20,7 +20,7 @@ func route_edit_topic(w http.ResponseWriter, r *http.Request) { is_js = "0" } - if !user.Is_Admin { + if !user.Is_Mod && !user.Is_Admin { NoPermissionsJSQ(w,r,user,is_js) return } @@ -62,7 +62,7 @@ func route_edit_topic(w http.ResponseWriter, r *http.Request) { func route_delete_topic(w http.ResponseWriter, r *http.Request) { user := SessionCheck(w,r) - if !user.Is_Admin { + if !user.Is_Mod && !user.Is_Admin { NoPermissions(w,r,user) return } @@ -94,7 +94,7 @@ func route_delete_topic(w http.ResponseWriter, r *http.Request) { func route_stick_topic(w http.ResponseWriter, r *http.Request) { user := SessionCheck(w,r) - if !user.Is_Admin { + if !user.Is_Mod && !user.Is_Admin { NoPermissions(w,r,user) return } @@ -116,7 +116,7 @@ func route_stick_topic(w http.ResponseWriter, r *http.Request) { func route_unstick_topic(w http.ResponseWriter, r *http.Request) { user := SessionCheck(w,r) - if !user.Is_Admin { + if !user.Is_Mod && !user.Is_Admin { NoPermissions(w,r,user) return } @@ -149,7 +149,7 @@ func route_reply_edit_submit(w http.ResponseWriter, r *http.Request) { is_js = "0" } - if !user.Is_Admin { + if !user.Is_Mod && !user.Is_Admin { NoPermissionsJSQ(w,r,user,is_js) return } @@ -195,7 +195,7 @@ func route_reply_delete_submit(w http.ResponseWriter, r *http.Request) { is_js = "0" } - if !user.Is_Admin { + if !user.Is_Mod && !user.Is_Admin { NoPermissionsJSQ(w,r,user,is_js) return } @@ -243,27 +243,27 @@ func route_profile_reply_edit_submit(w http.ResponseWriter, r *http.Request) { is_js = "0" } - if !user.Is_Admin { - NoPermissionsJSQ(w,r,user,is_js) - return - } - rid, err := strconv.Atoi(r.URL.Path[len("/profile/reply/edit/submit/"):]) if err != nil { LocalError("The provided Reply ID is not a valid number.",w,r,user) return } - content := html.EscapeString(r.PostFormValue("edit_item")) - _, err = edit_profile_reply_stmt.Exec(content, parse_message(content), rid) + // Get the Reply ID.. + var uid int + err = db.QueryRow("select uid from users_replies where rid = ?", rid).Scan(&uid) if err != nil { InternalError(err,w,r,user) return } - // Get the Reply ID.. - var uid int - err = db.QueryRow("select tid from users_replies where rid = ?", rid).Scan(&uid) + if user.ID != uid && !user.Is_Mod && !user.Is_Admin { + NoPermissionsJSQ(w,r,user,is_js) + return + } + + content := html.EscapeString(r.PostFormValue("edit_item")) + _, err = edit_profile_reply_stmt.Exec(content, parse_message(content), rid) if err != nil { InternalError(err,w,r,user) return @@ -289,11 +289,6 @@ func route_profile_reply_delete_submit(w http.ResponseWriter, r *http.Request) { is_js = "0" } - if !user.Is_Admin { - NoPermissionsJSQ(w,r,user,is_js) - return - } - rid, err := strconv.Atoi(r.URL.Path[len("/profile/reply/delete/submit/"):]) if err != nil { LocalErrorJSQ("The provided Reply ID is not a valid number.",w,r,user,is_js) @@ -310,6 +305,11 @@ func route_profile_reply_delete_submit(w http.ResponseWriter, r *http.Request) { return } + if user.ID != uid && !user.Is_Mod && !user.Is_Admin { + NoPermissionsJSQ(w,r,user,is_js) + return + } + _, err = delete_profile_reply_stmt.Exec(rid) if err != nil { InternalErrorJSQ(err,w,r,user,is_js) diff --git a/routes.go b/routes.go index 3dc3a001..bc6af420 100644 --- a/routes.go +++ b/routes.go @@ -119,7 +119,15 @@ func route_topics(w http.ResponseWriter, r *http.Request){ InternalError(err,w,r,user) return } - pi := Page{"Topic List","topics",user,topicList,0} + + var msg string + if len(topicList) == 0 { + msg = "There aren't any topics yet." + } else { + msg = "" + } + + pi := Page{"Topic List","topics",user,topicList,msg} err = templates.ExecuteTemplate(w,"topics.html", pi) if err != nil { InternalError(err, w, r, user) @@ -194,7 +202,15 @@ func route_forum(w http.ResponseWriter, r *http.Request){ InternalError(err,w,r,user) return } - pi := Page{forums[fid].Name,"forum",user,topicList,0} + + var msg string + if len(topicList) == 0 { + msg = "There aren't any topics in this forum yet." + } else { + msg = "" + } + + pi := Page{forums[fid].Name,"forum",user,topicList,msg} err = templates.ExecuteTemplate(w,"forum.html", pi) if err != nil { InternalError(err, w, r, user) @@ -283,7 +299,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){ } else { topic.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(topic.CreatedBy),1) } - if is_super_admin || groups[group].Is_Admin { + if is_super_admin || groups[group].Is_Mod || groups[group].Is_Admin { topic.Css = staff_css_tmpl } if groups[group].Tag != "" { @@ -309,7 +325,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){ } replyLines = strings.Count(replyContent,"\n") - if is_super_admin || groups[group].Is_Admin { + if is_super_admin || groups[group].Is_Mod || groups[group].Is_Admin { replyCss = staff_css_tmpl } else { replyCss = no_css_tmpl @@ -367,24 +383,32 @@ func route_profile(w http.ResponseWriter, r *http.Request){ replyList = make(map[int]interface{}) currentID = 0 - puser := User{0,"",0,false,false,false,"",false,""} + puser := User{0,"",0,false,false,false,false,false,"",false,""} puser.ID, err = strconv.Atoi(r.URL.Path[len("/user/"):]) if err != nil { LocalError("The provided TopicID is not a valid number.",w,r,user) return } - // Fetch the user data - err = db.QueryRow("SELECT `name`, `group`, `is_super_admin`, `avatar` FROM `users` WHERE `uid` = ?", puser.ID).Scan(&puser.Name, &puser.Group, &puser.Is_Super_Admin, &puser.Avatar) - if err == sql.ErrNoRows { - NotFound(w,r,user) - return - } else if err != nil { - InternalError(err,w,r,user) - return + if puser.ID == user.ID { + user.Is_Mod = true + puser = user + } else { + // Fetch the user data + err = db.QueryRow("SELECT `name`, `group`, `is_super_admin`, `avatar` FROM `users` WHERE `uid` = ?", puser.ID).Scan(&puser.Name, &puser.Group, &puser.Is_Super_Admin, &puser.Avatar) + if err == sql.ErrNoRows { + NotFound(w,r,user) + return + } else if err != nil { + InternalError(err,w,r,user) + return + } + + puser.Is_Admin = puser.Is_Super_Admin || groups[puser.Group].Is_Admin + puser.Is_Super_Mod = puser.Is_Admin || groups[puser.Group].Is_Mod + puser.Is_Mod = puser.Is_Super_Mod } - puser.Is_Admin = puser.Is_Super_Admin if puser.Avatar != "" { if puser.Avatar[0] == '.' { puser.Avatar = "/uploads/avatar_" + strconv.Itoa(puser.ID) + puser.Avatar @@ -409,7 +433,7 @@ func route_profile(w http.ResponseWriter, r *http.Request){ } replyLines = strings.Count(replyContent,"\n") - if is_super_admin || groups[group].Is_Admin { + if is_super_admin || groups[group].Is_Mod || groups[group].Is_Admin { replyCss = staff_css_tmpl } else { replyCss = no_css_tmpl diff --git a/templates/forum.html b/templates/forum.html index 8365abad..23fd6be9 100644 --- a/templates/forum.html +++ b/templates/forum.html @@ -7,4 +7,9 @@ {{.Title}} {{if .Is_Closed}}closed{{else}}open{{end}} {{end}} +{{if .Something}} +