diff --git a/data.sql b/data.sql index 6bed1d25..c54754e9 100644 --- a/data.sql +++ b/data.sql @@ -189,6 +189,11 @@ EditUserPassword EditUserGroup EditUserGroupSuperMod EditUserGroupAdmin +EditGroup +EditGroupLocalPerms +EditGroupGlobalPerms +EditGroupSuperMod +EditGroupAdmin ManageForums EditSettings ManageThemes @@ -207,8 +212,8 @@ PinTopic CloseTopic */ -INSERT INTO users_groups(`name`,`permissions`,`is_mod`,`is_admin`,`tag`) VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewIPs":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true}',1,1,"Admin"); -INSERT INTO users_groups(`name`,`permissions`,`is_mod`,`tag`) VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserPassword":false,"EditUserGroup":true,"EditUserGroupSuperMod":false,"EditUserGroupAdmin":false,"ManageForums":false,"EditSettings":false,"ManageThemes":false,"ManagePlugins":false,"ViewIPs":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true}',1,"Mod"); +INSERT INTO users_groups(`name`,`permissions`,`is_mod`,`is_admin`,`tag`) VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"EditUser":true,"EditUserEmail":true,"EditUserPassword":true,"EditUserGroup":true,"EditUserGroupSuperMod":true,"EditUserGroupAdmin":false,"EditGroup":true,"EditGroupLocalPerms":true,"EditGroupGlobalPerms":true,"EditGroupSuperMod":true,"EditGroupAdmin":false,"ManageForums":true,"EditSettings":true,"ManageThemes":true,"ManagePlugins":true,"ViewIPs":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true}',1,1,"Admin"); +INSERT INTO users_groups(`name`,`permissions`,`is_mod`,`tag`) VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"EditUser":true,"EditUserEmail":false,"EditUserGroup":true,"ViewIPs":true,"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true}',1,"Mod"); INSERT INTO users_groups(`name`,`permissions`) VALUES ('Member','{"ViewTopic":true,"LikeItem":true,"CreateTopic":true,"CreateReply":true}'); INSERT INTO users_groups(`name`,`permissions`,`is_banned`) VALUES ('Banned','{"ViewTopic":true}',1); INSERT INTO users_groups(`name`,`permissions`) VALUES ('Awaiting Activation','{"ViewTopic":true}'); diff --git a/group.go b/group.go index a0782461..9fdf0ca8 100644 --- a/group.go +++ b/group.go @@ -1,5 +1,19 @@ package main +import "sync" + +var group_update_mutex sync.Mutex + +type GroupAdmin struct +{ + ID int + Name string + Rank string + RankEmoji string + CanEdit bool + CanDelete bool +} + type Group struct { ID int @@ -13,3 +27,10 @@ type Group struct Forums []ForumPerms CanSee []int // The IDs of the forums this group can see } + +func group_exists(gid int) bool { + //fmt.Println(gid <= groupCapCount) + //fmt.Println(gid > 0) + //fmt.Println(groups[gid].Name!="") + return (gid <= groupCapCount) && (gid > 0) && groups[gid].Name!="" +} diff --git a/images/group_editor_wip.png b/images/group_editor_wip.png new file mode 100644 index 00000000..b0d4c781 Binary files /dev/null and b/images/group_editor_wip.png differ diff --git a/images/group_list_wip.png b/images/group_list_wip.png new file mode 100644 index 00000000..18651a73 Binary files /dev/null and b/images/group_list_wip.png differ diff --git a/main.go b/main.go index 8bfb6cae..7e518e1e 100644 --- a/main.go +++ b/main.go @@ -228,7 +228,7 @@ func main(){ router.HandleFunc("/user/edit/username/", route_account_own_edit_username) router.HandleFunc("/user/edit/username/submit/", route_account_own_edit_username_submit) router.HandleFunc("/user/edit/email/", route_account_own_edit_email) - router.HandleFunc("/user/edit/email/token/", route_account_own_edit_email_token_submit) + router.HandleFunc("/user/edit/token/", route_account_own_edit_email_token_submit) router.HandleFunc("/user/", route_profile) router.HandleFunc("/profile/reply/create/", route_profile_reply_create) router.HandleFunc("/profile/reply/edit/submit/", route_profile_reply_edit_submit) @@ -259,6 +259,8 @@ func main(){ router.HandleFunc("/panel/users/edit/", route_panel_users_edit) router.HandleFunc("/panel/users/edit/submit/", route_panel_users_edit_submit) router.HandleFunc("/panel/groups/", route_panel_groups) + router.HandleFunc("/panel/groups/edit/", route_panel_groups_edit) + router.HandleFunc("/panel/groups/edit/submit/", route_panel_groups_edit_submit) router.HandleFunc("/api/", route_api) //router.HandleFunc("/exit/", route_exit) diff --git a/mod_routes.go b/mod_routes.go index eb0c6104..c07036e7 100644 --- a/mod_routes.go +++ b/mod_routes.go @@ -1393,13 +1393,231 @@ func route_panel_groups(w http.ResponseWriter, r *http.Request){ var groupList []interface{} for _, group := range groups[1:] { - groupList = append(groupList, group) + var rank string + var rank_emoji string + var can_edit bool + var can_delete bool = false + + if group.Is_Admin { + rank = "Admin" + rank_emoji = "👑" + } else if group.Is_Mod { + rank = "Mod" + rank_emoji = "👮" + } else if group.Is_Banned { + rank = "Banned" + rank_emoji = "⛓️" + } else if group.ID == 6 { + rank = "Guest" + rank_emoji = "👽" + } else { + rank = "Member" + rank_emoji = "👪" + } + + if user.Perms.EditGroup && (!group.Is_Admin || user.Perms.EditGroupAdmin) && (!group.Is_Mod || user.Perms.EditGroupSuperMod) { + can_edit = true + } else { + can_edit = false + } + + groupList = append(groupList, GroupAdmin{group.ID,group.Name,rank,rank_emoji,can_edit,can_delete}) } + //fmt.Printf("%+v\n", groupList) pi := Page{"Group Manager",user,noticeList,groupList,nil} templates.ExecuteTemplate(w,"panel-groups.html",pi) } +func route_panel_groups_edit(w http.ResponseWriter, r *http.Request){ + user, noticeList, ok := SessionCheck(w,r) + if !ok { + return + } + if !user.Is_Super_Mod || !user.Perms.EditGroup { + NoPermissions(w,r,user) + return + } + + gid, err := strconv.Atoi(r.URL.Path[len("/panel/groups/edit/"):]) + if err != nil { + LocalError("The Group ID is not a valid integer.",w,r,user) + return + } + + if !group_exists(gid) { + //fmt.Println("aaaaa monsters") + NotFound(w,r) + return + } + + group := groups[gid] + if group.Is_Admin && !user.Perms.EditGroupAdmin { + LocalError("You need the EditGroupAdmin permission to edit an admin group.",w,r,user) + return + } + if group.Is_Mod && !user.Perms.EditGroupSuperMod { + LocalError("You need the EditGroupSuperMod permission to edit an super-mod group.",w,r,user) + return + } + + var rank string + if group.Is_Admin { + rank = "Admin" + } else if group.Is_Mod { + rank = "Mod" + } else if group.Is_Banned { + rank = "Banned" + } else if group.ID == 6 { + rank = "Guest" + } else { + rank = "Member" + } + + var disable_rank bool + if !user.Perms.EditGroupGlobalPerms || (group.ID == 6) { + disable_rank = true + } + + pi := EditGroupPage{"Group Editor",user,noticeList,group.ID,group.Name,group.Tag,rank,disable_rank,nil} + err = templates.ExecuteTemplate(w,"panel-group-edit.html",pi) + if err != nil { + InternalError(err,w,r) + } +} + +func route_panel_groups_edit_submit(w http.ResponseWriter, r *http.Request){ + user, ok := SimpleSessionCheck(w,r) + if !ok { + return + } + if !user.Is_Super_Mod || !user.Perms.EditGroup { + NoPermissions(w,r,user) + return + } + if r.FormValue("session") != user.Session { + SecurityError(w,r,user) + return + } + + gid, err := strconv.Atoi(r.URL.Path[len("/panel/groups/edit/submit/"):]) + if err != nil { + LocalError("The Group ID is not a valid integer.",w,r,user) + return + } + + if !group_exists(gid) { + //fmt.Println("aaaaa monsters") + NotFound(w,r) + return + } + + group := groups[gid] + if group.Is_Admin && !user.Perms.EditGroupAdmin { + LocalError("You need the EditGroupAdmin permission to edit an admin group.",w,r,user) + return + } + if group.Is_Mod && !user.Perms.EditGroupSuperMod { + LocalError("You need the EditGroupSuperMod permission to edit an super-mod group.",w,r,user) + return + } + + gname := r.FormValue("group-name") + if gname == "" { + LocalError("The group name can't be left blank.",w,r,user) + return + } + gtag := r.FormValue("group-tag") + rank := r.FormValue("group-type") + + var original_rank string + if group.Is_Admin { + original_rank = "Admin" + } else if group.Is_Mod { + original_rank = "Mod" + } else if group.Is_Banned { + original_rank = "Banned" + } else if group.ID == 6 { + original_rank = "Guest" + } else { + original_rank = "Member" + } + + group_update_mutex.Lock() + defer group_update_mutex.Unlock() + if rank != original_rank { + if !user.Perms.EditGroupGlobalPerms { + LocalError("You need the EditGroupGlobalPerms permission to change the group type.",w,r,user) + return + } + + switch(rank) { + case "Admin": + if !user.Perms.EditGroupAdmin { + LocalError("You need the EditGroupAdmin permission to designate this group as an admin group.",w,r,user) + return + } + + _, err = update_group_rank_stmt.Exec(1,1,0,gid) + if err != nil { + InternalError(err,w,r) + return + } + groups[gid].Is_Admin = true + groups[gid].Is_Mod = true + groups[gid].Is_Banned = false + case "Mod": + if !user.Perms.EditGroupSuperMod { + LocalError("You need the EditGroupSuperMod permission to designate this group as an admin group.",w,r,user) + return + } + + _, err = update_group_rank_stmt.Exec(0,1,0,gid) + if err != nil { + InternalError(err,w,r) + return + } + groups[gid].Is_Admin = false + groups[gid].Is_Mod = true + groups[gid].Is_Banned = false + case "Banned": + _, err = update_group_rank_stmt.Exec(0,0,1,gid) + if err != nil { + InternalError(err,w,r) + return + } + groups[gid].Is_Admin = false + groups[gid].Is_Mod = false + groups[gid].Is_Banned = true + case "Guest": + LocalError("You can't designate a group as a guest group.",w,r,user) + return + case "Member": + _, err = update_group_rank_stmt.Exec(0,0,0,gid) + if err != nil { + InternalError(err,w,r) + return + } + groups[gid].Is_Admin = false + groups[gid].Is_Mod = false + groups[gid].Is_Banned = false + default: + LocalError("Invalid group type.",w,r,user) + return + } + } + + _, err = update_group_stmt.Exec(gname,gtag,gid) + if err != nil { + InternalError(err,w,r) + return + } + groups[gid].Name = gname + groups[gid].Tag = gtag + + http.Redirect(w,r,"/panel/groups/edit/" + strconv.Itoa(gid),http.StatusSeeOther) +} + func route_panel_themes(w http.ResponseWriter, r *http.Request){ user, noticeList, ok := SessionCheck(w,r) if !ok { diff --git a/mysql.go b/mysql.go index c04f31ec..4cf87e34 100644 --- a/mysql.go +++ b/mysql.go @@ -83,6 +83,8 @@ var update_setting_stmt *sql.Stmt var add_plugin_stmt *sql.Stmt var update_plugin_stmt *sql.Stmt var update_user_stmt *sql.Stmt +var update_group_rank_stmt *sql.Stmt +var update_group_stmt *sql.Stmt var add_theme_stmt *sql.Stmt var update_theme_stmt *sql.Stmt @@ -552,6 +554,18 @@ func init_database(err error) { log.Fatal(err) } + log.Print("Preparing update_group_rank statement.") + update_group_rank_stmt, err = db.Prepare("update `users_groups` set `is_admin` = ?, `is_mod` = ?, `is_banned` = ? where `gid` = ?") + if err != nil { + log.Fatal(err) + } + + log.Print("Preparing update_group statement.") + update_group_stmt, err = db.Prepare("update `users_groups` set `name` = ?, `tag` = ? where `gid` = ?") + if err != nil { + log.Fatal(err) + } + log.Print("Loading the usergroups.") groups = append(groups, Group{ID:0,Name:"System"}) @@ -591,6 +605,7 @@ func init_database(err error) { if err != nil { log.Fatal(err) } + groupCapCount = i log.Print("Binding the Not Loggedin Group") GuestPerms = groups[6].Perms diff --git a/pages.go b/pages.go index c5b0227f..5b380658 100644 --- a/pages.go +++ b/pages.go @@ -86,6 +86,19 @@ type ThemesPage struct ExtData interface{} } +type EditGroupPage struct +{ + Title string + CurrentUser User + NoticeList []string + ID int + Name string + Tag string + Rank string + DisableRank bool + ExtData interface{} +} + type PageSimple struct { Title string diff --git a/permissions.go b/permissions.go index eb17e3ef..e5513e8b 100644 --- a/permissions.go +++ b/permissions.go @@ -26,6 +26,11 @@ type Perms struct EditUserGroup bool EditUserGroupSuperMod bool EditUserGroupAdmin bool + EditGroup bool + EditGroupLocalPerms bool + EditGroupGlobalPerms bool + EditGroupSuperMod bool + EditGroupAdmin bool ManageForums bool // This could be local, albeit limited for per-forum managers EditSettings bool ManageThemes bool @@ -94,6 +99,11 @@ func init() { EditUserGroup: true, EditUserGroupSuperMod: true, EditUserGroupAdmin: true, + EditGroup: true, + EditGroupLocalPerms: true, + EditGroupGlobalPerms: true, + EditGroupSuperMod: true, + EditGroupAdmin: true, ManageForums: true, EditSettings: true, ManageThemes: true, diff --git a/routes.go b/routes.go index 7bc9e5e7..490f23fc 100644 --- a/routes.go +++ b/routes.go @@ -1403,21 +1403,23 @@ func route_account_own_edit_email_token_submit(w http.ResponseWriter, r *http.Re LocalError("You need to login to edit your account.",w,r,user) return } - token := r.URL.Path[len("/user/edit/email/token/"):] + token := r.URL.Path[len("/user/edit/token/"):] email := Email{UserID: user.ID} targetEmail := Email{UserID: user.ID} var emailList []interface{} rows, err := db.Query("select email, validated, token from emails where uid = ?", user.ID) if err != nil { - log.Fatal(err) + InternalError(err,w,r) + return } defer rows.Close() for rows.Next() { err := rows.Scan(&email.Email, &email.Validated, &email.Token) if err != nil { - log.Fatal(err) + InternalError(err,w,r) + return } if email.Email == user.Email { @@ -1430,7 +1432,8 @@ func route_account_own_edit_email_token_submit(w http.ResponseWriter, r *http.Re } err = rows.Err() if err != nil { - log.Fatal(err) + InternalError(err,w,r) + return } if len(emailList) == 0 { diff --git a/templates/account-menu.html b/templates/account-menu.html index 0a8e88dc..0595ca9f 100644 --- a/templates/account-menu.html +++ b/templates/account-menu.html @@ -1,10 +1,14 @@ -