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:
parent
cce87e2d70
commit
0416b1ed91
|
@ -182,6 +182,7 @@ type PanelAnalyticsRoutesPage struct {
|
|||
Stats PanelStats
|
||||
Zone string
|
||||
ItemList []PanelAnalyticsRoutesItem
|
||||
TimeRange string
|
||||
}
|
||||
|
||||
type PanelAnalyticsAgentsItem struct {
|
||||
|
@ -196,6 +197,7 @@ type PanelAnalyticsAgentsPage struct {
|
|||
Stats PanelStats
|
||||
Zone string
|
||||
ItemList []PanelAnalyticsAgentsItem
|
||||
TimeRange string
|
||||
}
|
||||
|
||||
type PanelAnalyticsRoutePage struct {
|
||||
|
|
|
@ -97,6 +97,11 @@ var RouteMap = map[string]interface{}{
|
|||
"routeProfileReplyCreateSubmit": routeProfileReplyCreateSubmit,
|
||||
"routeProfileReplyEditSubmit": routeProfileReplyEditSubmit,
|
||||
"routeProfileReplyDeleteSubmit": routeProfileReplyDeleteSubmit,
|
||||
"routeLogin": routeLogin,
|
||||
"routeRegister": routeRegister,
|
||||
"routeLogout": routeLogout,
|
||||
"routeLoginSubmit": routeLoginSubmit,
|
||||
"routeRegisterSubmit": routeRegisterSubmit,
|
||||
"routeDynamic": routeDynamic,
|
||||
"routeUploads": routeUploads,
|
||||
}
|
||||
|
@ -185,8 +190,13 @@ var routeMapEnum = map[string]int{
|
|||
"routeProfileReplyCreateSubmit": 79,
|
||||
"routeProfileReplyEditSubmit": 80,
|
||||
"routeProfileReplyDeleteSubmit": 81,
|
||||
"routeDynamic": 82,
|
||||
"routeUploads": 83,
|
||||
"routeLogin": 82,
|
||||
"routeRegister": 83,
|
||||
"routeLogout": 84,
|
||||
"routeLoginSubmit": 85,
|
||||
"routeRegisterSubmit": 86,
|
||||
"routeDynamic": 87,
|
||||
"routeUploads": 88,
|
||||
}
|
||||
var reverseRouteMapEnum = map[int]string{
|
||||
0: "routeAPI",
|
||||
|
@ -271,8 +281,13 @@ var reverseRouteMapEnum = map[int]string{
|
|||
79: "routeProfileReplyCreateSubmit",
|
||||
80: "routeProfileReplyEditSubmit",
|
||||
81: "routeProfileReplyDeleteSubmit",
|
||||
82: "routeDynamic",
|
||||
83: "routeUploads",
|
||||
82: "routeLogin",
|
||||
83: "routeRegister",
|
||||
84: "routeLogout",
|
||||
85: "routeLoginSubmit",
|
||||
86: "routeRegisterSubmit",
|
||||
87: "routeDynamic",
|
||||
88: "routeUploads",
|
||||
}
|
||||
var agentMapEnum = map[string]int{
|
||||
"unknown": 0,
|
||||
|
@ -379,6 +394,19 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
var prefix, extraData string
|
||||
prefix = req.URL.Path[0:strings.IndexByte(req.URL.Path[1:],'/') + 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:]
|
||||
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)
|
||||
err = routePanelAnalyticsViews(w,req,user)
|
||||
case "/panel/analytics/routes/":
|
||||
err = common.ParseForm(w,req,user)
|
||||
if err != nil {
|
||||
router.handleError(err,w,req,user)
|
||||
return
|
||||
}
|
||||
|
||||
common.RouteViewCounter.Bump(37)
|
||||
err = routePanelAnalyticsRoutes(w,req,user)
|
||||
case "/panel/analytics/agents/":
|
||||
err = common.ParseForm(w,req,user)
|
||||
if err != nil {
|
||||
router.handleError(err,w,req,user)
|
||||
return
|
||||
}
|
||||
|
||||
common.RouteViewCounter.Bump(38)
|
||||
err = routePanelAnalyticsAgents(w,req,user)
|
||||
case "/panel/analytics/route/":
|
||||
|
@ -1298,6 +1338,51 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
if err != nil {
|
||||
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
|
||||
req.URL.Path += extraData
|
||||
err = sitemapSwitch(w,req)
|
||||
|
@ -1309,7 +1394,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
common.NotFound(w,req)
|
||||
return
|
||||
}
|
||||
common.RouteViewCounter.Bump(83)
|
||||
common.RouteViewCounter.Bump(88)
|
||||
req.URL.Path += extraData
|
||||
// TODO: Find a way to propagate errors up from this?
|
||||
router.UploadHandler(w,req) // TODO: Count these views
|
||||
|
@ -1353,7 +1438,7 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
router.RUnlock()
|
||||
|
||||
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
|
||||
err = handle(w,req,user)
|
||||
if err != nil {
|
||||
|
|
11
main.go
11
main.go
|
@ -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: 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 {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -303,15 +303,6 @@ func main() {
|
|||
// TODO: Move these routes into the new routes list
|
||||
log.Print("Initialising the router")
|
||||
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)
|
||||
|
||||
log.Print("Initialising the plugins")
|
||||
|
|
|
@ -16,11 +16,25 @@ import (
|
|||
"./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 allow banned users to make reports? How should we handle report abuse?
|
||||
// TODO: Add a permission to stop certain users from using custom avatars
|
||||
// ? - Log username changes and put restrictions on this?
|
||||
|
||||
func routeTopicCreate(w http.ResponseWriter, r *http.Request, user common.User, sfid string) common.RouteError {
|
||||
var fid int
|
||||
var err error
|
||||
|
|
|
@ -834,39 +834,9 @@ func routePanelAnalyticsPosts(w http.ResponseWriter, r *http.Request, user commo
|
|||
headerVars.Stylesheets = append(headerVars.Stylesheets, "chartist/chartist.min.css")
|
||||
headerVars.Scripts = append(headerVars.Scripts, "chartist/chartist.min.js")
|
||||
|
||||
var timeQuantity = 6
|
||||
var timeUnit = "hour"
|
||||
var timeSlices = 12
|
||||
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)
|
||||
timeRange, err := panelAnalyticsTimeRange(r.FormValue("timeRange"))
|
||||
if err != nil {
|
||||
return common.LocalError(err.Error(), w, r, user)
|
||||
}
|
||||
|
||||
var revLabelList []int64
|
||||
|
@ -874,8 +844,8 @@ func routePanelAnalyticsPosts(w http.ResponseWriter, r *http.Request, user commo
|
|||
var viewMap = make(map[int64]int64)
|
||||
var currentTime = time.Now().Unix()
|
||||
|
||||
for i := 1; i <= timeSlices; i++ {
|
||||
var label = currentTime - int64(i*sliceWidth)
|
||||
for i := 1; i <= timeRange.Slices; i++ {
|
||||
var label = currentTime - int64(i*timeRange.SliceWidth)
|
||||
revLabelList = append(revLabelList, label)
|
||||
viewMap[label] = 0
|
||||
}
|
||||
|
@ -887,7 +857,7 @@ func routePanelAnalyticsPosts(w http.ResponseWriter, r *http.Request, user commo
|
|||
log.Print("in routePanelAnalyticsPosts")
|
||||
|
||||
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 {
|
||||
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}
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -936,8 +906,13 @@ func routePanelAnalyticsRoutes(w http.ResponseWriter, r *http.Request, user comm
|
|||
}
|
||||
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()
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -980,8 +955,13 @@ func routePanelAnalyticsAgents(w http.ResponseWriter, r *http.Request, user comm
|
|||
}
|
||||
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()
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
|
||||
|
@ -1505,7 +1485,7 @@ func routePanelUsersEdit(w http.ResponseWriter, r *http.Request, user common.Use
|
|||
}
|
||||
|
||||
var groupList []interface{}
|
||||
for _, group := range groups[1:] {
|
||||
for _, group := range groups {
|
||||
if !user.Perms.EditUserGroupAdmin && group.IsAdmin {
|
||||
continue
|
||||
}
|
||||
|
@ -1600,6 +1580,8 @@ func routePanelUsersEditSubmit(w http.ResponseWriter, r *http.Request, user comm
|
|||
|
||||
if newpassword != "" {
|
||||
common.SetPassword(targetUser.ID, newpassword)
|
||||
// Log the user out as a safety precaution
|
||||
common.Auth.ForceLogout(targetUser.ID)
|
||||
}
|
||||
|
||||
targetUser.CacheRemove()
|
||||
|
|
|
@ -181,6 +181,7 @@ func main() {
|
|||
for id, agent := range tmplVars.AllAgentNames {
|
||||
tmplVars.AllAgentMap[agent] = id
|
||||
}
|
||||
var graveSym = "`"
|
||||
|
||||
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. */
|
||||
|
@ -284,6 +285,19 @@ func (router *GenRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
|
|||
var prefix, extraData string
|
||||
prefix = req.URL.Path[0:strings.IndexByte(req.URL.Path[1:],'/') + 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:]
|
||||
req.URL.Path = req.URL.Path[:strings.LastIndexByte(req.URL.Path,'/') + 1]
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ func routes() {
|
|||
buildTopicRoutes()
|
||||
buildReplyRoutes()
|
||||
buildProfileReplyRoutes()
|
||||
buildAccountRoutes()
|
||||
}
|
||||
|
||||
// TODO: Test the email token route
|
||||
|
@ -101,6 +102,19 @@ func buildProfileReplyRoutes() {
|
|||
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() {
|
||||
panelGroup := newRouteGroup("/panel/").Before("SuperModOnly")
|
||||
panelGroup.Routes(
|
||||
|
@ -138,8 +152,8 @@ func buildPanelRoutes() {
|
|||
Action("routePanelUsersEditSubmit", "/panel/users/edit/submit/", "extraData"),
|
||||
|
||||
View("routePanelAnalyticsViews", "/panel/analytics/views/").Before("ParseForm"),
|
||||
View("routePanelAnalyticsRoutes", "/panel/analytics/routes/"),
|
||||
View("routePanelAnalyticsAgents", "/panel/analytics/agents/"),
|
||||
View("routePanelAnalyticsRoutes", "/panel/analytics/routes/").Before("ParseForm"),
|
||||
View("routePanelAnalyticsAgents", "/panel/analytics/agents/").Before("ParseForm"),
|
||||
View("routePanelAnalyticsRouteViews", "/panel/analytics/route/", "extraData"),
|
||||
View("routePanelAnalyticsAgentViews", "/panel/analytics/agent/", "extraData"),
|
||||
View("routePanelAnalyticsPosts", "/panel/analytics/posts/").Before("ParseForm"),
|
||||
|
|
14
routes.go
14
routes.go
|
@ -746,10 +746,6 @@ func routeLoginSubmit(w http.ResponseWriter, r *http.Request, user common.User)
|
|||
if user.Loggedin {
|
||||
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))
|
||||
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 {
|
||||
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))
|
||||
if username == "" {
|
||||
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?
|
||||
err = common.WeakPassword(password)
|
||||
err := common.WeakPassword(password)
|
||||
if err != nil {
|
||||
return common.LocalError(err.Error(), w, r, user)
|
||||
}
|
||||
|
||||
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..?
|
||||
if password != confirmPassword {
|
||||
|
|
2
run.bat
2
run.bat
|
@ -34,5 +34,5 @@ if %errorlevel% neq 0 (
|
|||
echo Running Gosora
|
||||
gosora.exe
|
||||
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
|
|
@ -2,9 +2,20 @@
|
|||
<div class="colstack panel_stack">
|
||||
{{template "panel-menu.html" . }}
|
||||
<main id="panel_dashboard_right" class="colstack_right">
|
||||
<div class="colstack_item colstack_head">
|
||||
<div class="rowitem"><a>User Agents (24 hours)</a></div>
|
||||
</div>
|
||||
<form id="timeRangeForm" name="timeRangeForm" action="/panel/analytics/agents/" method="get">
|
||||
<div class="colstack_item colstack_head">
|
||||
<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">
|
||||
{{range .ItemList}}
|
||||
<div class="rowitem panel_compactrow editable_parent">
|
||||
|
|
|
@ -2,9 +2,20 @@
|
|||
<div class="colstack panel_stack">
|
||||
{{template "panel-menu.html" . }}
|
||||
<main id="panel_dashboard_right" class="colstack_right">
|
||||
<div class="colstack_item colstack_head">
|
||||
<div class="rowitem"><a>Routes (24 hours)</a></div>
|
||||
</div>
|
||||
<form id="timeRangeForm" name="timeRangeForm" action="/panel/analytics/routes/" method="get">
|
||||
<div class="colstack_item colstack_head">
|
||||
<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">
|
||||
{{range .ItemList}}
|
||||
<div class="rowitem panel_compactrow editable_parent">
|
||||
|
|
|
@ -207,9 +207,12 @@ ul {
|
|||
font-size: 15px;
|
||||
display: flex;
|
||||
}
|
||||
.alertItem.withAvatar .text {
|
||||
margin-top: 8px;
|
||||
}
|
||||
.alertItem.withAvatar:not(:last-child) .text {
|
||||
border-bottom: 1px solid var(--element-border-color);
|
||||
margin-top: 8px;
|
||||
padding-bottom: 16px;
|
||||
}
|
||||
.alertItem .bgsub {
|
||||
width: 32px;
|
||||
|
@ -217,6 +220,9 @@ ul {
|
|||
border-radius: 30px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
.alertItem.withAvatar:not(:first-child) {
|
||||
padding-top: 0px;
|
||||
}
|
||||
|
||||
.rowblock, .colstack_head {
|
||||
margin-bottom: 12px;
|
||||
|
@ -820,6 +826,18 @@ textarea {
|
|||
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 {
|
||||
display: flex;
|
||||
margin-bottom: 16px;
|
||||
|
|
Loading…
Reference in New Issue