Added the User Manager.
Added the activation and deactivation handlers to plugins. Experimenting to see the best way of implementing variadic hooks. Added the ability to deactivate plugins. Added the preparse_preassign and parse_assign parser hooks. Added a simple Markdown plugin. Added the group tag to the profiles. Improved the open / close status on /topics/ Added the ability to report profile comments. Added the report_preassign vhook. This is probably going to be changed.
This commit is contained in:
parent
ec2c02d7c9
commit
086239f88c
3
data.sql
3
data.sql
|
@ -6,6 +6,7 @@ CREATE TABLE `users`(
|
||||||
`password` varchar(100) not null,
|
`password` varchar(100) not null,
|
||||||
`salt` varchar(80) DEFAULT '' not null,
|
`salt` varchar(80) DEFAULT '' not null,
|
||||||
`group` int not null,
|
`group` int not null,
|
||||||
|
`active` tinyint DEFAULT 0 not null,
|
||||||
`is_super_admin` tinyint(1) not null,
|
`is_super_admin` tinyint(1) not null,
|
||||||
`createdAt` datetime not null,
|
`createdAt` datetime not null,
|
||||||
`lastActiveAt` datetime not null,
|
`lastActiveAt` datetime not null,
|
||||||
|
@ -99,7 +100,7 @@ INSERT INTO settings(`name`,`content`,`type`) VALUES ('url_tags','1','bool');
|
||||||
INSERT INTO users(`name`,`group`,`is_super_admin`,`createdAt`,`lastActiveAt`,`message`)
|
INSERT INTO users(`name`,`group`,`is_super_admin`,`createdAt`,`lastActiveAt`,`message`)
|
||||||
VALUES ('Admin',1,1,NOW(),NOW(),'');
|
VALUES ('Admin',1,1,NOW(),NOW(),'');
|
||||||
|
|
||||||
INSERT INTO users_groups(`name`,`permissions`,`is_mod`,`is_admin`,`tag`) VALUES ('Administrator','{}',1,1,"Admin");
|
INSERT INTO users_groups(`name`,`permissions`,`active`,`is_mod`,`is_admin`,`tag`) VALUES ('Administrator','{}',1,1,1,"Admin");
|
||||||
INSERT INTO users_groups(`name`,`permissions`,`is_mod`,`tag`) VALUES ('Moderator','{}',1,"Mod");
|
INSERT INTO users_groups(`name`,`permissions`,`is_mod`,`tag`) VALUES ('Moderator','{}',1,"Mod");
|
||||||
INSERT INTO users_groups(`name`,`permissions`) VALUES ('Member','{}');
|
INSERT INTO users_groups(`name`,`permissions`) VALUES ('Member','{}');
|
||||||
INSERT INTO users_groups(`name`,`permissions`,`is_banned`) VALUES ('Banned','{}',1);
|
INSERT INTO users_groups(`name`,`permissions`,`is_banned`) VALUES ('Banned','{}',1);
|
||||||
|
|
11
extend.go
11
extend.go
|
@ -3,6 +3,7 @@ package main
|
||||||
|
|
||||||
var plugins map[string]Plugin = make(map[string]Plugin)
|
var plugins map[string]Plugin = make(map[string]Plugin)
|
||||||
var hooks map[string]func(interface{})interface{} = make(map[string]func(interface{})interface{})
|
var hooks map[string]func(interface{})interface{} = make(map[string]func(interface{})interface{})
|
||||||
|
var vhooks map[string]func(...interface{})interface{} = make(map[string]func(...interface{})interface{})
|
||||||
|
|
||||||
type Plugin struct
|
type Plugin struct
|
||||||
{
|
{
|
||||||
|
@ -14,12 +15,22 @@ type Plugin struct
|
||||||
Active bool
|
Active bool
|
||||||
Type string
|
Type string
|
||||||
Init func()
|
Init func()
|
||||||
|
Activate func()
|
||||||
|
Deactivate func()
|
||||||
}
|
}
|
||||||
|
|
||||||
func add_hook(name string, handler func(interface{})interface{}) {
|
func add_hook(name string, handler func(interface{})interface{}) {
|
||||||
hooks[name] = handler
|
hooks[name] = handler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func remove_hook(name string) {
|
||||||
|
delete(hooks, name)
|
||||||
|
}
|
||||||
|
|
||||||
func run_hook(name string, data interface{}) interface{} {
|
func run_hook(name string, data interface{}) interface{} {
|
||||||
return hooks[name](data)
|
return hooks[name](data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func run_hook_v(name string, data ...interface{}) {
|
||||||
|
vhooks[name](data...)
|
||||||
|
}
|
BIN
gosora.exe
BIN
gosora.exe
Binary file not shown.
Binary file not shown.
After Width: | Height: | Size: 32 KiB |
Binary file not shown.
After Width: | Height: | Size: 182 KiB |
Binary file not shown.
After Width: | Height: | Size: 37 KiB |
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
3
main.go
3
main.go
|
@ -135,7 +135,8 @@ func main(){
|
||||||
http.HandleFunc("/panel/settings/edit/submit/", route_panel_setting_edit)
|
http.HandleFunc("/panel/settings/edit/submit/", route_panel_setting_edit)
|
||||||
http.HandleFunc("/panel/plugins/", route_panel_plugins)
|
http.HandleFunc("/panel/plugins/", route_panel_plugins)
|
||||||
http.HandleFunc("/panel/plugins/activate/", route_panel_plugins_activate)
|
http.HandleFunc("/panel/plugins/activate/", route_panel_plugins_activate)
|
||||||
//http.HandleFunc("/panel/plugins/deactivate/", route_panel_plugins_deactivate)
|
http.HandleFunc("/panel/plugins/deactivate/", route_panel_plugins_deactivate)
|
||||||
|
http.HandleFunc("/panel/users/", route_panel_users)
|
||||||
|
|
||||||
http.HandleFunc("/", default_route)
|
http.HandleFunc("/", default_route)
|
||||||
|
|
||||||
|
|
111
mod_routes.go
111
mod_routes.go
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import "log"
|
import "log"
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
import "strings"
|
||||||
import "strconv"
|
import "strconv"
|
||||||
import "net/http"
|
import "net/http"
|
||||||
import "html"
|
import "html"
|
||||||
|
@ -723,7 +724,6 @@ func route_panel_plugins_activate(w http.ResponseWriter, r *http.Request){
|
||||||
}
|
}
|
||||||
|
|
||||||
uname := r.URL.Path[len("/panel/plugins/activate/"):]
|
uname := r.URL.Path[len("/panel/plugins/activate/"):]
|
||||||
|
|
||||||
plugin, ok := plugins[uname]
|
plugin, ok := plugins[uname]
|
||||||
if !ok {
|
if !ok {
|
||||||
LocalError("The plugin isn't registered in the system",w,r,user)
|
LocalError("The plugin isn't registered in the system",w,r,user)
|
||||||
|
@ -743,6 +743,11 @@ func route_panel_plugins_activate(w http.ResponseWriter, r *http.Request){
|
||||||
LocalError("The plugin is already active",w,r,user)
|
LocalError("The plugin is already active",w,r,user)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
_, err = update_plugin_stmt.Exec(1, uname)
|
||||||
|
if err != nil {
|
||||||
|
InternalError(err,w,r,user)
|
||||||
|
return
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
_, err := add_plugin_stmt.Exec(uname,1)
|
_, err := add_plugin_stmt.Exec(uname,1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -757,3 +762,107 @@ func route_panel_plugins_activate(w http.ResponseWriter, r *http.Request){
|
||||||
|
|
||||||
http.Redirect(w,r,"/panel/plugins/",http.StatusSeeOther)
|
http.Redirect(w,r,"/panel/plugins/",http.StatusSeeOther)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func route_panel_plugins_deactivate(w http.ResponseWriter, r *http.Request){
|
||||||
|
user := SessionCheck(w,r)
|
||||||
|
if !user.Is_Admin {
|
||||||
|
NoPermissions(w,r,user)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
uname := r.URL.Path[len("/panel/plugins/deactivate/"):]
|
||||||
|
plugin, ok := plugins[uname]
|
||||||
|
if !ok {
|
||||||
|
LocalError("The plugin isn't registered in the system",w,r,user)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var active bool
|
||||||
|
err := db.QueryRow("SELECT active from plugins where uname = ?", uname).Scan(&active)
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
LocalError("The plugin you're trying to deactivate isn't active",w,r,user)
|
||||||
|
return
|
||||||
|
} else if err != nil {
|
||||||
|
InternalError(err,w,r,user)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !active {
|
||||||
|
LocalError("The plugin you're trying to deactivate isn't active",w,r,user)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = update_plugin_stmt.Exec(0, uname)
|
||||||
|
if err != nil {
|
||||||
|
InternalError(err,w,r,user)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin.Active = false
|
||||||
|
plugins[uname] = plugin
|
||||||
|
plugins[uname].Deactivate()
|
||||||
|
|
||||||
|
http.Redirect(w,r,"/panel/plugins/",http.StatusSeeOther)
|
||||||
|
}
|
||||||
|
|
||||||
|
func route_panel_users(w http.ResponseWriter, r *http.Request){
|
||||||
|
user := SessionCheck(w,r)
|
||||||
|
if !user.Is_Admin {
|
||||||
|
NoPermissions(w,r,user)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var userList map[int]interface{} = make(map[int]interface{})
|
||||||
|
currentID := 0
|
||||||
|
|
||||||
|
rows, err := db.Query("SELECT `uid`, `name`, `group`, `active`, `is_super_admin`, `avatar` FROM users")
|
||||||
|
if err != nil {
|
||||||
|
InternalError(err,w,r,user)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
puser := User{0,"",0,false,false,false,false,false,false,"",false,"","","","",""}
|
||||||
|
err := rows.Scan(&puser.ID, &puser.Name, &puser.Group, &puser.Active, &puser.Is_Super_Admin, &puser.Avatar)
|
||||||
|
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_Banned = groups[puser.Group].Is_Banned
|
||||||
|
if puser.Is_Banned && puser.Is_Super_Mod {
|
||||||
|
puser.Is_Banned = false
|
||||||
|
}
|
||||||
|
|
||||||
|
if puser.Avatar != "" {
|
||||||
|
if puser.Avatar[0] == '.' {
|
||||||
|
puser.Avatar = "/uploads/avatar_" + strconv.Itoa(puser.ID) + puser.Avatar
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
puser.Avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(puser.ID),1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if groups[puser.Group].Tag != "" {
|
||||||
|
puser.Tag = groups[puser.Group].Tag
|
||||||
|
} else {
|
||||||
|
puser.Tag = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
userList[currentID] = puser
|
||||||
|
currentID++
|
||||||
|
}
|
||||||
|
err = rows.Err()
|
||||||
|
if err != nil {
|
||||||
|
InternalError(err,w,r,user)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pi := Page{"User Manager","panel-users",user,userList,0}
|
||||||
|
err = templates.ExecuteTemplate(w,"panel-users.html", pi)
|
||||||
|
if err != nil {
|
||||||
|
InternalError(err, w, r, user)
|
||||||
|
}
|
||||||
|
}
|
7
mysql.go
7
mysql.go
|
@ -37,6 +37,7 @@ var delete_forum_stmt *sql.Stmt
|
||||||
var update_forum_stmt *sql.Stmt
|
var update_forum_stmt *sql.Stmt
|
||||||
var update_setting_stmt *sql.Stmt
|
var update_setting_stmt *sql.Stmt
|
||||||
var add_plugin_stmt *sql.Stmt
|
var add_plugin_stmt *sql.Stmt
|
||||||
|
var update_plugin_stmt *sql.Stmt
|
||||||
|
|
||||||
func init_database(err error) {
|
func init_database(err error) {
|
||||||
if(dbpassword != ""){
|
if(dbpassword != ""){
|
||||||
|
@ -230,6 +231,12 @@ func init_database(err error) {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Print("Preparing update_plugin statement.")
|
||||||
|
update_plugin_stmt, err = db.Prepare("UPDATE plugins SET active = ? WHERE uname = ?")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
log.Print("Loading the usergroups.")
|
log.Print("Loading the usergroups.")
|
||||||
rows, err := db.Query("SELECT gid,name,permissions,is_mod,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 {
|
if err != nil {
|
||||||
|
|
14
pages.go
14
pages.go
|
@ -63,10 +63,15 @@ func shortcode_to_unicode(msg string) string {
|
||||||
msg = strings.Replace(msg,":sleeping:","😴",-1)
|
msg = strings.Replace(msg,":sleeping:","😴",-1)
|
||||||
msg = strings.Replace(msg,":relieved:","😌",-1)
|
msg = strings.Replace(msg,":relieved:","😌",-1)
|
||||||
msg = strings.Replace(msg,":nerd:","🤓",-1)
|
msg = strings.Replace(msg,":nerd:","🤓",-1)
|
||||||
return strings.Replace(msg,":stuck_out_tongue:","😛",-1)
|
msg = strings.Replace(msg,":stuck_out_tongue:","😛",-1)
|
||||||
|
return msg
|
||||||
}
|
}
|
||||||
|
|
||||||
func preparse_message(msg string) string {
|
func preparse_message(msg string) string {
|
||||||
|
if hooks["preparse_preassign"] != nil {
|
||||||
|
out := run_hook("preparse_preassign", msg)
|
||||||
|
msg = out.(string)
|
||||||
|
}
|
||||||
return shortcode_to_unicode(msg)
|
return shortcode_to_unicode(msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,5 +79,10 @@ func parse_message(msg string) string {
|
||||||
msg = strings.Replace(msg,":)","😀",-1)
|
msg = strings.Replace(msg,":)","😀",-1)
|
||||||
msg = strings.Replace(msg,":D","😃",-1)
|
msg = strings.Replace(msg,":D","😃",-1)
|
||||||
msg = strings.Replace(msg,":P","😛",-1)
|
msg = strings.Replace(msg,":P","😛",-1)
|
||||||
return strings.Replace(msg,"\n","<br>",-1)
|
msg = strings.Replace(msg,"\n","<br>",-1)
|
||||||
|
if hooks["parse_assign"] != nil {
|
||||||
|
out := run_hook("parse_assign", msg)
|
||||||
|
msg = out.(string)
|
||||||
|
}
|
||||||
|
return msg
|
||||||
}
|
}
|
|
@ -2,7 +2,7 @@ package main
|
||||||
import "html/template"
|
import "html/template"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
plugins["helloworld"] = Plugin{"helloworld","Hello World","Azareal","http://github.com/Azareal","",false,"",init_helloworld}
|
plugins["helloworld"] = Plugin{"helloworld","Hello World","Azareal","http://github.com/Azareal","",false,"",init_helloworld,nil,deactivate_helloworld}
|
||||||
}
|
}
|
||||||
|
|
||||||
// init_helloworld is separate from init() as we don't want the plugin to run if the plugin is disabled
|
// init_helloworld is separate from init() as we don't want the plugin to run if the plugin is disabled
|
||||||
|
@ -10,10 +10,14 @@ func init_helloworld() {
|
||||||
add_hook("rrow_assign", helloworld_reply)
|
add_hook("rrow_assign", helloworld_reply)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func deactivate_helloworld() {
|
||||||
|
remove_hook("rrow_assign")
|
||||||
|
}
|
||||||
|
|
||||||
func helloworld_reply(data interface{}) interface{} {
|
func helloworld_reply(data interface{}) interface{} {
|
||||||
reply := data.(Reply)
|
reply := data.(Reply)
|
||||||
reply.Content = "Hello World!"
|
reply.Content = "Hello World!"
|
||||||
reply.ContentHtml = template.HTML("Hello World!")
|
reply.ContentHtml = template.HTML("Hello World!")
|
||||||
reply.Tag = "Automated"
|
reply.Tag = "Auto"
|
||||||
return reply
|
return reply
|
||||||
}
|
}
|
|
@ -0,0 +1,30 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import "regexp"
|
||||||
|
|
||||||
|
var bold_italic *regexp.Regexp
|
||||||
|
var bold *regexp.Regexp
|
||||||
|
var italic *regexp.Regexp
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
plugins["markdown"] = Plugin{"markdown","Markdown","Azareal","http://github.com/Azareal","",false,"",init_markdown,nil,deactivate_markdown}
|
||||||
|
}
|
||||||
|
|
||||||
|
func init_markdown() {
|
||||||
|
add_hook("parse_assign", markdown_parse)
|
||||||
|
bold_italic = regexp.MustCompile(`\*\*\*(.*)\*\*\*`)
|
||||||
|
bold = regexp.MustCompile(`\*\*(.*)\*\*`)
|
||||||
|
italic = regexp.MustCompile(`\*(.*)\*`)
|
||||||
|
}
|
||||||
|
|
||||||
|
func deactivate_markdown() {
|
||||||
|
remove_hook("parse_assign")
|
||||||
|
}
|
||||||
|
|
||||||
|
func markdown_parse(data interface{}) interface{} {
|
||||||
|
msg := data.(string)
|
||||||
|
msg = bold_italic.ReplaceAllString(msg,"<i><b>$1</b></i>")
|
||||||
|
msg = bold.ReplaceAllString(msg,"<b>$1</b>")
|
||||||
|
msg = italic.ReplaceAllString(msg,"<i>$1</i>")
|
||||||
|
return msg
|
||||||
|
}
|
|
@ -3,15 +3,28 @@ package main
|
||||||
func init() {
|
func init() {
|
||||||
/*
|
/*
|
||||||
The UName field should match the name in the URL minus plugin_ and the file extension. The same name as the map index. Please choose a unique name which won't clash with any other plugins.
|
The UName field should match the name in the URL minus plugin_ and the file extension. The same name as the map index. Please choose a unique name which won't clash with any other plugins.
|
||||||
|
|
||||||
The Name field is for the friendly name of the plugin shown to the end-user.
|
The Name field is for the friendly name of the plugin shown to the end-user.
|
||||||
|
|
||||||
The Author field is the author of this plugin. The one who created it.
|
The Author field is the author of this plugin. The one who created it.
|
||||||
|
|
||||||
The URL field is for the URL pointing to the location where you can download this plugin.
|
The URL field is for the URL pointing to the location where you can download this plugin.
|
||||||
|
|
||||||
The Settings field points to the route for managing the settings for this plugin. Coming soon.
|
The Settings field points to the route for managing the settings for this plugin. Coming soon.
|
||||||
|
|
||||||
The Active field should always be set to false in the init() function of a plugin. It's used internally by the software to determine whether an admin has enabled a plugin or not and whether to run it. This will be overwritten by the user's preference.
|
The Active field should always be set to false in the init() function of a plugin. It's used internally by the software to determine whether an admin has enabled a plugin or not and whether to run it. This will be overwritten by the user's preference.
|
||||||
|
|
||||||
The Type field is for the type of the plugin. This gets changed to "go" automatically and we would suggest leaving "".
|
The Type field is for the type of the plugin. This gets changed to "go" automatically and we would suggest leaving "".
|
||||||
|
|
||||||
The Init field is for the initialisation handler which is called by the software to run this plugin. This expects a function. You should add your hooks, init logic, initial queries, etc. in said function.
|
The Init field is for the initialisation handler which is called by the software to run this plugin. This expects a function. You should add your hooks, init logic, initial queries, etc. in said function.
|
||||||
|
|
||||||
|
The Activate field is for the handler which is called by the software when the admin hits the Activate button in the control panel. This is separate from the Init handler which is called upon the start of the server and upon activation. Use nil if you don't have a handler for this.
|
||||||
|
|
||||||
|
The Deactivate field is for the handler which is called by the software when the admin hits the Deactivate button in the control panel. You should clean-up any resources you have allocated, remove any hooks, close any statements, etc. within this handler.
|
||||||
*/
|
*/
|
||||||
plugins["skeleton"] = Plugin{"skeleton","Skeleton","Azareal","","",false,"",init_test}
|
plugins["skeleton"] = Plugin{"skeleton","Skeleton","Azareal","","",false,"",init_skeleton, activate_skeleton, deactivate_skeleton}
|
||||||
}
|
}
|
||||||
|
|
||||||
func init_test() {}
|
func init_skeleton() {}
|
||||||
|
func activate_skeleton() {}
|
||||||
|
func deactivate_skeleton() {}
|
40
routes.go
40
routes.go
|
@ -55,10 +55,13 @@ func route_custom_page(w http.ResponseWriter, r *http.Request){
|
||||||
user := SessionCheck(w,r)
|
user := SessionCheck(w,r)
|
||||||
|
|
||||||
name := r.URL.Path[len("/pages/"):]
|
name := r.URL.Path[len("/pages/"):]
|
||||||
|
if custom_pages.Lookup(name) == nil {
|
||||||
|
NotFound(w,r,user)
|
||||||
|
}
|
||||||
pi := Page{"Page","page",user,tList,0}
|
pi := Page{"Page","page",user,tList,0}
|
||||||
err := custom_pages.ExecuteTemplate(w,name,pi)
|
err := custom_pages.ExecuteTemplate(w,name,pi)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
NotFound(w,r,user)
|
InternalError(err, w, r, user)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,7 +419,7 @@ func route_profile(w http.ResponseWriter, r *http.Request){
|
||||||
replyList = make(map[int]interface{})
|
replyList = make(map[int]interface{})
|
||||||
currentID = 0
|
currentID = 0
|
||||||
|
|
||||||
puser := User{0,"",0,false,false,false,false,false,"",false,"","","",""}
|
puser := User{0,"",0,false,false,false,false,false,false,"",false,"","","","",""}
|
||||||
puser.ID, err = strconv.Atoi(r.URL.Path[len("/user/"):])
|
puser.ID, err = strconv.Atoi(r.URL.Path[len("/user/"):])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LocalError("The provided TopicID is not a valid number.",w,r,user)
|
LocalError("The provided TopicID is not a valid number.",w,r,user)
|
||||||
|
@ -446,6 +449,12 @@ func route_profile(w http.ResponseWriter, r *http.Request){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if groups[puser.Group].Tag != "" {
|
||||||
|
puser.Tag = groups[puser.Group].Tag
|
||||||
|
} else {
|
||||||
|
puser.Tag = ""
|
||||||
|
}
|
||||||
|
|
||||||
if puser.Avatar != "" {
|
if puser.Avatar != "" {
|
||||||
if puser.Avatar[0] == '.' {
|
if puser.Avatar[0] == '.' {
|
||||||
puser.Avatar = "/uploads/avatar_" + strconv.Itoa(puser.ID) + puser.Avatar
|
puser.Avatar = "/uploads/avatar_" + strconv.Itoa(puser.ID) + puser.Avatar
|
||||||
|
@ -721,11 +730,11 @@ func route_report_submit(w http.ResponseWriter, r *http.Request) {
|
||||||
LocalError("Bad Form", w, r, user)
|
LocalError("Bad Form", w, r, user)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if r.FormValue("session") != user.Session {
|
if r.FormValue("session") != user.Session {
|
||||||
SecurityError(w,r,user)
|
SecurityError(w,r,user)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
item_id, err := strconv.Atoi(r.URL.Path[len("/report/submit/"):])
|
item_id, err := strconv.Atoi(r.URL.Path[len("/report/submit/"):])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
LocalError("Bad ID", w, r, user)
|
LocalError("Bad ID", w, r, user)
|
||||||
|
@ -758,6 +767,25 @@ func route_report_submit(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
content = content + "<br><br>Original Post: <a href='/topic/" + strconv.Itoa(tid) + "'>" + title + "</a>"
|
content = content + "<br><br>Original Post: <a href='/topic/" + strconv.Itoa(tid) + "'>" + title + "</a>"
|
||||||
|
} else if item_type == "user-reply" {
|
||||||
|
err = db.QueryRow("select uid, content from users_replies where rid = ?", item_id).Scan(&tid, &content)
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
LocalError("We were unable to find the reported post", w, r, user)
|
||||||
|
return
|
||||||
|
} else if err != nil {
|
||||||
|
InternalError(err,w,r,user)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = db.QueryRow("select name from users where uid = ?", tid).Scan(&title)
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
LocalError("We were unable to find the profile which the reported post is supposed to be on", w, r, user)
|
||||||
|
return
|
||||||
|
} else if err != nil {
|
||||||
|
InternalError(err,w,r,user)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
content = content + "<br><br>Original Post: <a href='/user/" + strconv.Itoa(tid) + "'>" + title + "</a>"
|
||||||
} else if item_type == "topic" {
|
} else if item_type == "topic" {
|
||||||
err = db.QueryRow("select title, content from topics where tid = ?", item_id).Scan(&title,&content)
|
err = db.QueryRow("select title, content from topics where tid = ?", item_id).Scan(&title,&content)
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
|
@ -769,6 +797,11 @@ func route_report_submit(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
content = content + "<br><br>Original Post: <a href='/topic/" + strconv.Itoa(item_id) + "'>" + title + "</a>"
|
content = content + "<br><br>Original Post: <a href='/topic/" + strconv.Itoa(item_id) + "'>" + title + "</a>"
|
||||||
} else {
|
} else {
|
||||||
|
if vhooks["report_preassign"] != nil {
|
||||||
|
run_hook_v("report_preassign", &item_id, &item_type)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Don't try to guess the type
|
// Don't try to guess the type
|
||||||
LocalError("Unknown type", w, r, user)
|
LocalError("Unknown type", w, r, user)
|
||||||
return
|
return
|
||||||
|
@ -780,7 +813,6 @@ func route_report_submit(w http.ResponseWriter, r *http.Request) {
|
||||||
InternalError(err,w,r,user)
|
InternalError(err,w,r,user)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
err = rows.Scan(&count)
|
err = rows.Scan(&count)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
<div class="rowitem passive"><a href="/panel/forums/">Forums</a></div>
|
<div class="rowitem passive"><a href="/panel/forums/">Forums</a></div>
|
||||||
<div class="rowitem passive"><a href="/panel/settings/">Settings</a></div>
|
<div class="rowitem passive"><a href="/panel/settings/">Settings</a></div>
|
||||||
<div class="rowitem passive"><a href="/panel/plugins/">Plugins</a></div>
|
<div class="rowitem passive"><a href="/panel/plugins/">Plugins</a></div>
|
||||||
|
<div class="rowitem passive"><a href="/panel/users/">Users</a></div>
|
||||||
|
<div class="rowitem passive"><a href="/panel/groups/">Groups</a></div>
|
||||||
<div class="rowitem passive"><a>Coming Soon</a></div>
|
<div class="rowitem passive"><a>Coming Soon</a></div>
|
||||||
<div class="rowitem passive"><a>Coming Soon</a></div>
|
<div class="rowitem passive"><a>Coming Soon</a></div>
|
||||||
<div class="rowitem passive"><a>Coming Soon</a></div>
|
<div class="rowitem passive"><a>Coming Soon</a></div>
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
<div class="rowitem passive"><a href="/panel/forums/">Forums</a></div>
|
<div class="rowitem passive"><a href="/panel/forums/">Forums</a></div>
|
||||||
<div class="rowitem passive"><a href="/panel/settings/">Settings</a></div>
|
<div class="rowitem passive"><a href="/panel/settings/">Settings</a></div>
|
||||||
<div class="rowitem passive"><a href="/panel/plugins/">Plugins</a></div>
|
<div class="rowitem passive"><a href="/panel/plugins/">Plugins</a></div>
|
||||||
|
<div class="rowitem passive"><a href="/panel/users/">Users</a></div>
|
||||||
|
<div class="rowitem passive"><a href="/panel/groups/">Groups</a></div>
|
||||||
<div class="rowitem passive"><a>Coming Soon</a></div>
|
<div class="rowitem passive"><a>Coming Soon</a></div>
|
||||||
<div class="rowitem passive"><a>Coming Soon</a></div>
|
<div class="rowitem passive"><a>Coming Soon</a></div>
|
||||||
<div class="rowitem passive"><a>Coming Soon</a></div>
|
<div class="rowitem passive"><a>Coming Soon</a></div>
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
<div class="rowitem passive"><a href="/panel/forums/">Forums</a></div>
|
<div class="rowitem passive"><a href="/panel/forums/">Forums</a></div>
|
||||||
<div class="rowitem passive"><a href="/panel/settings/">Settings</a></div>
|
<div class="rowitem passive"><a href="/panel/settings/">Settings</a></div>
|
||||||
<div class="rowitem passive"><a href="/panel/plugins/">Plugins</a></div>
|
<div class="rowitem passive"><a href="/panel/plugins/">Plugins</a></div>
|
||||||
|
<div class="rowitem passive"><a href="/panel/users/">Users</a></div>
|
||||||
|
<div class="rowitem passive"><a href="/panel/groups/">Groups</a></div>
|
||||||
<div class="rowitem passive"><a>Coming Soon</a></div>
|
<div class="rowitem passive"><a>Coming Soon</a></div>
|
||||||
<div class="rowitem passive"><a>Coming Soon</a></div>
|
<div class="rowitem passive"><a>Coming Soon</a></div>
|
||||||
<div class="rowitem passive"><a>Coming Soon</a></div>
|
<div class="rowitem passive"><a>Coming Soon</a></div>
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
<div class="rowitem passive"><a href="/panel/forums/">Forums</a></div>
|
<div class="rowitem passive"><a href="/panel/forums/">Forums</a></div>
|
||||||
<div class="rowitem passive"><a href="/panel/settings/">Settings</a></div>
|
<div class="rowitem passive"><a href="/panel/settings/">Settings</a></div>
|
||||||
<div class="rowitem passive"><a href="/panel/plugins/">Plugins</a></div>
|
<div class="rowitem passive"><a href="/panel/plugins/">Plugins</a></div>
|
||||||
|
<div class="rowitem passive"><a href="/panel/users/">Users</a></div>
|
||||||
|
<div class="rowitem passive"><a href="/panel/groups/">Groups</a></div>
|
||||||
<div class="rowitem passive"><a>Coming Soon</a></div>
|
<div class="rowitem passive"><a>Coming Soon</a></div>
|
||||||
<div class="rowitem passive"><a>Coming Soon</a></div>
|
<div class="rowitem passive"><a>Coming Soon</a></div>
|
||||||
<div class="rowitem passive"><a>Coming Soon</a></div>
|
<div class="rowitem passive"><a>Coming Soon</a></div>
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
{{template "header.html" . }}
|
||||||
|
<div class="colblock_left">
|
||||||
|
<div class="rowitem"><a>Control Panel</a></div>
|
||||||
|
<div class="rowitem passive"><a href="/panel/forums/">Forums</a></div>
|
||||||
|
<div class="rowitem passive"><a href="/panel/settings/">Settings</a></div>
|
||||||
|
<div class="rowitem passive"><a href="/panel/plugins/">Plugins</a></div>
|
||||||
|
<div class="rowitem passive"><a href="/panel/users/">Users</a></div>
|
||||||
|
<div class="rowitem passive"><a href="/panel/groups/">Groups</a></div>
|
||||||
|
<div class="rowitem passive"><a>Coming Soon</a></div>
|
||||||
|
<div class="rowitem passive"><a>Coming Soon</a></div>
|
||||||
|
<div class="rowitem passive"><a>Coming Soon</a></div>
|
||||||
|
<div class="rowitem passive"><a href="/forum/-1">Reports</a></div>
|
||||||
|
</div>
|
||||||
|
<div class="colblock_right">
|
||||||
|
<div class="rowitem"><a>Users</a></div>
|
||||||
|
</div>
|
||||||
|
<div class="colblock_right">
|
||||||
|
{{range .ItemList}}
|
||||||
|
<div class="rowitem editable_parent" style="font-weight: normal;text-transform: none;">
|
||||||
|
<a href="/user/{{.ID}}" class="editable_block" style="font-size: 20px;position:relative;top: -2px;">{{.Name}}</a>
|
||||||
|
{{if .Tag}}<span class="username" style="margin-left 4px;{{if (.Is_Super_Mod) and (.Active)}}float: right;{{end}}">{{.Tag}}</span>{{end}}
|
||||||
|
<span style="float: right;">
|
||||||
|
{{if .Is_Banned}}<a href="/users/unban/{{.ID}}?session={{$.CurrentUser.Session}}" class="username">Unban</a>{{else if not .Is_Super_Mod}}<a href="/users/ban/{{.ID}}?session={{$.CurrentUser.Session}}" class="username">Ban</a>{{end}}
|
||||||
|
{{if not .Active}}<a href="/users/activate/{{.ID}}?session={{$.CurrentUser.Session}}" class="username">Activate</a>{{end}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
{{end}}
|
||||||
|
</div>
|
||||||
|
{{template "footer.html" . }}
|
|
@ -1,13 +1,15 @@
|
||||||
{{template "header.html" . }}
|
{{template "header.html" . }}
|
||||||
<div class="colblock_left" style="max-width: 220px;">
|
<div class="colblock_left" style="max-width: 220px;">
|
||||||
<div class="rowitem" style="padding: 0;"><img src="{{.Something.Avatar}}" style="max-width: 100%;margin: 0;"/></div>
|
<div class="rowitem" style="padding: 0;"><img src="{{.Something.Avatar}}" style="max-width: 100%;margin: 0;"/></div>
|
||||||
<div class="rowitem">{{.Something.Name}}</div>
|
<div class="rowitem" style="text-transform: capitalize;">
|
||||||
|
<span style="font-size: 18px;">{{.Something.Name}}</span>{{if .Something.Tag}}<span class="username" style="float: right;">{{.Something.Tag}}</span>{{end}}
|
||||||
|
</div>
|
||||||
<div class="rowitem passive">
|
<div class="rowitem passive">
|
||||||
<a class="username">Add Friend</a>
|
<a class="username">Add Friend</a>
|
||||||
{{if (.CurrentUser.Is_Super_Mod) and not (.Something.Is_Super_Mod) }}
|
{{if (.CurrentUser.Is_Super_Mod) and not (.Something.Is_Super_Mod) }}
|
||||||
{{if .Something.Is_Banned }}<a href="/users/unban/{{.Something.ID}}" class="username">Unban</a>{{else}}<a href="/users/ban/{{.Something.ID}}" class="username">Ban</a>{{end}}
|
{{if .Something.Is_Banned }}<a href="/users/unban/{{.Something.ID}}" class="username">Unban</a>{{else}}<a href="/users/ban/{{.Something.ID}}" class="username">Ban</a>{{end}}
|
||||||
{{end}}
|
{{end}}
|
||||||
<a class="username">Report</a>
|
<a href="/report/submit/{{.Something.ID}}?session={{.CurrentUser.Session}}&type=user" class="username report_item">Report</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="colblock_right">
|
<div class="colblock_right">
|
||||||
|
@ -21,7 +23,7 @@
|
||||||
<a href="/user/{{$element.CreatedBy}}" class="username">{{$element.CreatedByName}}</a>
|
<a href="/user/{{$element.CreatedBy}}" class="username">{{$element.CreatedByName}}</a>
|
||||||
{{if $.CurrentUser.Is_Mod}}<a href="/profile/reply/edit/submit/{{$element.ID}}"><button class="username edit_item">Edit</button></a>
|
{{if $.CurrentUser.Is_Mod}}<a href="/profile/reply/edit/submit/{{$element.ID}}"><button class="username edit_item">Edit</button></a>
|
||||||
<a href="/profile/reply/delete/submit/{{$element.ID}}"><button class="username delete_item">Delete</button></a>{{end}}
|
<a href="/profile/reply/delete/submit/{{$element.ID}}"><button class="username delete_item">Delete</button></a>{{end}}
|
||||||
<a href="/profile/reply/report/submit/{{$element.ID}}"><button class="username report_item">Report</button></a>
|
<a href="/report/submit/{{$element.ID}}?session={{$.CurrentUser.Session}}&type=user-reply"><button class="username report_item">Report</button></a>
|
||||||
{{ if $element.Tag }}<a class="username" style="float: right;">{{$element.Tag}}</a>{{end}}
|
{{ if $element.Tag }}<a class="username" style="float: right;">{{$element.Tag}}</a>{{end}}
|
||||||
</div>{{end}}
|
</div>{{end}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="rowblock">
|
<div class="rowblock">
|
||||||
{{range .ItemList}}<div class="rowitem passive" style="{{ if .Avatar }}background-image: url({{ .Avatar }});background-position: left;background-repeat: no-repeat;background-size: 64px;padding-left: 72px;{{end}}{{ if .Sticky }}background-color: #FFFFCC;{{end}}">
|
{{range .ItemList}}<div class="rowitem passive" style="{{ if .Avatar }}background-image: url({{ .Avatar }});background-position: left;background-repeat: no-repeat;background-size: 64px;padding-left: 72px;{{end}}{{ if .Sticky }}background-color: #FFFFCC;{{end}}">
|
||||||
<a href="/topic/{{.ID}}">{{.Title}}</a> {{if .Is_Closed}}<span class="topic_status topic_status_closed">closed</span>{{else}}<span class="topic_status topic_status_open">open</span>{{end}}
|
<a href="/topic/{{.ID}}">{{.Title}}</a> {{if .Is_Closed}}<span class="username topic_status_e topic_status_closed" style="float: right;">closed</span>
|
||||||
|
{{else}}<span class="username topic_status_e topic_status_open" style="float: right;">open</span>{{end}}
|
||||||
|
<span class="username" style="border-right: 0;float: right;">Status</span>
|
||||||
</div>{{end}}
|
</div>{{end}}
|
||||||
</div>
|
</div>
|
||||||
{{if .Something}}
|
{{if .Something}}
|
||||||
|
|
4
user.go
4
user.go
|
@ -12,6 +12,7 @@ type User struct
|
||||||
ID int
|
ID int
|
||||||
Name string
|
Name string
|
||||||
Group int
|
Group int
|
||||||
|
Active bool
|
||||||
Is_Mod bool
|
Is_Mod bool
|
||||||
Is_Super_Mod bool
|
Is_Super_Mod bool
|
||||||
Is_Admin bool
|
Is_Admin bool
|
||||||
|
@ -23,6 +24,7 @@ type User struct
|
||||||
Message string
|
Message string
|
||||||
URLPrefix string
|
URLPrefix string
|
||||||
URLName string
|
URLName string
|
||||||
|
Tag string
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetPassword(uid int, password string) (error) {
|
func SetPassword(uid int, password string) (error) {
|
||||||
|
@ -45,7 +47,7 @@ func SetPassword(uid int, password string) (error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func SessionCheck(w http.ResponseWriter, r *http.Request) (User) {
|
func SessionCheck(w http.ResponseWriter, r *http.Request) (User) {
|
||||||
user := User{0,"",0,false,false,false,false,false,"",false,"","","",""}
|
user := User{0,"",0,false,false,false,false,false,false,"",false,"","","","",""}
|
||||||
var err error
|
var err error
|
||||||
var cookie *http.Cookie
|
var cookie *http.Cookie
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue