mirror of https://github.com/statping/statping
upgrades
parent
dc110c0412
commit
470ffb090a
14
checker.go
14
checker.go
|
@ -10,8 +10,6 @@ import (
|
||||||
|
|
||||||
func CheckServices() {
|
func CheckServices() {
|
||||||
services, _ = SelectAllServices()
|
services, _ = SelectAllServices()
|
||||||
core.Communications, _ = SelectAllCommunications()
|
|
||||||
LoadDefaultCommunications()
|
|
||||||
for _, v := range services {
|
for _, v := range services {
|
||||||
obj := v
|
obj := v
|
||||||
go obj.StartCheckins()
|
go obj.StartCheckins()
|
||||||
|
@ -42,18 +40,24 @@ func (s *Service) Check() *Service {
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
defer response.Body.Close()
|
defer response.Body.Close()
|
||||||
|
contents, _ := ioutil.ReadAll(response.Body)
|
||||||
if s.Expected != "" {
|
if s.Expected != "" {
|
||||||
contents, _ := ioutil.ReadAll(response.Body)
|
|
||||||
match, _ := regexp.MatchString(s.Expected, string(contents))
|
match, _ := regexp.MatchString(s.Expected, string(contents))
|
||||||
if !match {
|
if !match {
|
||||||
|
s.LastResponse = string(contents)
|
||||||
|
s.LastStatusCode = response.StatusCode
|
||||||
s.Failure(fmt.Sprintf("HTTP Response Body did not match '%v'", s.Expected))
|
s.Failure(fmt.Sprintf("HTTP Response Body did not match '%v'", s.Expected))
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if s.ExpectedStatus != response.StatusCode {
|
if s.ExpectedStatus != response.StatusCode {
|
||||||
|
s.LastResponse = string(contents)
|
||||||
|
s.LastStatusCode = response.StatusCode
|
||||||
s.Failure(fmt.Sprintf("HTTP Status Code %v did not match %v", response.StatusCode, s.ExpectedStatus))
|
s.Failure(fmt.Sprintf("HTTP Status Code %v did not match %v", response.StatusCode, s.ExpectedStatus))
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
|
s.LastResponse = string(contents)
|
||||||
|
s.LastStatusCode = response.StatusCode
|
||||||
s.Online = true
|
s.Online = true
|
||||||
s.Record(response)
|
s.Record(response)
|
||||||
return s
|
return s
|
||||||
|
@ -65,6 +69,7 @@ type HitData struct {
|
||||||
|
|
||||||
func (s *Service) Record(response *http.Response) {
|
func (s *Service) Record(response *http.Response) {
|
||||||
s.Online = true
|
s.Online = true
|
||||||
|
s.LastOnline = time.Now()
|
||||||
data := HitData{
|
data := HitData{
|
||||||
Latency: s.Latency,
|
Latency: s.Latency,
|
||||||
}
|
}
|
||||||
|
@ -82,5 +87,8 @@ func (s *Service) Failure(issue string) {
|
||||||
Issue: issue,
|
Issue: issue,
|
||||||
}
|
}
|
||||||
s.CreateFailure(data)
|
s.CreateFailure(data)
|
||||||
|
|
||||||
|
SendFailureEmail(s)
|
||||||
|
|
||||||
OnFailure(s)
|
OnFailure(s)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
package comms
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"crypto/tls"
|
|
||||||
"fmt"
|
|
||||||
"github.com/hunterlong/statup/types"
|
|
||||||
"gopkg.in/gomail.v2"
|
|
||||||
"html/template"
|
|
||||||
"log"
|
|
||||||
"time"
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
Emailer *gomail.Dialer
|
|
||||||
Outgoing []*types.Email
|
|
||||||
)
|
|
||||||
|
|
||||||
func AddEmail(email *types.Email) {
|
|
||||||
Outgoing = append(Outgoing, email)
|
|
||||||
}
|
|
||||||
|
|
||||||
func EmailerQueue() {
|
|
||||||
defer EmailerQueue()
|
|
||||||
for _, out := range Outgoing {
|
|
||||||
fmt.Printf("sending email to: %v \n", out.To)
|
|
||||||
Send(out)
|
|
||||||
}
|
|
||||||
Outgoing = nil
|
|
||||||
fmt.Println("running emailer queue")
|
|
||||||
time.Sleep(10 * time.Second)
|
|
||||||
}
|
|
||||||
|
|
||||||
func Send(em *types.Email) {
|
|
||||||
source := EmailTemplate("comms/templates/error.html", nil)
|
|
||||||
m := gomail.NewMessage()
|
|
||||||
m.SetHeader("From", "info@betatude.com")
|
|
||||||
m.SetHeader("To", em.To)
|
|
||||||
m.SetHeader("Subject", em.Subject)
|
|
||||||
m.SetBody("text/html", source)
|
|
||||||
if err := Emailer.DialAndSend(m); err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func SendSample(em *types.Email) {
|
|
||||||
source := EmailTemplate("comms/templates/error.html", nil)
|
|
||||||
m := gomail.NewMessage()
|
|
||||||
m.SetHeader("From", "info@betatude.com")
|
|
||||||
m.SetHeader("To", em.To)
|
|
||||||
m.SetHeader("Subject", em.Subject)
|
|
||||||
m.SetBody("text/html", source)
|
|
||||||
if err := Emailer.DialAndSend(m); err != nil {
|
|
||||||
fmt.Println(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func LoadMailer(config *types.Communication) *gomail.Dialer {
|
|
||||||
Emailer = gomail.NewDialer(config.Host, config.Port, config.Username, config.Password)
|
|
||||||
Emailer.TLSConfig = &tls.Config{InsecureSkipVerify: true}
|
|
||||||
return Emailer
|
|
||||||
}
|
|
||||||
|
|
||||||
func EmailTemplate(tmpl string, data interface{}) string {
|
|
||||||
t := template.New("error.html")
|
|
||||||
var err error
|
|
||||||
t, err = t.ParseFiles(tmpl)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
var tpl bytes.Buffer
|
|
||||||
if err := t.Execute(&tpl, data); err != nil {
|
|
||||||
log.Println(err)
|
|
||||||
}
|
|
||||||
result := tpl.String()
|
|
||||||
return result
|
|
||||||
}
|
|
|
@ -1,15 +1,16 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/hunterlong/statup/comms"
|
"fmt"
|
||||||
"github.com/hunterlong/statup/types"
|
"github.com/hunterlong/statup/types"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
func LoadDefaultCommunications() {
|
func LoadDefaultCommunications() {
|
||||||
emailer := SelectCommunication(1)
|
emailer := SelectCommunication(1)
|
||||||
comms.LoadMailer(emailer)
|
fmt.Println(emailer)
|
||||||
go comms.EmailerQueue()
|
LoadMailer(emailer)
|
||||||
|
go EmailerQueue()
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadComms() {
|
func LoadComms() {
|
||||||
|
@ -27,7 +28,7 @@ func Run(c *types.Communication) {
|
||||||
Subject: "Test Email from Statup",
|
Subject: "Test Email from Statup",
|
||||||
}
|
}
|
||||||
|
|
||||||
comms.AddEmail(sample)
|
AddEmail(sample)
|
||||||
}
|
}
|
||||||
|
|
||||||
func SelectAllCommunications() ([]*types.Communication, error) {
|
func SelectAllCommunications() ([]*types.Communication, error) {
|
||||||
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/tls"
|
||||||
|
"fmt"
|
||||||
|
"github.com/hunterlong/statup/types"
|
||||||
|
"gopkg.in/gomail.v2"
|
||||||
|
"html/template"
|
||||||
|
"log"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
emailQue *Que
|
||||||
|
)
|
||||||
|
|
||||||
|
type Que struct {
|
||||||
|
Mailer *gomail.Dialer
|
||||||
|
Outgoing []*types.Email
|
||||||
|
LastSent int
|
||||||
|
LastSentTime time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
func AddEmail(email *types.Email) {
|
||||||
|
emailQue.Outgoing = append(emailQue.Outgoing, email)
|
||||||
|
}
|
||||||
|
|
||||||
|
func EmailerQueue() {
|
||||||
|
defer EmailerQueue()
|
||||||
|
uniques := []*types.Email{}
|
||||||
|
for _, out := range emailQue.Outgoing {
|
||||||
|
if isUnique(uniques, out) {
|
||||||
|
fmt.Printf("sending email to: %v \n", out.To)
|
||||||
|
Send(out)
|
||||||
|
uniques = append(uniques, out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
emailQue.Outgoing = nil
|
||||||
|
fmt.Println("running emailer queue")
|
||||||
|
time.Sleep(60 * time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
func isUnique(arr []*types.Email, obj *types.Email) bool {
|
||||||
|
for _, v := range arr {
|
||||||
|
if v.To == obj.To && v.Subject == obj.Subject {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func Send(em *types.Email) {
|
||||||
|
source := EmailTemplate(em.Template, em.Data)
|
||||||
|
m := gomail.NewMessage()
|
||||||
|
m.SetHeader("From", "info@betatude.com")
|
||||||
|
m.SetHeader("To", em.To)
|
||||||
|
m.SetHeader("Subject", em.Subject)
|
||||||
|
m.SetBody("text/html", source)
|
||||||
|
if err := emailQue.Mailer.DialAndSend(m); err != nil {
|
||||||
|
fmt.Println(err)
|
||||||
|
}
|
||||||
|
emailQue.LastSent++
|
||||||
|
emailQue.LastSentTime = time.Now()
|
||||||
|
}
|
||||||
|
|
||||||
|
func SendFailureEmail(service *Service) {
|
||||||
|
email := &types.Email{
|
||||||
|
To: "info@socialeck.com",
|
||||||
|
Subject: fmt.Sprintf("Service %v is Failing", service.Name),
|
||||||
|
Template: "failure.html",
|
||||||
|
Data: service,
|
||||||
|
}
|
||||||
|
AddEmail(email)
|
||||||
|
}
|
||||||
|
|
||||||
|
func LoadMailer(config *types.Communication) *gomail.Dialer {
|
||||||
|
emailQue = &Que{}
|
||||||
|
emailQue.Outgoing = []*types.Email{}
|
||||||
|
emailQue.Mailer = gomail.NewDialer(config.Host, config.Port, config.Username, config.Password)
|
||||||
|
emailQue.Mailer.TLSConfig = &tls.Config{InsecureSkipVerify: true}
|
||||||
|
return emailQue.Mailer
|
||||||
|
}
|
||||||
|
|
||||||
|
func EmailTemplate(tmpl string, data interface{}) string {
|
||||||
|
emailTpl, err := emailBox.String(tmpl)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
t := template.New("email")
|
||||||
|
t, err = t.Parse(emailTpl)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
var tpl bytes.Buffer
|
||||||
|
if err := t.Execute(&tpl, data); err != nil {
|
||||||
|
log.Println(err)
|
||||||
|
}
|
||||||
|
result := tpl.String()
|
||||||
|
return result
|
||||||
|
}
|
28
exporter.go
28
exporter.go
|
@ -9,9 +9,16 @@ import (
|
||||||
|
|
||||||
var httpFunctions template.FuncMap
|
var httpFunctions template.FuncMap
|
||||||
|
|
||||||
func init() {
|
func ExportIndexHTML() string {
|
||||||
|
out := index{*core, services}
|
||||||
httpFunctions = template.FuncMap{
|
nav, _ := tmplBox.String("nav.html")
|
||||||
|
footer, _ := tmplBox.String("footer.html")
|
||||||
|
render, err := tmplBox.String("index.html")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
t := template.New("message")
|
||||||
|
t.Funcs(template.FuncMap{
|
||||||
"js": func(html string) template.JS {
|
"js": func(html string) template.JS {
|
||||||
return template.JS(html)
|
return template.JS(html)
|
||||||
},
|
},
|
||||||
|
@ -24,20 +31,7 @@ func init() {
|
||||||
"underscore": func(html string) string {
|
"underscore": func(html string) string {
|
||||||
return UnderScoreString(html)
|
return UnderScoreString(html)
|
||||||
},
|
},
|
||||||
}
|
})
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func ExportIndexHTML() string {
|
|
||||||
out := index{*core, services}
|
|
||||||
nav, _ := tmplBox.String("nav.html")
|
|
||||||
footer, _ := tmplBox.String("footer.html")
|
|
||||||
render, err := tmplBox.String("index.html")
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
t := template.New("message")
|
|
||||||
t.Funcs(httpFunctions)
|
|
||||||
t, _ = t.Parse(nav)
|
t, _ = t.Parse(nav)
|
||||||
t, _ = t.Parse(footer)
|
t, _ = t.Parse(footer)
|
||||||
t.Parse(render)
|
t.Parse(render)
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xmlns="http://www.w3.org/1999/xhtml">
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<title>Sample Email</title>
|
||||||
|
|
||||||
|
|
||||||
|
</head>
|
||||||
|
<body style="-webkit-text-size-adjust: none; box-sizing: border-box; color: #74787E; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; height: 100%; line-height: 1.4; margin: 0; width: 100% !important;" bgcolor="#F2F4F6"><style type="text/css">
|
||||||
|
body {
|
||||||
|
width: 100% !important; height: 100%; margin: 0; line-height: 1.4; background-color: #F2F4F6; color: #74787E; -webkit-text-size-adjust: none;
|
||||||
|
}
|
||||||
|
@media only screen and (max-width: 600px) {
|
||||||
|
.email-body_inner {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
.email-footer {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media only screen and (max-width: 500px) {
|
||||||
|
.button {
|
||||||
|
width: 100% !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<table class="email-wrapper" width="100%" cellpadding="0" cellspacing="0" style="box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; margin: 0; padding: 0; width: 100%;" bgcolor="#F2F4F6">
|
||||||
|
<tr>
|
||||||
|
<td align="center" style="box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; word-break: break-word;">
|
||||||
|
<table class="email-content" width="100%" cellpadding="0" cellspacing="0" style="box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; margin: 0; padding: 0; width: 100%;">
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="email-body" width="100%" cellpadding="0" cellspacing="0" style="-premailer-cellpadding: 0; -premailer-cellspacing: 0; border-bottom-color: #EDEFF2; border-bottom-style: solid; border-bottom-width: 1px; border-top-color: #EDEFF2; border-top-style: solid; border-top-width: 1px; box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; margin: 0; padding: 0; width: 100%; word-break: break-word;" bgcolor="#FFFFFF">
|
||||||
|
<table class="email-body_inner" align="center" width="570" cellpadding="0" cellspacing="0" style="box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; margin: 0 auto; padding: 0; width: 570px;" bgcolor="#FFFFFF">
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td class="content-cell" style="box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; padding: 35px; word-break: break-word;">
|
||||||
|
<h1 style="box-sizing: border-box; color: #2F3133; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 19px; font-weight: bold; margin-top: 0;" align="left">{{ .Name }} is Offline!</h1>
|
||||||
|
<p style="box-sizing: border-box; color: #74787E; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 16px; line-height: 1.5em; margin-top: 0;" align="left">
|
||||||
|
Your Statup service named '{{.Name}}' has been triggered with a HTTP status code of '{{.LastStatusCode}}' and is currently offline based on your requirements.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h1 style="box-sizing: border-box; color: #2F3133; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 19px; font-weight: bold; margin-top: 0;" align="left">Last Response</h1>
|
||||||
|
<p style="box-sizing: border-box; color: #74787E; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 16px; line-height: 1.5em; margin-top: 0;" align="left">
|
||||||
|
{{ .LastResponse }}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<table class="body-sub" style="border-top-color: #EDEFF2; border-top-style: solid; border-top-width: 1px; box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; margin-top: 25px; padding-top: 25px;">
|
||||||
|
<td style="box-sizing: border-box; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; word-break: break-word;">
|
||||||
|
<a href="/service/{{.Id}}" class="button button--blue" target="_blank" style="-webkit-text-size-adjust: none; background: #3869D4; border-color: #3869d4; border-radius: 3px; border-style: solid; border-width: 10px 18px; box-shadow: 0 2px 3px rgba(0, 0, 0, 0.16); box-sizing: border-box; color: #FFF; display: inline-block; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; text-decoration: none;">View Service</a>
|
||||||
|
</td>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -163,6 +163,20 @@
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="col-12">
|
||||||
|
<h3>Last Response</h3>
|
||||||
|
|
||||||
|
<textarea class="form-control" readonly>{{ .LastResponse }}</textarea>
|
||||||
|
|
||||||
|
<div class="form-group row mt-2">
|
||||||
|
<label for="last_status_code" class="col-sm-3 col-form-label">Status Code</label>
|
||||||
|
<div class="col-sm-9">
|
||||||
|
<input type="text" id="last_status_code" class="form-control" value="{{ .LastStatusCode }}">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -74,6 +74,11 @@
|
||||||
<input type="text" name="username" class="form-control" value="{{.Username}}" id="formGroupExampleInput" value="admin" placeholder="admin">
|
<input type="text" name="username" class="form-control" value="{{.Username}}" id="formGroupExampleInput" value="admin" placeholder="admin">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="formGroupExampleInput">Admin Email Address</label>
|
||||||
|
<input type="email" name="email" class="form-control" value="{{.Email}}" id="formGroupExampleInput" placeholder="info@admin.com">
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="formGroupExampleInput">Admin Password</label>
|
<label for="formGroupExampleInput">Admin Password</label>
|
||||||
<input type="password" name="password" class="form-control" value="{{.Password}}" id="formGroupExampleInput" value="admin" placeholder="admin">
|
<input type="password" name="password" class="form-control" value="{{.Password}}" id="formGroupExampleInput" value="admin" placeholder="admin">
|
||||||
|
|
4
main.go
4
main.go
|
@ -26,6 +26,7 @@ var (
|
||||||
cssBox *rice.Box
|
cssBox *rice.Box
|
||||||
jsBox *rice.Box
|
jsBox *rice.Box
|
||||||
tmplBox *rice.Box
|
tmplBox *rice.Box
|
||||||
|
emailBox *rice.Box
|
||||||
setupMode bool
|
setupMode bool
|
||||||
allPlugins []plugin.PluginActions
|
allPlugins []plugin.PluginActions
|
||||||
)
|
)
|
||||||
|
@ -152,6 +153,8 @@ func mainProcess() {
|
||||||
RunHTTPServer()
|
RunHTTPServer()
|
||||||
}
|
}
|
||||||
CheckServices()
|
CheckServices()
|
||||||
|
core.Communications, _ = SelectAllCommunications()
|
||||||
|
LoadDefaultCommunications()
|
||||||
if !setupMode {
|
if !setupMode {
|
||||||
LoadPlugins()
|
LoadPlugins()
|
||||||
RunHTTPServer()
|
RunHTTPServer()
|
||||||
|
@ -221,6 +224,7 @@ func RenderBoxes() {
|
||||||
cssBox = rice.MustFindBox("html/css")
|
cssBox = rice.MustFindBox("html/css")
|
||||||
jsBox = rice.MustFindBox("html/js")
|
jsBox = rice.MustFindBox("html/js")
|
||||||
tmplBox = rice.MustFindBox("html/tmpl")
|
tmplBox = rice.MustFindBox("html/tmpl")
|
||||||
|
emailBox = rice.MustFindBox("html/emails")
|
||||||
}
|
}
|
||||||
|
|
||||||
func LoadConfig() (*Config, error) {
|
func LoadConfig() (*Config, error) {
|
||||||
|
|
|
@ -35,6 +35,9 @@ type Service struct {
|
||||||
Failures []*Failure `json:"failures"`
|
Failures []*Failure `json:"failures"`
|
||||||
Checkins []*Checkin `json:"checkins"`
|
Checkins []*Checkin `json:"checkins"`
|
||||||
runRoutine bool
|
runRoutine bool
|
||||||
|
LastResponse string
|
||||||
|
LastStatusCode int
|
||||||
|
LastOnline time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
func serviceCol() db.Collection {
|
func serviceCol() db.Collection {
|
||||||
|
|
2
setup.go
2
setup.go
|
@ -45,6 +45,7 @@ func ProcessSetupHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
sample := r.PostForm.Get("sample_data")
|
sample := r.PostForm.Get("sample_data")
|
||||||
description := r.PostForm.Get("description")
|
description := r.PostForm.Get("description")
|
||||||
domain := r.PostForm.Get("domain")
|
domain := r.PostForm.Get("domain")
|
||||||
|
email := r.PostForm.Get("email")
|
||||||
|
|
||||||
config := &DbConfig{
|
config := &DbConfig{
|
||||||
dbConn,
|
dbConn,
|
||||||
|
@ -85,6 +86,7 @@ func ProcessSetupHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
admin := &User{
|
admin := &User{
|
||||||
Username: config.Username,
|
Username: config.Username,
|
||||||
Password: config.Password,
|
Password: config.Password,
|
||||||
|
Email: email,
|
||||||
Admin: true,
|
Admin: true,
|
||||||
}
|
}
|
||||||
admin.Create()
|
admin.Create()
|
||||||
|
|
|
@ -24,5 +24,4 @@ type Email struct {
|
||||||
Subject string
|
Subject string
|
||||||
Template string
|
Template string
|
||||||
Data interface{}
|
Data interface{}
|
||||||
Body string
|
|
||||||
}
|
}
|
||||||
|
|
17
users.go
17
users.go
|
@ -2,6 +2,7 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,6 +17,19 @@ type User struct {
|
||||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SessionUser(r *http.Request) *User {
|
||||||
|
session, _ := store.Get(r, cookieKey)
|
||||||
|
if session == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
uuid := session.Values["user_id"]
|
||||||
|
var user *User
|
||||||
|
col := dbSession.Collection("users")
|
||||||
|
res := col.Find("id", uuid)
|
||||||
|
res.One(&user)
|
||||||
|
return user
|
||||||
|
}
|
||||||
|
|
||||||
func SelectUser(id int64) (*User, error) {
|
func SelectUser(id int64) (*User, error) {
|
||||||
var user User
|
var user User
|
||||||
col := dbSession.Collection("users")
|
col := dbSession.Collection("users")
|
||||||
|
@ -40,8 +54,7 @@ func (u *User) Delete() error {
|
||||||
|
|
||||||
func (u *User) Create() (int64, error) {
|
func (u *User) Create() (int64, error) {
|
||||||
u.CreatedAt = time.Now()
|
u.CreatedAt = time.Now()
|
||||||
password := HashPassword(u.Password)
|
u.Password = HashPassword(u.Password)
|
||||||
u.Password = password
|
|
||||||
u.ApiKey = NewSHA1Hash(5)
|
u.ApiKey = NewSHA1Hash(5)
|
||||||
u.ApiSecret = NewSHA1Hash(10)
|
u.ApiSecret = NewSHA1Hash(10)
|
||||||
col := dbSession.Collection("users")
|
col := dbSession.Collection("users")
|
||||||
|
|
20
web.go
20
web.go
|
@ -5,7 +5,6 @@ import (
|
||||||
"github.com/fatih/structs"
|
"github.com/fatih/structs"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/gorilla/sessions"
|
"github.com/gorilla/sessions"
|
||||||
"github.com/hunterlong/statup/comms"
|
|
||||||
"github.com/hunterlong/statup/types"
|
"github.com/hunterlong/statup/types"
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -96,9 +95,10 @@ func LoginHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
r.ParseForm()
|
r.ParseForm()
|
||||||
username := r.PostForm.Get("username")
|
username := r.PostForm.Get("username")
|
||||||
password := r.PostForm.Get("password")
|
password := r.PostForm.Get("password")
|
||||||
_, auth := AuthUser(username, password)
|
user, auth := AuthUser(username, password)
|
||||||
if auth {
|
if auth {
|
||||||
session.Values["authenticated"] = true
|
session.Values["authenticated"] = true
|
||||||
|
session.Values["user_id"] = user.Id
|
||||||
session.Save(r, w)
|
session.Save(r, w)
|
||||||
http.Redirect(w, r, "/dashboard", http.StatusSeeOther)
|
http.Redirect(w, r, "/dashboard", http.StatusSeeOther)
|
||||||
} else {
|
} else {
|
||||||
|
@ -265,13 +265,11 @@ func SaveEmailSettingsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
Update(emailer)
|
Update(emailer)
|
||||||
|
|
||||||
sample := &types.Email{
|
sample := &types.Email{
|
||||||
To: "info@socialeck.com",
|
To: SessionUser(r).Email,
|
||||||
Subject: "Sample Email",
|
Subject: "Sample Email",
|
||||||
Template: "templates/error.html",
|
Template: "error.html",
|
||||||
Body: "okkokkok",
|
|
||||||
}
|
}
|
||||||
|
AddEmail(sample)
|
||||||
comms.AddEmail(sample)
|
|
||||||
|
|
||||||
http.Redirect(w, r, "/settings", http.StatusSeeOther)
|
http.Redirect(w, r, "/settings", http.StatusSeeOther)
|
||||||
}
|
}
|
||||||
|
@ -416,11 +414,6 @@ func ServicesBadgeHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func ServicesViewHandler(w http.ResponseWriter, r *http.Request) {
|
func ServicesViewHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
auth := IsAuthenticated(r)
|
|
||||||
if !auth {
|
|
||||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
vars := mux.Vars(r)
|
vars := mux.Vars(r)
|
||||||
service := SelectService(StringInt(vars["id"]))
|
service := SelectService(StringInt(vars["id"]))
|
||||||
ExecuteResponse(w, r, "service.html", service)
|
ExecuteResponse(w, r, "service.html", service)
|
||||||
|
@ -450,6 +443,9 @@ func ExecuteResponse(w http.ResponseWriter, r *http.Request, file string, data i
|
||||||
"underscore": func(html string) string {
|
"underscore": func(html string) string {
|
||||||
return UnderScoreString(html)
|
return UnderScoreString(html)
|
||||||
},
|
},
|
||||||
|
"User": func() *User {
|
||||||
|
return SessionUser(r)
|
||||||
|
},
|
||||||
})
|
})
|
||||||
t, _ = t.Parse(nav)
|
t, _ = t.Parse(nav)
|
||||||
t, _ = t.Parse(footer)
|
t, _ = t.Parse(footer)
|
||||||
|
|
Loading…
Reference in New Issue