mirror of https://github.com/statping/statping
comments and organization
parent
b4159359b2
commit
4cd669b9d0
|
|
@ -0,0 +1,51 @@
|
||||||
|
package handlers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/subtle"
|
||||||
|
"github.com/statping/statping/types/core"
|
||||||
|
"github.com/statping/statping/utils"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
// hasSetupEnv checks to see if the GO_ENV is set to 'true'
|
||||||
|
// or if the Statping instance has not been setup yet
|
||||||
|
func hasSetupEnv() bool {
|
||||||
|
if utils.Params.Get("GO_ENV") == "test" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if core.App == nil {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
if !core.App.Setup {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// hasAPIQuery checks the `api` query parameter against the API Secret Key
|
||||||
|
func hasAPIQuery(r *http.Request) bool {
|
||||||
|
query := r.URL.Query()
|
||||||
|
key := query.Get("api")
|
||||||
|
if key == "" {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
if subtle.ConstantTimeCompare([]byte(key), []byte(core.App.ApiSecret)) == 1 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// hasAuthorizationHeader check to see if the Authorization header is the correct API Secret Key
|
||||||
|
func hasAuthorizationHeader(r *http.Request) bool {
|
||||||
|
var token string
|
||||||
|
tokens, ok := r.Header["Authorization"]
|
||||||
|
if ok && len(tokens) >= 1 {
|
||||||
|
token = tokens[0]
|
||||||
|
token = strings.TrimPrefix(token, "Bearer ")
|
||||||
|
if subtle.ConstantTimeCompare([]byte(token), []byte(core.App.ApiSecret)) == 1 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
@ -21,10 +21,8 @@ func findGroup(r *http.Request) (*groups.Group, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if !g.Public.Bool {
|
if !g.Public.Bool && !IsReadAuthenticated(r) {
|
||||||
if !IsReadAuthenticated(r) {
|
return nil, errors.NotAuthenticated
|
||||||
return nil, errors.NotAuthenticated
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return g, nil
|
return g, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,14 @@
|
||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/subtle"
|
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/dgrijalva/jwt-go"
|
"github.com/dgrijalva/jwt-go"
|
||||||
"github.com/statping/statping/types/core"
|
|
||||||
"github.com/statping/statping/types/errors"
|
"github.com/statping/statping/types/errors"
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/statping/statping/source"
|
"github.com/statping/statping/source"
|
||||||
|
|
@ -86,22 +83,14 @@ func RunHTTPServer(ip string, port int) error {
|
||||||
|
|
||||||
// IsReadAuthenticated will allow Read Only authentication for some routes
|
// IsReadAuthenticated will allow Read Only authentication for some routes
|
||||||
func IsReadAuthenticated(r *http.Request) bool {
|
func IsReadAuthenticated(r *http.Request) bool {
|
||||||
if !core.App.Setup {
|
if ok := hasSetupEnv(); ok {
|
||||||
return false
|
|
||||||
}
|
|
||||||
var token string
|
|
||||||
query := r.URL.Query()
|
|
||||||
key := query.Get("api")
|
|
||||||
if subtle.ConstantTimeCompare([]byte(key), []byte(core.App.ApiSecret)) == 1 {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
tokens, ok := r.Header["Authorization"]
|
if ok := hasAPIQuery(r); ok {
|
||||||
if ok && len(tokens) >= 1 {
|
return true
|
||||||
token = tokens[0]
|
}
|
||||||
token = strings.TrimPrefix(token, "Bearer ")
|
if ok := hasAuthorizationHeader(r); ok {
|
||||||
if subtle.ConstantTimeCompare([]byte(token), []byte(core.App.ApiSecret)) == 1 {
|
return true
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return IsFullAuthenticated(r)
|
return IsFullAuthenticated(r)
|
||||||
}
|
}
|
||||||
|
|
@ -109,23 +98,14 @@ func IsReadAuthenticated(r *http.Request) bool {
|
||||||
// IsFullAuthenticated returns true if the HTTP request is authenticated. You can set the environment variable GO_ENV=test
|
// IsFullAuthenticated returns true if the HTTP request is authenticated. You can set the environment variable GO_ENV=test
|
||||||
// to bypass the admin authenticate to the dashboard features.
|
// to bypass the admin authenticate to the dashboard features.
|
||||||
func IsFullAuthenticated(r *http.Request) bool {
|
func IsFullAuthenticated(r *http.Request) bool {
|
||||||
if utils.Params.Get("GO_ENV") == "test" {
|
if ok := hasSetupEnv(); ok {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if core.App == nil {
|
if ok := hasAPIQuery(r); ok {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if !core.App.Setup {
|
if ok := hasAuthorizationHeader(r); ok {
|
||||||
return false
|
return true
|
||||||
}
|
|
||||||
var token string
|
|
||||||
tokens, ok := r.Header["Authorization"]
|
|
||||||
if ok && len(tokens) >= 1 {
|
|
||||||
token = tokens[0]
|
|
||||||
token = strings.TrimPrefix(token, "Bearer ")
|
|
||||||
if subtle.ConstantTimeCompare([]byte(token), []byte(core.App.ApiSecret)) == 1 {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return IsAdmin(r)
|
return IsAdmin(r)
|
||||||
}
|
}
|
||||||
|
|
@ -155,7 +135,15 @@ func getJwtToken(r *http.Request) (JwtClaim, error) {
|
||||||
return claims, err
|
return claims, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ScopeName will show private JSON fields in the API.
|
||||||
|
// It will return "admin" if request has valid admin authentication.
|
||||||
func ScopeName(r *http.Request) string {
|
func ScopeName(r *http.Request) string {
|
||||||
|
if ok := hasAPIQuery(r); ok {
|
||||||
|
return "admin"
|
||||||
|
}
|
||||||
|
if ok := hasAuthorizationHeader(r); ok {
|
||||||
|
return "admin"
|
||||||
|
}
|
||||||
claim, err := getJwtToken(r)
|
claim, err := getJwtToken(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ""
|
return ""
|
||||||
|
|
@ -168,12 +156,6 @@ func ScopeName(r *http.Request) string {
|
||||||
|
|
||||||
// IsAdmin returns true if the user session is an administrator
|
// IsAdmin returns true if the user session is an administrator
|
||||||
func IsAdmin(r *http.Request) bool {
|
func IsAdmin(r *http.Request) bool {
|
||||||
if !core.App.Setup {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if utils.Params.GetString("GO_ENV") == "test" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
claim, err := getJwtToken(r)
|
claim, err := getJwtToken(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
|
|
@ -183,10 +165,7 @@ func IsAdmin(r *http.Request) bool {
|
||||||
|
|
||||||
// IsUser returns true if the user is registered
|
// IsUser returns true if the user is registered
|
||||||
func IsUser(r *http.Request) bool {
|
func IsUser(r *http.Request) bool {
|
||||||
if !core.App.Setup {
|
if ok := hasSetupEnv(); ok {
|
||||||
return false
|
|
||||||
}
|
|
||||||
if utils.Params.Get("GO_ENV") == "test" {
|
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
tk, err := getJwtToken(r)
|
tk, err := getJwtToken(r)
|
||||||
|
|
|
||||||
|
|
@ -90,6 +90,9 @@ func sendLog(next http.Handler) http.Handler {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// scoped is a middleware handler that will remove private fields based on struct tags
|
||||||
|
// this will look for the `scope:"user,admin"` tag and remove the JSON field from response
|
||||||
|
// if user is not authenticated based on the scope.
|
||||||
func scoped(handler func(r *http.Request) interface{}) http.Handler {
|
func scoped(handler func(r *http.Request) interface{}) http.Handler {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
data := handler(r)
|
data := handler(r)
|
||||||
|
|
|
||||||
|
|
@ -215,10 +215,9 @@ func apiServiceDeleteHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func apiAllServicesHandler(r *http.Request) interface{} {
|
func apiAllServicesHandler(r *http.Request) interface{} {
|
||||||
user := IsUser(r)
|
|
||||||
var srvs []services.Service
|
var srvs []services.Service
|
||||||
for _, v := range services.AllInOrder() {
|
for _, v := range services.AllInOrder() {
|
||||||
if !v.Public.Bool && !user {
|
if !v.Public.Bool && !IsUser(r) {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
srvs = append(srvs, v)
|
srvs = append(srvs, v)
|
||||||
|
|
|
||||||
|
|
@ -26,14 +26,16 @@ func LoadServicesYaml() (*yamlFile, error) {
|
||||||
log.Infof("Found %d services inside services.yml file", len(svrs.Services))
|
log.Infof("Found %d services inside services.yml file", len(svrs.Services))
|
||||||
|
|
||||||
for _, svr := range svrs.Services {
|
for _, svr := range svrs.Services {
|
||||||
log.Infof("Service %s %d, hash: %s", svr.Name, svr.Id, svr.Hash())
|
serviceByHash := findServiceByHash(svr.Hash())
|
||||||
if findServiceByHash(svr.Hash()) == nil {
|
if serviceByHash == nil {
|
||||||
if err := svr.Create(); err != nil {
|
if err := svr.Create(); err != nil {
|
||||||
return nil, errors.Wrapf(err, "could not create service %s", svr.Name)
|
return nil, errors.Wrapf(err, "could not create service %s", svr.Name)
|
||||||
}
|
}
|
||||||
log.Infof("Automatically created service '%s' checking %s", svr.Name, svr.Domain)
|
log.Infof("Automatically creating service '%s' checking %s", svr.Name, svr.Domain)
|
||||||
|
|
||||||
go ServiceCheckQueue(svr, true)
|
go ServiceCheckQueue(svr, true)
|
||||||
|
} else {
|
||||||
|
log.Infof("Service %s #%d, already inserted", svr.Name, serviceByHash.Id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue