Fixed the Cosora Alerts CSS.

Fixed the topic edit input CSS.
You can now filter the time range of the routes list.
You can now filter the time range of the agents list.
Renamed operations.log to ops.log
Moved the account routes into the new router.
Log suspicious requests.
Removed some duplicated code in the control panel routes.
Fixed a bug in the User Editor where the Administrator group didn't show up.
Users are now force logged out when an admin changes their password.
This commit is contained in:
Azareal 2018-01-17 11:13:08 +00:00
parent cce87e2d70
commit 0416b1ed91
12 changed files with 215 additions and 79 deletions

View File

@ -182,6 +182,7 @@ type PanelAnalyticsRoutesPage struct {
Stats PanelStats Stats PanelStats
Zone string Zone string
ItemList []PanelAnalyticsRoutesItem ItemList []PanelAnalyticsRoutesItem
TimeRange string
} }
type PanelAnalyticsAgentsItem struct { type PanelAnalyticsAgentsItem struct {
@ -196,6 +197,7 @@ type PanelAnalyticsAgentsPage struct {
Stats PanelStats Stats PanelStats
Zone string Zone string
ItemList []PanelAnalyticsAgentsItem ItemList []PanelAnalyticsAgentsItem
TimeRange string
} }
type PanelAnalyticsRoutePage struct { type PanelAnalyticsRoutePage struct {

View File

@ -97,6 +97,11 @@ var RouteMap = map[string]interface{}{
"routeProfileReplyCreateSubmit": routeProfileReplyCreateSubmit, "routeProfileReplyCreateSubmit": routeProfileReplyCreateSubmit,
"routeProfileReplyEditSubmit": routeProfileReplyEditSubmit, "routeProfileReplyEditSubmit": routeProfileReplyEditSubmit,
"routeProfileReplyDeleteSubmit": routeProfileReplyDeleteSubmit, "routeProfileReplyDeleteSubmit": routeProfileReplyDeleteSubmit,
"routeLogin": routeLogin,
"routeRegister": routeRegister,
"routeLogout": routeLogout,
"routeLoginSubmit": routeLoginSubmit,
"routeRegisterSubmit": routeRegisterSubmit,
"routeDynamic": routeDynamic, "routeDynamic": routeDynamic,
"routeUploads": routeUploads, "routeUploads": routeUploads,
} }
@ -185,8 +190,13 @@ var routeMapEnum = map[string]int{
"routeProfileReplyCreateSubmit": 79, "routeProfileReplyCreateSubmit": 79,
"routeProfileReplyEditSubmit": 80, "routeProfileReplyEditSubmit": 80,
"routeProfileReplyDeleteSubmit": 81, "routeProfileReplyDeleteSubmit": 81,
"routeDynamic": 82, "routeLogin": 82,
"routeUploads": 83, "routeRegister": 83,
"routeLogout": 84,
"routeLoginSubmit": 85,
"routeRegisterSubmit": 86,
"routeDynamic": 87,
"routeUploads": 88,
} }
var reverseRouteMapEnum = map[int]string{ var reverseRouteMapEnum = map[int]string{
0: "routeAPI", 0: "routeAPI",
@ -271,8 +281,13 @@ var reverseRouteMapEnum = map[int]string{
79: "routeProfileReplyCreateSubmit", 79: "routeProfileReplyCreateSubmit",
80: "routeProfileReplyEditSubmit", 80: "routeProfileReplyEditSubmit",
81: "routeProfileReplyDeleteSubmit", 81: "routeProfileReplyDeleteSubmit",
82: "routeDynamic", 82: "routeLogin",
83: "routeUploads", 83: "routeRegister",
84: "routeLogout",
85: "routeLoginSubmit",
86: "routeRegisterSubmit",
87: "routeDynamic",
88: "routeUploads",
} }
var agentMapEnum = map[string]int{ var agentMapEnum = map[string]int{
"unknown": 0, "unknown": 0,
@ -379,6 +394,19 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
var prefix, extraData string var prefix, extraData string
prefix = req.URL.Path[0:strings.IndexByte(req.URL.Path[1:],'/') + 1] prefix = req.URL.Path[0:strings.IndexByte(req.URL.Path[1:],'/') + 1]
if req.URL.Path[len(req.URL.Path) - 1] != '/' { if req.URL.Path[len(req.URL.Path) - 1] != '/' {
// TODO: Cover more suspicious strings and at a lower layer than this and more efficiently
if strings.Contains(req.URL.Path,"'") || strings.Contains(req.URL.Path,";") || strings.Contains(req.URL.Path,"\"") || strings.Contains(req.URL.Path,"`") || strings.Contains(req.URL.Path,"%") {
log.Print("Suspicious UA: ", req.UserAgent())
log.Print("Method: ", req.Method)
for key, value := range req.Header {
for _, vvalue := range value {
log.Print("Header '" + key + "': " + vvalue + "!!")
}
}
log.Print("req.URL.Path: ", req.URL.Path)
log.Print("req.Referer(): ", req.Referer())
log.Print("req.RemoteAddr: ", req.RemoteAddr)
}
extraData = req.URL.Path[strings.LastIndexByte(req.URL.Path,'/') + 1:] extraData = req.URL.Path[strings.LastIndexByte(req.URL.Path,'/') + 1:]
req.URL.Path = req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/') + 1] req.URL.Path = req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/') + 1]
} }
@ -775,9 +803,21 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
common.RouteViewCounter.Bump(36) common.RouteViewCounter.Bump(36)
err = routePanelAnalyticsViews(w,req,user) err = routePanelAnalyticsViews(w,req,user)
case "/panel/analytics/routes/": case "/panel/analytics/routes/":
err = common.ParseForm(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
common.RouteViewCounter.Bump(37) common.RouteViewCounter.Bump(37)
err = routePanelAnalyticsRoutes(w,req,user) err = routePanelAnalyticsRoutes(w,req,user)
case "/panel/analytics/agents/": case "/panel/analytics/agents/":
err = common.ParseForm(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
common.RouteViewCounter.Bump(38) common.RouteViewCounter.Bump(38)
err = routePanelAnalyticsAgents(w,req,user) err = routePanelAnalyticsAgents(w,req,user)
case "/panel/analytics/route/": case "/panel/analytics/route/":
@ -1298,6 +1338,51 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
if err != nil { if err != nil {
router.handleError(err,w,req,user) router.handleError(err,w,req,user)
} }
case "/accounts":
switch(req.URL.Path) {
case "/accounts/login/":
common.RouteViewCounter.Bump(82)
err = routeLogin(w,req,user)
case "/accounts/create/":
common.RouteViewCounter.Bump(83)
err = routeRegister(w,req,user)
case "/accounts/logout/":
err = common.NoSessionMismatch(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
err = common.MemberOnly(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
common.RouteViewCounter.Bump(84)
err = routeLogout(w,req,user)
case "/accounts/login/submit/":
err = common.ParseForm(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
common.RouteViewCounter.Bump(85)
err = routeLoginSubmit(w,req,user)
case "/accounts/create/submit/":
err = common.ParseForm(w,req,user)
if err != nil {
router.handleError(err,w,req,user)
return
}
common.RouteViewCounter.Bump(86)
err = routeRegisterSubmit(w,req,user)
}
if err != nil {
router.handleError(err,w,req,user)
}
/*case "/sitemaps": // TODO: Count these views /*case "/sitemaps": // TODO: Count these views
req.URL.Path += extraData req.URL.Path += extraData
err = sitemapSwitch(w,req) err = sitemapSwitch(w,req)
@ -1309,7 +1394,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
common.NotFound(w,req) common.NotFound(w,req)
return return
} }
common.RouteViewCounter.Bump(83) common.RouteViewCounter.Bump(88)
req.URL.Path += extraData req.URL.Path += extraData
// TODO: Find a way to propagate errors up from this? // TODO: Find a way to propagate errors up from this?
router.UploadHandler(w,req) // TODO: Count these views router.UploadHandler(w,req) // TODO: Count these views
@ -1353,7 +1438,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
router.RUnlock() router.RUnlock()
if ok { if ok {
common.RouteViewCounter.Bump(82) // TODO: Be more specific about *which* dynamic route it is common.RouteViewCounter.Bump(87) // TODO: Be more specific about *which* dynamic route it is
req.URL.Path += extraData req.URL.Path += extraData
err = handle(w,req,user) err = handle(w,req,user)
if err != nil { if err != nil {

11
main.go
View File

@ -130,7 +130,7 @@ func main() {
// TODO: Have a file for each run with the time/date the server started as the file name? // TODO: Have a file for each run with the time/date the server started as the file name?
// TODO: Log panics with recover() // TODO: Log panics with recover()
f, err := os.OpenFile("./operations.log", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0755) f, err := os.OpenFile("./ops.log", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0755)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
@ -303,15 +303,6 @@ func main() {
// TODO: Move these routes into the new routes list // TODO: Move these routes into the new routes list
log.Print("Initialising the router") log.Print("Initialising the router")
router = NewGenRouter(http.FileServer(http.Dir("./uploads"))) router = NewGenRouter(http.FileServer(http.Dir("./uploads")))
// Accounts
router.HandleFunc("/accounts/login/", routeLogin)
router.HandleFunc("/accounts/create/", routeRegister)
router.HandleFunc("/accounts/logout/", routeLogout)
router.HandleFunc("/accounts/login/submit/", routeLoginSubmit)
router.HandleFunc("/accounts/create/submit/", routeRegisterSubmit)
//router.HandleFunc("/accounts/list/", routeLogin) // Redirect /accounts/ and /user/ to here.. // Get a list of all of the accounts on the forum
router.HandleFunc("/ws/", routeWebsockets) router.HandleFunc("/ws/", routeWebsockets)
log.Print("Initialising the plugins") log.Print("Initialising the plugins")

View File

@ -16,11 +16,25 @@ import (
"./common" "./common"
) )
// Experimenting
/*func memberRenderTemplate(tmplName string, themeName string, w http.ResponseWriter, r *http.Request, user common.User, pi interface{}) common.RouteError {
if common.PreRenderHooks["pre_render_"+tmplName] != nil {
if common.RunPreRenderHook("pre_render_"+tmplName, w, r, &user, pi) {
return nil
}
}
err := common.RunThemeTemplate(themeName, tmplName, pi, w)
if err != nil {
return common.InternalError(err, w, r)
}
return nil
}*/
// ? - Should we add a new permission or permission zone (like per-forum permissions) specifically for profile comment creation // ? - Should we add a new permission or permission zone (like per-forum permissions) specifically for profile comment creation
// ? - Should we allow banned users to make reports? How should we handle report abuse? // ? - Should we allow banned users to make reports? How should we handle report abuse?
// TODO: Add a permission to stop certain users from using custom avatars // TODO: Add a permission to stop certain users from using custom avatars
// ? - Log username changes and put restrictions on this? // ? - Log username changes and put restrictions on this?
func routeTopicCreate(w http.ResponseWriter, r *http.Request, user common.User, sfid string) common.RouteError { func routeTopicCreate(w http.ResponseWriter, r *http.Request, user common.User, sfid string) common.RouteError {
var fid int var fid int
var err error var err error

View File

@ -834,39 +834,9 @@ func routePanelAnalyticsPosts(w http.ResponseWriter, r *http.Request, user commo
headerVars.Stylesheets = append(headerVars.Stylesheets, "chartist/chartist.min.css") headerVars.Stylesheets = append(headerVars.Stylesheets, "chartist/chartist.min.css")
headerVars.Scripts = append(headerVars.Scripts, "chartist/chartist.min.js") headerVars.Scripts = append(headerVars.Scripts, "chartist/chartist.min.js")
var timeQuantity = 6 timeRange, err := panelAnalyticsTimeRange(r.FormValue("timeRange"))
var timeUnit = "hour" if err != nil {
var timeSlices = 12 return common.LocalError(err.Error(), w, r, user)
var sliceWidth = 60 * 30
var timeRange = "six-hours"
switch r.FormValue("timeRange") {
case "one-month":
timeQuantity = 30
timeUnit = "day"
timeSlices = 30
sliceWidth = 60 * 60 * 24
timeRange = "one-month"
case "two-days": // Two days is experimental
timeQuantity = 2
timeUnit = "day"
timeSlices = 24
sliceWidth = 60 * 60 * 2
timeRange = "two-days"
case "one-day":
timeQuantity = 1
timeUnit = "day"
timeSlices = 24
sliceWidth = 60 * 60
timeRange = "one-day"
case "twelve-hours":
timeQuantity = 12
timeSlices = 24
timeRange = "twelve-hours"
case "six-hours", "":
timeRange = "six-hours"
default:
return common.LocalError("Unknown time range", w, r, user)
} }
var revLabelList []int64 var revLabelList []int64
@ -874,8 +844,8 @@ func routePanelAnalyticsPosts(w http.ResponseWriter, r *http.Request, user commo
var viewMap = make(map[int64]int64) var viewMap = make(map[int64]int64)
var currentTime = time.Now().Unix() var currentTime = time.Now().Unix()
for i := 1; i <= timeSlices; i++ { for i := 1; i <= timeRange.Slices; i++ {
var label = currentTime - int64(i*sliceWidth) var label = currentTime - int64(i*timeRange.SliceWidth)
revLabelList = append(revLabelList, label) revLabelList = append(revLabelList, label)
viewMap[label] = 0 viewMap[label] = 0
} }
@ -887,7 +857,7 @@ func routePanelAnalyticsPosts(w http.ResponseWriter, r *http.Request, user commo
log.Print("in routePanelAnalyticsPosts") log.Print("in routePanelAnalyticsPosts")
acc := qgen.Builder.Accumulator() acc := qgen.Builder.Accumulator()
rows, err := acc.Select("postchunks").Columns("count, createdAt").DateCutoff("createdAt", timeQuantity, timeUnit).Query() rows, err := acc.Select("postchunks").Columns("count, createdAt").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
if err != nil && err != ErrNoRows { if err != nil && err != ErrNoRows {
return common.InternalError(err, w, r) return common.InternalError(err, w, r)
} }
@ -925,7 +895,7 @@ func routePanelAnalyticsPosts(w http.ResponseWriter, r *http.Request, user commo
graph := common.PanelTimeGraph{Series: viewList, Labels: labelList} graph := common.PanelTimeGraph{Series: viewList, Labels: labelList}
log.Printf("graph: %+v\n", graph) log.Printf("graph: %+v\n", graph)
pi := common.PanelAnalyticsPage{common.GetTitlePhrase("panel_analytics"), user, headerVars, stats, "analytics", graph, viewItems, timeRange} pi := common.PanelAnalyticsPage{common.GetTitlePhrase("panel_analytics"), user, headerVars, stats, "analytics", graph, viewItems, timeRange.Range}
return panelRenderTemplate("panel_analytics_posts", w, r, user, &pi) return panelRenderTemplate("panel_analytics_posts", w, r, user, &pi)
} }
@ -936,8 +906,13 @@ func routePanelAnalyticsRoutes(w http.ResponseWriter, r *http.Request, user comm
} }
var routeMap = make(map[string]int) var routeMap = make(map[string]int)
timeRange, err := panelAnalyticsTimeRange(r.FormValue("timeRange"))
if err != nil {
return common.LocalError(err.Error(), w, r, user)
}
acc := qgen.Builder.Accumulator() acc := qgen.Builder.Accumulator()
rows, err := acc.Select("viewchunks").Columns("count, route").Where("route != ''").DateCutoff("createdAt", 1, "day").Query() rows, err := acc.Select("viewchunks").Columns("count, route").Where("route != ''").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
if err != nil && err != ErrNoRows { if err != nil && err != ErrNoRows {
return common.InternalError(err, w, r) return common.InternalError(err, w, r)
} }
@ -969,7 +944,7 @@ func routePanelAnalyticsRoutes(w http.ResponseWriter, r *http.Request, user comm
}) })
} }
pi := common.PanelAnalyticsRoutesPage{common.GetTitlePhrase("panel_analytics"), user, headerVars, stats, "analytics", routeItems} pi := common.PanelAnalyticsRoutesPage{common.GetTitlePhrase("panel_analytics"), user, headerVars, stats, "analytics", routeItems, timeRange.Range}
return panelRenderTemplate("panel_analytics_routes", w, r, user, &pi) return panelRenderTemplate("panel_analytics_routes", w, r, user, &pi)
} }
@ -980,8 +955,13 @@ func routePanelAnalyticsAgents(w http.ResponseWriter, r *http.Request, user comm
} }
var agentMap = make(map[string]int) var agentMap = make(map[string]int)
timeRange, err := panelAnalyticsTimeRange(r.FormValue("timeRange"))
if err != nil {
return common.LocalError(err.Error(), w, r, user)
}
acc := qgen.Builder.Accumulator() acc := qgen.Builder.Accumulator()
rows, err := acc.Select("viewchunks_agents").Columns("count, browser").DateCutoff("createdAt", 1, "day").Query() rows, err := acc.Select("viewchunks_agents").Columns("count, browser").DateCutoff("createdAt", timeRange.Quantity, timeRange.Unit).Query()
if err != nil && err != ErrNoRows { if err != nil && err != ErrNoRows {
return common.InternalError(err, w, r) return common.InternalError(err, w, r)
} }
@ -1013,7 +993,7 @@ func routePanelAnalyticsAgents(w http.ResponseWriter, r *http.Request, user comm
}) })
} }
pi := common.PanelAnalyticsAgentsPage{common.GetTitlePhrase("panel_analytics"), user, headerVars, stats, "analytics", agentItems} pi := common.PanelAnalyticsAgentsPage{common.GetTitlePhrase("panel_analytics"), user, headerVars, stats, "analytics", agentItems, timeRange.Range}
return panelRenderTemplate("panel_analytics_agents", w, r, user, &pi) return panelRenderTemplate("panel_analytics_agents", w, r, user, &pi)
} }
@ -1505,7 +1485,7 @@ func routePanelUsersEdit(w http.ResponseWriter, r *http.Request, user common.Use
} }
var groupList []interface{} var groupList []interface{}
for _, group := range groups[1:] { for _, group := range groups {
if !user.Perms.EditUserGroupAdmin && group.IsAdmin { if !user.Perms.EditUserGroupAdmin && group.IsAdmin {
continue continue
} }
@ -1600,6 +1580,8 @@ func routePanelUsersEditSubmit(w http.ResponseWriter, r *http.Request, user comm
if newpassword != "" { if newpassword != "" {
common.SetPassword(targetUser.ID, newpassword) common.SetPassword(targetUser.ID, newpassword)
// Log the user out as a safety precaution
common.Auth.ForceLogout(targetUser.ID)
} }
targetUser.CacheRemove() targetUser.CacheRemove()

View File

@ -181,6 +181,7 @@ func main() {
for id, agent := range tmplVars.AllAgentNames { for id, agent := range tmplVars.AllAgentNames {
tmplVars.AllAgentMap[agent] = id tmplVars.AllAgentMap[agent] = id
} }
var graveSym = "`"
var fileData = `// Code generated by. DO NOT EDIT. var fileData = `// Code generated by. DO NOT EDIT.
/* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */ /* This file was automatically generated by the software. Please don't edit it as your changes may be overwritten at any moment. */
@ -284,6 +285,19 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
var prefix, extraData string var prefix, extraData string
prefix = req.URL.Path[0:strings.IndexByte(req.URL.Path[1:],'/') + 1] prefix = req.URL.Path[0:strings.IndexByte(req.URL.Path[1:],'/') + 1]
if req.URL.Path[len(req.URL.Path) - 1] != '/' { if req.URL.Path[len(req.URL.Path) - 1] != '/' {
// TODO: Cover more suspicious strings and at a lower layer than this and more efficiently
if strings.Contains(req.URL.Path,"'") || strings.Contains(req.URL.Path,";") || strings.Contains(req.URL.Path,"\"") || strings.Contains(req.URL.Path,"` + graveSym + `") || strings.Contains(req.URL.Path,"%") {
log.Print("Suspicious UA: ", req.UserAgent())
log.Print("Method: ", req.Method)
for key, value := range req.Header {
for _, vvalue := range value {
log.Print("Header '" + key + "': " + vvalue + "!!")
}
}
log.Print("req.URL.Path: ", req.URL.Path)
log.Print("req.Referer(): ", req.Referer())
log.Print("req.RemoteAddr: ", req.RemoteAddr)
}
extraData = req.URL.Path[strings.LastIndexByte(req.URL.Path,'/') + 1:] extraData = req.URL.Path[strings.LastIndexByte(req.URL.Path,'/') + 1:]
req.URL.Path = req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/') + 1] req.URL.Path = req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/') + 1]
} }

View File

@ -29,6 +29,7 @@ func routes() {
buildTopicRoutes() buildTopicRoutes()
buildReplyRoutes() buildReplyRoutes()
buildProfileReplyRoutes() buildProfileReplyRoutes()
buildAccountRoutes()
} }
// TODO: Test the email token route // TODO: Test the email token route
@ -101,6 +102,19 @@ func buildProfileReplyRoutes() {
addRouteGroup(pReplyGroup) addRouteGroup(pReplyGroup)
} }
func buildAccountRoutes() {
//router.HandleFunc("/accounts/list/", routeLogin) // Redirect /accounts/ and /user/ to here.. // Get a list of all of the accounts on the forum
accReplyGroup := newRouteGroup("/accounts/")
accReplyGroup.Routes(
View("routeLogin", "/accounts/login/"),
View("routeRegister", "/accounts/create/"),
Action("routeLogout", "/accounts/logout/"),
AnonAction("routeLoginSubmit", "/accounts/login/submit/"), // TODO: Guard this with a token, maybe the IP hashed with a rotated key?
AnonAction("routeRegisterSubmit", "/accounts/create/submit/"),
)
addRouteGroup(accReplyGroup)
}
func buildPanelRoutes() { func buildPanelRoutes() {
panelGroup := newRouteGroup("/panel/").Before("SuperModOnly") panelGroup := newRouteGroup("/panel/").Before("SuperModOnly")
panelGroup.Routes( panelGroup.Routes(
@ -138,8 +152,8 @@ func buildPanelRoutes() {
Action("routePanelUsersEditSubmit", "/panel/users/edit/submit/", "extraData"), Action("routePanelUsersEditSubmit", "/panel/users/edit/submit/", "extraData"),
View("routePanelAnalyticsViews", "/panel/analytics/views/").Before("ParseForm"), View("routePanelAnalyticsViews", "/panel/analytics/views/").Before("ParseForm"),
View("routePanelAnalyticsRoutes", "/panel/analytics/routes/"), View("routePanelAnalyticsRoutes", "/panel/analytics/routes/").Before("ParseForm"),
View("routePanelAnalyticsAgents", "/panel/analytics/agents/"), View("routePanelAnalyticsAgents", "/panel/analytics/agents/").Before("ParseForm"),
View("routePanelAnalyticsRouteViews", "/panel/analytics/route/", "extraData"), View("routePanelAnalyticsRouteViews", "/panel/analytics/route/", "extraData"),
View("routePanelAnalyticsAgentViews", "/panel/analytics/agent/", "extraData"), View("routePanelAnalyticsAgentViews", "/panel/analytics/agent/", "extraData"),
View("routePanelAnalyticsPosts", "/panel/analytics/posts/").Before("ParseForm"), View("routePanelAnalyticsPosts", "/panel/analytics/posts/").Before("ParseForm"),

View File

@ -746,10 +746,6 @@ func routeLoginSubmit(w http.ResponseWriter, r *http.Request, user common.User)
if user.Loggedin { if user.Loggedin {
return common.LocalError("You're already logged in.", w, r, user) return common.LocalError("You're already logged in.", w, r, user)
} }
err := r.ParseForm()
if err != nil {
return common.LocalError("Bad Form", w, r, user)
}
username := html.EscapeString(strings.Replace(r.PostFormValue("username"), "\n", "", -1)) username := html.EscapeString(strings.Replace(r.PostFormValue("username"), "\n", "", -1))
uid, err := common.Auth.Authenticate(username, r.PostFormValue("password")) uid, err := common.Auth.Authenticate(username, r.PostFormValue("password"))
@ -807,10 +803,6 @@ func routeRegister(w http.ResponseWriter, r *http.Request, user common.User) com
func routeRegisterSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError { func routeRegisterSubmit(w http.ResponseWriter, r *http.Request, user common.User) common.RouteError {
headerLite, _ := common.SimpleUserCheck(w, r, &user) headerLite, _ := common.SimpleUserCheck(w, r, &user)
err := r.ParseForm()
if err != nil {
return common.LocalError("Bad Form", w, r, user)
}
username := html.EscapeString(strings.Replace(r.PostFormValue("username"), "\n", "", -1)) username := html.EscapeString(strings.Replace(r.PostFormValue("username"), "\n", "", -1))
if username == "" { if username == "" {
return common.LocalError("You didn't put in a username.", w, r, user) return common.LocalError("You didn't put in a username.", w, r, user)
@ -831,13 +823,15 @@ func routeRegisterSubmit(w http.ResponseWriter, r *http.Request, user common.Use
} }
// ? Move this into Create()? What if we want to programatically set weak passwords for tests? // ? Move this into Create()? What if we want to programatically set weak passwords for tests?
err = common.WeakPassword(password) err := common.WeakPassword(password)
if err != nil { if err != nil {
return common.LocalError(err.Error(), w, r, user) return common.LocalError(err.Error(), w, r, user)
} }
confirmPassword := r.PostFormValue("confirm_password") confirmPassword := r.PostFormValue("confirm_password")
log.Print("Registration Attempt! common.Username: " + username) // TODO: Add more controls over what is logged when? if common.Dev.DebugMode {
log.Print("Registration Attempt! Username: " + username) // TODO: Add more controls over what is logged when?
}
// Do the two inputted passwords match..? // Do the two inputted passwords match..?
if password != confirmPassword { if password != confirmPassword {

View File

@ -34,5 +34,5 @@ if %errorlevel% neq 0 (
echo Running Gosora echo Running Gosora
gosora.exe gosora.exe
rem Or you could redirect the output to a file rem Or you could redirect the output to a file
rem gosora.exe > operations.log 2>&1 rem gosora.exe > ops.log 2>&1
pause pause

View File

@ -2,9 +2,20 @@
<div class="colstack panel_stack"> <div class="colstack panel_stack">
{{template "panel-menu.html" . }} {{template "panel-menu.html" . }}
<main id="panel_dashboard_right" class="colstack_right"> <main id="panel_dashboard_right" class="colstack_right">
<div class="colstack_item colstack_head"> <form id="timeRangeForm" name="timeRangeForm" action="/panel/analytics/agents/" method="get">
<div class="rowitem"><a>User Agents (24 hours)</a></div> <div class="colstack_item colstack_head">
</div> <div class="rowitem">
<a>User Agents</a>
<select class="timeRangeSelector to_right" name="timeRange">
<option val="one-month"{{if eq .TimeRange "one-month"}} selected{{end}}>1 month</option>
<option val="two-days"{{if eq .TimeRange "two-days"}} selected{{end}}>2 days</option>
<option val="one-day"{{if eq .TimeRange "one-day"}} selected{{end}}>1 day</option>
<option val="twelve-hours"{{if eq .TimeRange "twelve-hours"}} selected{{end}}>12 hours</option>
<option val="six-hours"{{if eq .TimeRange "six-hours"}} selected{{end}}>6 hours</option>
</select>
</div>
</div>
</form>
<div id="panel_analytics_agents" class="colstack_item rowlist"> <div id="panel_analytics_agents" class="colstack_item rowlist">
{{range .ItemList}} {{range .ItemList}}
<div class="rowitem panel_compactrow editable_parent"> <div class="rowitem panel_compactrow editable_parent">

View File

@ -2,9 +2,20 @@
<div class="colstack panel_stack"> <div class="colstack panel_stack">
{{template "panel-menu.html" . }} {{template "panel-menu.html" . }}
<main id="panel_dashboard_right" class="colstack_right"> <main id="panel_dashboard_right" class="colstack_right">
<div class="colstack_item colstack_head"> <form id="timeRangeForm" name="timeRangeForm" action="/panel/analytics/routes/" method="get">
<div class="rowitem"><a>Routes (24 hours)</a></div> <div class="colstack_item colstack_head">
</div> <div class="rowitem">
<a>Routes</a>
<select class="timeRangeSelector to_right" name="timeRange">
<option val="one-month"{{if eq .TimeRange "one-month"}} selected{{end}}>1 month</option>
<option val="two-days"{{if eq .TimeRange "two-days"}} selected{{end}}>2 days</option>
<option val="one-day"{{if eq .TimeRange "one-day"}} selected{{end}}>1 day</option>
<option val="twelve-hours"{{if eq .TimeRange "twelve-hours"}} selected{{end}}>12 hours</option>
<option val="six-hours"{{if eq .TimeRange "six-hours"}} selected{{end}}>6 hours</option>
</select>
</div>
</div>
</form>
<div id="panel_analytics_routes" class="colstack_item rowlist"> <div id="panel_analytics_routes" class="colstack_item rowlist">
{{range .ItemList}} {{range .ItemList}}
<div class="rowitem panel_compactrow editable_parent"> <div class="rowitem panel_compactrow editable_parent">

View File

@ -207,9 +207,12 @@ ul {
font-size: 15px; font-size: 15px;
display: flex; display: flex;
} }
.alertItem.withAvatar .text {
margin-top: 8px;
}
.alertItem.withAvatar:not(:last-child) .text { .alertItem.withAvatar:not(:last-child) .text {
border-bottom: 1px solid var(--element-border-color); border-bottom: 1px solid var(--element-border-color);
margin-top: 8px; padding-bottom: 16px;
} }
.alertItem .bgsub { .alertItem .bgsub {
width: 32px; width: 32px;
@ -217,6 +220,9 @@ ul {
border-radius: 30px; border-radius: 30px;
margin-right: 12px; margin-right: 12px;
} }
.alertItem.withAvatar:not(:first-child) {
padding-top: 0px;
}
.rowblock, .colstack_head { .rowblock, .colstack_head {
margin-bottom: 12px; margin-bottom: 12px;
@ -820,6 +826,18 @@ textarea {
margin-right: 8px; margin-right: 8px;
} }
.topic_item {
display: flex;
}
.topic_item .topic_name_input {
width: 100%;
padding-left: 12px;
margin-right: 12px;
}
.topic_item .formbutton {
margin-top: 0px;
}
.post_item { .post_item {
display: flex; display: flex;
margin-bottom: 16px; margin-bottom: 16px;