Go to Slack Apps and create a new Application.
@@ -145,15 +151,6 @@
Optional comma delimited list of email addresses
@@ -169,8 +166,15 @@
-
-
+
+
-
-
@@ -257,6 +251,13 @@
local_enabled: false,
custom_enabled: false,
loading: false,
+ expanded: {
+ github: false,
+ google: false,
+ slack: false,
+ custom: false,
+ openid: false,
+ },
oauth: {
gh_client_id: "",
gh_client_secret: "",
diff --git a/frontend/src/forms/User.vue b/frontend/src/forms/User.vue
index bdd4efc4..d3251bfe 100644
--- a/frontend/src/forms/User.vue
+++ b/frontend/src/forms/User.vue
@@ -32,11 +32,22 @@
+
-
-
-
-
![]()
-
-
-
@@ -149,7 +142,6 @@
data() {
return {
tab: "v-pills-home-tab",
- qrcode: "",
}
},
computed: {
@@ -172,9 +164,6 @@
this.$store.commit('setCore', c)
const n = await Api.notifiers()
this.$store.commit('setNotifiers', n)
-
- const u = `statping://setup?domain=${c.domain}&api=${c.api_secret}`
- this.qrcode = "https://chart.googleapis.com/chart?chs=500x500&cht=qr&chl=" + encodeURIComponent(u)
this.cache = await Api.cache()
},
changeTab(e) {
diff --git a/handlers/authentication.go b/handlers/authentication.go
index 9dfc93ae..1d4e4e39 100644
--- a/handlers/authentication.go
+++ b/handlers/authentication.go
@@ -3,6 +3,7 @@ package handlers
import (
"crypto/subtle"
"github.com/statping/statping/types/core"
+ "github.com/statping/statping/types/users"
"github.com/statping/statping/utils"
"net/http"
"strings"
@@ -33,6 +34,14 @@ func hasAPIQuery(r *http.Request) bool {
if subtle.ConstantTimeCompare([]byte(key), []byte(core.App.ApiSecret)) == 1 {
return true
}
+ // find user with API key
+ user, err := users.FindByAPIKey(key)
+ if err != nil {
+ return false
+ }
+ if subtle.ConstantTimeCompare([]byte(key), []byte(user.ApiKey)) == 1 {
+ return true
+ }
return false
}
diff --git a/handlers/jwt.go b/handlers/jwt.go
index 76a8abc8..4c57b15a 100644
--- a/handlers/jwt.go
+++ b/handlers/jwt.go
@@ -11,6 +11,7 @@ import (
type JwtClaim struct {
Username string `json:"username"`
Admin bool `json:"admin"`
+ Scopes string `json:"scopes"`
jwt.StandardClaims
}
@@ -29,6 +30,7 @@ func setJwtToken(user *users.User, w http.ResponseWriter) (JwtClaim, string) {
jwtClaim := JwtClaim{
Username: user.Username,
Admin: user.Admin.Bool,
+ Scopes: user.Scopes,
StandardClaims: jwt.StandardClaims{
ExpiresAt: expirationTime.Unix(),
}}
diff --git a/notifiers/command.go b/notifiers/command.go
index 47a6ee4f..bc44c285 100644
--- a/notifiers/command.go
+++ b/notifiers/command.go
@@ -1,6 +1,7 @@
package notifiers
import (
+ "github.com/statping/statping/types/errors"
"github.com/statping/statping/types/failures"
"github.com/statping/statping/types/notifications"
"github.com/statping/statping/types/notifier"
@@ -28,44 +29,44 @@ var Command = &commandLine{¬ifications.Notification{
AuthorUrl: "https://github.com/hunterlong",
Delay: time.Duration(1 * time.Second),
Icon: "fas fa-terminal",
- Host: "/bin/bash",
- SuccessData: "curl -L http://localhost:8080",
- FailureData: "curl -L http://localhost:8080",
+ SuccessData: "/usr/bin/curl -L http://localhost:8080",
+ FailureData: "/usr/bin/curl -L http://localhost:8080",
DataType: "text",
Limits: 60,
- Form: []notifications.NotificationForm{{
- Type: "text",
- Title: "Executable Path",
- Placeholder: "/usr/bin/curl",
- DbField: "host",
- SmallText: "You can use '/bin/sh', '/bin/bash', '/usr/bin/curl' or an absolute path for an application.",
- }}},
-}
+}}
-func runCommand(app string, cmd ...string) (string, string, error) {
- utils.Log.Infof("Command notifier sending: %s %s", app, strings.Join(cmd, " "))
- outStr, errStr, err := utils.Command(app, cmd...)
+func runCommand(cmd string) (string, string, error) {
+ utils.Log.Infof("Command notifier sending: %s", cmd)
+ cmdApp := strings.Split(cmd, " ")
+ if len(cmd) == 0 {
+ return "", "", errors.New("you need at least 1 command")
+ }
+ var cmdArgs []string
+ if len(cmd) > 1 {
+ cmdArgs = append(cmdArgs, cmd[1:])
+ }
+ outStr, errStr, err := utils.Command(cmdApp[0], cmdArgs...)
return outStr, errStr, err
}
// OnSuccess for commandLine will trigger successful service
func (c *commandLine) OnSuccess(s services.Service) (string, error) {
tmpl := ReplaceVars(c.SuccessData, s, failures.Failure{})
- out, _, err := runCommand(c.Host, tmpl)
+ out, _, err := runCommand(tmpl)
return out, err
}
// OnFailure for commandLine will trigger failing service
func (c *commandLine) OnFailure(s services.Service, f failures.Failure) (string, error) {
tmpl := ReplaceVars(c.FailureData, s, f)
- _, ouerr, err := runCommand(c.Host, tmpl)
- return ouerr, err
+ out, _, err := runCommand(tmpl)
+ return out, err
}
// OnTest for commandLine triggers when this notifier has been saved
func (c *commandLine) OnTest() (string, error) {
tmpl := ReplaceVars(c.Var1, services.Example(true), failures.Example())
- in, out, err := runCommand(c.Host, tmpl)
+ in, out, err := runCommand(tmpl)
utils.Log.Infoln(in)
utils.Log.Infoln(out)
return out, err
diff --git a/notifiers/statping_emailer.go b/notifiers/statping_emailer.go
index 81208f20..a6b5165d 100644
--- a/notifiers/statping_emailer.go
+++ b/notifiers/statping_emailer.go
@@ -39,7 +39,7 @@ var statpingMailer = &statpingEmailer{¬ifications.Notification{
Form: []notifications.NotificationForm{{
Type: "email",
Title: "Send to Email Address",
- Placeholder: "Insert your email address",
+ Placeholder: "info@statping.com",
DbField: "Host",
Required: true,
}}},
diff --git a/types/configs/connection.go b/types/configs/connection.go
index 92b632a5..9f795864 100644
--- a/types/configs/connection.go
+++ b/types/configs/connection.go
@@ -88,6 +88,7 @@ func CreateAdminUser(c *DbConfig) error {
Username: adminUser,
Password: adminPass,
Email: adminEmail,
+ Scopes: "admin",
Admin: null.NewNullBool(true),
}
diff --git a/types/core/database.go b/types/core/database.go
index 1d9cf743..f1ae12dc 100644
--- a/types/core/database.go
+++ b/types/core/database.go
@@ -47,22 +47,8 @@ func Select() (*Core, error) {
}
func (c *Core) Create() error {
- secret := utils.Params.GetString("API_SECRET")
- if secret == "" {
- secret = utils.RandomString(32)
- }
- newCore := &Core{
- Name: c.Name,
- Description: c.Description,
- ConfigFile: utils.Directory + "/config.yml",
- ApiSecret: secret,
- Version: App.Version,
- Domain: c.Domain,
- Language: c.Language,
- MigrationId: utils.Now().Unix(),
- }
- q := db.Create(&newCore)
- utils.Log.Infof("API Key created: %s", secret)
+ q := db.Create(c)
+ utils.Log.Infof("API Key created: %s", c.ApiSecret)
return q.Error()
}
diff --git a/types/core/samples.go b/types/core/samples.go
index 15810248..8c59a67b 100644
--- a/types/core/samples.go
+++ b/types/core/samples.go
@@ -41,6 +41,7 @@ func Samples() error {
MigrationId: utils.Now().Unix(),
Language: utils.Params.GetString("LANGUAGE"),
OAuth: oauth,
+ Version: utils.Version,
}
return core.Create()
diff --git a/types/users/database.go b/types/users/database.go
index 3b8952b4..3092638c 100644
--- a/types/users/database.go
+++ b/types/users/database.go
@@ -43,6 +43,12 @@ func FindByUsername(username string) (*User, error) {
return &user, q.Error()
}
+func FindByAPIKey(key string) (*User, error) {
+ var user User
+ q := db.Where("api_key = ?", key).Find(&user)
+ return &user, q.Error()
+}
+
func All() []*User {
var users []*User
db.Find(&users)
diff --git a/types/users/hooks.go b/types/users/hooks.go
index aeda3ff9..c66ca1af 100644
--- a/types/users/hooks.go
+++ b/types/users/hooks.go
@@ -5,6 +5,5 @@ 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/types/users/sample.go b/types/users/sample.go
index ecaa3409..1e6b455c 100644
--- a/types/users/sample.go
+++ b/types/users/sample.go
@@ -10,6 +10,7 @@ func Samples() error {
Username: "testadmin",
Password: "password123",
Email: "info@betatude.com",
+ Scopes: "admin",
Admin: null.NewNullBool(true),
}
@@ -21,6 +22,7 @@ func Samples() error {
Username: "testadmin2",
Password: "password123",
Email: "info@adminhere.com",
+ Scopes: "admin",
Admin: null.NewNullBool(true),
}
diff --git a/types/users/scopes.go b/types/users/scopes.go
new file mode 100644
index 00000000..8e8215a9
--- /dev/null
+++ b/types/users/scopes.go
@@ -0,0 +1,43 @@
+package users
+
+import "strings"
+
+type Scope string
+
+const (
+ FullAdmin Scope = "admin"
+ ReadOnly Scope = "readonly"
+ RServices Scope = "read:services"
+ RWServices Scope = "write:services"
+ RIncidents Scope = "read:incidents"
+ RWIncidents Scope = "write:incidents"
+
+ EmptyUser Scope = "none"
+)
+
+func namedScope(name string) Scope {
+ switch name {
+ case "admin":
+ return FullAdmin
+ case "readonly":
+ return ReadOnly
+ case "read:services":
+ return RServices
+ case "write:services":
+ return RWServices
+ case "read:incidents":
+ return RIncidents
+ case "write:incidents":
+ return RWIncidents
+ default:
+ return EmptyUser
+ }
+}
+
+func (u *User) AllScopes() []Scope {
+ var scopes []Scope
+ for _, s := range strings.Split(u.Scopes, ",") {
+ scopes = append(scopes, namedScope(s))
+ }
+ return scopes
+}
diff --git a/types/users/struct.go b/types/users/struct.go
index 78f4b423..07138969 100644
--- a/types/users/struct.go
+++ b/types/users/struct.go
@@ -12,7 +12,7 @@ type User struct {
Password string `gorm:"column:password" json:"password,omitempty"`
Email string `gorm:"type:varchar(100);column:email" json:"email,omitempty"`
ApiKey string `gorm:"column:api_key" json:"api_key,omitempty"`
- ApiSecret string `gorm:"column:api_secret" json:"api_secret,omitempty"`
+ Scopes string `gorm:"column:scopes" json:"scopes,omitempty"`
Admin null.NullBool `gorm:"column:administrator" json:"admin,omitempty"`
CreatedAt time.Time `gorm:"column:created_at" json:"created_at"`
UpdatedAt time.Time `gorm:"column:updated_at" json:"updated_at"`