Added the Group Permissions system.

Added the account activation system (just manual activations, email ones are coming later o.o).
Changed the benchmark test to an interface{} struct versus a typed one.
Changed the compiled template holders from a map of functions to handle variables.
Added elses for loops in the template compiler.
Added the list setting type.
Added friendlier values to the setting page :)
Added a link to the profile on the User Manager and new mini-tag mark-up to go with it.
This commit is contained in:
Azareal 2016-12-21 02:30:32 +00:00
parent b9885e9d7a
commit 78a6eae0e8
33 changed files with 550 additions and 454 deletions

View File

@ -13,6 +13,7 @@ var max_request_size = 5 * megabyte
// Misc
var default_route = route_topics
var default_group = 3
var activation_group = 5
var staff_css = " background-color: #ffeaff;"
var uncategorised_forum_visible = true
var enable_emails = false

View File

@ -100,14 +100,37 @@ CREATE TABLE `plugins`(
);
INSERT INTO settings(`name`,`content`,`type`) VALUES ('url_tags','1','bool');
INSERT INTO settings(`name`,`content`,`type`,`constraints`) VALUES ('activation_type','1','list','1-3',);
INSERT INTO users(`name`,`group`,`is_super_admin`,`createdAt`,`lastActiveAt`,`message`)
VALUES ('Admin',1,1,NOW(),NOW(),'');
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`) VALUES ('Member','{}');
INSERT INTO users_groups(`name`,`permissions`,`is_banned`) VALUES ('Banned','{}',1);
/*
The Permissions:
BanUsers
ActivateUsers
ManageForums
EditSettings
ManagePlugins
ViewIPs
ViewTopic
CreateTopic
EditTopic
DeleteTopic
CreateReply
EditReply
DeleteReply
PinTopic
CloseTopic
*/
INSERT INTO users_groups(`name`,`permissions`,`active`,`is_mod`,`is_admin`,`tag`) VALUES ('Administrator','{"BanUsers":true,"ActivateUsers":true,"ManageForums":true,"EditSettings":true,"ManagePlugins":true,"ViewIPs":true,"ViewTopic":true,"CreateTopic":true,"EditTopic":true,"DeleteTopic":true,"CreateReply":true,"EditReply":true,"DeleteReply":true,"PinTopic":true,"CloseTopic":true}',1,1,1,"Admin");
INSERT INTO users_groups(`name`,`permissions`,`is_mod`,`tag`) VALUES ('Moderator','{"BanUsers":true,"ActivateUsers":false,"ManageForums":false,"EditSettings":false,"ManagePlugins":false,"ViewIPs":true,"ViewTopic":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','{"BanUsers":false,"ActivateUsers":false,"ManageForums":false,"EditSettings":false,"ManagePlugins":false,"ViewIPs":false,"ViewTopic":true,"CreateTopic":true,"EditTopic":false,"DeleteTopic":false,"CreateReply":true,"EditReply":false,"DeleteReply":false,"PinTopic":false,"CloseTopic":false}');
INSERT INTO users_groups(`name`,`permissions`,`is_banned`) VALUES ('Banned','{"BanUsers":false,"ActivateUsers":false,"ManageForums":false,"EditSettings":false,"ManagePlugins":false,"ViewIPs":false,"ViewTopic":true,"CreateTopic":false,"EditTopic":false,"DeleteTopic":false,"CreateReply":false,"EditReply":false,"DeleteReply":false,"PinTopic":false,"CloseTopic":false}',1);
INSERT INTO users_groups(`name`,`permissions`,`is_banned`) VALUES ('Awaiting Activation','{"BanUsers":false,"ActivateUsers":false,"ManageForums":false,"EditSettings":false,"ManagePlugins":false,"ViewIPs":false,"ViewTopic":true,"CreateTopic":false,"EditTopic":false,"DeleteTopic":false,"CreateReply":false,"EditReply":false,"DeleteReply":false,"PinTopic":false,"CloseTopic":false}');
INSERT INTO forums(`name`,`lastTopicTime`) VALUES ('General',NOW());
INSERT INTO topics(`title`,`content`,`createdAt`,`lastReplyAt`,`createdBy`,`parentID`)

View File

@ -35,7 +35,7 @@ func add_hook(name string, handler interface{}) {
}
}
func remove_hook(name string) {
func remove_hook(name string/*, plugin string */) {
delete(hooks, name)
}

View File

@ -4,26 +4,27 @@ import "io/ioutil"
import "html/template"
func BenchmarkTemplates(b *testing.B) {
user := User{0,"Bob",0,false,false,false,false,false,false,"",false,"","","","",""}
admin := User{1,"Admin",0,true,true,true,true,true,false,"",false,"","","","",""}
user := User{0,"Bob",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","",""}
admin := User{1,"Admin",0,true,true,true,true,true,false,AllPerms,"",false,"","","","",""}
var noticeList map[int]string = make(map[int]string)
noticeList[0] = "test"
topic := TopicUser{0,"Lol",template.HTML("Hey everyone!"),0,false,false,"",0,"","","",no_css_tmpl,0,"","","",""}
var replyList map[int]interface{} = make(map[int]interface{})
replyList[0] = Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""}
replyList[1] = Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""}
replyList[2] = Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""}
replyList[3] = Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""}
replyList[4] = Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""}
replyList[5] = Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""}
replyList[6] = Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""}
replyList[7] = Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""}
replyList[8] = Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""}
replyList[9] = Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""}
var replyList []interface{}
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
replyList = append(replyList, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
var replyList2 []interface{}
var replyList2 []Reply
replyList2 = append(replyList2, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
replyList2 = append(replyList2, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
replyList2 = append(replyList2, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
@ -35,41 +36,52 @@ func BenchmarkTemplates(b *testing.B) {
replyList2 = append(replyList2, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
replyList2 = append(replyList2, Reply{0,0,"Hey everyone!",template.HTML("Hey everyone!"),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
pi := Page2{"Topic Blah","topic",user,noticeList,replyList,topic}
pi2 := Page2{"Topic Blah","topic",admin,noticeList,replyList,topic}
pi3 := Page{"Topic Blah","topic",user,noticeList,replyList2,topic}
pi4 := Page{"Topic Blah","topic",admin,noticeList,replyList2,topic}
pi := Page{"Topic Blah","topic",user,noticeList,replyList,topic}
pi2 := Page{"Topic Blah","topic",admin,noticeList,replyList,topic}
tpage := TopicPage{"Topic Blah","topic",user,noticeList,replyList2,topic,false}
tpage2 := TopicPage{"Topic Blah","topic",admin,noticeList,replyList2,topic,false}
w := ioutil.Discard
b.Run("compiled_sliceloop_useradmin", func(b *testing.B) {
b.Run("compiled_useradmin", func(b *testing.B) {
for i := 0; i < b.N; i++ {
template_topic(pi4,w)
template_topic_2(pi2,w)
}
})
b.Run("compiled_maploop_useradmin", func(b *testing.B) {
for i := 0; i < b.N; i++ {
template_topic_maploop(pi2,w)
}
})
b.Run("interpreted_useradmin", func(b *testing.B) {
/*b.Run("interpreted_useradmin", func(b *testing.B) {
for i := 0; i < b.N; i++ {
templates.ExecuteTemplate(w,"topic.html", pi2)
}
})
b.Run("compiled_sliceloop_userguest", func(b *testing.B) {
})*/
b.Run("compiled_userguest", func(b *testing.B) {
for i := 0; i < b.N; i++ {
template_topic(pi3,w)
template_topic_2(pi,w)
}
})
b.Run("compiled_maploop_userguest", func(b *testing.B) {
for i := 0; i < b.N; i++ {
template_topic_maploop(pi,w)
}
})
b.Run("interpreted_userguest", func(b *testing.B) {
/*b.Run("interpreted_userguest", func(b *testing.B) {
for i := 0; i < b.N; i++ {
templates.ExecuteTemplate(w,"topic.html", pi)
}
})*/
b.Run("compiled_customstruct_useradmin", func(b *testing.B) {
for i := 0; i < b.N; i++ {
template_topic(tpage2,w)
}
})
b.Run("interpreted_customstruct_useradmin", func(b *testing.B) {
for i := 0; i < b.N; i++ {
templates.ExecuteTemplate(w,"topic.html", tpage2)
}
})
b.Run("compiled_customstruct_userguest", func(b *testing.B) {
for i := 0; i < b.N; i++ {
template_topic(tpage,w)
}
})
b.Run("interpreted_customstruct_userguest", func(b *testing.B) {
for i := 0; i < b.N; i++ {
templates.ExecuteTemplate(w,"topic.html", tpage)
}
})
}

Binary file not shown.

Binary file not shown.

View File

@ -1,12 +1,98 @@
package main
import "fmt"
var GuestPerms Perms
var AllPerms Perms
type Group struct
{
ID int
Name string
Permissions string
Perms Perms
PermissionsText []byte
Is_Mod bool
Is_Admin bool
Is_Banned bool
Tag string
}
type Perms struct
{
// Global Permissions
BanUsers bool
ActivateUsers bool
ManageForums bool // This could be local, albeit limited for per-forum managers
EditSettings bool
ManagePlugins bool
ViewIPs bool
// Forum permissions
ViewTopic bool
CreateTopic bool
EditTopic bool
DeleteTopic bool
CreateReply bool
//CreateReplyToOwn bool
EditReply bool
//EditOwnReply bool
DeleteReply bool
PinTopic bool
CloseTopic bool
//CloseOwnTopic bool
ExtData interface{}
}
/* Inherit from group permissions for ones we don't have */
type ForumPerms struct
{
ViewTopic bool
CreateTopic bool
EditTopic bool
DeleteTopic bool
CreateReply bool
//CreateReplyToOwn bool
EditReply bool
//EditOwnReply bool
DeleteReply bool
PinTopic bool
CloseTopic bool
//CloseOwnTopic bool
ExtData map[string]bool
}
func init() {
GuestPerms = Perms{
ViewTopic: true,
ExtData: make(map[string]bool),
}
AllPerms = Perms{
BanUsers: true,
ActivateUsers: true,
ManageForums: true,
EditSettings: true,
ManagePlugins: true,
ViewIPs: true,
ViewTopic: true,
CreateTopic: true,
EditTopic: true,
DeleteTopic: true,
CreateReply: true,
EditReply: true,
DeleteReply: true,
PinTopic: true,
CloseTopic: true,
ExtData: make(map[string]bool),
}
if debug {
fmt.Printf("Guest Perms: ")
fmt.Printf("%+v\n", GuestPerms)
fmt.Printf("All Perms: ")
fmt.Printf("%+v\n", AllPerms)
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

29
main.go
View File

@ -4,7 +4,6 @@ package main
import (
"net/http"
"log"
//"fmt"
"mime"
"strings"
"path/filepath"
@ -24,7 +23,6 @@ const saltLength int = 32
const sessionLength int = 80
var templates = template.Must(template.ParseGlob("templates/*"))
//var custom_pages = template.Must(template.ParseGlob("pages/*"))
var no_css_tmpl = template.CSS("")
var staff_css_tmpl = template.CSS(staff_css)
var settings map[string]interface{} = make(map[string]interface{})
@ -32,29 +30,33 @@ var external_sites map[string]string = make(map[string]string)
var groups map[int]Group = make(map[int]Group)
var forums map[int]Forum = make(map[int]Forum)
var static_files map[string]SFile = make(map[string]SFile)
var ctemplates map[string]func(Page,io.Writer) = make(map[string]func(Page,io.Writer))
var ctemplates []string
var template_topic_handle func(TopicPage,io.Writer) = nil
var template_topics_handle func(Page,io.Writer) = nil
var template_forum_handle func(Page,io.Writer) = nil
var template_forums_handle func(Page,io.Writer) = nil
var template_profile_handle func(Page,io.Writer) = nil
func compile_templates() {
var c CTemplateSet
user := User{0,"",0,false,false,false,false,false,false,"",false,"","","","",""}
user := User{0,"",0,false,false,false,false,false,false,GuestPerms,"",false,"","","","",""}
var noticeList map[int]string = make(map[int]string)
noticeList[0] = "test"
log.Print("Compiling the templates")
topic := TopicUser{0,"",template.HTML(""),0,false,false,"",0,"","","",no_css_tmpl,0,"","","",""}
var replyList []interface{}
var replyList []Reply
replyList = append(replyList, Reply{0,0,"",template.HTML(""),0,"","",0,0,"",no_css_tmpl,0,"","","",""})
var varList map[string]VarItem = make(map[string]VarItem)
varList["extra_data"] = VarItem{"extra_data","tmpl_topic_vars.Something.(TopicUser)","TopicUser"}
pi := Page{"Title","name",user,noticeList,replyList,topic}
topic_id_tmpl := c.compile_template("topic.html","templates/","Page", pi, varList)
var varList map[string]VarItem = make(map[string]VarItem)
tpage := TopicPage{"Title","name",user,noticeList,replyList,topic,false}
topic_id_tmpl := c.compile_template("topic.html","templates/","TopicPage", tpage, varList)
varList = make(map[string]VarItem)
varList["extra_data"] = VarItem{"extra_data","tmpl_profile_vars.Something.(User)","User"}
pi = Page{"Title","name",user,noticeList,replyList,user}
profile_tmpl := c.compile_template("profile.html","templates/","Page", pi, varList)
//pi := Page{"Title","name",user,noticeList,replyList,user}
//profile_tmpl := c.compile_template("profile.html","templates/","Page", pi, varList)
var forumList []interface{}
for _, forum := range forums {
@ -63,7 +65,7 @@ func compile_templates() {
}
}
varList = make(map[string]VarItem)
pi = Page{"Forum List","forums",user,noticeList,forumList,0}
pi := Page{"Forum List","forums",user,noticeList,forumList,0}
forums_tmpl := c.compile_template("forums.html","templates/","Page", pi, varList)
var topicList []interface{}
@ -76,7 +78,7 @@ func compile_templates() {
log.Print("Writing the templates")
write_template("topic", topic_id_tmpl)
write_template("profile", profile_tmpl)
//write_template("profile", profile_tmpl)
write_template("forums", forums_tmpl)
write_template("topics", topics_tmpl)
write_template("forum", forum_tmpl)
@ -203,6 +205,7 @@ func main(){
http.HandleFunc("/panel/plugins/activate/", route_panel_plugins_activate)
http.HandleFunc("/panel/plugins/deactivate/", route_panel_plugins_deactivate)
http.HandleFunc("/panel/users/", route_panel_users)
http.HandleFunc("/panel/users/edit/", route_panel_users_edit)
http.HandleFunc("/", default_route)

View File

@ -24,15 +24,10 @@ func route_edit_topic(w http.ResponseWriter, r *http.Request) {
if is_js == "" {
is_js = "0"
}
if !user.Is_Mod && !user.Is_Admin {
if !user.Perms.ViewTopic || !user.Perms.EditTopic {
NoPermissionsJSQ(w,r,user,is_js)
return
}
if user.Is_Banned {
BannedJSQ(w,r,user,is_js)
return
}
var tid int
tid, err = strconv.Atoi(r.URL.Path[len("/topic/edit/submit/"):])
@ -70,8 +65,7 @@ func route_delete_topic(w http.ResponseWriter, r *http.Request) {
if !ok {
return
}
if !user.Is_Mod && !user.Is_Admin {
if !user.Perms.ViewTopic || !user.Perms.DeleteTopic {
NoPermissions(w,r,user)
return
}
@ -106,8 +100,7 @@ func route_stick_topic(w http.ResponseWriter, r *http.Request) {
if !ok {
return
}
if !user.Is_Mod && !user.Is_Admin {
if !user.Perms.ViewTopic || !user.Perms.PinTopic {
NoPermissions(w,r,user)
return
}
@ -123,7 +116,6 @@ func route_stick_topic(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r,user)
return
}
http.Redirect(w, r, "/topic/" + strconv.Itoa(tid), http.StatusSeeOther)
}
@ -132,8 +124,7 @@ func route_unstick_topic(w http.ResponseWriter, r *http.Request) {
if !ok {
return
}
if !user.Is_Mod && !user.Is_Admin {
if !user.Perms.ViewTopic || !user.Perms.PinTopic {
NoPermissions(w,r,user)
return
}
@ -149,7 +140,6 @@ func route_unstick_topic(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r,user)
return
}
http.Redirect(w, r, "/topic/" + strconv.Itoa(tid), http.StatusSeeOther)
}
@ -169,8 +159,7 @@ func route_reply_edit_submit(w http.ResponseWriter, r *http.Request) {
if is_js == "" {
is_js = "0"
}
if !user.Is_Mod && !user.Is_Admin {
if !user.Perms.ViewTopic || !user.Perms.EditReply {
NoPermissionsJSQ(w,r,user,is_js)
return
}
@ -214,13 +203,12 @@ func route_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
LocalError("Bad Form", w, r, user)
return
}
is_js := r.PostFormValue("is_js")
if is_js == "" {
is_js = "0"
}
if !user.Is_Mod && !user.Is_Admin {
if !user.Perms.ViewTopic || !user.Perms.DeleteReply {
NoPermissionsJSQ(w,r,user,is_js)
return
}
@ -266,7 +254,6 @@ func route_profile_reply_edit_submit(w http.ResponseWriter, r *http.Request) {
LocalError("Bad Form", w, r, user)
return
}
is_js := r.PostFormValue("js")
if is_js == "" {
is_js = "0"
@ -286,7 +273,7 @@ func route_profile_reply_edit_submit(w http.ResponseWriter, r *http.Request) {
return
}
if user.ID != uid && !user.Is_Mod && !user.Is_Admin {
if user.ID != uid && !user.Perms.EditReply {
NoPermissionsJSQ(w,r,user,is_js)
return
}
@ -338,7 +325,7 @@ func route_profile_reply_delete_submit(w http.ResponseWriter, r *http.Request) {
return
}
if user.ID != uid && !user.Is_Mod && !user.Is_Admin {
if user.ID != uid && !user.Perms.DeleteReply {
NoPermissionsJSQ(w,r,user,is_js)
return
}
@ -363,7 +350,7 @@ func route_ban(w http.ResponseWriter, r *http.Request) {
return
}
if !user.Is_Mod && !user.Is_Admin {
if !user.Perms.BanUsers {
NoPermissions(w,r,user)
return
}
@ -397,7 +384,7 @@ func route_ban_submit(w http.ResponseWriter, r *http.Request) {
return
}
if !user.Is_Mod && !user.Is_Admin {
if !user.Perms.BanUsers {
NoPermissions(w,r,user)
return
}
@ -454,7 +441,7 @@ func route_unban(w http.ResponseWriter, r *http.Request) {
if !ok {
return
}
if !user.Is_Mod && !user.Is_Admin {
if !user.Perms.BanUsers {
NoPermissions(w,r,user)
return
}
@ -494,7 +481,7 @@ func route_activate(w http.ResponseWriter, r *http.Request) {
if !ok {
return
}
if !user.Is_Mod && !user.Is_Admin {
if !user.Perms.ActivateUsers {
NoPermissions(w,r,user)
return
}
@ -526,6 +513,12 @@ func route_activate(w http.ResponseWriter, r *http.Request) {
InternalError(err,w,r,user)
return
}
_, err = change_group_stmt.Exec(default_group, uid)
if err != nil {
InternalError(err,w,r,user)
return
}
http.Redirect(w,r,"/users/" + strconv.Itoa(uid),http.StatusSeeOther)
}
@ -534,8 +527,7 @@ func route_panel_forums(w http.ResponseWriter, r *http.Request){
if !ok {
return
}
if !user.Is_Admin {
if !user.Perms.ManageForums {
NoPermissions(w,r,user)
return
}
@ -556,8 +548,7 @@ func route_panel_forums_create_submit(w http.ResponseWriter, r *http.Request){
if !ok {
return
}
if !user.Is_Admin {
if !user.Perms.ManageForums {
NoPermissions(w,r,user)
return
}
@ -594,11 +585,11 @@ func route_panel_forums_delete(w http.ResponseWriter, r *http.Request){
if !ok {
return
}
if !user.Is_Admin {
if !user.Perms.ManageForums {
NoPermissions(w,r,user)
return
}
if r.FormValue("session") != user.Session {
SecurityError(w,r,user)
return
@ -627,11 +618,11 @@ func route_panel_forums_delete_submit(w http.ResponseWriter, r *http.Request) {
if !ok {
return
}
if !user.Is_Admin {
if !user.Perms.ManageForums {
NoPermissions(w,r,user)
return
}
if r.FormValue("session") != user.Session {
SecurityError(w,r,user)
return
@ -665,8 +656,7 @@ func route_panel_forums_edit_submit(w http.ResponseWriter, r *http.Request) {
if !ok {
return
}
if !user.Is_Admin {
if !user.Perms.ManageForums {
NoPermissions(w,r,user)
return
}
@ -711,15 +701,51 @@ func route_panel_settings(w http.ResponseWriter, r *http.Request){
if !ok {
return
}
if !user.Is_Admin {
if !user.Perms.EditSettings {
NoPermissions(w,r,user)
return
}
var settingList map[string]interface{} = make(map[string]interface{})
for name, content := range settings {
settingList[name] = content
rows, err := db.Query("SELECT name, content, type FROM settings")
if err != nil {
InternalError(err,w,r,user)
return
}
defer rows.Close()
var sname string
var scontent string
var stype string
for rows.Next() {
err := rows.Scan(&sname, &scontent, &stype)
if err != nil {
InternalError(err,w,r,user)
return
}
if stype == "list" {
llist := settingLabels[sname]
labels := strings.Split(llist,",")
conv, err := strconv.Atoi(scontent)
if err != nil {
LocalError("The setting '" + sname + "' can't be converted to an integer",w,r,user)
return
}
scontent = labels[conv - 1]
} else if stype == "bool" {
if scontent == "1" {
scontent = "Yes"
} else {
scontent = "No"
}
}
settingList[sname] = scontent
}
err = rows.Err()
if err != nil {
InternalError(err,w,r,user)
return
}
pi := Page{"Setting Manager","panel-settings",user, noticeList,tList,settingList}
@ -731,13 +757,12 @@ func route_panel_setting(w http.ResponseWriter, r *http.Request){
if !ok {
return
}
if !user.Is_Admin {
if !user.Perms.EditSettings {
NoPermissions(w,r,user)
return
}
setting := Setting{"","",""}
setting := Setting{"","","",""}
setting.Name = r.URL.Path[len("/panel/settings/edit/"):]
err := db.QueryRow("SELECT content, type from settings where name = ?", setting.Name).Scan(&setting.Content, &setting.Type)
@ -749,7 +774,31 @@ func route_panel_setting(w http.ResponseWriter, r *http.Request){
return
}
pi := Page{"Edit Setting","panel-setting",user,noticeList,tList,setting}
var itemList []interface{}
if setting.Type == "list" {
llist, ok := settingLabels[setting.Name]
if !ok {
LocalError("The labels for this setting don't exist",w,r,user)
return
}
conv, err := strconv.Atoi(setting.Content)
if err != nil {
LocalError("The value of this setting couldn't be converted to an integer",w,r,user)
return
}
labels := strings.Split(llist,",")
for index, label := range labels {
itemList = append(itemList, SettingLabel{
Label: label,
Value: index + 1,
Selected: conv == (index + 1),
})
}
}
pi := Page{"Edit Setting","panel-setting",user,noticeList,itemList,setting}
templates.ExecuteTemplate(w,"panel-setting.html", pi)
}
@ -758,8 +807,7 @@ func route_panel_setting_edit(w http.ResponseWriter, r *http.Request) {
if !ok {
return
}
if !user.Is_Admin {
if !user.Perms.EditSettings {
NoPermissions(w,r,user)
return
}
@ -775,10 +823,11 @@ func route_panel_setting_edit(w http.ResponseWriter, r *http.Request) {
}
var stype string
var sconstraints string
sname := r.URL.Path[len("/panel/settings/edit/submit/"):]
scontent := r.PostFormValue("setting-value")
err = db.QueryRow("SELECT name, type from settings where name = ?", sname).Scan(&sname, &stype)
err = db.QueryRow("SELECT name, type, constraints from settings where name = ?", sname).Scan(&sname, &stype, &sconstraints)
if err == sql.ErrNoRows {
LocalError("The setting you want to edit doesn't exist.",w,r,user)
return
@ -801,7 +850,7 @@ func route_panel_setting_edit(w http.ResponseWriter, r *http.Request) {
return
}
errmsg := parseSetting(sname, scontent, stype)
errmsg := parseSetting(sname, scontent, stype, sconstraints)
if errmsg != "" {
LocalError(errmsg,w,r,user)
return
@ -814,7 +863,7 @@ func route_panel_plugins(w http.ResponseWriter, r *http.Request){
if !ok {
return
}
if !user.Is_Admin {
if !user.Perms.ManagePlugins {
NoPermissions(w,r,user)
return
}
@ -833,8 +882,7 @@ func route_panel_plugins_activate(w http.ResponseWriter, r *http.Request){
if !ok {
return
}
if !user.Is_Admin {
if !user.Perms.ManagePlugins {
NoPermissions(w,r,user)
return
}
@ -892,8 +940,7 @@ func route_panel_plugins_deactivate(w http.ResponseWriter, r *http.Request){
if !ok {
return
}
if !user.Is_Admin {
if !user.Perms.ManagePlugins {
NoPermissions(w,r,user)
return
}
@ -937,8 +984,7 @@ func route_panel_users(w http.ResponseWriter, r *http.Request){
if !ok {
return
}
if !user.Is_Admin {
if !user.Is_Super_Mod {
NoPermissions(w,r,user)
return
}
@ -952,7 +998,7 @@ func route_panel_users(w http.ResponseWriter, r *http.Request){
defer rows.Close()
for rows.Next() {
puser := User{0,"",0,false,false,false,false,false,false,"",false,"","","","",""}
puser := User{ID: 0,}
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)
@ -994,4 +1040,8 @@ func route_panel_users(w http.ResponseWriter, r *http.Request){
if err != nil {
InternalError(err, w, r, user)
}
}
}
func route_panel_users_edit(w http.ResponseWriter, r *http.Request){
}

View File

@ -3,8 +3,9 @@ package main
import "database/sql"
import _ "github.com/go-sql-driver/mysql"
import "strconv"
import "log"
import "fmt"
import "encoding/json"
var db *sql.DB
var get_session_stmt *sql.Stmt
@ -167,7 +168,7 @@ func init_database(err error) {
// create_account_stmt, err = db.Prepare("INSERT INTO
log.Print("Preparing register statement.")
register_stmt, err = db.Prepare("INSERT INTO users(`name`,`email`,`password`,`salt`,`group`,`is_super_admin`,`session`,`message`) VALUES(?,?,?,?," + strconv.Itoa(default_group) + ",0,?,'')")
register_stmt, err = db.Prepare("INSERT INTO users(`name`,`email`,`password`,`salt`,`group`,`is_super_admin`,`session`,`active`,`message`) VALUES(?,?,?,?,?,0,?,?,'')")
if err != nil {
log.Fatal(err)
}
@ -252,11 +253,21 @@ func init_database(err error) {
defer rows.Close()
for rows.Next() {
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)
group := Group{ID: 0,}
err := rows.Scan(&group.ID, &group.Name, &group.PermissionsText, &group.Is_Mod, &group.Is_Admin, &group.Is_Banned, &group.Tag)
if err != nil {
log.Fatal(err)
}
err = json.Unmarshal(group.PermissionsText, &group.Perms)
if err != nil {
log.Fatal(err)
}
fmt.Println(group.Name + ": ")
fmt.Printf("%+v\n", group.Perms)
group.Perms.ExtData = make(map[string]bool)
groups[group.ID] = group
}
err = rows.Err()
@ -301,7 +312,7 @@ func init_database(err error) {
forums[-1] = Forum{-1,"Reports",false,"",0,"",0,""}
log.Print("Loading the settings.")
rows, err = db.Query("SELECT name, content, type FROM settings")
rows, err = db.Query("SELECT name, content, type, constraints FROM settings")
if err != nil {
log.Fatal(err)
}
@ -310,12 +321,13 @@ func init_database(err error) {
var sname string
var scontent string
var stype string
var sconstraints string
for rows.Next() {
err := rows.Scan(&sname, &scontent, &stype)
err := rows.Scan(&sname, &scontent, &stype, &sconstraints)
if err != nil {
log.Fatal(err)
}
errmsg := parseSetting(sname, scontent, stype)
errmsg := parseSetting(sname, scontent, stype, sconstraints)
if errmsg != "" {
log.Fatal(err)
}

BIN
old-images/settings.PNG Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@ -12,15 +12,15 @@ type Page struct
Something interface{}
}
/* For testing maps versus slices */
type Page2 struct
type TopicPage struct
{
Title string
Name string
CurrentUser User
NoticeList map[int]string
ItemList map[int]interface{}
Something interface{}
ItemList []Reply
Topic TopicUser
ExtData interface{}
}
type PageSimple struct

View File

@ -297,6 +297,21 @@ button.username
position: relative;
top: -0.25px;
}
.tag-mini
{
text-transform: none;
margin-left: 0px;
padding-left: 3px;
padding-right: 3px;
padding-top: 1.5px;
padding-bottom: 0px;
color: #505050; /* 80,80,80 */
background-color: #FFFFFF;
border-style: dotted;
border-color: #505050; /* 232,232,232. All three RGB colours being the same seems to create a shade of gray */
border-width: 1px;
font-size: 10px;
}
.show_on_edit
{

125
routes.go
View File

@ -1,7 +1,6 @@
/* Copyright Azareal 2016 - 2017 */
package main
import "errors"
import "log"
import "fmt"
import "strconv"
@ -78,11 +77,14 @@ func route_topics(w http.ResponseWriter, r *http.Request){
if !ok {
return
}
// I'll have to find a solution which doesn't involve shutting down all of the routes for a user, if they don't have ANY permissions
/*if !user.Perms.ViewTopic {
NoPermissions(w,r,user)
return
}*/
var(
topicList []interface{}
currentID int
tid int
title string
content string
@ -123,11 +125,11 @@ func route_topics(w http.ResponseWriter, r *http.Request){
avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(createdBy),1)
}
topicList = append(topicList, TopicUser{tid,title,content,createdBy,is_closed,sticky, createdAt,parentID,status,name,avatar,"",0,"","","",""})
topicItem := TopicUser{tid,title,content,createdBy,is_closed,sticky, createdAt,parentID,status,name,avatar,"",0,"","","",""}
if hooks["trow_assign"] != nil {
topicList[currentID] = run_hook("trow_assign", topicList[currentID])
topicItem = run_hook("trow_assign", topicItem).(TopicUser)
}
topicList = append(topicList, topicItem)
}
err = rows.Err()
if err != nil {
@ -135,16 +137,9 @@ func route_topics(w http.ResponseWriter, r *http.Request){
return
}
var msg string
if len(topicList) == 0 {
msg = "There aren't any topics yet."
} else {
msg = ""
}
pi := Page{"Topic List","topics",user,noticeList,topicList,msg}
if ctemplates["topics"] != nil {
ctemplates["topics"](pi,w)
pi := Page{"Topic List","topics",user,noticeList,topicList,0}
if template_topics_handle != nil {
template_topics_handle(pi,w)
} else {
err = templates.ExecuteTemplate(w,"topics.html", pi)
if err != nil {
@ -161,8 +156,6 @@ func route_forum(w http.ResponseWriter, r *http.Request){
var(
topicList []interface{}
currentID int
tid int
title string
content string
@ -187,6 +180,10 @@ func route_forum(w http.ResponseWriter, r *http.Request){
NotFound(w,r,user)
return
}
if !user.Perms.ViewTopic {
NoPermissions(w,r,user)
return
}
rows, err := db.Query("select topics.tid, topics.title, topics.content, topics.createdBy, topics.is_closed, topics.sticky, topics.createdAt, topics.parentID, users.name, users.avatar from topics left join users ON topics.createdBy = users.uid WHERE topics.parentID = ? order by topics.sticky DESC, topics.lastReplyAt DESC, topics.createdBy DESC", fid)
if err != nil {
@ -215,11 +212,11 @@ func route_forum(w http.ResponseWriter, r *http.Request){
avatar = strings.Replace(noavatar,"{id}",strconv.Itoa(createdBy),1)
}
topicList = append(topicList, TopicUser{tid,title,content,createdBy,is_closed,sticky,createdAt,parentID,status,name,avatar,"",0,"","","",""})
topicItem := TopicUser{tid,title,content,createdBy,is_closed,sticky,createdAt,parentID,status,name,avatar,"",0,"","","",""}
if hooks["trow_assign"] != nil {
topicList[currentID] = run_hook("trow_assign", topicList[currentID])
topicItem = run_hook("trow_assign", topicItem).(TopicUser)
}
topicList = append(topicList, topicItem)
}
err = rows.Err()
if err != nil {
@ -227,16 +224,9 @@ func route_forum(w http.ResponseWriter, r *http.Request){
return
}
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,noticeList,topicList,msg}
if ctemplates["forum"] != nil {
ctemplates["forum"](pi,w)
pi := Page{forums[fid].Name,"forum",user,noticeList,topicList,0}
if template_forum_handle != nil {
template_forum_handle(pi,w)
} else {
err = templates.ExecuteTemplate(w,"forum.html", pi)
if err != nil {
@ -258,14 +248,9 @@ func route_forums(w http.ResponseWriter, r *http.Request){
}
}
if len(forums) == 0 {
InternalError(errors.New("No forums"),w,r,user)
return
}
pi := Page{"Forum List","forums",user,noticeList,forumList,0}
if ctemplates["forums"] != nil {
ctemplates["forums"](pi,w)
if template_forums_handle != nil {
template_forums_handle(pi,w)
} else {
err := templates.ExecuteTemplate(w,"forums.html", pi)
if err != nil {
@ -300,7 +285,7 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
is_super_admin bool
group int
replyList []interface{}
replyList []Reply
)
topic := TopicUser{0,"","",0,false,false,"",0,"","","",no_css_tmpl,0,"","","",""}
@ -309,6 +294,10 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
LocalError("The provided TopicID is not a valid number.",w,r,user)
return
}
if !user.Perms.ViewTopic {
NoPermissions(w,r,user)
return
}
// Get the topic..
err = db.QueryRow("select topics.title, topics.content, topics.createdBy, topics.createdAt, topics.is_closed, topics.sticky, topics.parentID, users.name, users.avatar, users.is_super_admin, users.group, users.url_prefix, users.url_name from topics left join users ON topics.createdBy = users.uid where tid = ?", topic.ID).Scan(&topic.Title, &content, &topic.CreatedBy, &topic.CreatedAt, &topic.Is_Closed, &topic.Sticky, &topic.ParentID, &topic.CreatedByName, &topic.Avatar, &is_super_admin, &group, &topic.URLPrefix, &topic.URLName)
@ -411,11 +400,11 @@ func route_topic_id(w http.ResponseWriter, r *http.Request){
return
}
pi := Page{topic.Title,"topic",user,noticeList,replyList,topic}
if ctemplates["topic"] != nil {
ctemplates["topic"](pi,w)
tpage := TopicPage{topic.Title,"topic",user,noticeList,replyList,topic,0}
if template_topic_handle != nil {
template_topic_handle(tpage,w)
} else {
err = templates.ExecuteTemplate(w,"topic.html", pi)
err = templates.ExecuteTemplate(w,"topic.html", tpage)
if err != nil {
InternalError(err, w, r, user)
}
@ -447,7 +436,7 @@ func route_profile(w http.ResponseWriter, r *http.Request){
replyList []interface{}
)
puser := User{0,"",0,false,false,false,false,false,false,"",false,"","","","",""}
puser := User{ID: 0,}
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)
@ -536,8 +525,8 @@ func route_profile(w http.ResponseWriter, r *http.Request){
}
pi := Page{puser.Name + "'s Profile","profile",user,noticeList,replyList,puser}
if ctemplates["profile"] != nil {
ctemplates["profile"](pi,w)
if template_profile_handle != nil {
template_profile_handle(pi,w)
} else {
err = templates.ExecuteTemplate(w,"profile.html", pi)
if err != nil {
@ -551,9 +540,8 @@ func route_topic_create(w http.ResponseWriter, r *http.Request){
if !ok {
return
}
if user.Is_Banned {
Banned(w,r,user)
if !user.Loggedin || !user.Perms.CreateTopic {
NoPermissions(w,r,user)
return
}
@ -567,13 +555,8 @@ func route_create_topic(w http.ResponseWriter, r *http.Request) {
if !ok {
return
}
if !user.Loggedin {
LoginRequired(w,r,user)
return
}
if user.Is_Banned {
Banned(w,r,user)
if !user.Loggedin || !user.Perms.CreateTopic {
NoPermissions(w,r,user)
return
}
@ -622,13 +605,8 @@ func route_create_reply(w http.ResponseWriter, r *http.Request) {
if !ok {
return
}
if !user.Loggedin {
LoginRequired(w,r,user)
return
}
if user.Is_Banned {
Banned(w,r,user)
if !user.Loggedin || !user.Perms.CreateReply {
NoPermissions(w,r,user)
return
}
@ -698,13 +676,8 @@ func route_profile_reply_create(w http.ResponseWriter, r *http.Request) {
if !ok {
return
}
if !user.Loggedin {
LoginRequired(w,r,user)
return
}
if user.Is_Banned {
Banned(w,r,user)
if !user.Loggedin || !user.Perms.CreateReply {
NoPermissions(w,r,user)
return
}
@ -1452,7 +1425,17 @@ func route_register_submit(w http.ResponseWriter, r *http.Request) {
return
}
res, err := register_stmt.Exec(username,email,string(hashed_password),salt,session)
var active int
var group int
if settings["activation_type"] == 1 {
active = 1
group = default_group
} else {
active = 0
group = activation_group
}
res, err := register_stmt.Exec(username,email,string(hashed_password),salt,group,session,active)
if err != nil {
InternalError(err,w,r,user)
return

View File

@ -1,14 +1,30 @@
package main
import "strconv"
import "strings"
var settingLabels map[string]string
type SettingLabel struct
{
Label string
Value int
Selected bool
}
type Setting struct
{
Name string
Content string
Type string
Constraint string
}
func parseSetting(sname string, scontent string, stype string) string {
func init() {
settingLabels = make(map[string]string)
settingLabels["activation_type"] = "Activate All,Email Activation,Admin Approval"
}
func parseSetting(sname string, scontent string, stype string, constraint string) string {
var err error
if stype == "bool" {
if scontent == "1" {
@ -26,6 +42,30 @@ func parseSetting(sname string, scontent string, stype string) string {
if err != nil {
return "You were supposed to enter an integer x.x\nType mismatch in " + sname
}
} else if stype == "list" {
cons := strings.Split(constraint,"-")
if len(cons) < 2 {
return "Invalid constraint! The second field wasn't set!"
}
con1, err := strconv.Atoi(cons[0])
if err != nil {
return "Invalid contraint! The constraint field wasn't an integer!"
}
con2, err := strconv.Atoi(cons[1])
if err != nil {
return "Invalid contraint! The constraint field wasn't an integer!"
}
value, err := strconv.Atoi(scontent)
if err != nil {
return "Only integers are allowed in this setting x.x\nType mismatch in " + sname
}
if value < con1 || value > con2 {
return "Only integers between a certain range are allowed in this setting"
}
settings[sname] = value
} else {
settings[sname] = scontent
}

View File

@ -1,9 +1,9 @@
package main
import "strconv"
import "io"
import "strconv"
func init() {
ctemplates["forum"] = template_forum
template_forum_handle = template_forum
}
func template_forum(tmpl_forum_vars Page, w io.Writer) {
@ -83,20 +83,14 @@ w.Write([]byte(`<span class="username topic_status_e topic_status_open" style="f
}
w.Write([]byte(`
<span class="username" style="border-right: 0;float: right;">Status</span>
</div>`))
</div>
`))
}
} else {
w.Write([]byte(`<div class="rowitem passive">There aren't any topics in this forum yet.</div>`))
}
w.Write([]byte(`
</div>
`))
if tmpl_forum_vars.Something.(string) != "" {
w.Write([]byte(`
<div class="rowblock">
<div class="rowitem passive">` + tmpl_forum_vars.Something.(string) + `</div>
</div>
`))
}
w.Write([]byte(`
<!--<link rel="stylesheet" href="https://use.fontawesome.com/8670aa03ca.css">-->
</div>
</body>

View File

@ -3,7 +3,7 @@ import "io"
import "strconv"
func init() {
ctemplates["forums"] = template_forums
template_forums_handle = template_forums
}
func template_forums(tmpl_forums_vars Page, w io.Writer) {
@ -66,8 +66,11 @@ for _, item := range tmpl_forums_vars.ItemList {
w.Write([]byte(`<div class="rowitem">
<a href="/forum/` + strconv.Itoa(item.(Forum).ID) + `" style="font-size: 20px;position:relative;top: -2px;font-weight: normal;text-transform: none;">` + item.(Forum).Name + `</a>
<a href="/topic/` + strconv.Itoa(item.(Forum).LastTopicID) + `" style="font-weight: normal;text-transform: none;float: right;">` + item.(Forum).LastTopic + ` <small style="font-size: 12px;">` + item.(Forum).LastTopicTime + `</small></a>
</div>`))
</div>
`))
}
} else {
w.Write([]byte(`<div class="rowitem passive">You don't have access to any forums.</div>`))
}
w.Write([]byte(`
</div>

View File

@ -1,148 +0,0 @@
package main
import "io"
import "strconv"
func init() {
ctemplates["profile"] = template_profile
}
func template_profile(tmpl_profile_vars Page, w io.Writer) {
var extra_data User = tmpl_profile_vars.Something.(User)
w.Write([]byte(`<!doctype html>
<html lang="en">
<head>
<title>` + tmpl_profile_vars.Title + `</title>
<link href="/static/main.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/static/jquery-1.12.3.min.js"></script>
<script type="text/javascript">
var session = "` + tmpl_profile_vars.CurrentUser.Session + `";
</script>
<script type="text/javascript" src="/static/global.js"></script>
</head>
<body>
<div class="container">
<div class="nav">
<div class="move_left">
<div class="move_right">
<ul>
<li class="menu_left menu_overview"><a href="/">Overview</a></li>
<li class="menu_left menu_forums"><a href="/forums/">Forums</a></li>
<li class="menu_left menu_topics"><a href="/">Topics</a></li>
<li class="menu_left menu_create_topic"><a href="/topics/create/">Create Topic</a></li>
`))
if tmpl_profile_vars.CurrentUser.Loggedin {
w.Write([]byte(`
<li class="menu_left menu_account"><a href="/user/edit/critical/">Account</a></li>
<li class="menu_left menu_account"><a href="/user/` + strconv.Itoa(tmpl_profile_vars.CurrentUser.ID) + `">Profile</a></li>
`))
if tmpl_profile_vars.CurrentUser.Is_Super_Mod {
w.Write([]byte(`<li class="menu_left menu_account"><a href="/panel/forums/">Panel</a></li>`))
}
w.Write([]byte(`
<li class="menu_left menu_logout"><a href="/accounts/logout?session=` + tmpl_profile_vars.CurrentUser.Session + `">Logout</a></li>
`))
} else {
w.Write([]byte(`
<li class="menu_left menu_register"><a href="/accounts/create/">Register</a></li>
<li class="menu_left menu_login"><a href="/accounts/login/">Login</a></li>
`))
}
w.Write([]byte(`
</ul>
</div>
</div>
<div style="clear: both;"></div>
</div>
`))
if len(tmpl_profile_vars.NoticeList) != 0 {
for _, item := range tmpl_profile_vars.NoticeList {
w.Write([]byte(`<div class="alert">` + item + `</div>`))
}
}
w.Write([]byte(`
<div class="colblock_left" style="max-width: 220px;">
<div class="rowitem" style="padding: 0;"><img src="` + extra_data.Avatar + `" style="max-width: 100%;margin: 0;"/></div>
<div class="rowitem" style="text-transform: capitalize;">
<span style="font-size: 18px;">` + extra_data.Name + `</span>`))
if extra_data.Tag != "" {
w.Write([]byte(`<span class="username" style="float: right;">` + extra_data.Tag + `</span>`))
}
w.Write([]byte(`
</div>
<div class="rowitem passive">
<a class="username">Add Friend</a>
`))
if tmpl_profile_vars.CurrentUser.Is_Super_Mod && !extra_data.Is_Super_Mod {
w.Write([]byte(`
`))
if extra_data.Is_Banned {
w.Write([]byte(`<a href="/users/unban/` + strconv.Itoa(extra_data.ID) + `" class="username">Unban</a>`))
} else {
w.Write([]byte(`<a href="/users/ban/` + strconv.Itoa(extra_data.ID) + `" class="username">Ban</a>`))
}
w.Write([]byte(`
`))
}
w.Write([]byte(`
<a href="/report/submit/` + strconv.Itoa(extra_data.ID) + `?session=` + tmpl_profile_vars.CurrentUser.Session + `&type=user" class="username report_item">Report</a>
</div>
</div>
<div class="colblock_right">
<div class="rowitem"><a>Comments</a></div>
</div>
<div class="colblock_right" style="overflow: hidden;">
`))
if len(tmpl_profile_vars.ItemList) != 0 {
for _, item := range tmpl_profile_vars.ItemList {
w.Write([]byte(`
<div class="rowitem passive deletable_block editable_parent" style="`))
if item.(Reply).Avatar != "" {
w.Write([]byte(`background-image: url(` + item.(Reply).Avatar + `), url(/static/white-dot.jpg);background-position: 0px `))
if item.(Reply).ContentLines <= 5 {
w.Write([]byte(`-1`))
}
w.Write([]byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;` + string(item.(Reply).Css)))
}
w.Write([]byte(`">
<span class="editable_block user_content">` + string(item.(Reply).ContentHtml) + `</span>
<br /><br />
<a href="/user/` + strconv.Itoa(item.(Reply).CreatedBy) + `" class="username">` + item.(Reply).CreatedByName + `</a>
`))
if tmpl_profile_vars.CurrentUser.Is_Mod {
w.Write([]byte(`<a href="/profile/reply/edit/submit/` + strconv.Itoa(item.(Reply).ID) + `"><button class="username edit_item">Edit</button></a>
<a href="/profile/reply/delete/submit/` + strconv.Itoa(item.(Reply).ID) + `"><button class="username delete_item">Delete</button></a>`))
}
w.Write([]byte(`
<a href="/report/submit/` + strconv.Itoa(item.(Reply).ID) + `?session=` + tmpl_profile_vars.CurrentUser.Session + `&type=user-reply"><button class="username report_item">Report</button></a>
`))
if item.(Reply).Tag != "" {
w.Write([]byte(`<a class="username" style="float: right;">` + item.(Reply).Tag + `</a>`))
}
w.Write([]byte(`
</div>`))
}
}
w.Write([]byte(`
</div>
`))
if !tmpl_profile_vars.CurrentUser.Is_Banned {
w.Write([]byte(`
<div class="colblock_right">
<form action="/profile/reply/create/" method="post">
<input name="uid" value='` + strconv.Itoa(extra_data.ID) + `' type="hidden" />
<div class="formrow">
<div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div>
</div>
<div class="formrow">
<div class="formitem"><button name="reply-button" class="formbutton">Create Reply</button></div>
</div>
</form>
</div>
`))
}
w.Write([]byte(`
<!--<link rel="stylesheet" href="https://use.fontawesome.com/8670aa03ca.css">-->
</div>
</body>
</html>`))
}

View File

@ -4,11 +4,10 @@ import "strconv"
import "html/template"
func init() {
ctemplates["topic"] = template_topic
template_topic_handle = template_topic
}
func template_topic(tmpl_topic_vars Page, w io.Writer) {
var extra_data TopicUser = tmpl_topic_vars.Something.(TopicUser)
func template_topic(tmpl_topic_vars TopicPage, w io.Writer) {
w.Write([]byte(`<!doctype html>
<html lang="en">
<head>
@ -62,29 +61,29 @@ w.Write([]byte(`<div class="alert">` + item + `</div>`))
}
w.Write([]byte(`
<div class="rowblock">
<form action='/topic/edit/submit/` + strconv.Itoa(extra_data.ID) + `' method="post">
<form action='/topic/edit/submit/` + strconv.Itoa(tmpl_topic_vars.Topic.ID) + `' method="post">
<div class="rowitem"`))
if extra_data.Sticky {
if tmpl_topic_vars.Topic.Sticky {
w.Write([]byte(` style="background-color: #FFFFEA;"`))
}
w.Write([]byte(`>
<a class='topic_name hide_on_edit'>` + extra_data.Title + `</a>
<span class='username topic_status_e topic_status_` + extra_data.Status + ` hide_on_edit' style="font-weight:normal;float: right;">` + extra_data.Status + `</span>
<a class='topic_name hide_on_edit'>` + tmpl_topic_vars.Topic.Title + `</a>
<span class='username topic_status_e topic_status_` + tmpl_topic_vars.Topic.Status + ` hide_on_edit' style="font-weight:normal;float: right;">` + tmpl_topic_vars.Topic.Status + `</span>
<span class="username" style="border-right: 0;font-weight: normal;float: right;">Status</span>
`))
if tmpl_topic_vars.CurrentUser.Is_Mod {
w.Write([]byte(`
<a href='/topic/edit/` + strconv.Itoa(extra_data.ID) + `' class="username hide_on_edit open_edit" style="font-weight: normal;margin-left: 6px;">Edit</a>
<a href='/topic/delete/submit/` + strconv.Itoa(extra_data.ID) + `' class="username" style="font-weight: normal;">Delete</a>
<a href='/topic/edit/` + strconv.Itoa(tmpl_topic_vars.Topic.ID) + `' class="username hide_on_edit open_edit" style="font-weight: normal;margin-left: 6px;">Edit</a>
<a href='/topic/delete/submit/` + strconv.Itoa(tmpl_topic_vars.Topic.ID) + `' class="username" style="font-weight: normal;">Delete</a>
`))
if extra_data.Sticky {
w.Write([]byte(`<a href='/topic/unstick/submit/` + strconv.Itoa(extra_data.ID) + `' class="username" style="font-weight: normal;">Unpin</a>`))
if tmpl_topic_vars.Topic.Sticky {
w.Write([]byte(`<a href='/topic/unstick/submit/` + strconv.Itoa(tmpl_topic_vars.Topic.ID) + `' class="username" style="font-weight: normal;">Unpin</a>`))
} else {
w.Write([]byte(`<a href='/topic/stick/submit/` + strconv.Itoa(extra_data.ID) + `' class="username" style="font-weight: normal;">Pin</a>`))
w.Write([]byte(`<a href='/topic/stick/submit/` + strconv.Itoa(tmpl_topic_vars.Topic.ID) + `' class="username" style="font-weight: normal;">Pin</a>`))
}
w.Write([]byte(`
<input class='show_on_edit topic_name_input' name="topic_name" value='` + extra_data.Title + `' type="text" />
<input class='show_on_edit topic_name_input' name="topic_name" value='` + tmpl_topic_vars.Topic.Title + `' type="text" />
<select name="topic_status" class='show_on_edit topic_status_input' style='float: right;'>
<option>open</option>
<option>closed</option>
@ -93,31 +92,31 @@ w.Write([]byte(`
`))
}
w.Write([]byte(`
<a href="/report/submit/` + strconv.Itoa(extra_data.ID) + `?session=` + tmpl_topic_vars.CurrentUser.Session + `&type=topic" class="username report_item" style="font-weight: normal;">Report</a>
<a href="/report/submit/` + strconv.Itoa(tmpl_topic_vars.Topic.ID) + `?session=` + tmpl_topic_vars.CurrentUser.Session + `&type=topic" class="username report_item" style="font-weight: normal;">Report</a>
</div>
</form>
</div>
<div class="rowblock">
<div class="rowitem passive editable_parent" style="border-bottom: none;`))
if extra_data.Avatar != "" {
w.Write([]byte(`background-image: url(` + extra_data.Avatar + `), url(/static/white-dot.jpg);background-position: 0px `))
if extra_data.ContentLines <= 5 {
if tmpl_topic_vars.Topic.Avatar != "" {
w.Write([]byte(`background-image: url(` + tmpl_topic_vars.Topic.Avatar + `), url(/static/white-dot.jpg);background-position: 0px `))
if tmpl_topic_vars.Topic.ContentLines <= 5 {
w.Write([]byte(`-1`))
}
w.Write([]byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;` + string(extra_data.Css)))
w.Write([]byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;` + string(tmpl_topic_vars.Topic.Css)))
}
w.Write([]byte(`">
<span class="hide_on_edit topic_content user_content">` + string(extra_data.Content.(template.HTML)) + `</span>
<textarea name="topic_content" class="show_on_edit topic_content_input">` + string(extra_data.Content.(template.HTML)) + `</textarea>
<span class="hide_on_edit topic_content user_content">` + string(tmpl_topic_vars.Topic.Content.(template.HTML)) + `</span>
<textarea name="topic_content" class="show_on_edit topic_content_input">` + string(tmpl_topic_vars.Topic.Content.(template.HTML)) + `</textarea>
<br /><br />
<a href="/user/` + strconv.Itoa(extra_data.CreatedBy) + `" class="username">` + extra_data.CreatedByName + `</a>
<a href="/user/` + strconv.Itoa(tmpl_topic_vars.Topic.CreatedBy) + `" class="username">` + tmpl_topic_vars.Topic.CreatedByName + `</a>
`))
if extra_data.Tag != "" {
w.Write([]byte(`<a class="username" style="float: right;">` + extra_data.Tag + `</a>`))
if tmpl_topic_vars.Topic.Tag != "" {
w.Write([]byte(`<a class="username" style="float: right;">` + tmpl_topic_vars.Topic.Tag + `</a>`))
} else {
if extra_data.URLName != "" {
w.Write([]byte(`<a href="` + extra_data.URL + `" class="username" style="color: #505050;float: right;">` + extra_data.URLName + `</a>
<a class="username" style="color: #505050;float: right;border-right: 0;">` + extra_data.URLPrefix + `</a>`))
if tmpl_topic_vars.Topic.URLName != "" {
w.Write([]byte(`<a href="` + tmpl_topic_vars.Topic.URL + `" class="username" style="color: #505050;float: right;">` + tmpl_topic_vars.Topic.URLName + `</a>
<a class="username" style="color: #505050;float: right;border-right: 0;">` + tmpl_topic_vars.Topic.URLPrefix + `</a>`))
}
}
w.Write([]byte(`
@ -129,31 +128,35 @@ if len(tmpl_topic_vars.ItemList) != 0 {
for _, item := range tmpl_topic_vars.ItemList {
w.Write([]byte(`
<div class="rowitem passive deletable_block editable_parent" style="`))
if item.(Reply).Avatar != "" {
w.Write([]byte(`background-image: url(` + item.(Reply).Avatar + `), url(/static/white-dot.jpg);background-position: 0px `))
if item.(Reply).ContentLines <= 5 {
if item.Avatar != "" {
w.Write([]byte(`background-image: url(` + item.Avatar + `), url(/static/white-dot.jpg);background-position: 0px `))
if item.ContentLines <= 5 {
w.Write([]byte(`-1`))
}
w.Write([]byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;` + string(item.(Reply).Css)))
w.Write([]byte(`0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;` + string(item.Css)))
}
w.Write([]byte(`">
<span class="editable_block user_content">` + string(item.(Reply).ContentHtml) + `</span>
<span class="editable_block user_content">` + string(item.ContentHtml) + `</span>
<br /><br />
<a href="/user/` + strconv.Itoa(item.(Reply).CreatedBy) + `" class="username">` + item.(Reply).CreatedByName + `</a>
<a href="/user/` + strconv.Itoa(item.CreatedBy) + `" class="username">` + item.CreatedByName + `</a>
`))
if tmpl_topic_vars.CurrentUser.Is_Mod {
w.Write([]byte(`<a href="/reply/edit/submit/` + strconv.Itoa(item.(Reply).ID) + `"><button class="username edit_item">Edit</button></a>
<a href="/reply/delete/submit/` + strconv.Itoa(item.(Reply).ID) + `"><button class="username delete_item">Delete</button></a>`))
if tmpl_topic_vars.CurrentUser.Perms.EditReply {
w.Write([]byte(`<a href="/reply/edit/submit/` + strconv.Itoa(item.ID) + `"><button class="username edit_item">Edit</button></a>`))
}
w.Write([]byte(`
<a href="/report/submit/` + strconv.Itoa(item.(Reply).ID) + `?session=` + tmpl_topic_vars.CurrentUser.Session + `&type=reply"><button class="username report_item">Report</button></a>
`))
if item.(Reply).Tag != "" {
w.Write([]byte(`<a class="username" style="float: right;">` + item.(Reply).Tag + `</a>`))
if tmpl_topic_vars.CurrentUser.Perms.DeleteReply {
w.Write([]byte(`<a href="/reply/delete/submit/` + strconv.Itoa(item.ID) + `"><button class="username delete_item">Delete</button></a>`))
}
w.Write([]byte(`
<a href="/report/submit/` + strconv.Itoa(item.ID) + `?session=` + tmpl_topic_vars.CurrentUser.Session + `&type=reply"><button class="username report_item">Report</button></a>
`))
if item.Tag != "" {
w.Write([]byte(`<a class="username" style="float: right;">` + item.Tag + `</a>`))
} else {
if item.(Reply).URLName != "" {
w.Write([]byte(`<a href="` + item.(Reply).URL + `" class="username" style="color: #505050;float: right;" rel="nofollow">` + item.(Reply).URLName + `</a>
<a class="username" style="color: #505050;float: right;border-right: 0;">` + item.(Reply).URLPrefix + `</a>`))
if item.URLName != "" {
w.Write([]byte(`<a href="` + item.URL + `" class="username" style="color: #505050;float: right;" rel="nofollow">` + item.URLName + `</a>
<a class="username" style="color: #505050;float: right;border-right: 0;">` + item.URLPrefix + `</a>`))
}
}
w.Write([]byte(`
@ -163,11 +166,11 @@ w.Write([]byte(`
w.Write([]byte(`
</div>
`))
if !tmpl_topic_vars.CurrentUser.Is_Banned && tmpl_topic_vars.CurrentUser.Loggedin {
if tmpl_topic_vars.CurrentUser.Perms.CreateReply {
w.Write([]byte(`
<div class="rowblock">
<form action="/reply/create/" method="post">
<input name="tid" value='` + strconv.Itoa(extra_data.ID) + `' type="hidden" />
<input name="tid" value='` + strconv.Itoa(tmpl_topic_vars.Topic.ID) + `' type="hidden" />
<div class="formrow">
<div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div>
</div>

View File

@ -3,11 +3,11 @@ import "io"
import "strconv"
import "html/template"
func init() {
/*func init() {
ctemplates["topic"] = template_topic
}
}*/
func template_topic_maploop(tmpl_topic_vars Page2, w io.Writer) {
func template_topic_2(tmpl_topic_vars Page, w io.Writer) {
var extra_data TopicUser = tmpl_topic_vars.Something.(TopicUser)
w.Write([]byte(`<!doctype html>
<html lang="en">

View File

@ -3,7 +3,7 @@ import "io"
import "strconv"
func init() {
ctemplates["topics"] = template_topics
template_topics_handle = template_topics
}
func template_topics(tmpl_topics_vars Page, w io.Writer) {
@ -83,20 +83,14 @@ w.Write([]byte(`<span class="username topic_status_e topic_status_open" style="f
}
w.Write([]byte(`
<span class="username" style="border-right: 0;float: right;">Status</span>
</div>`))
</div>
`))
}
} else {
w.Write([]byte(`<div class="rowitem passive">There aren't any topics yet.</div>`))
}
w.Write([]byte(`
</div>
`))
if tmpl_topics_vars.Something.(string) != "" {
w.Write([]byte(`
<div class="rowblock">
<div class="rowitem passive">` + tmpl_topics_vars.Something.(string) + `</div>
</div>
`))
}
w.Write([]byte(`
<!--<link rel="stylesheet" href="https://use.fontawesome.com/8670aa03ca.css">-->
</div>
</body>

View File

@ -126,7 +126,7 @@ func (c *CTemplateSet) compile_template(name string, dir string, expects string,
varString += "var " + varItem.Name + " " + varItem.Type + " = " + varItem.Destination + "\n"
}
out = "package main\n" + importList + c.pVarList + "\nfunc init() {\nctemplates[\"" + fname + "\"] = template_" + fname + "\n}\n\nfunc template_" + fname + "(tmpl_" + fname + "_vars " + expects + ", w io.Writer) {\n" + varString + out + "}\n"
out = "package main\n" + importList + c.pVarList + "\nfunc init() {\ntemplate_" + fname +"_handle = template_" + fname + "\n}\n\nfunc template_" + fname + "(tmpl_" + fname + "_vars " + expects + ", w io.Writer) {\n" + varString + out + "}\n"
out = strings.Replace(out,`))
w.Write([]byte(`," + ",-1)
@ -224,7 +224,11 @@ func (c *CTemplateSet) compile_switch(varholder string, holdreflect reflect.Valu
item = outVal.MapIndex(key)
}
out = "if len(" + out + ") != 0 {\nfor _, item := range " + out + " {\n" + c.compile_switch("item", item, template_name, node.List) + "}\n}"
if node.ElseList != nil {
out = "if len(" + out + ") != 0 {\nfor _, item := range " + out + " {\n" + c.compile_switch("item", item, template_name, node.List) + "}\n} else {\n" + c.compile_switch("item", item, template_name, node.ElseList) + "}\n"
} else {
out = "if len(" + out + ") != 0 {\nfor _, item := range " + out + " {\n" + c.compile_switch("item", item, template_name, node.List) + "}\n}"
}
case reflect.Slice:
item := outVal.Index(0)

View File

@ -7,11 +7,7 @@
<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>
{{else}}<div class="rowitem passive">There aren't any topics in this forum yet.</div>{{end}}
</div>
{{if .Something}}
<div class="rowblock">
<div class="rowitem passive">{{.Something}}</div>
</div>
{{end}}
{{template "footer.html" . }}

View File

@ -3,6 +3,7 @@
{{range .ItemList}}<div class="rowitem">
<a href="/forum/{{.ID}}" style="font-size: 20px;position:relative;top: -2px;font-weight: normal;text-transform: none;">{{.Name}}</a>
<a href="/topic/{{.LastTopicID}}" style="font-weight: normal;text-transform: none;float: right;">{{.LastTopic}} <small style="font-size: 12px;">{{.LastTopicTime}}</small></a>
</div>{{end}}
</div>
{{else}}<div class="rowitem passive">You don't have access to any forums.</div>{{end}}
</div>
{{template "footer.html" . }}

View File

@ -20,7 +20,16 @@
<div class="formitem"><a>Setting Name</a></div>
<div class="formitem">{{.Something.Name}}</div>
</div>
{{if eq .Something.Type "bool"}}
{{if eq .Something.Type "list"}}
<div class="formrow">
<div class="formitem"><a>Setting Value</a></div>
<div class="formitem">
<select name="setting-value">
{{range .ItemList}}<option{{if .Selected}} selected{{end}} value="{{.Value}}">{{.Label}}</option>{{end}}
</select>
</div>
</div>
{{else if eq .Something.Type "bool"}}
<div class="formrow">
<div class="formitem"><a>Setting Value</a></div>
<div class="formitem"><input name="setting-value" type="checkbox"{{if eq .Something.Content "1"}} checked{{end}} /></div>

View File

@ -16,9 +16,9 @@
</div>
<div class="colblock_right">
{{ range $key, $value := .Something }}
<div class="rowitem editable_parent" style="font-weight: normal;">
<a href="/panel/settings/edit/{{$key}}" class="editable_block" style="font-size: 20px;position:relative;top: -2px;text-transform: none;">{{$key}}</a>
<a style="float: right;text-transform: lowercase;">{{$value}}</a>
<div class="rowitem editable_parent" style="font-weight: normal;text-transform: none;">
<a href="/panel/settings/edit/{{$key}}" class="editable_block" style="font-size: 20px;position:relative;top: -2px;">{{$key}}</a>
<a style="float: right;">{{$value}}</a>
</div>
{{end}}
</div>

View File

@ -17,7 +17,8 @@
<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>
<a href="/panel/users/edit/{{.ID}}?session={{$.CurrentUser.Session}}" class="editable_block" style="font-size: 20px;position:relative;top: -2px;">{{.Name}}</a>
<a href="/user/{{.ID}}" class="tag-mini" style="margin-left: 3px;position: relative;top:-5px;color: #505050;">Profile</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}}

View File

@ -2,7 +2,7 @@
<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="text-transform: capitalize;">
<span style="font-size: 18px;">{{.Something.Name}}</span>{{if .Something.Tag}}<span class="username" style="float: right;">{{.Something.Tag}}</span>{{end}}
<span style="font-size: 18px;">{{.Something.Name}}</span>{{if .Something.Tag}}<span class="username" style="float: right;font-weight: normal;">{{.Something.Tag}}</span>{{end}}
</div>
<div class="rowitem passive">
<a class="username">Add Friend</a>

View File

@ -1,34 +1,34 @@
{{template "header.html" . }}
<div class="rowblock">
<form action='/topic/edit/submit/{{.Something.ID}}' method="post">
<div class="rowitem"{{ if .Something.Sticky }} style="background-color: #FFFFEA;"{{end}}>
<a class='topic_name hide_on_edit'>{{.Something.Title}}</a>
<span class='username topic_status_e topic_status_{{.Something.Status}} hide_on_edit' style="font-weight:normal;float: right;">{{.Something.Status}}</span>
<form action='/topic/edit/submit/{{.Topic.ID}}' method="post">
<div class="rowitem"{{ if .Topic.Sticky }} style="background-color: #FFFFEA;"{{end}}>
<a class='topic_name hide_on_edit'>{{.Topic.Title}}</a>
<span class='username topic_status_e topic_status_{{.Topic.Status}} hide_on_edit' style="font-weight:normal;float: right;">{{.Topic.Status}}</span>
<span class="username" style="border-right: 0;font-weight: normal;float: right;">Status</span>
{{if .CurrentUser.Is_Mod}}
<a href='/topic/edit/{{.Something.ID}}' class="username hide_on_edit open_edit" style="font-weight: normal;margin-left: 6px;">Edit</a>
<a href='/topic/delete/submit/{{.Something.ID}}' class="username" style="font-weight: normal;">Delete</a>
{{ if .Something.Sticky }}<a href='/topic/unstick/submit/{{.Something.ID}}' class="username" style="font-weight: normal;">Unpin</a>{{else}}<a href='/topic/stick/submit/{{.Something.ID}}' class="username" style="font-weight: normal;">Pin</a>{{end}}
<a href='/topic/edit/{{.Topic.ID}}' class="username hide_on_edit open_edit" style="font-weight: normal;margin-left: 6px;">Edit</a>
<a href='/topic/delete/submit/{{.Topic.ID}}' class="username" style="font-weight: normal;">Delete</a>
{{ if .Topic.Sticky }}<a href='/topic/unstick/submit/{{.Topic.ID}}' class="username" style="font-weight: normal;">Unpin</a>{{else}}<a href='/topic/stick/submit/{{.Topic.ID}}' class="username" style="font-weight: normal;">Pin</a>{{end}}
<input class='show_on_edit topic_name_input' name="topic_name" value='{{.Something.Title}}' type="text" />
<input class='show_on_edit topic_name_input' name="topic_name" value='{{.Topic.Title}}' type="text" />
<select name="topic_status" class='show_on_edit topic_status_input' style='float: right;'>
<option>open</option>
<option>closed</option>
</select>
<button name="topic-button" class="formbutton show_on_edit submit_edit">Update</button>
{{end}}
<a href="/report/submit/{{.Something.ID}}?session={{.CurrentUser.Session}}&type=topic" class="username report_item" style="font-weight: normal;">Report</a>
<a href="/report/submit/{{.Topic.ID}}?session={{.CurrentUser.Session}}&type=topic" class="username report_item" style="font-weight: normal;">Report</a>
</div>
</form>
</div>
<div class="rowblock">
<div class="rowitem passive editable_parent" style="border-bottom: none;{{ if .Something.Avatar }}background-image: url({{ .Something.Avatar }}), url(/static/white-dot.jpg);background-position: 0px {{if le .Something.ContentLines 5}}-1{{end}}0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;{{.Something.Css}}{{end}}">
<span class="hide_on_edit topic_content user_content">{{.Something.Content}}</span>
<textarea name="topic_content" class="show_on_edit topic_content_input">{{.Something.Content}}</textarea>
<div class="rowitem passive editable_parent" style="border-bottom: none;{{ if .Topic.Avatar }}background-image: url({{ .Topic.Avatar }}), url(/static/white-dot.jpg);background-position: 0px {{if le .Topic.ContentLines 5}}-1{{end}}0px;background-repeat: no-repeat, repeat-y;background-size: 128px;padding-left: 136px;{{.Topic.Css}}{{end}}">
<span class="hide_on_edit topic_content user_content">{{.Topic.Content}}</span>
<textarea name="topic_content" class="show_on_edit topic_content_input">{{.Topic.Content}}</textarea>
<br /><br />
<a href="/user/{{.Something.CreatedBy}}" class="username">{{.Something.CreatedByName}}</a>
{{if .Something.Tag}}<a class="username" style="float: right;">{{.Something.Tag}}</a>{{else if .Something.URLName}}<a href="{{.Something.URL}}" class="username" style="color: #505050;float: right;">{{.Something.URLName}}</a>
<a class="username" style="color: #505050;float: right;border-right: 0;">{{.Something.URLPrefix}}</a>{{end}}
<a href="/user/{{.Topic.CreatedBy}}" class="username">{{.Topic.CreatedByName}}</a>
{{if .Topic.Tag}}<a class="username" style="float: right;">{{.Topic.Tag}}</a>{{else if .Topic.URLName}}<a href="{{.Topic.URL}}" class="username" style="color: #505050;float: right;">{{.Topic.URLName}}</a>
<a class="username" style="color: #505050;float: right;border-right: 0;">{{.Topic.URLPrefix}}</a>{{end}}
</div>
</div><br />
<div class="rowblock" style="overflow: hidden;">
@ -37,17 +37,17 @@
<span class="editable_block user_content">{{.ContentHtml}}</span>
<br /><br />
<a href="/user/{{.CreatedBy}}" class="username">{{.CreatedByName}}</a>
{{if $.CurrentUser.Is_Mod}}<a href="/reply/edit/submit/{{.ID}}"><button class="username edit_item">Edit</button></a>
<a href="/reply/delete/submit/{{.ID}}"><button class="username delete_item">Delete</button></a>{{end}}
{{if $.CurrentUser.Perms.EditReply}}<a href="/reply/edit/submit/{{.ID}}"><button class="username edit_item">Edit</button></a>{{end}}
{{if $.CurrentUser.Perms.DeleteReply}}<a href="/reply/delete/submit/{{.ID}}"><button class="username delete_item">Delete</button></a>{{end}}
<a href="/report/submit/{{.ID}}?session={{$.CurrentUser.Session}}&type=reply"><button class="username report_item">Report</button></a>
{{if .Tag}}<a class="username" style="float: right;">{{.Tag}}</a>{{else if .URLName}}<a href="{{.URL}}" class="username" style="color: #505050;float: right;" rel="nofollow">{{.URLName}}</a>
<a class="username" style="color: #505050;float: right;border-right: 0;">{{.URLPrefix}}</a>{{end}}
</div>{{end}}
</div>
{{if not (.CurrentUser.Is_Banned) and (.CurrentUser.Loggedin)}}
{{if .CurrentUser.Perms.CreateReply}}
<div class="rowblock">
<form action="/reply/create/" method="post">
<input name="tid" value='{{.Something.ID}}' type="hidden" />
<input name="tid" value='{{.Topic.ID}}' type="hidden" />
<div class="formrow">
<div class="formitem"><textarea name="reply-content" placeholder="Insert reply here"></textarea></div>
</div>

View File

@ -7,11 +7,7 @@
<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>
{{else}}<div class="rowitem passive">There aren't any topics yet.</div>{{end}}
</div>
{{if .Something}}
<div class="rowblock">
<div class="rowitem passive">{{.Something}}</div>
</div>
{{end}}
{{template "footer.html" . }}

20
user.go
View File

@ -1,5 +1,4 @@
package main
//import "log"
import "strings"
import "strconv"
import "net/http"
@ -18,6 +17,7 @@ type User struct
Is_Admin bool
Is_Super_Admin bool
Is_Banned bool
Perms Perms
Session string
Loggedin bool
Avatar string
@ -53,15 +53,18 @@ func SessionCheck(w http.ResponseWriter, r *http.Request) (user User, noticeList
// Assign it to user.name to avoid having to create a temporary variable for the type conversion
cookie, err := r.Cookie("uid")
if err != nil {
user.Perms = GuestPerms
return user, noticeList, true
}
user.Name = cookie.Value
user.ID, err = strconv.Atoi(user.Name)
if err != nil {
user.Perms = GuestPerms
return user, noticeList, true
}
cookie, err = r.Cookie("session")
if err != nil {
user.Perms = GuestPerms
return user, noticeList, true
}
user.Session = cookie.Value
@ -84,6 +87,12 @@ func SessionCheck(w http.ResponseWriter, r *http.Request) (user User, noticeList
user.Is_Banned = false
}
if user.Is_Super_Admin {
user.Perms = AllPerms
} else {
user.Perms = groups[user.Group].Perms
}
if user.Is_Banned {
noticeList[0] = "Your account has been suspended. Some of your permissions may have been revoked."
}
@ -103,15 +112,18 @@ func SimpleSessionCheck(w http.ResponseWriter, r *http.Request) (user User, succ
// Assign it to user.name to avoid having to create a temporary variable for the type conversion
cookie, err := r.Cookie("uid")
if err != nil {
user.Perms = GuestPerms
return user, true
}
user.Name = cookie.Value
user.ID, err = strconv.Atoi(user.Name)
if err != nil {
user.Perms = GuestPerms
return user, true
}
cookie, err = r.Cookie("session")
if err != nil {
user.Perms = GuestPerms
return user, true
}
user.Session = cookie.Value
@ -134,6 +146,12 @@ func SimpleSessionCheck(w http.ResponseWriter, r *http.Request) (user User, succ
user.Is_Banned = false
}
if user.Is_Super_Admin {
user.Perms = AllPerms
} else {
user.Perms = groups[user.Group].Perms
}
if user.Avatar != "" {
if user.Avatar[0] == '.' {
user.Avatar = "/uploads/avatar_" + strconv.Itoa(user.ID) + user.Avatar