commands working ish
This commit is contained in:
parent
f119f7086f
commit
caa371eff1
6 changed files with 62 additions and 13 deletions
|
@ -276,24 +276,25 @@ func (r *RefreshToken) AccessToken(req *http.Request) (string, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *authenticator) ValidateAccessToken(token AccessToken) *RefreshToken {
|
func (a *authenticator) ValidateAccessToken(token AccessToken) *RefreshToken {
|
||||||
|
var uvIssRT *RefreshToken
|
||||||
claims := &jwt.StandardClaims{}
|
claims := &jwt.StandardClaims{}
|
||||||
tok, err := jwt.ParseWithClaims(string(token), claims, func(jt *jwt.Token) (interface{}, error) {
|
_, err := jwt.ParseWithClaims(string(token), claims, func(jt *jwt.Token) (interface{}, error) {
|
||||||
iss := jt.Claims.(*jwt.StandardClaims).Issuer
|
iss := jt.Claims.(*jwt.StandardClaims).Issuer
|
||||||
rt := a.store.GetRefreshToken(RefreshTokenID(iss))
|
uvIssRT = a.store.GetRefreshToken(RefreshTokenID(iss))
|
||||||
if rt == nil {
|
if uvIssRT == nil {
|
||||||
return nil, fmt.Errorf("bad token")
|
return nil, fmt.Errorf("bad token")
|
||||||
}
|
}
|
||||||
|
|
||||||
return rt.JWTKey, nil
|
return []byte(uvIssRT.JWTKey), nil
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msg("validateAccessToken")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
iss := tok.Claims.(*jwt.StandardClaims).Issuer
|
return uvIssRT
|
||||||
return a.store.GetRefreshToken(RefreshTokenID(iss))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *authenticator) verifyAndGetCredential(tr *TokenRequest) *Credentials {
|
func (a *authenticator) verifyAndGetCredential(tr *TokenRequest) *Credentials {
|
||||||
|
|
|
@ -100,7 +100,7 @@ func (as *authStore) GetRefreshToken(tid RefreshTokenID) *RefreshToken {
|
||||||
|
|
||||||
for _, u := range as.Users {
|
for _, u := range as.Users {
|
||||||
for _, rt := range u.RefreshTokens {
|
for _, rt := range u.RefreshTokens {
|
||||||
if subtle.ConstantTimeCompare([]byte(tid), []byte(rt.ID)) == 1 {
|
if subtle.ConstantTimeCompare([]byte(tid), []byte(rt.ID.String())) == 1 {
|
||||||
found = rt
|
found = rt
|
||||||
found.User = u
|
found.User = u
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"dynatron.me/x/blasphem/pkg/components"
|
"dynatron.me/x/blasphem/pkg/components"
|
||||||
"dynatron.me/x/blasphem/pkg/config"
|
"dynatron.me/x/blasphem/pkg/config"
|
||||||
"dynatron.me/x/blasphem/pkg/storage"
|
"dynatron.me/x/blasphem/pkg/storage"
|
||||||
|
"dynatron.me/x/blasphem/pkg/wsapi"
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
)
|
)
|
||||||
|
@ -82,6 +83,7 @@ func New(cfg *config.Config) (b *Blas, err error) {
|
||||||
Bus: bus.New(),
|
Bus: bus.New(),
|
||||||
Config: cfg,
|
Config: cfg,
|
||||||
components: make(components.ComponentStore),
|
components: make(components.ComponentStore),
|
||||||
|
WebSocketManager: wsapi.NewManager(),
|
||||||
}
|
}
|
||||||
|
|
||||||
err = b.openStore()
|
err = b.openStore()
|
||||||
|
|
|
@ -36,7 +36,7 @@ type WebSocketSession interface {
|
||||||
Blas() Blas
|
Blas() Blas
|
||||||
}
|
}
|
||||||
|
|
||||||
type Handler func(wss WebSocketSession, msg interface{}) error
|
type Handler func(wss WebSocketSession, msgID int, msg interface{}) error
|
||||||
type NewData func() interface{}
|
type NewData func() interface{}
|
||||||
|
|
||||||
type Shutdowner interface {
|
type Shutdowner interface {
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
|
|
||||||
var (
|
var (
|
||||||
NoSuchHandlerErr = errors.New("bad websocket command")
|
NoSuchHandlerErr = errors.New("bad websocket command")
|
||||||
|
NoMessageIDErr = errors.New("no message ID")
|
||||||
)
|
)
|
||||||
|
|
||||||
type Type string
|
type Type string
|
||||||
|
@ -113,6 +114,30 @@ type cmdMsg struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type MsgType string
|
type MsgType string
|
||||||
|
const (
|
||||||
|
ResultMsgType MsgType = "result"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Error struct {
|
||||||
|
Code string `json:"code"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type WSError struct {
|
||||||
|
ID *int `json:"id,omitempty"`
|
||||||
|
Type MsgType `json:"type"`
|
||||||
|
Success bool `json:"success"`
|
||||||
|
Error Error `json:"error"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (ws *cmdHandler) writeError(id int, err Error) error {
|
||||||
|
return ws.WriteJSON(WSError{
|
||||||
|
ID: &id,
|
||||||
|
Type: ResultMsgType,
|
||||||
|
Success: false,
|
||||||
|
Error: err,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (ws *cmdHandler) handleMsg(r io.Reader) error {
|
func (ws *cmdHandler) handleMsg(r io.Reader) error {
|
||||||
var msgMap map[string]interface{}
|
var msgMap map[string]interface{}
|
||||||
|
@ -126,11 +151,33 @@ func (ws *cmdHandler) handleMsg(r io.Reader) error {
|
||||||
return NoSuchHandlerErr
|
return NoSuchHandlerErr
|
||||||
}
|
}
|
||||||
|
|
||||||
newData, hand, err := ws.b.WSCommandHandler(msgType)
|
idFl, ok := msgMap["id"].(float64)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
return ws.WriteJSON(
|
||||||
|
WSError{
|
||||||
|
Type: ResultMsgType,
|
||||||
|
Success: false,
|
||||||
|
Error: Error{
|
||||||
|
Code: "invalid_id",
|
||||||
|
Message: "command has no ID",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
id := int(idFl)
|
||||||
|
|
||||||
|
newData, hand, err := ws.b.WSCommandHandler(msgType)
|
||||||
|
switch err {
|
||||||
|
case nil:
|
||||||
|
case NoSuchHandlerErr:
|
||||||
|
return ws.writeError(id, Error{
|
||||||
|
Code: "invalid_type",
|
||||||
|
Message: "no such command",
|
||||||
|
})
|
||||||
|
default:
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
nd := newData()
|
nd := newData()
|
||||||
return hand(ws, nd)
|
return hand(ws, id, nd)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ type authPhase struct {
|
||||||
func (ws *wsSession) sendAuthRequired() error {
|
func (ws *wsSession) sendAuthRequired() error {
|
||||||
authReq := &struct {
|
authReq := &struct {
|
||||||
MsgBase
|
MsgBase
|
||||||
Version string `json:"version"`
|
Version string `json:"ha_version"`
|
||||||
}{
|
}{
|
||||||
MsgBase{"auth_required"},
|
MsgBase{"auth_required"},
|
||||||
ws.b.Version(),
|
ws.b.Version(),
|
||||||
|
@ -37,13 +37,12 @@ func (ap *authPhase) finishAuth(rt *auth.RefreshToken) {
|
||||||
ap.user = rt.User
|
ap.user = rt.User
|
||||||
ap.refreshToken = rt
|
ap.refreshToken = rt
|
||||||
ap.h = &cmdHandler{ap.wsSession}
|
ap.h = &cmdHandler{ap.wsSession}
|
||||||
ap.sendAuthOK()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ap *authPhase) sendAuthOK() error {
|
func (ap *authPhase) sendAuthOK() error {
|
||||||
return ap.WriteJSON(struct {
|
return ap.WriteJSON(struct {
|
||||||
Type string `json:"type"`
|
Type string `json:"type"`
|
||||||
Version string `json:"version"`
|
Version string `json:"ha_version"`
|
||||||
}{Type: "auth_ok", Version: ap.Blas().Version()})
|
}{Type: "auth_ok", Version: ap.Blas().Version()})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue