diff --git a/handlers/routes.go b/handlers/routes.go index 46e6aaf5..c91b842d 100644 --- a/handlers/routes.go +++ b/handlers/routes.go @@ -59,6 +59,7 @@ func Router() *mux.Router { r.HandleFunc("/debug/pprof/symbol", pprof.Symbol) r.HandleFunc("/debug/pprof/trace", pprof.Trace) http.ListenAndServe(":9090", r) + // pprof -http=:9000 http://localhost:9090/debug/pprof/heap?debug=1 }() } diff --git a/notifiers/mobile.go b/notifiers/mobile.go index 8ade1a8e..3cbbfa87 100644 --- a/notifiers/mobile.go +++ b/notifiers/mobile.go @@ -14,8 +14,6 @@ import ( var _ notifier.Notifier = (*mobilePush)(nil) -const mobileIdentifier = "com.statping" - type mobilePush struct { *notifications.Notification } @@ -78,7 +76,6 @@ func (m *mobilePush) OnFailure(s *services.Service, f *failures.Failure) error { msg := &pushArray{ Message: fmt.Sprintf("Your service '%v' is currently failing! Reason: %v", s.Name, f.Issue), Title: "Service Offline", - Topic: mobileIdentifier, Data: data, } return m.Send(msg) @@ -88,10 +85,10 @@ func (m *mobilePush) OnFailure(s *services.Service, f *failures.Failure) error { func (m *mobilePush) OnSuccess(s *services.Service) error { data := dataJson(s, nil) msg := &pushArray{ - Message: "Service is Online!", - Title: "Service Online", - Topic: mobileIdentifier, - Data: data, + Message: "Service is Online!", + Title: "Service Online", + Data: data, + Platform: 2, } return m.Send(msg) } @@ -101,9 +98,8 @@ func (m *mobilePush) OnTest() (string, error) { msg := &pushArray{ Message: "Testing the Mobile Notifier", Title: "Testing Notifications", - Topic: mobileIdentifier, Tokens: []string{m.Var1}, - Platform: utils.ToInt(m.Var2), + Platform: 2, } body, err := pushRequest(msg) if err != nil { @@ -134,9 +130,6 @@ func (m *mobilePush) Send(pushMessage *pushArray) error { } func pushRequest(msg *pushArray) ([]byte, error) { - if msg.Platform == 1 { - msg.Title = "" - } body, err := json.Marshal(&PushNotification{[]*pushArray{msg}}) if err != nil { return nil, err diff --git a/notifiers/mobile_test.go b/notifiers/mobile_test.go index 21dd777b..f4eeb73e 100644 --- a/notifiers/mobile_test.go +++ b/notifiers/mobile_test.go @@ -7,14 +7,12 @@ import ( "github.com/statping/statping/utils" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "os" "testing" "time" ) var ( - MOBILE_ID string - MOBILE_NUMBER string + mobileToken string ) func TestMobileNotifier(t *testing.T) { @@ -22,25 +20,22 @@ func TestMobileNotifier(t *testing.T) { err := utils.InitLogs() require.Nil(t, err) - MOBILE_ID = utils.Params.GetString("MOBILE_ID") - MOBILE_NUMBER = utils.Params.GetString("MOBILE_NUMBER") - Mobile.Var1 = MOBILE_ID + mobileToken = utils.Params.GetString("MOBILE_TOKEN") + Mobile.Var1 = mobileToken db, err := database.OpenTester() require.Nil(t, err) db.AutoMigrate(¬ifications.Notification{}) notifications.SetDB(db) - Mobile.Var1 = MOBILE_ID - Mobile.Var2 = os.Getenv("MOBILE_NUMBER") - if MOBILE_ID == "" { + Mobile.Var1 = mobileToken + if mobileToken == "" { t.Log("Mobile notifier testing skipped, missing MOBILE_ID environment variable") t.SkipNow() } t.Run("Load Mobile", func(t *testing.T) { - Mobile.Var1 = MOBILE_ID - Mobile.Var2 = MOBILE_NUMBER + Mobile.Var1 = mobileToken Mobile.Delay = time.Duration(100 * time.Millisecond) Mobile.Limits = 10 Mobile.Enabled = null.NewNullBool(true) @@ -48,8 +43,7 @@ func TestMobileNotifier(t *testing.T) { Add(Mobile) assert.Equal(t, "Hunter Long", Mobile.Author) - assert.Equal(t, MOBILE_ID, Mobile.Var1) - assert.Equal(t, MOBILE_NUMBER, Mobile.Var2) + assert.Equal(t, mobileToken, Mobile.Var1) }) t.Run("Mobile Notifier Tester", func(t *testing.T) { @@ -67,7 +61,6 @@ func TestMobileNotifier(t *testing.T) { }) t.Run("Mobile Test", func(t *testing.T) { - t.SkipNow() _, err := Mobile.OnTest() assert.Nil(t, err) }) diff --git a/notifiers/twilio.go b/notifiers/twilio.go index 12be4f2e..860c4d27 100644 --- a/notifiers/twilio.go +++ b/notifiers/twilio.go @@ -1,6 +1,7 @@ package notifiers import ( + "encoding/base64" "encoding/json" "errors" "fmt" @@ -70,7 +71,7 @@ func (t *twilio) sendMessage(message string) (string, error) { v.Set("Body", message) rb := strings.NewReader(v.Encode()) - authHeader := utils.Base64(fmt.Sprintf("%s:%s", t.ApiKey, t.ApiSecret)) + authHeader := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", t.ApiKey, t.ApiSecret))) contents, _, err := utils.HttpRequest(twilioUrl, "POST", "application/x-www-form-urlencoded", []string{"Authorization=Basic " + authHeader}, rb, 10*time.Second, true, nil) success, _ := twilioSuccess(contents) diff --git a/types/checkins/database.go b/types/checkins/database.go index 877d67db..9c21abaf 100644 --- a/types/checkins/database.go +++ b/types/checkins/database.go @@ -2,7 +2,6 @@ package checkins import ( "github.com/statping/statping/database" - "github.com/statping/statping/utils" ) var db database.Database @@ -32,13 +31,7 @@ func All() []*Checkin { } func (c *Checkin) Create() error { - if c.ApiKey == "" { - c.ApiKey = utils.RandomString(32) - } q := db.Create(c) - - c.Start() - go c.CheckinRoutine() return q.Error() } @@ -48,11 +41,6 @@ func (c *Checkin) Update() error { } func (c *Checkin) Delete() error { - c.Close() - q := dbHits.Where("checkin = ?", c.Id).Delete(&CheckinHit{}) - if err := q.Error(); err != nil { - return err - } - q = db.Model(&Checkin{}).Delete(c) + q := db.Delete(c) return q.Error() } diff --git a/types/checkins/hooks.go b/types/checkins/hooks.go new file mode 100644 index 00000000..5a57e796 --- /dev/null +++ b/types/checkins/hooks.go @@ -0,0 +1,25 @@ +package checkins + +import "github.com/statping/statping/utils" + +func (c *Checkin) BeforeCreate() error { + if c.ApiKey == "" { + c.ApiKey = utils.RandomString(32) + } + return nil +} + +func (c *Checkin) AfterCreate() error { + c.Start() + go c.CheckinRoutine() + return nil +} + +func (c *Checkin) BeforeDelete() error { + c.Close() + q := dbHits.Where("checkin = ?", c.Id).Delete(&CheckinHit{}) + if err := q.Error(); err != nil { + return err + } + return nil +} diff --git a/types/checkins/struct.go b/types/checkins/struct.go index 30c1f6b6..82f725c6 100644 --- a/types/checkins/struct.go +++ b/types/checkins/struct.go @@ -2,7 +2,6 @@ package checkins import ( "github.com/statping/statping/types/failures" - "github.com/statping/statping/utils" "time" ) @@ -30,10 +29,3 @@ type CheckinHit struct { From string `gorm:"column:from_location" json:"from"` CreatedAt time.Time `gorm:"column:created_at" json:"created_at"` } - -func (c *Checkin) BeforeCreate() (err error) { - if c.ApiKey == "" { - c.ApiKey = utils.RandomString(7) - } - return nil -} diff --git a/types/configs/connection.go b/types/configs/connection.go index ea5023de..c32c4fe2 100644 --- a/types/configs/connection.go +++ b/types/configs/connection.go @@ -23,8 +23,6 @@ import ( // Connect will attempt to connect to the sqlite, postgres, or mysql database func Connect(configs *DbConfig, retry bool) error { conn := configs.ConnectionString() - p := utils.Params - var err error log.WithFields(utils.ToFields(configs, conn)).Debugln("attempting to connect to database") @@ -40,20 +38,16 @@ func Connect(configs *DbConfig, retry bool) error { } } - apiSecret := p.GetString("API_SECRET") - configs.ApiSecret = apiSecret + configs.ApiSecret = utils.Params.GetString("API_SECRET") log.WithFields(utils.ToFields(dbSession)).Debugln("connected to database") - maxOpenConn := p.GetInt("MAX_OPEN_CONN") - maxIdleConn := p.GetInt("MAX_IDLE_CONN") - maxLifeConn := p.GetDuration("MAX_LIFE_CONN") + db := dbSession.DB() + db.SetMaxOpenConns(utils.Params.GetInt("MAX_OPEN_CONN")) + db.SetMaxIdleConns(utils.Params.GetInt("MAX_IDLE_CONN")) + db.SetConnMaxLifetime(utils.Params.GetDuration("MAX_LIFE_CONN")) - dbSession.DB().SetMaxOpenConns(maxOpenConn) - dbSession.DB().SetMaxIdleConns(maxIdleConn) - dbSession.DB().SetConnMaxLifetime(maxLifeConn) - - if dbSession.DB().Ping() == nil { + if db.Ping() == nil { if utils.VerboseMode >= 4 { dbSession.LogMode(true).Debug().SetLogger(gorm.Logger{log}) } diff --git a/types/configs/database.go b/types/configs/database.go index f400875c..4841f49a 100644 --- a/types/configs/database.go +++ b/types/configs/database.go @@ -66,11 +66,6 @@ func (d *DbConfig) Update() error { return nil } -// Save will initially create the config.yml file -func (d *DbConfig) Delete() error { - return os.Remove(d.filename) -} - // DropDatabase will DROP each table Statping created func (d *DbConfig) DropDatabase() error { var DbModels = []interface{}{&services.Service{}, &users.User{}, &hits.Hit{}, &failures.Failure{}, &messages.Message{}, &groups.Group{}, &checkins.Checkin{}, &checkins.CheckinHit{}, ¬ifications.Notification{}, &incidents.Incident{}, &incidents.IncidentUpdate{}} diff --git a/types/configs/migration.go b/types/configs/migration.go index def9c29f..48c87660 100644 --- a/types/configs/migration.go +++ b/types/configs/migration.go @@ -70,7 +70,6 @@ func (d *DbConfig) BackupAssets() error { //This function will NOT remove previous records, tables or columns from the database. //If this function has an issue, it will ROLLBACK to the previous state. func (d *DbConfig) MigrateDatabase() error { - var DbModels = []interface{}{&services.Service{}, &users.User{}, &hits.Hit{}, &failures.Failure{}, &messages.Message{}, &groups.Group{}, &checkins.Checkin{}, &checkins.CheckinHit{}, ¬ifications.Notification{}, &incidents.Incident{}, &incidents.IncidentUpdate{}} log.Infoln("Migrating Database Tables...") diff --git a/types/configs/seed_test.go b/types/configs/seed_test.go deleted file mode 100644 index b6c16e58..00000000 --- a/types/configs/seed_test.go +++ /dev/null @@ -1,11 +0,0 @@ -package configs - -//func preparePostgresDB(t *testing.T) (database.Database, error) { -// dbName := fmt.Sprintf("db_%d", time.Now().UnixNano()) -// db, err := database.Openw("sqlite3", dbName) -// if err != nil { -// t.Fatalf("open connection: %s", err) -// } -// -// return db, db.Error() -//} diff --git a/types/failures/samples.go b/types/failures/samples.go index d84f4b24..db42f3c1 100644 --- a/types/failures/samples.go +++ b/types/failures/samples.go @@ -22,14 +22,18 @@ func Samples() error { Issue: "Server failure", CreatedAt: utils.Now().Add(-time.Duration(3*i) * 86400), } - f1.Create() + if err := f1.Create(); err != nil { + return err + } f2 := &Failure{ Service: i, Issue: "Server failure", CreatedAt: utils.Now().Add(-time.Duration(5*i) * 12400), } - f2.Create() + if err := f2.Create(); err != nil { + return err + } log.Infoln(fmt.Sprintf("Adding %v Failure records to service", 400)) diff --git a/types/messages/hooks.go b/types/messages/hooks.go new file mode 100644 index 00000000..5eee1912 --- /dev/null +++ b/types/messages/hooks.go @@ -0,0 +1,14 @@ +package messages + +import ( + "github.com/statping/statping/utils" +) + +// BeforeCreate for Message will set CreatedAt to UTC +func (m *Message) BeforeCreate() (err error) { + if m.CreatedAt.IsZero() { + m.CreatedAt = utils.Now() + m.UpdatedAt = utils.Now() + } + return +} diff --git a/types/messages/struct.go b/types/messages/struct.go index c0af7386..cadf3cf1 100644 --- a/types/messages/struct.go +++ b/types/messages/struct.go @@ -20,12 +20,3 @@ type Message struct { CreatedAt time.Time `gorm:"column:created_at" json:"created_at" json:"created_at"` UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at" json:"updated_at"` } - -// BeforeCreate for Message will set CreatedAt to UTC -func (m *Message) BeforeCreate() (err error) { - if m.CreatedAt.IsZero() { - m.CreatedAt = time.Now().UTC() - m.UpdatedAt = time.Now().UTC() - } - return -} diff --git a/types/notifications/hooks.go b/types/notifications/hooks.go new file mode 100644 index 00000000..a6d2caf5 --- /dev/null +++ b/types/notifications/hooks.go @@ -0,0 +1,10 @@ +package notifications + +import "github.com/statping/statping/utils" + +// AfterFind for Notification will set the timezone +func (n *Notification) AfterFind() (err error) { + n.CreatedAt = utils.Now() + n.UpdatedAt = utils.Now() + return +} diff --git a/types/notifications/methods.go b/types/notifications/methods.go index 6b2e527d..71c82337 100644 --- a/types/notifications/methods.go +++ b/types/notifications/methods.go @@ -13,25 +13,6 @@ func (n *Notification) Name() string { return newName } -// AfterFind for Notification will set the timezone -func (n *Notification) AfterFind() (err error) { - n.CreatedAt = utils.Now() - n.UpdatedAt = utils.Now() - return -} - -// AddQueue will add any type of interface (json, string, struct, etc) into the Notifiers queue -//func (n *Notification) AddQueue(uid string, msg interface{}) { -// data := &QueueData{uid, msg} -// n.Queue = append(n.Queue, data) -// log.WithFields(utils.ToFields(data, n)).Debug(fmt.Sprintf("Notifier '%v' added new item (%v) to the queue. (%v queued)", n.Method, uid, len(n.Queue))) -//} - -// CanTest returns true if the notifier implements the OnTest interface -//func (n *Notification) CanTest() bool { -// return n.testable -//} - // LastSent returns a time.Duration of the last sent notification for the notifier func (n *Notification) LastSent() time.Duration { since := time.Since(n.lastSent) @@ -43,11 +24,6 @@ func (n *Notification) CanSend() bool { return false } - //fmt.Println("Last sent: ", n.lastSent.String()) - //fmt.Println("Last count: ", n.lastSentCount) - //fmt.Println("Limits: ", n.Limits) - //fmt.Println("Last sent before now: ", n.lastSent.Add(60*time.Second).Before(utils.Now())) - // the last sent notification was past 1 minute (limit per minute) if n.lastSent.Add(60 * time.Minute).Before(utils.Now()) { if n.lastSentCount != 0 { @@ -86,7 +62,7 @@ func (n *Notification) GetValue(dbField string) string { case "api_secret": return n.ApiSecret case "limits": - return utils.ToString(int(n.Limits)) + return utils.ToString(n.Limits) default: return "" } @@ -116,34 +92,3 @@ func (n *Notification) IsRunning() bool { return true } } - -// Init accepts the Notifier interface to initialize the notifier -//func Init(n Notifier) (*Notification, error) { -// if Exists(n.Select().Method) { -// AllCommunications = append(AllCommunications, n) -// } else { -// _, err := insertDatabase(n) -// if err != nil { -// log.Errorln(err) -// return nil, err -// } -// AllCommunications = append(AllCommunications, n) -// } -// -// notify, err := SelectNotification(n) -// if err != nil { -// return nil, errors.Wrap(err, "error selecting notification") -// } -// -// notify.CreatedAt = time.Now().UTC() -// notify.UpdatedAt = time.Now().UTC() -// if notify.Delay.Seconds() == 0 { -// notify.Delay = 1 * time.Second -// } -// notify.testable = utils.IsType(n, new(Tester)) -// notify.Form = n.Select().Form -// -// AllCommunications = append(AllCommunications, n) -// -// return nil, err -//} diff --git a/types/services/database.go b/types/services/database.go index 26fbc790..8f1aa79f 100644 --- a/types/services/database.go +++ b/types/services/database.go @@ -9,10 +9,19 @@ import ( ) var ( - db database.Database - log = utils.Log.WithField("type", "service") + db database.Database + log = utils.Log.WithField("type", "service") + allServices map[int64]*Service ) +func init() { + allServices = make(map[int64]*Service) +} + +func Services() map[int64]*Service { + return allServices +} + func SetDB(database database.Database) { db = database.Model(&Service{}) } @@ -54,30 +63,13 @@ func (s *Service) Create() error { return nil } -func (s *Service) AfterCreate() error { - allServices[s.Id] = s - return nil -} - func (s *Service) Update() error { q := db.Update(s) - allServices[s.Id] = s - s.Close() - s.SleepDuration = s.Duration() - go ServiceCheckQueue(allServices[s.Id], true) return q.Error() } func (s *Service) Delete() error { - s.Close() - if err := s.DeleteFailures(); err != nil { - return err - } - if err := s.DeleteHits(); err != nil { - return err - } - delete(allServices, s.Id) - q := db.Model(&Service{}).Delete(s) + q := db.Delete(s) return q.Error() } diff --git a/types/services/failures.go b/types/services/failures.go index e524d158..d670f58a 100644 --- a/types/services/failures.go +++ b/types/services/failures.go @@ -17,8 +17,7 @@ func (s *Service) AllFailures() failures.Failurer { } func (s *Service) FailuresSince(t time.Time) failures.Failurer { - fails := failures.Since(t, s) - return fails + return failures.Since(t, s) } func (s *Service) DowntimeAgo() string { diff --git a/types/services/hooks.go b/types/services/hooks.go new file mode 100644 index 00000000..4c774c4b --- /dev/null +++ b/types/services/hooks.go @@ -0,0 +1,37 @@ +package services + +import "github.com/statping/statping/utils" + +// BeforeCreate for Service will set CreatedAt to UTC +func (s *Service) BeforeCreate() (err error) { + if s.CreatedAt.IsZero() { + s.CreatedAt = utils.Now() + s.UpdatedAt = utils.Now() + } + return +} + +func (s *Service) AfterCreate() error { + allServices[s.Id] = s + return nil +} + +func (s *Service) AfterUpdate() error { + allServices[s.Id] = s + s.Close() + s.SleepDuration = s.Duration() + go ServiceCheckQueue(allServices[s.Id], true) + return nil +} + +func (s *Service) BeforeDelete() error { + s.Close() + if err := s.DeleteFailures(); err != nil { + return err + } + if err := s.DeleteHits(); err != nil { + return err + } + delete(allServices, s.Id) + return nil +} diff --git a/types/services/methods.go b/types/services/methods.go index 286f876b..7a37c62b 100644 --- a/types/services/methods.go +++ b/types/services/methods.go @@ -252,26 +252,18 @@ func SelectAllServices(start bool) (map[int64]*Service, error) { if len(allServices) > 0 { return allServices, nil } - for _, s := range all() { - if start { CheckinProcess(s) } - - fails := s.AllFailures().LastAmount(limitedFailures) - s.Failures = fails - + s.Failures = s.AllFailures().LastAmount(limitedFailures) for _, c := range s.Checkins() { s.AllCheckins = append(s.AllCheckins, c) } - // collect initial service stats s.UpdateStats() - allServices[s.Id] = s } - return allServices, nil } @@ -281,15 +273,16 @@ func (s *Service) UpdateStats() *Service { s.AvgResponse = s.AvgTime() s.FailuresLast24Hours = s.FailuresSince(utils.Now().Add(-time.Hour * 24)).Count() + allFails := s.AllFailures() if s.LastOffline.IsZero() { - lastFail := s.AllFailures().Last() + lastFail := allFails.Last() if lastFail != nil { s.LastOffline = lastFail.CreatedAt } } s.Stats = &Stats{ - Failures: s.AllFailures().Count(), + Failures: allFails.Count(), Hits: s.AllHits().Count(), FirstHit: s.FirstHit().CreatedAt, } @@ -309,11 +302,8 @@ func (s *Service) OnlineDaysPercent(days int) float32 { // OnlineSince accepts a time since parameter to return the percent of a service's uptime. func (s *Service) OnlineSince(ago time.Time) float32 { - failed := s.FailuresSince(ago) - failsList := failed.Count() - - total := s.HitsSince(ago) - hitsList := total.Count() + failsList := s.FailuresSince(ago).Count() + hitsList := s.HitsSince(ago).Count() if failsList == 0 { s.Online24Hours = 100.00 @@ -348,3 +338,11 @@ func (s *Service) Downtime() time.Duration { return fail.CreatedAt.Sub(hit.CreatedAt) } + +// ServiceOrder will reorder the services based on 'order_id' (Order) +type ServiceOrder []Service + +// Sort interface for resroting the Services in order +func (c ServiceOrder) Len() int { return len(c) } +func (c ServiceOrder) Swap(i, j int) { c[int64(i)], c[int64(j)] = c[int64(j)], c[int64(i)] } +func (c ServiceOrder) Less(i, j int) bool { return c[i].Order < c[j].Order } diff --git a/types/services/routine.go b/types/services/routine.go index b9e1f13c..82915a9f 100644 --- a/types/services/routine.go +++ b/types/services/routine.go @@ -21,7 +21,6 @@ import ( func CheckServices() { log.Infoln(fmt.Sprintf("Starting monitoring process for %v Services", len(allServices))) for _, s := range allServices { - //go CheckinRoutine() time.Sleep(250 * time.Millisecond) go ServiceCheckQueue(s, true) } @@ -43,14 +42,14 @@ CheckLoop: s.CheckService(record) s.UpdateStats() s.Checkpoint = s.Checkpoint.Add(s.Duration()) - sleep := s.Checkpoint.Sub(time.Now()) if !s.Online { s.SleepDuration = s.Duration() } else { - s.SleepDuration = sleep + s.SleepDuration = s.Checkpoint.Sub(time.Now()) } + default: + } - continue } } @@ -79,9 +78,7 @@ func dnsCheck(s *Service) (int64, error) { if err != nil { return 0, err } - t2 := utils.Now() - subTime := t2.Sub(t1).Microseconds() - return subTime, err + return utils.Now().Sub(t1).Microseconds(), err } func isIPv6(address string) bool { @@ -92,8 +89,7 @@ func isIPv6(address string) bool { func CheckIcmp(s *Service, record bool) (*Service, error) { defer s.updateLastCheck() - err := utils.Ping(s.Domain, s.Timeout) - if err != nil { + if err := utils.Ping(s.Domain, s.Timeout); err != nil { if record { recordFailure(s, fmt.Sprintf("Could not send ICMP to service %v, %v", s.Domain, err)) } @@ -140,8 +136,7 @@ func CheckGrpc(s *Service, record bool) (*Service, error) { } return s, err } - t2 := utils.Now() - s.Latency = t2.Sub(t1).Microseconds() + s.Latency = utils.Now().Sub(t1).Microseconds() s.LastResponse = "" s.Online = true if record { @@ -202,8 +197,7 @@ func CheckTcp(s *Service, record bool) (*Service, error) { defer conn.Close() } - t2 := utils.Now() - s.Latency = t2.Sub(t1).Microseconds() + s.Latency = utils.Now().Sub(t1).Microseconds() s.LastResponse = "" s.Online = true if record { @@ -279,8 +273,7 @@ func CheckHttp(s *Service, record bool) (*Service, error) { } return s, err } - t2 := utils.Now() - s.Latency = t2.Sub(t1).Microseconds() + s.Latency = utils.Now().Sub(t1).Microseconds() s.LastResponse = string(content) s.LastStatusCode = res.StatusCode diff --git a/types/services/struct.go b/types/services/struct.go index 88406f21..f6ea3d19 100644 --- a/types/services/struct.go +++ b/types/services/struct.go @@ -4,22 +4,9 @@ import ( "github.com/statping/statping/types/checkins" "github.com/statping/statping/types/failures" "github.com/statping/statping/types/null" - "github.com/statping/statping/utils" "time" ) -var ( - allServices map[int64]*Service -) - -func init() { - allServices = make(map[int64]*Service) -} - -func Services() map[int64]*Service { - return allServices -} - // Service is the main struct for Services type Service struct { Id int64 `gorm:"primary_key;column:id" json:"id" yaml:"id"` @@ -82,20 +69,3 @@ type Stats struct { Hits int `gorm:"-" json:"hits"` FirstHit time.Time `gorm:"-" json:"first_hit"` } - -// BeforeCreate for Service will set CreatedAt to UTC -func (s *Service) BeforeCreate() (err error) { - if s.CreatedAt.IsZero() { - s.CreatedAt = utils.Now() - s.UpdatedAt = utils.Now() - } - return -} - -// ServiceOrder will reorder the services based on 'order_id' (Order) -type ServiceOrder []Service - -// Sort interface for resroting the Services in order -func (c ServiceOrder) Len() int { return len(c) } -func (c ServiceOrder) Swap(i, j int) { c[int64(i)], c[int64(j)] = c[int64(j)], c[int64(i)] } -func (c ServiceOrder) Less(i, j int) bool { return c[i].Order < c[j].Order } diff --git a/types/services/yaml.go b/types/services/yaml.go index e3a73da8..1ae32c95 100644 --- a/types/services/yaml.go +++ b/types/services/yaml.go @@ -12,6 +12,10 @@ type yamlFile struct { // LoadServicesYaml will attempt to load the 'services.yml' file for Service Auto Creation on startup. func LoadServicesYaml() (*yamlFile, error) { + if !utils.FileExists(utils.Directory + "/services.yml") { + return nil, nil + } + f, err := utils.OpenFile(utils.Directory + "/services.yml") if err != nil { return nil, err diff --git a/types/users/auth.go b/types/users/auth.go index 760ff483..5a0c842f 100644 --- a/types/users/auth.go +++ b/types/users/auth.go @@ -2,7 +2,7 @@ package users import ( "fmt" - "golang.org/x/crypto/bcrypt" + "github.com/statping/statping/utils" "time" ) @@ -14,16 +14,10 @@ func AuthUser(username, password string) (*User, bool) { log.Warnln(fmt.Errorf("user %v not found", username)) return nil, false } - if checkHash(password, user.Password) { + if utils.CheckHash(password, user.Password) { user.UpdatedAt = time.Now().UTC() user.Update() return user, true } return nil, false } - -// checkHash returns true if the password matches with a hashed bcrypt password -func checkHash(password, hash string) bool { - err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) - return err == nil -} diff --git a/types/users/database.go b/types/users/database.go index e6d468bf..ea5d477f 100644 --- a/types/users/database.go +++ b/types/users/database.go @@ -52,10 +52,3 @@ func (u *User) Delete() error { } return q.Error() } - -func (u *User) BeforeCreate() error { - u.Password = utils.HashPassword(u.Password) - u.ApiKey = utils.NewSHA256Hash() - u.ApiSecret = utils.NewSHA256Hash() - return nil -} diff --git a/types/users/hooks.go b/types/users/hooks.go new file mode 100644 index 00000000..aeda3ff9 --- /dev/null +++ b/types/users/hooks.go @@ -0,0 +1,10 @@ +package users + +import "github.com/statping/statping/utils" + +func (u *User) BeforeCreate() error { + u.Password = utils.HashPassword(u.Password) + u.ApiKey = utils.NewSHA256Hash() + u.ApiSecret = utils.NewSHA256Hash() + return nil +} diff --git a/utils/encryption.go b/utils/encryption.go index 5fe29726..690f23e6 100644 --- a/utils/encryption.go +++ b/utils/encryption.go @@ -2,7 +2,6 @@ package utils import ( "crypto/sha256" - "encoding/base64" "fmt" "golang.org/x/crypto/bcrypt" "math/rand" @@ -15,6 +14,12 @@ func HashPassword(password string) string { return string(bytes) } +// CheckHash returns true if the password matches with a hashed bcrypt password +func CheckHash(password, hash string) bool { + err := bcrypt.CompareHashAndPassword([]byte(hash), []byte(password)) + return err == nil +} + // NewSHA1Hash returns a random SHA1 hash based on a specific length func NewSHA256Hash() string { d := make([]byte, 10) @@ -23,10 +28,6 @@ func NewSHA256Hash() string { return fmt.Sprintf("%x", sha256.Sum256(d)) } -func Base64(s string) string { - return base64.StdEncoding.EncodeToString([]byte(s)) -} - var characterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789") // RandomString generates a random string of n length diff --git a/utils/log.go b/utils/log.go index 3117718f..fb6c9512 100644 --- a/utils/log.go +++ b/utils/log.go @@ -139,7 +139,7 @@ func replaceVal(d interface{}) interface{} { // createLog will create the '/logs' directory based on a directory func createLog(dir string) error { if !FolderExists(dir + "/logs") { - CreateDirectory(dir + "/logs") + return CreateDirectory(dir + "/logs") } return nil } diff --git a/utils/time.go b/utils/time.go index 12601e9b..fd1a2394 100644 --- a/utils/time.go +++ b/utils/time.go @@ -5,14 +5,6 @@ import ( "time" ) -// Timezoner returns the time.Time with the user set timezone -func Timezoner(t time.Time, zone float32) time.Time { - zoneInt := float32(3600) * zone - loc := time.FixedZone("", int(zoneInt)) - timez := t.In(loc) - return timez -} - // Now returns the UTC timestamp func Now() time.Time { return time.Now().UTC() diff --git a/utils/utils_test.go b/utils/utils_test.go index 15088251..95ee5820 100644 --- a/utils/utils_test.go +++ b/utils/utils_test.go @@ -122,15 +122,6 @@ func ExampleStringInt() { // Output: 42 } -func TestTimezone(t *testing.T) { - zone := float32(-4.0) - loc, _ := time.LoadLocation("America/Los_Angeles") - timestamp := time.Date(2018, 1, 1, 10, 0, 0, 0, loc) - timezone := Timezoner(timestamp, zone) - assert.Equal(t, "2018-01-01 10:00:00 -0800 PST", timestamp.String()) - assert.Equal(t, "2018-01-01 18:00:00 +0000 UTC", timezone.UTC().String()) -} - func TestTimestamp_Ago(t *testing.T) { now := Timestamp(time.Now()) assert.Equal(t, "Just now", now.Ago())