diff --git a/cmd/main-server.go b/cmd/main-server.go index e723e6895..e706568c4 100644 --- a/cmd/main-server.go +++ b/cmd/main-server.go @@ -292,6 +292,7 @@ func HandleRunCommand(w http.ResponseWriter, r *http.Request) { } fmt.Printf("[error] in run-command: %v\n", r) debug.PrintStack() + WriteJsonError(w, fmt.Errorf("panic: %v", r)) return }() w.Header().Set("Access-Control-Allow-Origin", r.Header.Get("Origin")) diff --git a/db/migrations/000001_init.up.sql b/db/migrations/000001_init.up.sql index 71fc09b9a..2022e65f9 100644 --- a/db/migrations/000001_init.up.sql +++ b/db/migrations/000001_init.up.sql @@ -10,7 +10,7 @@ CREATE TABLE session ( sessionidx int NOT NULL, activescreenid varchar(36) NOT NULL, notifynum int NOT NULL, - owneruserid varchar(36) NOT NULL, + ownerid varchar(36) NOT NULL, sharemode varchar(12) NOT NULL, accesskey varchar(36) NOT NULL ); @@ -18,11 +18,11 @@ CREATE TABLE session ( CREATE TABLE window ( sessionid varchar(36) NOT NULL, windowid varchar(36) NOT NULL, - curremoteowneruserid varchar(36) NOT NULL, + curremoteownerid varchar(36) NOT NULL, curremoteid varchar(36) NOT NULL, curremotename varchar(50) NOT NULL, winopts json NOT NULL, - owneruserid varchar(36) NOT NULL, + ownerid varchar(36) NOT NULL, sharemode varchar(12) NOT NULL, shareopts json NOT NULL, PRIMARY KEY (sessionid, windowid) @@ -35,7 +35,7 @@ CREATE TABLE screen ( activewindowid varchar(36) NOT NULL, screenidx int NOT NULL, screenopts json NOT NULL, - owneruserid varchar(36) NOT NULL, + ownerid varchar(36) NOT NULL, sharemode varchar(12) NOT NULL, PRIMARY KEY (sessionid, screenid) ); @@ -54,7 +54,7 @@ CREATE TABLE remote_instance ( name varchar(50) NOT NULL, sessionid varchar(36) NOT NULL, windowid varchar(36) NOT NULL, - remoteowneruserid varchar(36) NOT NULL, + remoteownerid varchar(36) NOT NULL, remoteid varchar(36) NOT NULL, state json NOT NULL ); @@ -91,7 +91,9 @@ CREATE TABLE remote ( CREATE TABLE cmd ( sessionid varchar(36) NOT NULL, cmdid varchar(36) NOT NULL, + remoteownerid varchar(36) NOT NULL, remoteid varchar(36) NOT NULL, + remotename varchar(50) NOT NULL, cmdstr text NOT NULL, remotestate json NOT NULL, termopts json NOT NULL, diff --git a/db/schema.sql b/db/schema.sql index 94f91b6d8..fc98b13fa 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -11,18 +11,18 @@ CREATE TABLE session ( sessionidx int NOT NULL, activescreenid varchar(36) NOT NULL, notifynum int NOT NULL, - owneruserid varchar(36) NOT NULL, + ownerid varchar(36) NOT NULL, sharemode varchar(12) NOT NULL, accesskey varchar(36) NOT NULL ); CREATE TABLE window ( sessionid varchar(36) NOT NULL, windowid varchar(36) NOT NULL, - curremoteowneruserid varchar(36) NOT NULL, + curremoteownerid varchar(36) NOT NULL, curremoteid varchar(36) NOT NULL, curremotename varchar(50) NOT NULL, winopts json NOT NULL, - owneruserid varchar(36) NOT NULL, + ownerid varchar(36) NOT NULL, sharemode varchar(12) NOT NULL, shareopts json NOT NULL, PRIMARY KEY (sessionid, windowid) @@ -34,7 +34,7 @@ CREATE TABLE screen ( activewindowid varchar(36) NOT NULL, screenidx int NOT NULL, screenopts json NOT NULL, - owneruserid varchar(36) NOT NULL, + ownerid varchar(36) NOT NULL, sharemode varchar(12) NOT NULL, PRIMARY KEY (sessionid, screenid) ); @@ -51,7 +51,7 @@ CREATE TABLE remote_instance ( name varchar(50) NOT NULL, sessionid varchar(36) NOT NULL, windowid varchar(36) NOT NULL, - remoteowneruserid varchar(36) NOT NULL, + remoteownerid varchar(36) NOT NULL, remoteid varchar(36) NOT NULL, state json NOT NULL ); @@ -85,7 +85,9 @@ CREATE TABLE remote ( CREATE TABLE cmd ( sessionid varchar(36) NOT NULL, cmdid varchar(36) NOT NULL, + remoteownerid varchar(36) NOT NULL, remoteid varchar(36) NOT NULL, + remotename varchar(50) NOT NULL, cmdstr text NOT NULL, remotestate json NOT NULL, termopts json NOT NULL, diff --git a/pkg/cmdrunner/cmdrunner.go b/pkg/cmdrunner/cmdrunner.go index 0914af4a1..d68c29fc7 100644 --- a/pkg/cmdrunner/cmdrunner.go +++ b/pkg/cmdrunner/cmdrunner.go @@ -42,6 +42,7 @@ type resolvedIds struct { RemotePtr sstore.RemotePtrType RemoteState *sstore.RemoteState RemoteDisplayName string + RState remote.RemoteState } func SubMetaCmd(cmd string) string { @@ -229,26 +230,26 @@ func parseFullRemoteRef(fullRemoteRef string) (string, string, string, error) { return fields[0], fields[1], fields[2], nil } -// returns (remoteDisplayName, remoteptr, state, err) -func resolveRemote(ctx context.Context, fullRemoteRef string, sessionId string, windowId string) (string, *sstore.RemotePtrType, *sstore.RemoteState, error) { +// returns (remoteDisplayName, remoteptr, state, rstate, err) +func resolveRemote(ctx context.Context, fullRemoteRef string, sessionId string, windowId string) (string, *sstore.RemotePtrType, *sstore.RemoteState, *remote.RemoteState, error) { if fullRemoteRef == "" { - return "", nil, nil, nil + return "", nil, nil, nil, nil } userRef, remoteRef, remoteName, err := parseFullRemoteRef(fullRemoteRef) if err != nil { - return "", nil, nil, err + return "", nil, nil, nil, err } if userRef != "" { - return "", nil, nil, fmt.Errorf("invalid remote '%s', cannot resolve remote userid '%s'", fullRemoteRef, userRef) + return "", nil, nil, nil, fmt.Errorf("invalid remote '%s', cannot resolve remote userid '%s'", fullRemoteRef, userRef) } rstate := remote.ResolveRemoteRef(remoteRef) if rstate == nil { - return "", nil, nil, fmt.Errorf("cannot resolve remote '%s': not found", fullRemoteRef) + return "", nil, nil, nil, fmt.Errorf("cannot resolve remote '%s': not found", fullRemoteRef) } rptr := sstore.RemotePtrType{RemoteId: rstate.RemoteId, Name: remoteName} state, err := sstore.GetRemoteState(ctx, sessionId, windowId, rptr) if err != nil { - return "", nil, nil, fmt.Errorf("cannot resolve remote state '%s': %w", fullRemoteRef, err) + return "", nil, nil, nil, fmt.Errorf("cannot resolve remote state '%s': %w", fullRemoteRef, err) } rname := rstate.RemoteCanonicalName if rstate.RemoteAlias != "" { @@ -258,9 +259,9 @@ func resolveRemote(ctx context.Context, fullRemoteRef string, sessionId string, rname = fmt.Sprintf("%s:%s", rname, rptr.Name) } if state == nil { - return rname, &rptr, rstate.DefaultState, nil + return rname, &rptr, rstate.DefaultState, rstate, nil } - return rname, &rptr, state, nil + return rname, &rptr, state, rstate, nil } func resolveIds(ctx context.Context, pk *scpacket.FeCommandPacketType, rtype int) (resolvedIds, error) { @@ -298,7 +299,7 @@ func resolveIds(ctx context.Context, pk *scpacket.FeCommandPacketType, rtype int } } if (rtype&R_Remote)+(rtype&R_RemoteOpt) > 0 { - rname, rptr, rstate, err := resolveRemote(ctx, pk.Kwargs["remote"], rtn.SessionId, rtn.WindowId) + rname, rptr, state, rstate, err := resolveRemote(ctx, pk.Kwargs["remote"], rtn.SessionId, rtn.WindowId) if err != nil { return rtn, err } @@ -307,7 +308,8 @@ func resolveIds(ctx context.Context, pk *scpacket.FeCommandPacketType, rtype int } rtn.RemoteDisplayName = rname rtn.RemotePtr = *rptr - rtn.RemoteState = rstate + rtn.RemoteState = state + rtn.RState = *rstate } return rtn, nil } @@ -317,6 +319,12 @@ func RunCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.U if err != nil { return nil, fmt.Errorf("/run error: %w", err) } + if !ids.RState.IsConnected() { + return nil, fmt.Errorf("cannot run command, remote '%s' not connected", ids.RemoteDisplayName) + } + if ids.RemoteState == nil { + return nil, fmt.Errorf("cannot run command, remote '%s' has no state", ids.RemoteDisplayName) + } cmdId := uuid.New().String() cmdStr := firstArg(pk) runPacket := packet.MakeRunPacket() @@ -329,7 +337,7 @@ func RunCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.U runPacket.UsePty = true runPacket.TermOpts = &packet.TermOpts{Rows: remote.DefaultTermRows, Cols: remote.DefaultTermCols, Term: remote.DefaultTerm} runPacket.Command = strings.TrimSpace(cmdStr) - cmd, err := remote.RunCommand(ctx, cmdId, ids.RemotePtr.RemoteId, ids.RemoteState, runPacket) + cmd, err := remote.RunCommand(ctx, cmdId, ids.RemotePtr, ids.RemoteState, runPacket) if err != nil { return nil, err } @@ -507,15 +515,11 @@ func UnSetCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore if err != nil { return nil, err } - curRemote := remote.GetRemoteById(ids.RemotePtr.RemoteId) - if curRemote == nil { - return nil, fmt.Errorf("invalid remote, cannot unset") - } - if !curRemote.IsConnected() { - return nil, fmt.Errorf("remote is not connected, cannot unset") + if !ids.RState.IsConnected() { + return nil, fmt.Errorf("remote '%s' is not connected, cannot unset", ids.RemoteDisplayName) } if ids.RemoteState == nil { - return nil, fmt.Errorf("remote state is not available") + return nil, fmt.Errorf("remote '%s' state is not available, cannot unset", ids.RemoteDisplayName) } envMap := shexec.ParseEnv0(ids.RemoteState.Env0) unsetVars := make(map[string]bool) @@ -595,15 +599,11 @@ func SetEnvCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstor if err != nil { return nil, err } - curRemote := remote.GetRemoteById(ids.RemotePtr.RemoteId) - if curRemote == nil { - return nil, fmt.Errorf("invalid remote, cannot setenv") - } - if !curRemote.IsConnected() { - return nil, fmt.Errorf("remote is not connected, cannot setenv") + if !ids.RState.IsConnected() { + return nil, fmt.Errorf("remote '%s' is not connected, cannot setenv", ids.RemoteDisplayName) } if ids.RemoteState == nil { - return nil, fmt.Errorf("remote state is not available") + return nil, fmt.Errorf("remote '%s' state is not available, cannot setenv", ids.RemoteDisplayName) } envMap := shexec.ParseEnv0(ids.RemoteState.Env0) if len(pk.Args) == 0 { @@ -656,7 +656,7 @@ func CrCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.Up if newRemote == "" { return nil, nil } - remoteName, rptr, _, err := resolveRemote(ctx, newRemote, ids.SessionId, ids.WindowId) + remoteName, rptr, _, _, err := resolveRemote(ctx, newRemote, ids.SessionId, ids.WindowId) if err != nil { return nil, err } @@ -689,13 +689,13 @@ func CdCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.Up newDir := firstArg(pk) curRemote := remote.GetRemoteById(ids.RemotePtr.RemoteId) if curRemote == nil { - return nil, fmt.Errorf("invalid remote, cannot change directory") + return nil, fmt.Errorf("remote '%s' not found, cannot change directory", ids.RemoteDisplayName) } - if !curRemote.IsConnected() { - return nil, fmt.Errorf("remote is not connected, cannot change directory") + if !ids.RState.IsConnected() { + return nil, fmt.Errorf("remote '%s' is not connected, cannot change directory", ids.RemoteDisplayName) } if ids.RemoteState == nil { - return nil, fmt.Errorf("remote state is not available") + return nil, fmt.Errorf("remote '%s' state is not available, cannot change directory", ids.RemoteDisplayName) } if newDir == "" { return sstore.ModelUpdate{ @@ -704,7 +704,7 @@ func CdCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sstore.Up }, }, nil } - newDir, err = curRemote.ExpandHomeDir(newDir) + newDir, err = ids.RState.ExpandHomeDir(newDir) if err != nil { return nil, err } diff --git a/pkg/remote/remote.go b/pkg/remote/remote.go index 2d8cd6f79..eb1dcca12 100644 --- a/pkg/remote/remote.go +++ b/pkg/remote/remote.go @@ -68,6 +68,10 @@ type RemoteState struct { ConnectMode string `json:"connectmode"` } +func (state RemoteState) IsConnected() bool { + return state.Status == StatusConnected +} + type MShellProc struct { Lock *sync.Mutex Remote *sstore.RemoteType @@ -401,16 +405,11 @@ func replaceHomePath(pathStr string, homeDir string) string { return pathStr } -func (msh *MShellProc) ExpandHomeDir(pathStr string) (string, error) { +func (state RemoteState) ExpandHomeDir(pathStr string) (string, error) { if pathStr != "~" && !strings.HasPrefix(pathStr, "~/") { return pathStr, nil } - msh.Lock.Lock() - defer msh.Lock.Unlock() - if msh.ServerProc.InitPk == nil { - return "", fmt.Errorf("remote not connected, does not have home directory set for ~ expansion") - } - homeDir := msh.ServerProc.InitPk.HomeDir + homeDir := state.RemoteVars["home"] if homeDir == "" { return "", fmt.Errorf("remote does not have HOME set, cannot do ~ expansion") } @@ -449,13 +448,16 @@ func makeTermOpts() sstore.TermOpts { return sstore.TermOpts{Rows: DefaultTermRows, Cols: DefaultTermCols, FlexRows: true, MaxPtySize: DefaultMaxPtySize} } -func RunCommand(ctx context.Context, cmdId string, remoteId string, remoteState *sstore.RemoteState, runPacket *packet.RunPacketType) (*sstore.CmdType, error) { - msh := GetRemoteById(remoteId) +func RunCommand(ctx context.Context, cmdId string, remotePtr sstore.RemotePtrType, remoteState *sstore.RemoteState, runPacket *packet.RunPacketType) (*sstore.CmdType, error) { + if remotePtr.OwnerId != "" { + return nil, fmt.Errorf("cannot run command against another user's remote '%s'", remotePtr.MakeFullRemoteRef()) + } + msh := GetRemoteById(remotePtr.RemoteId) if msh == nil { - return nil, fmt.Errorf("no remote id=%s found", remoteId) + return nil, fmt.Errorf("no remote id=%s found", remotePtr.RemoteId) } if !msh.IsConnected() { - return nil, fmt.Errorf("remote '%s' is not connected", remoteId) + return nil, fmt.Errorf("remote '%s' is not connected", remotePtr.RemoteId) } if remoteState == nil { return nil, fmt.Errorf("no remote state passed to RunCommand") @@ -486,7 +488,7 @@ func RunCommand(ctx context.Context, cmdId string, remoteId string, remoteState SessionId: runPacket.CK.GetSessionId(), CmdId: startPk.CK.GetCmdId(), CmdStr: runPacket.Command, - RemoteId: msh.Remote.RemoteId, + Remote: remotePtr, RemoteState: *remoteState, TermOpts: makeTermOpts(), Status: status, diff --git a/pkg/scbase/scbase.go b/pkg/scbase/scbase.go index a64c39bdc..094d7b389 100644 --- a/pkg/scbase/scbase.go +++ b/pkg/scbase/scbase.go @@ -49,6 +49,9 @@ func AcquireSCLock() (*os.File, error) { } func EnsureSessionDir(sessionId string) (string, error) { + if sessionId == "" { + return "", fmt.Errorf("cannot get session dir for blank sessionid") + } BaseLock.Lock() sdir, ok := SessionDirCache[sessionId] BaseLock.Unlock() @@ -90,6 +93,12 @@ func PtyOutFile(sessionId string, cmdId string) (string, error) { if err != nil { return "", err } + if sessionId == "" { + return "", fmt.Errorf("cannot get ptyout file for blank sessionid") + } + if cmdId == "" { + return "", fmt.Errorf("cannot get ptyout file for blank cmdid") + } return fmt.Sprintf("%s/%s.ptyout.cf", sdir, cmdId), nil } @@ -98,10 +107,19 @@ func RunOutFile(sessionId string, cmdId string) (string, error) { if err != nil { return "", err } + if sessionId == "" { + return "", fmt.Errorf("cannot get runout file for blank sessionid") + } + if cmdId == "" { + return "", fmt.Errorf("cannot get runout file for blank cmdid") + } return fmt.Sprintf("%s/%s.runout", sdir, cmdId), nil } func RemotePtyOut(remoteId string) (string, error) { + if remoteId == "" { + return "", fmt.Errorf("cannot get remote ptyout file for blank remoteid") + } scHome := GetScHomeDir() rdir := path.Join(scHome, RemotesDirBaseName) err := ensureDir(rdir) diff --git a/pkg/scpacket/scpacket.go b/pkg/scpacket/scpacket.go index b5e32e0a8..8010873f2 100644 --- a/pkg/scpacket/scpacket.go +++ b/pkg/scpacket/scpacket.go @@ -3,17 +3,14 @@ package scpacket import ( "reflect" + "github.com/scripthaus-dev/mshell/pkg/base" "github.com/scripthaus-dev/mshell/pkg/packet" + "github.com/scripthaus-dev/sh2-server/pkg/sstore" ) const FeCommandPacketStr = "fecmd" const WatchScreenPacketStr = "watchscreen" - -type RemoteState struct { - RemoteId string `json:"remoteid"` - RemoteName string `json:"remotename"` - Cwd string `json:"cwd"` -} +const FeInputPacketStr = "feinput" type FeCommandPacketType struct { Type string `json:"type"` @@ -23,9 +20,20 @@ type FeCommandPacketType struct { Kwargs map[string]string `json:"kwargs,omitempty"` } +type FeInputPacketType struct { + Type string `json:"type"` + CK base.CommandKey `json:"ck"` + Remote sstore.RemotePtrType `json:"remote"` + InputData64 string `json:"inputdata"` + SigNum int `json:"signum,omitempty"` + WinSizeRows int `json:"winsizerows"` + WinSizeCols int `json:"winsizecols"` +} + func init() { packet.RegisterPacketType(FeCommandPacketStr, reflect.TypeOf(FeCommandPacketType{})) packet.RegisterPacketType(WatchScreenPacketStr, reflect.TypeOf(WatchScreenPacketType{})) + packet.RegisterPacketType(FeInputPacketStr, reflect.TypeOf(FeInputPacketType{})) } func (*FeCommandPacketType) GetType() string { @@ -36,6 +44,25 @@ func MakeFeCommandPacket() *FeCommandPacketType { return &FeCommandPacketType{Type: FeCommandPacketStr} } +func (*FeInputPacketType) GetType() string { + return FeInputPacketStr +} + +func MakeFeInputPacket() *FeInputPacketType { + return &FeInputPacketType{Type: FeInputPacketStr} +} + +func (p *FeInputPacketType) ConvertToInputPacket() *packet.InputPacketType { + rtn := packet.MakeInputPacket() + rtn.CK = p.CK + rtn.RemoteId = p.Remote.RemoteId + rtn.InputData64 = p.InputData64 + rtn.SigNum = p.SigNum + rtn.WinSizeRows = p.WinSizeRows + rtn.WinSizeCols = p.WinSizeCols + return rtn +} + type WatchScreenPacketType struct { Type string `json:"type"` SessionId string `json:"sessionid"` diff --git a/pkg/scws/scws.go b/pkg/scws/scws.go index 759e8747c..d8a810bcb 100644 --- a/pkg/scws/scws.go +++ b/pkg/scws/scws.go @@ -128,9 +128,19 @@ func (ws *WSState) RunWSRead() { fmt.Printf("error unmarshalling ws message: %v\n", err) continue } - if pk.GetType() == "input" { + if pk.GetType() == "feinput" { + feInputPk := pk.(*scpacket.FeInputPacketType) + if feInputPk.Remote.OwnerId != "" { + fmt.Printf("[error] cannot send input to remote with ownerid\n") + continue + } + if feInputPk.Remote.RemoteId == "" { + fmt.Printf("[error] invalid input packet, remoteid is not set\n") + continue + } + inputPk := feInputPk.ConvertToInputPacket() go func() { - err = sendCmdInput(pk.(*packet.InputPacketType)) + err = sendCmdInput(inputPk) if err != nil { fmt.Printf("[error] sending command input: %v\n", err) } diff --git a/pkg/sstore/dbops.go b/pkg/sstore/dbops.go index ac5772c38..735c92757 100644 --- a/pkg/sstore/dbops.go +++ b/pkg/sstore/dbops.go @@ -261,7 +261,7 @@ func InsertSessionWithName(ctx context.Context, sessionName string, activate boo names := tx.SelectStrings(`SELECT name FROM session`) sessionName = fmtUniqueName(sessionName, "session-%d", len(names)+1, names) maxSessionIdx := tx.GetInt(`SELECT COALESCE(max(sessionidx), 0) FROM session`) - query := `INSERT INTO session (sessionid, name, activescreenid, sessionidx, notifynum, owneruserid, sharemode, accesskey) VALUES (?, ?, '', ?, ?, '', 'local', '')` + query := `INSERT INTO session (sessionid, name, activescreenid, sessionidx, notifynum, ownerid, sharemode, accesskey) VALUES (?, ?, '', ?, ?, '', 'local', '')` tx.ExecWrap(query, newSessionId, sessionName, maxSessionIdx+1, 0) _, err := InsertScreen(tx.Context(), newSessionId, "", true) if err != nil { @@ -334,7 +334,7 @@ func InsertScreen(ctx context.Context, sessionId string, screenName string, acti screenNames := tx.SelectStrings(`SELECT name FROM screen WHERE sessionid = ?`, sessionId) screenName = fmtUniqueName(screenName, "s%d", maxScreenIdx+1, screenNames) newScreenId = uuid.New().String() - query = `INSERT INTO screen (sessionid, screenid, name, activewindowid, screenidx, screenopts, owneruserid, sharemode) VALUES (?, ?, ?, ?, ?, ?, '', 'local')` + query = `INSERT INTO screen (sessionid, screenid, name, activewindowid, screenidx, screenopts, ownerid, sharemode) VALUES (?, ?, ?, ?, ?, ?, '', 'local')` tx.ExecWrap(query, sessionId, newScreenId, screenName, newWindowId, maxScreenIdx+1, ScreenOptsType{}) layout := LayoutType{Type: LayoutFull} query = `INSERT INTO screen_window (sessionid, screenid, windowid, name, layout) VALUES (?, ?, ?, ?, ?)` @@ -388,8 +388,8 @@ func txCreateWindow(tx *TxWrap, sessionId string, curRemote RemotePtrType) strin ShareOpts: WindowShareOptsType{}, } wmap := w.ToMap() - query := `INSERT INTO window ( sessionid, windowid, curremoteowneruserid, curremoteid, curremotename, winopts, owneruserid, sharemode, shareopts) - VALUES (:sessionid,:windowid,:curremoteowneruserid,:curremoteid,:curremotename,:winopts,:owneruserid,:sharemode,:shareopts)` + query := `INSERT INTO window ( sessionid, windowid, curremoteownerid, curremoteid, curremotename, winopts, ownerid, sharemode, shareopts) + VALUES (:sessionid,:windowid,:curremoteownerid,:curremoteid,:curremotename,:winopts,:ownerid,:sharemode,:shareopts)` tx.NamedExecWrap(query, wmap) return w.WindowId } @@ -414,8 +414,8 @@ func InsertLine(ctx context.Context, line *LineType, cmd *CmdType) error { if cmd != nil { cmdMap := cmd.ToMap() query = ` -INSERT INTO cmd ( sessionid, cmdid, remoteid, cmdstr, remotestate, termopts, status, startpk, donepk, runout, usedrows) - VALUES (:sessionid,:cmdid,:remoteid,:cmdstr,:remotestate,:termopts,:status,:startpk,:donepk,:runout,:usedrows) +INSERT INTO cmd ( sessionid, cmdid, remoteownerid, remoteid, remotename, cmdstr, remotestate, termopts, status, startpk, donepk, runout, usedrows) + VALUES (:sessionid,:cmdid,:remoteownerid,:remoteid,:remotename,:cmdstr,:remotestate,:termopts,:status,:startpk,:donepk,:runout,:usedrows) ` tx.NamedExecWrap(query, cmdMap) } @@ -562,8 +562,8 @@ func GetRemoteState(ctx context.Context, sessionId string, windowId string, remo var remoteState *RemoteState txErr := WithTx(ctx, func(tx *TxWrap) error { var ri RemoteInstance - query := `SELECT * FROM remote_instance WHERE sessionid = ? AND windowid = ? AND remoteowneruserid = ? AND remoteid = ? AND name = ?` - found := tx.GetWrap(&ri, query, sessionId, windowId, remotePtr.OwnerUserId, remotePtr.RemoteId, remotePtr.Name) + query := `SELECT * FROM remote_instance WHERE sessionid = ? AND windowid = ? AND remoteownerid = ? AND remoteid = ? AND name = ?` + found := tx.GetWrap(&ri, query, sessionId, windowId, remotePtr.OwnerId, remotePtr.RemoteId, remotePtr.Name) if found { remoteState = &ri.State return nil @@ -599,26 +599,26 @@ func UpdateRemoteState(ctx context.Context, sessionId string, windowId string, r if err != nil { return fmt.Errorf("cannot update remote instance cwd: %w", err) } - query := `SELECT * FROM remote_instance WHERE sessionid = ? AND windowid = ? AND remoteowneruserid = ? AND remoteid = ? AND name = ?` - found := tx.GetWrap(&ri, query, sessionId, windowId, remotePtr.OwnerUserId, remotePtr.RemoteId, remotePtr.Name) + query := `SELECT * FROM remote_instance WHERE sessionid = ? AND windowid = ? AND remoteownerid = ? AND remoteid = ? AND name = ?` + found := tx.GetWrap(&ri, query, sessionId, windowId, remotePtr.OwnerId, remotePtr.RemoteId, remotePtr.Name) if !found { ri = RemoteInstance{ - RIId: uuid.New().String(), - Name: remotePtr.Name, - SessionId: sessionId, - WindowId: windowId, - RemoteOwnerUserId: remotePtr.OwnerUserId, - RemoteId: remotePtr.RemoteId, - State: state, + RIId: uuid.New().String(), + Name: remotePtr.Name, + SessionId: sessionId, + WindowId: windowId, + RemoteOwnerId: remotePtr.OwnerId, + RemoteId: remotePtr.RemoteId, + State: state, } - query = `INSERT INTO remote_instance ( riid, name, sessionid, windowid, remoteowneruserid, remoteid, state) - VALUES (:riid,:name,:sessionid,:windowid,:remoteowneruserid,:remoteid,:state)` + query = `INSERT INTO remote_instance ( riid, name, sessionid, windowid, remoteownerid, remoteid, state) + VALUES (:riid,:name,:sessionid,:windowid,:remoteownerid,:remoteid,:state)` tx.NamedExecWrap(query, ri) return nil } - query = `UPDATE remote_instance SET state = ? WHERE sessionid = ? AND windowid = ? AND remoteowneruserid = ? AND remoteid = ? AND name = ?` + query = `UPDATE remote_instance SET state = ? WHERE sessionid = ? AND windowid = ? AND remoteownerid = ? AND remoteid = ? AND name = ?` ri.State = state - tx.ExecWrap(query, ri.State, ri.SessionId, ri.WindowId, remotePtr.OwnerUserId, remotePtr.RemoteId, remotePtr.Name) + tx.ExecWrap(query, ri.State, ri.SessionId, ri.WindowId, remotePtr.OwnerId, remotePtr.RemoteId, remotePtr.Name) return nil }) return &ri, txErr @@ -630,8 +630,8 @@ func UpdateCurRemote(ctx context.Context, sessionId string, windowId string, rem if !tx.Exists(query, sessionId, windowId) { return fmt.Errorf("cannot update curremote: no window found") } - query = `UPDATE window SET curremoteowneruserid = ?, curremoteid = ?, curremotename = ? WHERE sessionid = ? AND windowid = ?` - tx.ExecWrap(query, remotePtr.OwnerUserId, remotePtr.RemoteId, remotePtr.Name, sessionId, windowId) + query = `UPDATE window SET curremoteownerid = ?, curremoteid = ?, curremotename = ? WHERE sessionid = ? AND windowid = ?` + tx.ExecWrap(query, remotePtr.OwnerId, remotePtr.RemoteId, remotePtr.Name, sessionId, windowId) return nil }) return txErr diff --git a/pkg/sstore/sstore.go b/pkg/sstore/sstore.go index 83b46cca0..0afb84412 100644 --- a/pkg/sstore/sstore.go +++ b/pkg/sstore/sstore.go @@ -99,7 +99,7 @@ type SessionType struct { Name string `json:"name"` SessionIdx int64 `json:"sessionidx"` ActiveScreenId string `json:"activescreenid"` - OwnerUserId string `json:"owneruserid"` + OwnerId string `json:"ownerid"` ShareMode string `json:"sharemode"` AccessKey string `json:"-"` NotifyNum int64 `json:"notifynum"` @@ -134,9 +134,9 @@ func (opts WindowShareOptsType) Value() (driver.Value, error) { } type RemotePtrType struct { - OwnerUserId string `json:"owneruserid"` - RemoteId string `json:"remoteid"` - Name string `json:"name"` + OwnerId string `json:"ownerid"` + RemoteId string `json:"remoteid"` + Name string `json:"name"` } func (r RemotePtrType) IsSessionScope() bool { @@ -147,28 +147,28 @@ func (r RemotePtrType) MakeFullRemoteRef() string { if r.RemoteId == "" { return "" } - if r.OwnerUserId == "" && r.Name == "" { + if r.OwnerId == "" && r.Name == "" { return r.RemoteId } - if r.OwnerUserId != "" && r.Name == "" { - return fmt.Sprintf("@%s:%s", r.OwnerUserId, r.RemoteId) + if r.OwnerId != "" && r.Name == "" { + return fmt.Sprintf("@%s:%s", r.OwnerId, r.RemoteId) } - if r.OwnerUserId == "" && r.Name != "" { + if r.OwnerId == "" && r.Name != "" { return fmt.Sprintf("%s:%s", r.RemoteId, r.Name) } - return fmt.Sprintf("@%s:%s:%s", r.OwnerUserId, r.RemoteId, r.Name) + return fmt.Sprintf("@%s:%s:%s", r.OwnerId, r.RemoteId, r.Name) } type WindowType struct { - SessionId string `json:"sessionid"` - WindowId string `json:"windowid"` - CurRemote RemotePtrType `json:"curremote"` - WinOpts WindowOptsType `json:"winopts"` - OwnerUserId string `json:"owneruserid"` - ShareMode string `json:"sharemode"` - ShareOpts WindowShareOptsType `json:"shareopts"` - Lines []*LineType `json:"lines"` - Cmds []*CmdType `json:"cmds"` + SessionId string `json:"sessionid"` + WindowId string `json:"windowid"` + CurRemote RemotePtrType `json:"curremote"` + WinOpts WindowOptsType `json:"winopts"` + OwnerId string `json:"ownerid"` + ShareMode string `json:"sharemode"` + ShareOpts WindowShareOptsType `json:"shareopts"` + Lines []*LineType `json:"lines"` + Cmds []*CmdType `json:"cmds"` // only for updates Remove bool `json:"remove,omitempty"` @@ -178,11 +178,11 @@ func (w *WindowType) ToMap() map[string]interface{} { rtn := make(map[string]interface{}) rtn["sessionid"] = w.SessionId rtn["windowid"] = w.WindowId - rtn["curremoteowneruserid"] = w.CurRemote.OwnerUserId + rtn["curremoteownerid"] = w.CurRemote.OwnerId rtn["curremoteid"] = w.CurRemote.RemoteId rtn["curremotename"] = w.CurRemote.Name rtn["winopts"] = quickJson(w.WinOpts) - rtn["owneruserid"] = w.OwnerUserId + rtn["ownerid"] = w.OwnerId rtn["sharemode"] = w.ShareMode rtn["shareopts"] = quickJson(w.ShareOpts) return rtn @@ -195,11 +195,11 @@ func WindowFromMap(m map[string]interface{}) *WindowType { var w WindowType quickSetStr(&w.SessionId, m, "sessionid") quickSetStr(&w.WindowId, m, "windowid") - quickSetStr(&w.CurRemote.OwnerUserId, m, "curremoteowneruserid") + quickSetStr(&w.CurRemote.OwnerId, m, "curremoteownerid") quickSetStr(&w.CurRemote.RemoteId, m, "curremoteid") quickSetStr(&w.CurRemote.Name, m, "curremotename") quickSetJson(&w.WinOpts, m, "winopts") - quickSetStr(&w.OwnerUserId, m, "owneruserid") + quickSetStr(&w.OwnerId, m, "ownerid") quickSetStr(&w.ShareMode, m, "sharemode") quickSetJson(&w.ShareOpts, m, "shareopts") return &w @@ -224,7 +224,7 @@ type ScreenType struct { Name string `json:"name"` ActiveWindowId string `json:"activewindowid"` ScreenOpts ScreenOptsType `json:"screenopts"` - OwnerUserId string `json:"owneruserid"` + OwnerId string `json:"ownerid"` ShareMode string `json:"sharemode"` Windows []*ScreenWindowType `json:"windows"` @@ -314,13 +314,13 @@ func (opts TermOpts) Value() (driver.Value, error) { } type RemoteInstance struct { - RIId string `json:"riid"` - Name string `json:"name"` - SessionId string `json:"sessionid"` - WindowId string `json:"windowid"` - RemoteOwnerUserId string `json:"remoteowneruserid"` - RemoteId string `json:"remoteid"` - State RemoteState `json:"state"` + RIId string `json:"riid"` + Name string `json:"name"` + SessionId string `json:"sessionid"` + WindowId string `json:"windowid"` + RemoteOwnerId string `json:"remoteownerid"` + RemoteId string `json:"remoteid"` + State RemoteState `json:"state"` // only for updates Remove bool `json:"remove,omitempty"` @@ -388,7 +388,7 @@ func (r *RemoteType) GetName() string { type CmdType struct { SessionId string `json:"sessionid"` CmdId string `json:"cmdid"` - RemoteId string `json:"remoteid"` + Remote RemotePtrType `json:"remote"` CmdStr string `json:"cmdstr"` RemoteState RemoteState `json:"remotestate"` TermOpts TermOpts `json:"termopts"` @@ -443,7 +443,9 @@ func (cmd *CmdType) ToMap() map[string]interface{} { rtn := make(map[string]interface{}) rtn["sessionid"] = cmd.SessionId rtn["cmdid"] = cmd.CmdId - rtn["remoteid"] = cmd.RemoteId + rtn["remoteownerid"] = cmd.Remote.OwnerId + rtn["remoteid"] = cmd.Remote.RemoteId + rtn["remotename"] = cmd.Remote.Name rtn["cmdstr"] = cmd.CmdStr rtn["remotestate"] = quickJson(cmd.RemoteState) rtn["termopts"] = quickJson(cmd.TermOpts) @@ -462,7 +464,9 @@ func CmdFromMap(m map[string]interface{}) *CmdType { var cmd CmdType quickSetStr(&cmd.SessionId, m, "sessionid") quickSetStr(&cmd.CmdId, m, "cmdid") - quickSetStr(&cmd.RemoteId, m, "remoteid") + quickSetStr(&cmd.Remote.OwnerId, m, "remoteownerid") + quickSetStr(&cmd.Remote.RemoteId, m, "remoteid") + quickSetStr(&cmd.Remote.Name, m, "remotename") quickSetStr(&cmd.CmdStr, m, "cmdstr") quickSetJson(&cmd.RemoteState, m, "remotestate") quickSetJson(&cmd.TermOpts, m, "termopts")