Check permissions when performing websocket actions
This commit is contained in:
parent
3edcd5f9c3
commit
45d441ac32
|
@ -3,6 +3,7 @@ package tokens
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"github.com/gbrlsnchs/jwt/v3"
|
"github.com/gbrlsnchs/jwt/v3"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
type WebsocketPayload struct {
|
type WebsocketPayload struct {
|
||||||
|
@ -20,7 +21,7 @@ func (p *WebsocketPayload) GetPayload() *jwt.Payload {
|
||||||
// Checks if the given token payload has a permission string.
|
// Checks if the given token payload has a permission string.
|
||||||
func (p *WebsocketPayload) HasPermission(permission string) bool {
|
func (p *WebsocketPayload) HasPermission(permission string) bool {
|
||||||
for _, k := range p.Permissions {
|
for _, k := range p.Permissions {
|
||||||
if k == permission {
|
if k == permission || (!strings.HasPrefix(permission, "admin") && k == "*") {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,6 +50,7 @@ func (h *Handler) ListenForServerEvents(ctx context.Context) {
|
||||||
server.ConsoleOutputEvent,
|
server.ConsoleOutputEvent,
|
||||||
server.InstallOutputEvent,
|
server.InstallOutputEvent,
|
||||||
server.DaemonMessageEvent,
|
server.DaemonMessageEvent,
|
||||||
|
server.BackupCompletedEvent,
|
||||||
}
|
}
|
||||||
|
|
||||||
eventChannel := make(chan server.Event)
|
eventChannel := make(chan server.Event)
|
||||||
|
|
|
@ -20,11 +20,14 @@ import (
|
||||||
var alg *jwt.HMACSHA
|
var alg *jwt.HMACSHA
|
||||||
|
|
||||||
const (
|
const (
|
||||||
PermissionConnect = "connect"
|
PermissionConnect = "websocket.*"
|
||||||
PermissionSendCommand = "send-command"
|
PermissionSendCommand = "control.console"
|
||||||
PermissionSendPower = "send-power"
|
PermissionSendPowerStart = "control.start"
|
||||||
PermissionReceiveErrors = "receive-errors"
|
PermissionSendPowerStop = "control.stop"
|
||||||
PermissionReceiveInstall = "receive-install"
|
PermissionSendPowerRestart = "control.restart"
|
||||||
|
PermissionReceiveErrors = "admin.errors"
|
||||||
|
PermissionReceiveInstall = "admin.install"
|
||||||
|
PermissionReceiveBackups = "backup.read"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Handler struct {
|
type Handler struct {
|
||||||
|
@ -88,6 +91,14 @@ func (h *Handler) SendJson(v *Message) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the user does not have permission to see backup events, do not emit
|
||||||
|
// them over the socket.
|
||||||
|
if v.Event == server.BackupCompletedEvent {
|
||||||
|
if h.JWT != nil && !h.JWT.HasPermission(PermissionReceiveBackups) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return h.unsafeSendJson(v)
|
return h.unsafeSendJson(v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,25 +214,31 @@ func (h *Handler) HandleInbound(m Message) error {
|
||||||
}
|
}
|
||||||
case SetStateEvent:
|
case SetStateEvent:
|
||||||
{
|
{
|
||||||
if !h.JWT.HasPermission(PermissionSendPower) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
switch strings.Join(m.Args, "") {
|
switch strings.Join(m.Args, "") {
|
||||||
case "start":
|
case "start":
|
||||||
return h.server.Environment.Start()
|
if h.JWT.HasPermission(PermissionSendPowerStart) {
|
||||||
|
return h.server.Environment.Start()
|
||||||
|
}
|
||||||
|
break
|
||||||
case "stop":
|
case "stop":
|
||||||
return h.server.Environment.Stop()
|
if h.JWT.HasPermission(PermissionSendPowerStop) {
|
||||||
|
return h.server.Environment.Stop()
|
||||||
|
}
|
||||||
|
break
|
||||||
case "restart":
|
case "restart":
|
||||||
{
|
if h.JWT.HasPermission(PermissionSendPowerRestart) {
|
||||||
if err := h.server.Environment.WaitForStop(60, false); err != nil {
|
if err := h.server.Environment.WaitForStop(60, false); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return h.server.Environment.Start()
|
return h.server.Environment.Start()
|
||||||
}
|
}
|
||||||
|
break
|
||||||
case "kill":
|
case "kill":
|
||||||
return h.server.Environment.Terminate(os.Kill)
|
if h.JWT.HasPermission(PermissionSendPowerStop) {
|
||||||
|
return h.server.Environment.Terminate(os.Kill)
|
||||||
|
}
|
||||||
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -7,11 +7,12 @@ import (
|
||||||
// Defines all of the possible output events for a server.
|
// Defines all of the possible output events for a server.
|
||||||
// noinspection GoNameStartsWithPackageName
|
// noinspection GoNameStartsWithPackageName
|
||||||
const (
|
const (
|
||||||
DaemonMessageEvent = "daemon message"
|
DaemonMessageEvent = "daemon message"
|
||||||
InstallOutputEvent = "install output"
|
InstallOutputEvent = "install output"
|
||||||
ConsoleOutputEvent = "console output"
|
ConsoleOutputEvent = "console output"
|
||||||
StatusEvent = "status"
|
StatusEvent = "status"
|
||||||
StatsEvent = "stats"
|
StatsEvent = "stats"
|
||||||
|
BackupCompletedEvent = "backup completed"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Event struct {
|
type Event struct {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user