Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v3.10.4 #1303

Merged
merged 19 commits into from
Feb 29, 2024
Merged

v3.10.4 #1303

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ all: koko-ui
$(call make_artifact_full,darwin,arm64)
$(call make_artifact_full,linux,amd64)
$(call make_artifact_full,linux,arm64)
$(call make_artifact_full,linux,mips64le)
$(call make_artifact_full,linux,ppc64le)
$(call make_artifact_full,linux,s390x)
$(call make_artifact_full,linux,riscv64)
Expand All @@ -83,6 +84,9 @@ linux-arm64: koko-ui
linux-loong64: koko-ui
$(call make_artifact_full,linux,loong64)

linux-mips64le: koko-ui
$(call make_artifact_full,linux,mips64le)

linux-ppc64le: koko-ui
$(call make_artifact_full,linux,ppc64le)

Expand Down
12 changes: 6 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ require (
github.com/spf13/viper v1.12.0
github.com/xlab/treeprint v1.1.0
go.mongodb.org/mongo-driver v1.8.3
golang.org/x/crypto v0.14.0
golang.org/x/term v0.13.0
golang.org/x/text v0.13.0
golang.org/x/crypto v0.19.0
golang.org/x/term v0.17.0
golang.org/x/text v0.14.0
gopkg.in/natefinch/lumberjack.v2 v2.0.0
k8s.io/api v0.23.1
k8s.io/apimachinery v0.23.1
Expand Down Expand Up @@ -106,7 +106,7 @@ require (
golang.org/x/net v0.17.0 // indirect
golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.13.0 // indirect
golang.org/x/sys v0.17.0 // indirect
golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect
golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df // indirect
google.golang.org/appengine v1.6.7 // indirect
Expand All @@ -125,6 +125,6 @@ require (
)

replace (
github.com/gliderlabs/ssh => github.com/LeeEirc/ssh v0.1.2-0.20231007053448-a6110c0dfc4a
golang.org/x/crypto => github.com/LeeEirc/crypto v0.0.0-20230919154755-059031d26b68
github.com/gliderlabs/ssh => github.com/jumpserver-dev/ssh v0.1.2-0.20240209035326-4f0f6365ccae
golang.org/x/crypto => github.com/jumpserver-dev/crypto v0.0.0-20240209025851-4b55dc4c3463
)
27 changes: 14 additions & 13 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,10 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/ClickHouse/clickhouse-go v1.5.4 h1:cKjXeYLNWVJIx2J1K6H2CqyRmfwVJVY1OV1coaaFcI0=
github.com/ClickHouse/clickhouse-go v1.5.4/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
github.com/LeeEirc/crypto v0.0.0-20230919154755-059031d26b68 h1:bkeuW/ujHp3Rr1K3Ah4/Onw9Ero9uMKX0rPxbzV5mvw=
github.com/LeeEirc/crypto v0.0.0-20230919154755-059031d26b68/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
github.com/LeeEirc/elfinder v0.0.14 h1:6ObxwIoC5zmrnKArUU5Mz++/T3lzgl1Ja0pS1Smd3j4=
github.com/LeeEirc/elfinder v0.0.14/go.mod h1:d1bMAAydkZSBxSN/EuQjBg6B0xcPP3boHuYEpzEHYTs=
github.com/LeeEirc/httpsig v1.2.1 h1:GGmCc2Bug3KeCchlZHwrfyjyAnw+JlzMjKDobPypirs=
github.com/LeeEirc/httpsig v1.2.1/go.mod h1:aoLZLXCSNDgkzsH2sGLWn3hlVbF+Voe8fCArxLt9nWA=
github.com/LeeEirc/ssh v0.1.2-0.20231007053448-a6110c0dfc4a h1:/EdJeCK6cTaKNgftQLP9uyBL4Q86MFawU0WsK22yn2A=
github.com/LeeEirc/ssh v0.1.2-0.20231007053448-a6110c0dfc4a/go.mod h1:O9BMs9PYwCJbftRP9O2Ig5Wd3hbLSpzhvP0bqU9EONg=
github.com/LeeEirc/tclientlib v0.0.3-0.20230803101925-fb52a90cb08d h1:4qUSGc/34IALiDs2kBrjbCKfx7zvAt16K+gTRzNN8Fo=
github.com/LeeEirc/tclientlib v0.0.3-0.20230803101925-fb52a90cb08d/go.mod h1:TF2v0XZYyRcZfx4NmA/EEFRkdKZLsQd8YnlhGKl1KUA=
github.com/LeeEirc/terminalparser v0.0.0-20220328021224-de16b7643ea4 h1:Gk7m4Nu2jqVqJAJqNlTYqkiq96WkANAtB4fVi+t7Xv8=
Expand Down Expand Up @@ -279,6 +275,10 @@ github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnr
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jumpserver-dev/crypto v0.0.0-20240209025851-4b55dc4c3463 h1:ZQTX/4gO/G8SFtzn9K8M2mac83TSIyEHX9/2bnBKf1Y=
github.com/jumpserver-dev/crypto v0.0.0-20240209025851-4b55dc4c3463/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU=
github.com/jumpserver-dev/ssh v0.1.2-0.20240209035326-4f0f6365ccae h1:zND4fMpJoOf90TILA9CY9KTub+YLK+pdiG6LM/+9UBo=
github.com/jumpserver-dev/ssh v0.1.2-0.20240209035326-4f0f6365ccae/go.mod h1:KdoSNwfOgcFXlcr2OQ34eeKfIl7K8l6cAQ6twkYaLcU=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
Expand Down Expand Up @@ -522,7 +522,7 @@ golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM=
golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
Expand Down Expand Up @@ -612,16 +612,17 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.13.0 h1:Af8nKPmuFypiUBjVoU9V20FiaFXOcuZI21p0ycVYYGE=
golang.org/x/sys v0.13.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y=
golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210615171337-6886f2dfbf5b/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
golang.org/x/term v0.13.0 h1:bb+I9cTfFazGW51MZqBVmZy7+JEJMouUHTUSKVQLBek=
golang.org/x/term v0.13.0/go.mod h1:LTmsnFJwVN6bCy1rVCoS+qHT1HhALEFxKncY3WNNh4U=
golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
golang.org/x/term v0.17.0 h1:mkTF7LCd6WGJNL3K1Ad7kwxNfYAW6a8a8QqtMblp/4U=
golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand All @@ -633,9 +634,9 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
Expand Down
37 changes: 19 additions & 18 deletions pkg/auth/ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ type SSHAuthFunc func(ctx ssh.Context, password, publicKey string) (res ssh.Auth

func SSHPasswordAndPublicKeyAuth(jmsService *service.JMService) SSHAuthFunc {
return func(ctx ssh.Context, password, publicKey string) (res ssh.AuthResult) {
if password == "" && publicKey == "" {
logger.Errorf("SSH conn[%s] no password and publickey", ctx.SessionID())
return ssh.AuthFailed
}
remoteAddr, _, _ := net.SplitHostPort(ctx.RemoteAddr().String())
username := ctx.User()
if req, ok := parseDirectLoginReq(jmsService, ctx); ok {
Expand All @@ -35,25 +39,22 @@ func SSHPasswordAndPublicKeyAuth(jmsService *service.JMService) SSHAuthFunc {
if password != "" {
authMethod = "password"
}
userAuthClient, ok := ctx.Value(ContextKeyClient).(*UserAuthClient)
if !ok {
newClient := jmsService.CloneClient()
var accessKey model.AccessKey
conf := config.GetConf()
_ = accessKey.LoadFromFile(conf.AccessKeyFilePath)
userClient := service.NewUserClient(
service.UserClientUsername(username),
service.UserClientRemoteAddr(remoteAddr),
service.UserClientLoginType("T"),
service.UserClientHttpClient(&newClient),
service.UserClientSvcSignKey(accessKey),
)
userAuthClient = &UserAuthClient{
UserClient: userClient,
authOptions: make(map[string]authOptions),
}
ctx.SetValue(ContextKeyClient, userAuthClient)
newClient := jmsService.CloneClient()
var accessKey model.AccessKey
conf := config.GetConf()
_ = accessKey.LoadFromFile(conf.AccessKeyFilePath)
userClient := service.NewUserClient(
service.UserClientUsername(username),
service.UserClientRemoteAddr(remoteAddr),
service.UserClientLoginType("T"),
service.UserClientHttpClient(&newClient),
service.UserClientSvcSignKey(accessKey),
)
userAuthClient := &UserAuthClient{
UserClient: userClient,
authOptions: make(map[string]authOptions),
}
ctx.SetValue(ContextKeyClient, userAuthClient)
userAuthClient.SetOption(service.UserClientPassword(password),
service.UserClientPublicKey(publicKey))
logger.Infof("SSH conn[%s] authenticating user %s %s", ctx.SessionID(), username, authMethod)
Expand Down
3 changes: 0 additions & 3 deletions pkg/handler/select_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"sort"
"strconv"
"strings"
"time"

"github.com/jumpserver/koko/pkg/i18n"
"github.com/jumpserver/koko/pkg/jms-sdk-go/model"
Expand Down Expand Up @@ -218,8 +217,6 @@ func (u *UserSelectHandler) DisplayCurrentResult() {

func (u *UserSelectHandler) Proxy(target model.PermAsset) {
u.proxyAsset(target)
time.Sleep(time.Second * 2)
u.DisplayCurrentResult()
}

func (u *UserSelectHandler) Retrieve(pageSize, offset int, searches ...string) []model.PermAsset {
Expand Down
35 changes: 31 additions & 4 deletions pkg/handler/server_ssh.go
Original file line number Diff line number Diff line change
Expand Up @@ -321,10 +321,28 @@ func (s *Server) proxyTokenInfo(sess ssh.Session, tokeInfo *model.ConnectToken)
}
}

func IsScpCommand(rawStr string) bool {
rawCommands := strings.Split(rawStr, ";")
for _, cmd := range rawCommands {
cmd = strings.TrimSpace(cmd)
if strings.HasPrefix(cmd, "scp") {
return true
}
}
return false
}

func (s *Server) recordSessionLifecycle(sid string, event model.LifecycleEvent, reason string) {
logObj := model.SessionLifecycleLog{Reason: reason}
if err2 := s.jmsService.RecordSessionLifecycleLog(sid, event, logObj); err2 != nil {
logger.Errorf("Record session %s lifecycle %s failed: %s", sid, event, err2)
}
}

func (s *Server) proxyAssetCommand(sess ssh.Session, sshClient *srvconn.SSHClient,
tokeInfo *model.ConnectToken) {
rawStr := sess.RawCommand()
if strings.HasPrefix(rawStr, "scp") && !config.GetConf().EnableVscodeSupport {
if IsScpCommand(rawStr) && !config.GetConf().EnableVscodeSupport {
logger.Errorf("Not support scp command: %s", rawStr)
utils.IgnoreErrWriteString(sess, "Not support scp command")
return
Expand Down Expand Up @@ -360,6 +378,7 @@ func (s *Server) proxyAssetCommand(sess ssh.Session, sshClient *srvconn.SSHClien
}
ctx, cancel := context.WithCancel(sess.Context())
defer cancel()

traceSession := session.NewSession(&respSession, func(task *model.TerminalTask) error {
switch task.Name {
case model.TaskKillSession:
Expand All @@ -372,7 +391,7 @@ func (s *Server) proxyAssetCommand(sess ssh.Session, sshClient *srvconn.SSHClien

defer func() {
if err2 := s.jmsService.SessionFinished(respSession.ID, modelCommon.NewNowUTCTime()); err2 != nil {
logger.Errorf("Create tunnel session err: %s", err)
logger.Errorf("Create tunnel session err: %s", err2)
}
session.RemoveSession(traceSession)
}()
Expand All @@ -382,6 +401,7 @@ func (s *Server) proxyAssetCommand(sess ssh.Session, sshClient *srvconn.SSHClien
logger.Errorf("Get SSH session failed: %s", err)
return
}
s.recordSessionLifecycle(respSession.ID, model.AssetConnectSuccess, "")
defer goSess.Close()
defer sshClient.ReleaseSession(goSess)
go func() {
Expand Down Expand Up @@ -444,6 +464,8 @@ func (s *Server) proxyAssetCommand(sess ssh.Session, sshClient *srvconn.SSHClien
logger.Errorf("User %s Run command %s failed: %s",
tokeInfo.User.String(), rawStr, err)
}
reason := string(model.ReasonErrConnectDisconnect)
s.recordSessionLifecycle(respSession.ID, model.AssetConnectFinished, reason)
}

func (s *Server) proxyVscodeShell(sess ssh.Session, vsReq *vscodeReq, sshClient *srvconn.SSHClient,
Expand All @@ -469,7 +491,7 @@ func (s *Server) proxyVscodeShell(sess ssh.Session, vsReq *vscodeReq, sshClient
session.AddSession(traceSession)
defer func() {
if err2 := s.jmsService.SessionFinished(respSession.ID, modelCommon.NewNowUTCTime()); err2 != nil {
logger.Errorf("Create tunnel session err: %s", err)
logger.Errorf("Create tunnel session err: %s", err2)
}
session.RemoveSession(traceSession)
}()
Expand All @@ -479,7 +501,7 @@ func (s *Server) proxyVscodeShell(sess ssh.Session, vsReq *vscodeReq, sshClient
logger.Errorf("Get SSH session failed: %s", err)
return err
}

s.recordSessionLifecycle(respSession.ID, model.AssetConnectSuccess, "")
defer goSess.Close()
defer sshClient.ReleaseSession(goSess)
stdOut, err := goSess.StdoutPipe()
Expand All @@ -495,6 +517,7 @@ func (s *Server) proxyVscodeShell(sess ssh.Session, vsReq *vscodeReq, sshClient
err = goSess.Shell()
if err != nil {
logger.Errorf("Get SSH session shell failed: %s", err)
s.recordSessionLifecycle(respSession.ID, model.AssetConnectFinished, err.Error())
return err
}
logger.Infof("User %s start vscode request to %s", vsReq.user, sshClient)
Expand All @@ -514,11 +537,15 @@ func (s *Server) proxyVscodeShell(sess ssh.Session, vsReq *vscodeReq, sshClient
case <-ctx.Done():
logger.Infof("SSH conn[%s] User %s end vscode request %s as session done",
vsReq.reqId, vsReq.user, sshClient)
reason := string(model.ReasonErrConnectDisconnect)
s.recordSessionLifecycle(respSession.ID, model.AssetConnectFinished, reason)
return nil
case now := <-ticker.C:
if vsReq.expireInfo.IsExpired(now) {
logger.Infof("SSH conn[%s] User %s end vscode request %s as permission has expired",
vsReq.reqId, vsReq.user, sshClient)
reason := string(model.ReasonErrPermissionExpired)
s.recordSessionLifecycle(respSession.ID, model.AssetConnectFinished, reason)
return nil
}
logger.Debugf("SSH conn[%s] user %s vscode request still alive", vsReq.reqId, vsReq.user)
Expand Down
6 changes: 6 additions & 0 deletions pkg/httpd/tty.go
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,8 @@ func (h *tty) JoinRoom(c *Client, roomID string) {
Body: nil,
Meta: meta,
})
logObj := model.SessionLifecycleLog{User: h.ws.user.String()}
h.ws.RecordLifecycleLog(roomID, model.UserJoinSession, logObj)
for {
buf := make([]byte, 1024)
nr, err := c.Read(buf)
Expand All @@ -451,6 +453,7 @@ func (h *tty) JoinRoom(c *Client, roomID string) {
Body: nil,
Meta: meta,
})
h.ws.RecordLifecycleLog(roomID, model.UserLeaveSession, logObj)
logger.Infof("Conn[%s] user read end", c.ID())
if err := h.ws.apiClient.FinishShareRoom(h.shareInfo.Record.ID); err != nil {
logger.Infof("Conn[%s] finish share room err: %s", c.ID(), err)
Expand All @@ -463,6 +466,8 @@ func (h *tty) Monitor(c *Client, roomID string) {
conn := exchange.WrapperUserCon(c)
room.Subscribe(conn)
defer room.UnSubscribe(conn)
logObj := model.SessionLifecycleLog{User: h.ws.user.String()}
h.ws.RecordLifecycleLog(roomID, model.AdminJoinMonitor, logObj)
for {
buf := make([]byte, 1024)
_, err := c.Read(buf)
Expand All @@ -473,5 +478,6 @@ func (h *tty) Monitor(c *Client, roomID string) {
logger.Debugf("Conn[%s] user monitor", c.ID())
}
logger.Infof("Conn[%s] user read end", c.ID())
h.ws.RecordLifecycleLog(roomID, model.AdminExitMonitor, logObj)
}
}
7 changes: 7 additions & 0 deletions pkg/httpd/userwebsocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,3 +241,10 @@ var (
ErrDisableShare = errors.New("disable share")
ErrPermissionDenied = errors.New("permission denied")
)

func (userCon *UserWebsocket) RecordLifecycleLog(sid string, event model.LifecycleEvent,
logObj model.SessionLifecycleLog) {
if err := userCon.apiClient.RecordSessionLifecycleLog(sid, event, logObj); err != nil {
logger.Errorf("Record session lifecycle log err: %s", err)
}
}
2 changes: 1 addition & 1 deletion pkg/httpd/webserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ func (s *Server) GenerateViewMeta(targetId string) (meta ViewPageMata) {
if err != nil {
logger.Errorf("Get core api public setting err: %s", err)
}
meta.IconURL = setting.LogoURLS.Favicon
meta.IconURL = setting.Interface.Favicon
return
}

Expand Down
38 changes: 38 additions & 0 deletions pkg/jms-sdk-go/model/session.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,41 @@ const (
SessionReplayErrUploadFailed ReplayError = "replay_upload_failed"
SessionReplayErrUnsupported ReplayError = "replay_unsupported"
)

type LifecycleEvent string

const (
AssetConnectSuccess LifecycleEvent = "asset_connect_success"
AssetConnectFinished LifecycleEvent = "asset_connect_finished"
CreateShareLink LifecycleEvent = "create_share_link"
UserJoinSession LifecycleEvent = "user_join_session"
UserLeaveSession LifecycleEvent = "user_leave_session"
AdminJoinMonitor LifecycleEvent = "admin_join_monitor"
AdminExitMonitor LifecycleEvent = "admin_exit_monitor"
ReplayConvertStart LifecycleEvent = "replay_convert_start"
ReplayConvertSuccess LifecycleEvent = "replay_convert_success"
ReplayConvertFailure LifecycleEvent = "replay_convert_failure"
ReplayUploadStart LifecycleEvent = "replay_upload_start"
ReplayUploadSuccess LifecycleEvent = "replay_upload_success"
ReplayUploadFailure LifecycleEvent = "replay_upload_failure"
)

type SessionLifecycleLog struct {
Reason string `json:"reason"`
User string `json:"user"`
}

var EmptyLifecycleLog = SessionLifecycleLog{}

type SessionLifecycleReasonErr string

const (
ReasonErrConnectFailed SessionLifecycleReasonErr = "connect_failed"
ReasonErrConnectDisconnect SessionLifecycleReasonErr = "connect_disconnect"
ReasonErrUserClose SessionLifecycleReasonErr = "user_close"
ReasonErrIdleDisconnect SessionLifecycleReasonErr = "idle_disconnect"
ReasonErrAdminTerminate SessionLifecycleReasonErr = "admin_terminate"
ReasonErrMaxSessionTimeout SessionLifecycleReasonErr = "max_session_timeout"
ReasonErrPermissionExpired SessionLifecycleReasonErr = "permission_expired"
ReasonErrNullStorage SessionLifecycleReasonErr = "null_storage"
)
Loading
Loading