From 21617298e9e4ab5ec9033aa45562bc98b47a91b8 Mon Sep 17 00:00:00 2001 From: sawka Date: Wed, 21 Sep 2022 22:02:38 -0700 Subject: [PATCH] origtermopts, clientdata to/from map --- db/migrations/000001_init.up.sql | 2 + db/schema.sql | 3 ++ pkg/cmdrunner/cmdrunner.go | 3 ++ pkg/sstore/dbops.go | 5 ++- pkg/sstore/quick.go | 11 +++++ pkg/sstore/sstore.go | 72 ++++++++++++++++++++++++-------- 6 files changed, 76 insertions(+), 20 deletions(-) diff --git a/db/migrations/000001_init.up.sql b/db/migrations/000001_init.up.sql index 5e8ef70a1..20fd6ca9b 100644 --- a/db/migrations/000001_init.up.sql +++ b/db/migrations/000001_init.up.sql @@ -1,4 +1,5 @@ CREATE TABLE client ( + clientid varchar(36) NOT NULL, userid varchar(36) NOT NULL, activesessionid varchar(36) NOT NULL, userpublickeybytes blob NOT NULL, @@ -104,6 +105,7 @@ CREATE TABLE cmd ( cmdstr text NOT NULL, remotestate json NOT NULL, termopts json NOT NULL, + origtermopts json NOT NULL, status varchar(10) NOT NULL, startpk json NOT NULL, donepk json NOT NULL, diff --git a/db/schema.sql b/db/schema.sql index a7054dd2b..c049c2391 100644 --- a/db/schema.sql +++ b/db/schema.sql @@ -1,6 +1,7 @@ CREATE TABLE schema_migrations (version uint64,dirty bool); CREATE UNIQUE INDEX version_unique ON schema_migrations (version); CREATE TABLE client ( + clientid varchar(36) NOT NULL, userid varchar(36) NOT NULL, activesessionid varchar(36) NOT NULL, userpublickeybytes blob NOT NULL, @@ -22,6 +23,7 @@ CREATE TABLE window ( curremoteownerid varchar(36) NOT NULL, curremoteid varchar(36) NOT NULL, curremotename varchar(50) NOT NULL, + nextlinenum int NOT NULL, winopts json NOT NULL, ownerid varchar(36) NOT NULL, sharemode varchar(12) NOT NULL, @@ -97,6 +99,7 @@ CREATE TABLE cmd ( cmdstr text NOT NULL, remotestate json NOT NULL, termopts json NOT NULL, + origtermopts json NOT NULL, status varchar(10) NOT NULL, startpk json NOT NULL, donepk json NOT NULL, diff --git a/pkg/cmdrunner/cmdrunner.go b/pkg/cmdrunner/cmdrunner.go index 2476813d9..74cd4309a 100644 --- a/pkg/cmdrunner/cmdrunner.go +++ b/pkg/cmdrunner/cmdrunner.go @@ -1310,6 +1310,9 @@ func LineShowCommand(ctx context.Context, pk *scpacket.FeCommandPacketType) (sst buf.WriteString(fmt.Sprintf(" %-15s %s\n", "cwd", cmd.RemoteState.Cwd)) } buf.WriteString(fmt.Sprintf(" %-15s %s\n", "termopts", formatTermOpts(cmd.TermOpts))) + if cmd.TermOpts != cmd.OrigTermOpts { + buf.WriteString(fmt.Sprintf(" %-15s %s\n", "orig-termopts", formatTermOpts(cmd.OrigTermOpts))) + } } update := sstore.ModelUpdate{ Info: &sstore.InfoMsgType{ diff --git a/pkg/sstore/dbops.go b/pkg/sstore/dbops.go index 487d7073d..20555ce2e 100644 --- a/pkg/sstore/dbops.go +++ b/pkg/sstore/dbops.go @@ -592,6 +592,7 @@ func InsertLine(ctx context.Context, line *LineType, cmd *CmdType) error { if line.LineNum != 0 { return fmt.Errorf("line should not hage linenum set") } + cmd.OrigTermOpts = cmd.TermOpts return WithTx(ctx, func(tx *TxWrap) error { query := `SELECT windowid FROM window WHERE sessionid = ? AND windowid = ?` if !tx.Exists(query, line.SessionId, line.WindowId) { @@ -608,8 +609,8 @@ func InsertLine(ctx context.Context, line *LineType, cmd *CmdType) error { if cmd != nil { cmdMap := cmd.ToMap() query = ` -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) +INSERT INTO cmd ( sessionid, cmdid, remoteownerid, remoteid, remotename, cmdstr, remotestate, termopts, origtermopts, status, startpk, donepk, runout, usedrows) + VALUES (:sessionid,:cmdid,:remoteownerid,:remoteid,:remotename,:cmdstr,:remotestate,:termopts,:origtermopts,:status,:startpk,:donepk,:runout,:usedrows) ` tx.NamedExecWrap(query, cmdMap) } diff --git a/pkg/sstore/quick.go b/pkg/sstore/quick.go index df7a26a71..df1882b76 100644 --- a/pkg/sstore/quick.go +++ b/pkg/sstore/quick.go @@ -54,6 +54,17 @@ func quickSetBool(bval *bool, m map[string]interface{}, name string) { } } +func quickSetBytes(bval *[]byte, m map[string]interface{}, name string) { + v, ok := m[name] + if !ok { + return + } + sqlBytes, ok := v.([]byte) + if ok { + *bval = sqlBytes + } +} + func quickSetJson(ptr interface{}, m map[string]interface{}, name string) { v, ok := m[name] if !ok { diff --git a/pkg/sstore/sstore.go b/pkg/sstore/sstore.go index 5833c970d..f3e96fabb 100644 --- a/pkg/sstore/sstore.go +++ b/pkg/sstore/sstore.go @@ -92,6 +92,7 @@ func GetDB(ctx context.Context) (*sqlx.DB, error) { } type ClientData struct { + ClientId string `json:"clientid"` UserId string `json:"userid"` UserPrivateKeyBytes []byte `json:"-"` UserPublicKeyBytes []byte `json:"-"` @@ -100,6 +101,29 @@ type ClientData struct { ActiveSessionId string `json:"activesessionid"` } +func (c *ClientData) ToMap() map[string]interface{} { + rtn := make(map[string]interface{}) + rtn["clientid"] = c.ClientId + rtn["userid"] = c.UserId + rtn["userprivatekeybytes"] = c.UserPrivateKeyBytes + rtn["userpublickeybytes"] = c.UserPublicKeyBytes + rtn["activesessionid"] = c.ActiveSessionId + return rtn +} + +func ClientDataFromMap(m map[string]interface{}) *ClientData { + if len(m) == 0 { + return nil + } + var c ClientData + quickSetStr(&c.ClientId, m, "clientid") + quickSetStr(&c.UserId, m, "userid") + quickSetBytes(&c.UserPrivateKeyBytes, m, "userprivatekeybytes") + quickSetBytes(&c.UserPublicKeyBytes, m, "userpublickeybytes") + quickSetStr(&c.ActiveSessionId, m, "activesessionid") + return &c +} + type SessionType struct { SessionId string `json:"sessionid"` Name string `json:"name"` @@ -480,18 +504,19 @@ func (r *RemoteType) GetName() string { } type CmdType struct { - SessionId string `json:"sessionid"` - CmdId string `json:"cmdid"` - Remote RemotePtrType `json:"remote"` - CmdStr string `json:"cmdstr"` - RemoteState RemoteState `json:"remotestate"` - TermOpts TermOpts `json:"termopts"` - Status string `json:"status"` - StartPk *packet.CmdStartPacketType `json:"startpk"` - DonePk *packet.CmdDonePacketType `json:"donepk"` - UsedRows int64 `json:"usedrows"` - RunOut []packet.PacketType `json:"runout"` - Remove bool `json:"remove"` + SessionId string `json:"sessionid"` + CmdId string `json:"cmdid"` + Remote RemotePtrType `json:"remote"` + CmdStr string `json:"cmdstr"` + RemoteState RemoteState `json:"remotestate"` + TermOpts TermOpts `json:"termopts"` + OrigTermOpts TermOpts `json:"origtermopts"` + Status string `json:"status"` + StartPk *packet.CmdStartPacketType `json:"startpk"` + DonePk *packet.CmdDonePacketType `json:"donepk"` + UsedRows int64 `json:"usedrows"` + RunOut []packet.PacketType `json:"runout"` + Remove bool `json:"remove"` } func (r *RemoteType) ToMap() map[string]interface{} { @@ -547,6 +572,7 @@ func (cmd *CmdType) ToMap() map[string]interface{} { rtn["cmdstr"] = cmd.CmdStr rtn["remotestate"] = quickJson(cmd.RemoteState) rtn["termopts"] = quickJson(cmd.TermOpts) + rtn["origtermopts"] = quickJson(cmd.OrigTermOpts) rtn["status"] = cmd.Status rtn["startpk"] = quickJson(cmd.StartPk) rtn["donepk"] = quickJson(cmd.DonePk) @@ -568,6 +594,7 @@ func CmdFromMap(m map[string]interface{}) *CmdType { quickSetStr(&cmd.CmdStr, m, "cmdstr") quickSetJson(&cmd.RemoteState, m, "remotestate") quickSetJson(&cmd.TermOpts, m, "termopts") + quickSetJson(&cmd.OrigTermOpts, m, "origtermopts") quickSetStr(&cmd.Status, m, "status") quickSetJson(&cmd.StartPk, m, "startpk") quickSetJson(&cmd.DonePk, m, "donepk") @@ -740,7 +767,6 @@ func EnsureDefaultSession(ctx context.Context) (*SessionType, error) { } func createClientData(tx *TxWrap) error { - userId := scbase.GenSCUUID() curve := elliptic.P384() pkey, err := ecdsa.GenerateKey(curve, rand.Reader) if err != nil { @@ -754,9 +780,17 @@ func createClientData(tx *TxWrap) error { if err != nil { return fmt.Errorf("marshaling (pkix) public key bytes: %w", err) } - query := `INSERT INTO client (userid, activesessionid, userpublickeybytes, userprivatekeybytes) VALUES (?, '', ?, ?)` - tx.ExecWrap(query, userId, pubBytes, pkBytes) - fmt.Printf("create new userid[%s] with public/private keypair\n", userId) + c := ClientData{ + ClientId: uuid.New().String(), + UserId: uuid.New().String(), + UserPrivateKeyBytes: pkBytes, + UserPublicKeyBytes: pubBytes, + ActiveSessionId: "", + } + query := `INSERT INTO client ( clientid, userid, activesessionid, userpublickeybytes, userprivatekeybytes) + VALUES (:clientid,:userid,:activesessionid,:userpublickeybytes,:userprivatekeybytes)` + tx.NamedExecWrap(query, c.ToMap()) + fmt.Printf("create new clientid[%s] userid[%s] with public/private keypair\n", c.ClientId, c.UserId) return nil } @@ -774,10 +808,12 @@ func EnsureClientData(ctx context.Context) (*ClientData, error) { return createErr } } - found := tx.GetWrap(&rtn, "SELECT * FROM client") - if !found { + m := tx.GetMap("SELECT * FROM client") + cdata := ClientDataFromMap(m) + if cdata == nil { return fmt.Errorf("invalid client data") } + rtn = *cdata return nil }) if err != nil {