http server refactor - tests

pull/156/head
Hunter Long 2019-03-05 12:13:25 -08:00
parent 22dc1955f6
commit 1402e3b17b
22 changed files with 172 additions and 351 deletions

View File

@ -33,13 +33,14 @@ var (
func init() {
dir = utils.Directory
core.SampleHits = 480
}
func TestStartServerCommand(t *testing.T) {
os.Setenv("DB_CONN", "sqlite")
cmd := helperCommand(nil, "")
var got = make(chan string)
commandAndSleep(cmd, time.Duration(360*time.Second), got)
commandAndSleep(cmd, time.Duration(60*time.Second), got)
os.Unsetenv("DB_CONN")
gg, _ := <-got
assert.Contains(t, gg, "DB_CONN environment variable was found")

View File

@ -33,6 +33,7 @@ func init() {
utils.InitLogs()
source.Assets()
skipNewDb = false
SampleHits = 480
}
func TestNewCore(t *testing.T) {

View File

@ -101,20 +101,20 @@ func (n *ExampleNotifier) Select() *Notification {
// OnSave is a required basic event for the Notifier interface
func (n *ExampleNotifier) OnSave() error {
msg := fmt.Sprintf("received on save trigger")
n.AddQueue(0, msg)
n.AddQueue("onsave", msg)
return errors.New("onsave triggered")
}
// OnSuccess is a required basic event for the Notifier interface
func (n *ExampleNotifier) OnSuccess(s *types.Service) {
msg := fmt.Sprintf("received a count trigger for service: %v\n", s.Name)
n.AddQueue(s.Id, msg)
n.AddQueue(fmt.Sprintf("service_%v", s.Id), msg)
}
// OnFailure is a required basic event for the Notifier interface
func (n *ExampleNotifier) OnFailure(s *types.Service, f *types.Failure) {
msg := fmt.Sprintf("received a failure trigger for service: %v\n", s.Name)
n.AddQueue(s.Id, msg)
n.AddQueue(fmt.Sprintf("service_%v", s.Id), msg)
}
// OnTest is a option testing event for the Notifier interface
@ -126,61 +126,61 @@ func (n *ExampleNotifier) OnTest() error {
// OnNewService is a option event for new services
func (n *ExampleNotifier) OnNewService(s *types.Service) {
msg := fmt.Sprintf("received a new service trigger for service: %v\n", s.Name)
n.AddQueue(s.Id, msg)
n.AddQueue(fmt.Sprintf("service_%v", s.Id), msg)
}
// OnUpdatedService is a option event for updated services
func (n *ExampleNotifier) OnUpdatedService(s *types.Service) {
msg := fmt.Sprintf("received a update service trigger for service: %v\n", s.Name)
n.AddQueue(s.Id, msg)
n.AddQueue(fmt.Sprintf("service_%v", s.Id), msg)
}
// OnDeletedService is a option event for deleted services
func (n *ExampleNotifier) OnDeletedService(s *types.Service) {
msg := fmt.Sprintf("received a delete service trigger for service: %v\n", s.Name)
n.AddQueue(s.Id, msg)
n.AddQueue(fmt.Sprintf("service_%v", s.Id), msg)
}
// OnNewUser is a option event for new users
func (n *ExampleNotifier) OnNewUser(s *types.User) {
msg := fmt.Sprintf("received a new user trigger for user: %v\n", s.Username)
n.AddQueue(s.Id, msg)
n.AddQueue(fmt.Sprintf("service_%v", s.Id), msg)
}
// OnUpdatedUser is a option event for updated users
func (n *ExampleNotifier) OnUpdatedUser(s *types.User) {
msg := fmt.Sprintf("received a updated user trigger for user: %v\n", s.Username)
n.AddQueue(s.Id, msg)
n.AddQueue(fmt.Sprintf("service_%v", s.Id), msg)
}
// OnDeletedUser is a option event for deleted users
func (n *ExampleNotifier) OnDeletedUser(s *types.User) {
msg := fmt.Sprintf("received a deleted user trigger for user: %v\n", s.Username)
n.AddQueue(s.Id, msg)
n.AddQueue(fmt.Sprintf("service_%v", s.Id), msg)
}
// OnUpdatedCore is a option event when the settings are updated
func (n *ExampleNotifier) OnUpdatedCore(s *types.Core) {
msg := fmt.Sprintf("received a updated core trigger for core: %v\n", s.Name)
n.AddQueue(0, msg)
n.AddQueue("core", msg)
}
// OnStart is triggered when statup has been started
func (n *ExampleNotifier) OnStart(s *types.Core) {
msg := fmt.Sprintf("received a trigger on Statping boot: %v\n", s.Name)
n.AddQueue(0, msg)
n.AddQueue(fmt.Sprintf("core"), msg)
}
// OnNewNotifier is triggered when a new notifier has initialized
func (n *ExampleNotifier) OnNewNotifier(s *Notification) {
msg := fmt.Sprintf("received a new notifier trigger for notifier: %v\n", s.Method)
n.AddQueue(s.Id, msg)
n.AddQueue(fmt.Sprintf("notifier_%v", s.Id), msg)
}
// OnUpdatedNotifier is triggered when a notifier has been updated
func (n *ExampleNotifier) OnUpdatedNotifier(s *Notification) {
msg := fmt.Sprintf("received a update notifier trigger for notifier: %v\n", s.Method)
n.AddQueue(s.Id, msg)
n.AddQueue(fmt.Sprintf("notifier_%v", s.Id), msg)
}
// Create a new notifier that includes a form for the end user to insert their own values
@ -224,7 +224,7 @@ func ExampleAddNotifier() {
// OnSuccess will be triggered everytime a service is online
func ExampleNotification_OnSuccess() {
msg := fmt.Sprintf("this is a successful message as a string passing into AddQueue function")
example.AddQueue(0, msg)
example.AddQueue("example", msg)
fmt.Println(len(example.Queue))
// Output: 1
}
@ -232,13 +232,13 @@ func ExampleNotification_OnSuccess() {
// Add a new message into the queue OnSuccess
func ExampleOnSuccess() {
msg := fmt.Sprintf("received a count trigger for service: %v\n", service.Name)
example.AddQueue(0, msg)
example.AddQueue("example", msg)
}
// Add a new message into the queue OnFailure
func ExampleOnFailure() {
msg := fmt.Sprintf("received a failing service: %v\n", service.Name)
example.AddQueue(0, msg)
example.AddQueue("example", msg)
}
// OnTest allows your notifier to be testable
@ -258,7 +258,7 @@ func ExampleNotification_CanTest() {
// Add any type of interface to the AddQueue function to be ran in the queue
func ExampleNotification_AddQueue() {
msg := fmt.Sprintf("this is a failing message as a string passing into AddQueue function")
example.AddQueue(0, msg)
example.AddQueue("example", msg)
queue := example.Queue
fmt.Printf("Example has %v items in the queue", len(queue))
// Output: Example has 2 items in the queue

View File

@ -100,7 +100,7 @@ func TestSelectNotification(t *testing.T) {
func TestAddQueue(t *testing.T) {
msg := "this is a test in the queue!"
example.AddQueue(fmt.Sprintf("service_%v", 0), msg)
assert.Equal(t, fmt.Sprintf("service_%v", 1), len(example.Queue))
assert.Equal(t, 1, len(example.Queue))
example.AddQueue(fmt.Sprintf("service_%v", 0), msg)
assert.Equal(t, 2, len(example.Queue))
example.AddQueue(fmt.Sprintf("service_%v", 0), msg)

View File

@ -24,7 +24,7 @@ import (
var (
sampleStart = time.Now().Add((-24 * 7) * time.Hour).UTC()
sampleHits = 9900.
SampleHits = 9900.
)
// InsertSampleData will create the example/dummy services for a brand new Statping installation
@ -173,12 +173,12 @@ func InsertSampleHits() error {
service := SelectService(i)
seed := time.Now().UnixNano()
utils.Log(1, fmt.Sprintf("Adding %v sample hit records to service %v", sampleHits, service.Name))
utils.Log(1, fmt.Sprintf("Adding %v sample hit records to service %v", SampleHits, service.Name))
createdAt := sampleStart
p := utils.NewPerlin(2., 2., 10, seed)
for hi := 0.; hi <= float64(sampleHits); hi++ {
for hi := 0.; hi <= float64(SampleHits); hi++ {
latency := p.Noise1D(hi / 500)
createdAt = createdAt.Add(60 * time.Second)
@ -440,17 +440,9 @@ func insertHitRecords(since time.Time, amount int64) {
service := SelectService(i)
utils.Log(1, fmt.Sprintf("Adding %v hit records to service %v", amount, service.Name))
createdAt := since
p := utils.NewPerlin(2, 2, 5, time.Now().UnixNano())
utils.Log(1, fmt.Sprint(p))
for hi := int64(1); hi <= amount; hi++ {
latency := p.Noise1D(float64(hi / 10))
fmt.Printf("%0.0f\t%0.4f\n", hi, latency)
createdAt = createdAt.Add(1 * time.Minute)
hit := &types.Hit{
Service: service.Id,

View File

@ -35,20 +35,12 @@ type apiResponse struct {
}
func apiIndexHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
coreClone := *core.CoreApp
coreClone.Started = utils.Timezoner(core.CoreApp.Started, core.CoreApp.Timezone)
returnJson(coreClone, w, r)
}
func apiRenewHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
var err error
core.CoreApp.ApiKey = utils.NewSHA1Hash(40)
core.CoreApp.ApiSecret = utils.NewSHA1Hash(40)
@ -61,10 +53,6 @@ func apiRenewHandler(w http.ResponseWriter, r *http.Request) {
}
func apiClearCacheHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
CacheStorage = NewStorage()
http.Redirect(w, r, "/", http.StatusSeeOther)
}

View File

@ -102,6 +102,12 @@ func TestMainApiRoutes(t *testing.T) {
URL: "/api/clear_cache",
Method: "POST",
ExpectedStatus: 303,
},
{
Name: "404 Error Page",
URL: "/api/missing_404_page",
Method: "GET",
ExpectedStatus: 404,
}}
for _, v := range tests {

View File

@ -1,9 +1,6 @@
package handlers
import (
"github.com/hunterlong/statping/core"
"net/http"
"net/http/httptest"
"sync"
"time"
)
@ -74,31 +71,3 @@ func (s Storage) Set(key string, content []byte, duration time.Duration) {
Expiration: time.Now().Add(duration).UnixNano(),
}
}
func cached(duration, contentType string, handler func(w http.ResponseWriter, r *http.Request)) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
content := CacheStorage.Get(r.RequestURI)
w.Header().Set("Content-Type", contentType)
if core.Configs == nil {
handler(w, r)
return
}
if content != nil {
w.Write(content)
} else {
c := httptest.NewRecorder()
handler(c, r)
content := c.Body.Bytes()
result := c.Result()
if result.StatusCode != 200 {
w.WriteHeader(result.StatusCode)
w.Write(content)
return
}
w.Write(content)
if d, err := time.ParseDuration(duration); err == nil {
go CacheStorage.Set(r.RequestURI, content, d)
}
}
})
}

View File

@ -28,10 +28,6 @@ import (
)
func apiAllCheckinsHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
checkins := core.AllCheckins()
for _, c := range checkins {
c.Hits = c.AllHits()
@ -41,10 +37,6 @@ func apiAllCheckinsHandler(w http.ResponseWriter, r *http.Request) {
}
func apiCheckinHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
vars := mux.Vars(r)
checkin := core.SelectCheckin(vars["api"])
if checkin == nil {
@ -57,10 +49,6 @@ func apiCheckinHandler(w http.ResponseWriter, r *http.Request) {
}
func checkinCreateHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
var checkin *core.Checkin
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&checkin)
@ -108,15 +96,10 @@ func checkinHitHandler(w http.ResponseWriter, r *http.Request) {
}
checkin.Failing = false
checkin.LastHit = utils.Timezoner(time.Now().UTC(), core.CoreApp.Timezone)
w.Header().Set("Content-Type", "application/json")
sendJsonAction(checkinHit, "update", w, r)
}
func checkinDeleteHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
vars := mux.Vars(r)
checkin := core.SelectCheckin(vars["api"])
if checkin == nil {

View File

@ -41,9 +41,9 @@ func loginHandler(w http.ResponseWriter, r *http.Request) {
resetCookies()
}
session, _ := sessionStore.Get(r, cookieKey)
r.ParseForm()
username := r.PostForm.Get("username")
password := r.PostForm.Get("password")
form := parseForm(r)
username := form.Get("username")
password := form.Get("password")
user, auth := core.AuthUser(username, password)
if auth {
session.Values["authenticated"] = true
@ -77,10 +77,6 @@ func helpHandler(w http.ResponseWriter, r *http.Request) {
}
func logsHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
utils.LockLines.Lock()
logs := make([]string, 0)
length := len(utils.LastLines)
@ -93,10 +89,6 @@ func logsHandler(w http.ResponseWriter, r *http.Request) {
}
func logsLineHandler(w http.ResponseWriter, r *http.Request) {
if !IsReadAuthenticated(r) {
w.WriteHeader(http.StatusInternalServerError)
return
}
if lastLine := utils.GetLastLine(); lastLine != nil {
w.Header().Set("Content-Type", "text/plain")
w.WriteHeader(http.StatusOK)
@ -105,11 +97,6 @@ func logsLineHandler(w http.ResponseWriter, r *http.Request) {
}
func exportHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
w.WriteHeader(http.StatusInternalServerError)
return
}
var notifiers []*notifier.Notification
for _, v := range core.CoreApp.Notifications {
notifier := v.(notifier.Notifier)

View File

@ -26,10 +26,6 @@ import (
// apiAllGroupHandler will show all the groups
func apiAllGroupHandler(w http.ResponseWriter, r *http.Request) {
if !IsReadAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
auth := IsUser(r)
groups := core.SelectGroups(false, auth)
returnJson(groups, w, r)
@ -37,10 +33,6 @@ func apiAllGroupHandler(w http.ResponseWriter, r *http.Request) {
// apiGroupHandler will show a single group
func apiGroupHandler(w http.ResponseWriter, r *http.Request) {
if !IsReadAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
vars := mux.Vars(r)
group := core.SelectGroup(utils.ToInt(vars["id"]))
if group == nil {
@ -52,10 +44,6 @@ func apiGroupHandler(w http.ResponseWriter, r *http.Request) {
// apiCreateGroupHandler accepts a POST method to create new groups
func apiCreateGroupHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
var group *core.Group
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&group)
@ -73,10 +61,6 @@ func apiCreateGroupHandler(w http.ResponseWriter, r *http.Request) {
// apiGroupDeleteHandler accepts a DELETE method to delete groups
func apiGroupDeleteHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
vars := mux.Vars(r)
group := core.SelectGroup(utils.ToInt(vars["id"]))
if group == nil {
@ -97,10 +81,6 @@ type groupOrder struct {
}
func apiGroupReorderHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
r.ParseForm()
var newOrder []*groupOrder
decoder := json.NewDecoder(r.Body)

View File

@ -217,13 +217,11 @@ func ExecuteResponse(w http.ResponseWriter, r *http.Request, file string, data i
utils.Log(4, err)
}
// render the page requested
_, err = mainTemplate.Parse(render)
if err != nil {
if _, err := mainTemplate.Parse(render); err != nil {
utils.Log(4, err)
}
// execute the template
err = mainTemplate.Execute(w, data)
if err != nil {
if err := mainTemplate.Execute(w, data); err != nil {
utils.Log(4, err)
}
}
@ -246,20 +244,16 @@ func executeJSResponse(w http.ResponseWriter, r *http.Request, file string, data
return core.CoreApp.Services
},
})
_, err = t.Parse(render)
if err != nil {
if _, err := t.Parse(render); err != nil {
utils.Log(4, err)
}
err = t.Execute(w, data)
if err != nil {
if err := t.Execute(w, data); err != nil {
utils.Log(4, err)
}
}
func returnJson(d interface{}, w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
json.NewEncoder(w).Encode(d)
}

View File

@ -35,10 +35,6 @@ func messagesHandler(w http.ResponseWriter, r *http.Request) {
}
func viewMessageHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
vars := mux.Vars(r)
id := utils.ToInt(vars["id"])
message, err := core.SelectMessage(id)
@ -50,10 +46,6 @@ func viewMessageHandler(w http.ResponseWriter, r *http.Request) {
}
func apiAllMessagesHandler(w http.ResponseWriter, r *http.Request) {
if !IsReadAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
messages, err := core.SelectMessages()
if err != nil {
sendErrorJson(err, w, r)
@ -63,10 +55,6 @@ func apiAllMessagesHandler(w http.ResponseWriter, r *http.Request) {
}
func apiMessageCreateHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
var message *types.Message
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&message)
@ -84,10 +72,6 @@ func apiMessageCreateHandler(w http.ResponseWriter, r *http.Request) {
}
func apiMessageGetHandler(w http.ResponseWriter, r *http.Request) {
if !IsReadAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
vars := mux.Vars(r)
message, err := core.SelectMessage(utils.ToInt(vars["id"]))
if err != nil {
@ -98,10 +82,6 @@ func apiMessageGetHandler(w http.ResponseWriter, r *http.Request) {
}
func apiMessageDeleteHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
vars := mux.Vars(r)
message, err := core.SelectMessage(utils.ToInt(vars["id"]))
if err != nil {
@ -117,10 +97,6 @@ func apiMessageDeleteHandler(w http.ResponseWriter, r *http.Request) {
}
func apiMessageUpdateHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
vars := mux.Vars(r)
message, err := core.SelectMessage(utils.ToInt(vars["id"]))
if err != nil {

68
handlers/middleware.go Normal file
View File

@ -0,0 +1,68 @@
package handlers
import (
"github.com/hunterlong/statping/core"
"net/http"
"net/http/httptest"
"time"
)
// authenticated is a middleware function to check if user is an Admin before running original request
func authenticated(handler func(w http.ResponseWriter, r *http.Request), redirect bool) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
if redirect {
http.Redirect(w, r, "/", http.StatusSeeOther)
} else {
sendUnauthorizedJson(w, r)
}
return
}
handler(w, r)
})
}
// readOnly is a middleware function to check if user is a User before running original request
func readOnly(handler func(w http.ResponseWriter, r *http.Request), redirect bool) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if !IsReadAuthenticated(r) {
if redirect {
http.Redirect(w, r, "/", http.StatusSeeOther)
} else {
sendUnauthorizedJson(w, r)
}
return
}
handler(w, r)
})
}
// cached is a middleware function that accepts a duration and content type and will cache the response of the original request
func cached(duration, contentType string, handler func(w http.ResponseWriter, r *http.Request)) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
content := CacheStorage.Get(r.RequestURI)
w.Header().Set("Content-Type", contentType)
w.Header().Set("Access-Control-Allow-Origin", "*")
if core.Configs == nil {
handler(w, r)
return
}
if content != nil {
w.Write(content)
} else {
c := httptest.NewRecorder()
handler(c, r)
content := c.Body.Bytes()
result := c.Result()
if result.StatusCode != 200 {
w.WriteHeader(result.StatusCode)
w.Write(content)
return
}
w.Write(content)
if d, err := time.ParseDuration(duration); err == nil {
go CacheStorage.Set(r.RequestURI, content, d)
}
}
})
}

View File

@ -27,10 +27,6 @@ import (
)
func apiNotifiersHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
var notifiers []*notifier.Notification
for _, n := range core.CoreApp.Notifications {
notif := n.(notifier.Notifier)
@ -40,10 +36,6 @@ func apiNotifiersHandler(w http.ResponseWriter, r *http.Request) {
}
func apiNotifierGetHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
vars := mux.Vars(r)
_, notifierObj, err := notifier.SelectNotifier(vars["notifier"])
if err != nil {
@ -54,10 +46,6 @@ func apiNotifierGetHandler(w http.ResponseWriter, r *http.Request) {
}
func apiNotifierUpdateHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
vars := mux.Vars(r)
notifer, not, err := notifier.SelectNotifier(vars["notifier"])
if err != nil {
@ -81,10 +69,6 @@ func apiNotifierUpdateHandler(w http.ResponseWriter, r *http.Request) {
func testNotificationHandler(w http.ResponseWriter, r *http.Request) {
var err error
if !IsFullAuthenticated(r) {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
form := parseForm(r)
vars := mux.Vars(r)
method := vars["method"]

View File

@ -27,10 +27,6 @@ type PluginSelect struct {
}
func pluginSavedHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
r.ParseForm()
//vars := mux.Vars(router)
//plug := SelectPlugin(vars["name"])
@ -43,11 +39,6 @@ func pluginSavedHandler(w http.ResponseWriter, r *http.Request) {
}
func pluginsDownloadHandler(w http.ResponseWriter, r *http.Request) {
auth := IsFullAuthenticated(r)
if !auth {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
//vars := mux.Vars(router)
//name := vars["name"]
//DownloadPlugin(name)

View File

@ -33,10 +33,6 @@ import (
//
func prometheusHandler(w http.ResponseWriter, r *http.Request) {
if !IsReadAuthenticated(r) {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
metrics := []string{}
system := fmt.Sprintf("statping_total_failures %v\n", core.CountFailures())
system += fmt.Sprintf("statping_total_services %v", len(core.CoreApp.Services))

View File

@ -59,85 +59,85 @@ func Router() *mux.Router {
r.Handle("/dashboard", http.HandlerFunc(dashboardHandler)).Methods("GET")
r.Handle("/dashboard", http.HandlerFunc(loginHandler)).Methods("POST")
r.Handle("/logout", http.HandlerFunc(logoutHandler))
r.Handle("/plugins/download/{name}", http.HandlerFunc(pluginsDownloadHandler))
r.Handle("/plugins/{name}/save", http.HandlerFunc(pluginSavedHandler)).Methods("POST")
r.Handle("/help", http.HandlerFunc(helpHandler))
r.Handle("/logs", http.HandlerFunc(logsHandler))
r.Handle("/logs/line", http.HandlerFunc(logsLineHandler))
r.Handle("/plugins/download/{name}", authenticated(pluginsDownloadHandler, true))
r.Handle("/plugins/{name}/save", authenticated(pluginSavedHandler, true)).Methods("POST")
r.Handle("/help", authenticated(helpHandler, true))
r.Handle("/logs", authenticated(logsHandler, true))
r.Handle("/logs/line", readOnly(logsLineHandler, true))
// USER Routes
r.Handle("/users", http.HandlerFunc(usersHandler)).Methods("GET")
r.Handle("/user/{id}", http.HandlerFunc(usersEditHandler)).Methods("GET")
r.Handle("/users", readOnly(usersHandler, true)).Methods("GET")
r.Handle("/user/{id}", authenticated(usersEditHandler, true)).Methods("GET")
// MESSAGES Routes
r.Handle("/messages", http.HandlerFunc(messagesHandler)).Methods("GET")
r.Handle("/message/{id}", http.HandlerFunc(viewMessageHandler)).Methods("GET")
r.Handle("/messages", authenticated(messagesHandler, true)).Methods("GET")
r.Handle("/message/{id}", authenticated(viewMessageHandler, true)).Methods("GET")
// SETTINGS Routes
r.Handle("/settings", http.HandlerFunc(settingsHandler)).Methods("GET")
r.Handle("/settings", http.HandlerFunc(saveSettingsHandler)).Methods("POST")
r.Handle("/settings/css", http.HandlerFunc(saveSASSHandler)).Methods("POST")
r.Handle("/settings/build", http.HandlerFunc(saveAssetsHandler)).Methods("GET")
r.Handle("/settings/delete_assets", http.HandlerFunc(deleteAssetsHandler)).Methods("GET")
r.Handle("/settings/export", http.HandlerFunc(exportHandler)).Methods("GET")
r.Handle("/settings", authenticated(settingsHandler, true)).Methods("GET")
r.Handle("/settings", authenticated(saveSettingsHandler, true)).Methods("POST")
r.Handle("/settings/css", authenticated(saveSASSHandler, true)).Methods("POST")
r.Handle("/settings/build", authenticated(saveAssetsHandler, true)).Methods("GET")
r.Handle("/settings/delete_assets", authenticated(deleteAssetsHandler, true)).Methods("GET")
r.Handle("/settings/export", authenticated(exportHandler, true)).Methods("GET")
// SERVICE Routes
r.Handle("/services", http.HandlerFunc(servicesHandler)).Methods("GET")
r.Handle("/service/{id}", http.HandlerFunc(servicesViewHandler)).Methods("GET")
r.Handle("/service/{id}/edit", http.HandlerFunc(servicesViewHandler)).Methods("GET")
r.Handle("/service/{id}/delete_failures", http.HandlerFunc(servicesDeleteFailuresHandler)).Methods("GET")
r.Handle("/service/{id}/edit", authenticated(servicesViewHandler, true)).Methods("GET")
r.Handle("/service/{id}/delete_failures", authenticated(servicesDeleteFailuresHandler, true)).Methods("GET")
// API GROUPS Routes
r.Handle("/api/groups", http.HandlerFunc(apiAllGroupHandler)).Methods("GET")
r.Handle("/api/groups", http.HandlerFunc(apiCreateGroupHandler)).Methods("POST")
r.Handle("/api/groups/{id}", http.HandlerFunc(apiGroupHandler)).Methods("GET")
r.Handle("/api/groups/{id}", http.HandlerFunc(apiGroupDeleteHandler)).Methods("DELETE")
r.Handle("/api/groups/reorder", http.HandlerFunc(apiGroupReorderHandler)).Methods("POST")
r.Handle("/api/groups", readOnly(apiAllGroupHandler, false)).Methods("GET")
r.Handle("/api/groups", authenticated(apiCreateGroupHandler, false)).Methods("POST")
r.Handle("/api/groups/{id}", readOnly(apiGroupHandler, false)).Methods("GET")
r.Handle("/api/groups/{id}", authenticated(apiGroupDeleteHandler, false)).Methods("DELETE")
r.Handle("/api/groups/reorder", authenticated(apiGroupReorderHandler, false)).Methods("POST")
// API Routes
r.Handle("/api", http.HandlerFunc(apiIndexHandler))
r.Handle("/api/renew", http.HandlerFunc(apiRenewHandler))
r.Handle("/api/clear_cache", http.HandlerFunc(apiClearCacheHandler))
r.Handle("/api", authenticated(apiIndexHandler, false))
r.Handle("/api/renew", authenticated(apiRenewHandler, false))
r.Handle("/api/clear_cache", authenticated(apiClearCacheHandler, false))
// API SERVICE Routes
r.Handle("/api/services", http.HandlerFunc(apiAllServicesHandler)).Methods("GET")
r.Handle("/api/services", http.HandlerFunc(apiCreateServiceHandler)).Methods("POST")
r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceHandler)).Methods("GET")
r.Handle("/api/services/reorder", http.HandlerFunc(reorderServiceHandler)).Methods("POST")
r.Handle("/api/services", readOnly(apiAllServicesHandler, false)).Methods("GET")
r.Handle("/api/services", authenticated(apiCreateServiceHandler, false)).Methods("POST")
r.Handle("/api/services/{id}", readOnly(apiServiceHandler, false)).Methods("GET")
r.Handle("/api/services/reorder", authenticated(reorderServiceHandler, false)).Methods("POST")
r.Handle("/api/services/{id}/data", cached("30s", "application/json", http.HandlerFunc(apiServiceDataHandler))).Methods("GET")
r.Handle("/api/services/{id}/ping", cached("30s", "application/json", http.HandlerFunc(apiServicePingDataHandler))).Methods("GET")
r.Handle("/api/services/{id}/heatmap", cached("30s", "application/json", http.HandlerFunc(apiServiceHeatmapHandler))).Methods("GET")
r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceUpdateHandler)).Methods("POST")
r.Handle("/api/services/{id}", http.HandlerFunc(apiServiceDeleteHandler)).Methods("DELETE")
r.Handle("/api/services/{id}/failures", http.HandlerFunc(apiServiceFailuresHandler)).Methods("GET")
r.Handle("/api/services/{id}/failures", http.HandlerFunc(servicesDeleteFailuresHandler)).Methods("DELETE")
r.Handle("/api/services/{id}/hits", http.HandlerFunc(apiServiceHitsHandler)).Methods("GET")
r.Handle("/api/services/{id}", authenticated(apiServiceUpdateHandler, false)).Methods("POST")
r.Handle("/api/services/{id}", authenticated(apiServiceDeleteHandler, false)).Methods("DELETE")
r.Handle("/api/services/{id}/failures", authenticated(apiServiceFailuresHandler, false)).Methods("GET")
r.Handle("/api/services/{id}/failures", authenticated(servicesDeleteFailuresHandler, false)).Methods("DELETE")
r.Handle("/api/services/{id}/hits", authenticated(apiServiceHitsHandler, false)).Methods("GET")
// API USER Routes
r.Handle("/api/users", http.HandlerFunc(apiAllUsersHandler)).Methods("GET")
r.Handle("/api/users", http.HandlerFunc(apiCreateUsersHandler)).Methods("POST")
r.Handle("/api/users/{id}", http.HandlerFunc(apiUserHandler)).Methods("GET")
r.Handle("/api/users/{id}", http.HandlerFunc(apiUserUpdateHandler)).Methods("POST")
r.Handle("/api/users/{id}", http.HandlerFunc(apiUserDeleteHandler)).Methods("DELETE")
r.Handle("/api/users", authenticated(apiAllUsersHandler, false)).Methods("GET")
r.Handle("/api/users", authenticated(apiCreateUsersHandler, false)).Methods("POST")
r.Handle("/api/users/{id}", authenticated(apiUserHandler, false)).Methods("GET")
r.Handle("/api/users/{id}", authenticated(apiUserUpdateHandler, false)).Methods("POST")
r.Handle("/api/users/{id}", authenticated(apiUserDeleteHandler, false)).Methods("DELETE")
// API NOTIFIER Routes
r.Handle("/api/notifiers", http.HandlerFunc(apiNotifiersHandler)).Methods("GET")
r.Handle("/api/notifier/{notifier}", http.HandlerFunc(apiNotifierGetHandler)).Methods("GET")
r.Handle("/api/notifier/{notifier}", http.HandlerFunc(apiNotifierUpdateHandler)).Methods("POST")
r.Handle("/api/notifier/{method}/test", http.HandlerFunc(testNotificationHandler)).Methods("POST")
r.Handle("/api/notifiers", authenticated(apiNotifiersHandler, false)).Methods("GET")
r.Handle("/api/notifier/{notifier}", authenticated(apiNotifierGetHandler, false)).Methods("GET")
r.Handle("/api/notifier/{notifier}", authenticated(apiNotifierUpdateHandler, false)).Methods("POST")
r.Handle("/api/notifier/{method}/test", authenticated(testNotificationHandler, false)).Methods("POST")
// API MESSAGES Routes
r.Handle("/api/messages", http.HandlerFunc(apiAllMessagesHandler)).Methods("GET")
r.Handle("/api/messages", http.HandlerFunc(apiMessageCreateHandler)).Methods("POST")
r.Handle("/api/messages/{id}", http.HandlerFunc(apiMessageGetHandler)).Methods("GET")
r.Handle("/api/messages/{id}", http.HandlerFunc(apiMessageUpdateHandler)).Methods("POST")
r.Handle("/api/messages/{id}", http.HandlerFunc(apiMessageDeleteHandler)).Methods("DELETE")
r.Handle("/api/messages", readOnly(apiAllMessagesHandler, false)).Methods("GET")
r.Handle("/api/messages", authenticated(apiMessageCreateHandler, false)).Methods("POST")
r.Handle("/api/messages/{id}", readOnly(apiMessageGetHandler, false)).Methods("GET")
r.Handle("/api/messages/{id}", authenticated(apiMessageUpdateHandler, false)).Methods("POST")
r.Handle("/api/messages/{id}", authenticated(apiMessageDeleteHandler, false)).Methods("DELETE")
// API CHECKIN Routes
r.Handle("/api/checkins", http.HandlerFunc(apiAllCheckinsHandler)).Methods("GET")
r.Handle("/api/checkin/{api}", http.HandlerFunc(apiCheckinHandler)).Methods("GET")
r.Handle("/api/checkin", http.HandlerFunc(checkinCreateHandler)).Methods("POST")
r.Handle("/api/checkin/{api}", http.HandlerFunc(checkinDeleteHandler)).Methods("DELETE")
r.Handle("/api/checkins", authenticated(apiAllCheckinsHandler, false)).Methods("GET")
r.Handle("/api/checkin/{api}", authenticated(apiCheckinHandler, false)).Methods("GET")
r.Handle("/api/checkin", authenticated(checkinCreateHandler, false)).Methods("POST")
r.Handle("/api/checkin/{api}", authenticated(checkinDeleteHandler, false)).Methods("DELETE")
r.Handle("/checkin/{api}", http.HandlerFunc(checkinHitHandler))
// Static Files Routes
@ -146,7 +146,7 @@ func Router() *mux.Router {
r.PathPrefix("/files/grafana.json").Handler(http.StripPrefix("/files/", http.FileServer(source.TmplBox.HTTPBox())))
// API Generic Routes
r.Handle("/metrics", http.HandlerFunc(prometheusHandler))
r.Handle("/metrics", readOnly(prometheusHandler, false))
r.Handle("/health", http.HandlerFunc(healthCheckHandler))
r.Handle("/.well-known/", http.StripPrefix("/.well-known/", http.FileServer(http.Dir(dir+"/.well-known"))))

View File

@ -49,10 +49,6 @@ func renderServiceChartsHandler(w http.ResponseWriter, r *http.Request) {
}
func servicesHandler(w http.ResponseWriter, r *http.Request) {
if !IsUser(r) {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
data := map[string]interface{}{
"Services": core.CoreApp.Services,
}
@ -65,10 +61,6 @@ type serviceOrder struct {
}
func reorderServiceHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
r.ParseForm()
var newOrder []*serviceOrder
decoder := json.NewDecoder(r.Body)
@ -130,10 +122,6 @@ func servicesViewHandler(w http.ResponseWriter, r *http.Request) {
}
func apiServiceHandler(w http.ResponseWriter, r *http.Request) {
if !IsReadAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
vars := mux.Vars(r)
servicer := core.SelectService(utils.ToInt(vars["id"]))
if servicer == nil {
@ -144,10 +132,6 @@ func apiServiceHandler(w http.ResponseWriter, r *http.Request) {
}
func apiCreateServiceHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
var service *types.Service
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&service)
@ -165,10 +149,6 @@ func apiCreateServiceHandler(w http.ResponseWriter, r *http.Request) {
}
func apiServiceUpdateHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
vars := mux.Vars(r)
service := core.SelectService(utils.ToInt(vars["id"]))
if service == nil {
@ -284,10 +264,6 @@ func apiServiceHeatmapHandler(w http.ResponseWriter, r *http.Request) {
}
func apiServiceDeleteHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
vars := mux.Vars(r)
service := core.SelectService(utils.ToInt(vars["id"]))
if service == nil {
@ -303,19 +279,11 @@ func apiServiceDeleteHandler(w http.ResponseWriter, r *http.Request) {
}
func apiAllServicesHandler(w http.ResponseWriter, r *http.Request) {
if !IsReadAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
services := core.Services()
returnJson(services, w, r)
}
func servicesDeleteFailuresHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
vars := mux.Vars(r)
service := core.SelectService(utils.ToInt(vars["id"]))
if service == nil {
@ -327,10 +295,6 @@ func servicesDeleteFailuresHandler(w http.ResponseWriter, r *http.Request) {
}
func apiServiceFailuresHandler(w http.ResponseWriter, r *http.Request) {
if !IsReadAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
vars := mux.Vars(r)
servicer := core.SelectService(utils.ToInt(vars["id"]))
if servicer == nil {
@ -341,10 +305,6 @@ func apiServiceFailuresHandler(w http.ResponseWriter, r *http.Request) {
}
func apiServiceHitsHandler(w http.ResponseWriter, r *http.Request) {
if !IsReadAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
vars := mux.Vars(r)
servicer := core.SelectService(utils.ToInt(vars["id"]))
if servicer == nil {

View File

@ -17,7 +17,6 @@ package handlers
import (
"fmt"
"github.com/gorilla/mux"
"github.com/hunterlong/statping/core"
"github.com/hunterlong/statping/source"
"github.com/hunterlong/statping/types"
@ -28,46 +27,38 @@ import (
)
func settingsHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
ExecuteResponse(w, r, "settings.gohtml", core.CoreApp, nil)
}
func saveSettingsHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
var err error
r.ParseForm()
form := parseForm(r)
app := core.CoreApp
name := r.PostForm.Get("project")
name := form.Get("project")
if name != "" {
app.Name = name
}
description := r.PostForm.Get("description")
description := form.Get("description")
if description != app.Description {
app.Description = description
}
style := r.PostForm.Get("style")
style := form.Get("style")
if style != app.Style {
app.Style = style
}
footer := r.PostForm.Get("footer")
footer := form.Get("footer")
if footer != app.Footer.String {
app.Footer = types.NewNullString(footer)
}
domain := r.PostForm.Get("domain")
domain := form.Get("domain")
if domain != app.Domain {
app.Domain = domain
}
timezone := r.PostForm.Get("timezone")
timezone := form.Get("timezone")
timeFloat, _ := strconv.ParseFloat(timezone, 10)
app.Timezone = float32(timeFloat)
app.UseCdn = types.NewNullBool(r.PostForm.Get("enable_cdn") == "on")
app.UseCdn = types.NewNullBool(form.Get("enable_cdn") == "on")
core.CoreApp, err = core.UpdateCore(app)
if err != nil {
utils.Log(3, fmt.Sprintf("issue updating Core: %v", err.Error()))
@ -77,12 +68,7 @@ func saveSettingsHandler(w http.ResponseWriter, r *http.Request) {
}
func saveSASSHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
r.ParseForm()
form := r.PostForm
form := parseForm(r)
theme := form.Get("theme")
variables := form.Get("variables")
mobile := form.Get("mobile")
@ -95,19 +81,13 @@ func saveSASSHandler(w http.ResponseWriter, r *http.Request) {
}
func saveAssetsHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
dir := utils.Directory
err := source.CreateAllAssets(dir)
if err != nil {
if err := source.CreateAllAssets(dir); err != nil {
utils.Log(3, err)
sendErrorJson(err, w, r)
return
}
err = source.CompileSASS(dir)
if err != nil {
if err := source.CompileSASS(dir); err != nil {
source.CopyToPublic(source.CssBox, dir+"/assets/css", "base.css")
utils.Log(3, "Default 'base.css' was inserted because SASS did not work.")
}
@ -116,20 +96,13 @@ func saveAssetsHandler(w http.ResponseWriter, r *http.Request) {
}
func deleteAssetsHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
if err := source.DeleteAllAssets(utils.Directory); err != nil {
utils.Log(3, fmt.Errorf("error deleting all assets %v", err))
}
source.DeleteAllAssets(utils.Directory)
resetRouter()
ExecuteResponse(w, r, "settings.gohtml", core.CoreApp, "/settings")
}
func parseId(r *http.Request) int64 {
vars := mux.Vars(r)
return utils.ToInt(vars["id"])
}
func parseForm(r *http.Request) url.Values {
r.ParseForm()
return r.PostForm

View File

@ -28,19 +28,11 @@ import (
)
func usersHandler(w http.ResponseWriter, r *http.Request) {
if !IsUser(r) {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
users, _ := core.SelectAllUsers()
ExecuteResponse(w, r, "users.gohtml", users, nil)
}
func usersEditHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}
vars := mux.Vars(r)
id, _ := strconv.Atoi(vars["id"])
user, _ := core.SelectUser(int64(id))
@ -48,10 +40,6 @@ func usersEditHandler(w http.ResponseWriter, r *http.Request) {
}
func apiUserHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
vars := mux.Vars(r)
user, err := core.SelectUser(utils.ToInt(vars["id"]))
if err != nil {
@ -63,10 +51,6 @@ func apiUserHandler(w http.ResponseWriter, r *http.Request) {
}
func apiUserUpdateHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
vars := mux.Vars(r)
user, err := core.SelectUser(utils.ToInt(vars["id"]))
if err != nil {
@ -87,10 +71,6 @@ func apiUserUpdateHandler(w http.ResponseWriter, r *http.Request) {
}
func apiUserDeleteHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
vars := mux.Vars(r)
users := core.CountUsers()
if users == 1 {
@ -111,10 +91,6 @@ func apiUserDeleteHandler(w http.ResponseWriter, r *http.Request) {
}
func apiAllUsersHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
users, err := core.SelectAllUsers()
if err != nil {
sendErrorJson(err, w, r)
@ -124,10 +100,6 @@ func apiAllUsersHandler(w http.ResponseWriter, r *http.Request) {
}
func apiCreateUsersHandler(w http.ResponseWriter, r *http.Request) {
if !IsFullAuthenticated(r) {
sendUnauthorizedJson(w, r)
return
}
var user *types.User
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&user)

View File

@ -1,6 +1,6 @@
// Code generated by go generate; DO NOT EDIT.
// This file was generated by robots at
// 2019-03-01 09:07:43.47095 -0800 PST m=+0.520001086
// 2019-03-05 12:12:13.088097 -0800 PST m=+0.505471244
//
// This contains the most recently Markdown source for the Statping Wiki.
package source