Skip to content

Commit 1c515c3

Browse files
authored
Merge pull request #394 from jumpserver/pr@v3@feat_create_share_link
feat: create share link
2 parents 9e7d884 + 24156b8 commit 1c515c3

34 files changed

Lines changed: 6692 additions & 436 deletions

‎main.go‎

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -68,9 +68,6 @@ func main() {
6868
Cache: &tunnel.GuaTunnelCacheManager{
6969
GuaTunnelCache: NewGuaTunnelCache(),
7070
},
71-
SessCache: &tunnel.SessionCache{
72-
Sessions: make(map[string]*session.TunnelSession),
73-
},
7471
JmsService: jmsService,
7572
SessionService: &session.Server{JmsService: jmsService,
7673
VideoWorkerClient: videoWorkerClient,
@@ -253,13 +250,20 @@ func registerRouter(jmsService *service.JMService, tunnelService *tunnel.Guacamo
253250
ctx.File("./ui/dist/index.html")
254251
})
255252
}
253+
254+
{
255+
shareGroup := lionGroup.Group("/share")
256+
shareGroup.Use(middleware.JmsCookieAuth(jmsService))
257+
shareGroup.Any("/:id", func(ctx *gin.Context) {
258+
ctx.File("./ui/dist/index.html")
259+
})
260+
}
261+
256262
// token 使用 lion 自带认证
257263

258264
{
259265
tokenGroup := lionGroup.Group("/token")
260266
tokenGroup.Use(middleware.SessionAuth(jmsService))
261-
tokenGroup.POST("/session", tunnelService.TokenSession)
262-
tokenGroup.DELETE("/sessions/:sid/", tunnelService.DeleteSession)
263267
tokenTunnels := tokenGroup.Group("/tunnels")
264268
tokenTunnels.GET("/:tid/streams/:index/:filename", tunnelService.DownloadFile)
265269
tokenTunnels.POST("/:tid/streams/:index/:filename", tunnelService.UploadFile)
@@ -273,17 +277,21 @@ func registerRouter(jmsService *service.JMService, tunnelService *tunnel.Guacamo
273277
wsGroup.Group("/monitor").Use(
274278
middleware.JmsCookieAuth(jmsService)).GET("/", tunnelService.Monitor)
275279

280+
wsGroup.Group("/share").Use(
281+
middleware.JmsCookieAuth(jmsService)).GET("/", tunnelService.Share)
282+
276283
wsGroup.Group("/token").Use(
277284
middleware.SessionAuth(jmsService)).GET("/", tunnelService.Connect)
278285
}
279286

280287
{
281288
apiGroup := lionGroup.Group("/api")
282289
apiGroup.Use(middleware.JmsCookieAuth(jmsService))
283-
apiGroup.POST("/session", tunnelService.CreateSession)
284-
apiGroup.DELETE("/sessions/:sid/", tunnelService.DeleteSession)
285290
apiGroup.GET("/tunnels/:tid/streams/:index/:filename", tunnelService.DownloadFile)
286291
apiGroup.POST("/tunnels/:tid/streams/:index/:filename", tunnelService.UploadFile)
292+
apiGroup.POST("/share/", tunnelService.CreateShare)
293+
apiGroup.POST("/share/remove/", tunnelService.DeleteShare)
294+
apiGroup.POST("/share/:id/", tunnelService.GetShare)
287295
}
288296

289297
pprofRouter := eng.Group("/debug/pprof")

‎pkg/guacd/tunnel.go‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ func NewTunnel(address string, config Configuration, info ClientInformation) (tu
122122
return nil, err
123123
}
124124

125-
tunnel.UUID = ready.Args[0]
125+
tunnel.uuid = ready.Args[0]
126126
tunnel.IsOpen = true
127127
return tunnel, nil
128128
}
@@ -131,11 +131,15 @@ type Tunnel struct {
131131
rw *bufio.ReadWriter
132132
conn net.Conn
133133

134-
UUID string
134+
uuid string
135135
Config Configuration
136136
IsOpen bool
137137
}
138138

139+
func (t *Tunnel) UUID() string {
140+
return t.uuid
141+
}
142+
139143
func (t *Tunnel) WriteInstructionAndFlush(instruction Instruction) (err error) {
140144
_, err = t.WriteAndFlush([]byte(instruction.String()))
141145
return

‎pkg/jms-sdk-go/model/permission.go‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ func (p *Permission) EnablePaste() bool {
2828
return p.haveAction(ActionPaste)
2929
}
3030

31+
func (p *Permission) EnableShare() bool {
32+
return p.haveAction(ActionShare)
33+
}
34+
3135
func (p *Permission) haveAction(action string) bool {
3236
for _, value := range p.Actions {
3337
if action == ActionALL || action == value {
@@ -44,6 +48,7 @@ const (
4448
ActionDownload = "download"
4549
ActionCopy = "copy"
4650
ActionPaste = "paste"
51+
ActionShare = "share"
4752
)
4853

4954
type ValidateResult struct {

‎pkg/jms-sdk-go/model/share.go‎

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package model
2+
3+
type SharingSession struct {
4+
ID string `json:"id"`
5+
IsActive bool `json:"is_active"`
6+
ExpiredTime int `json:"expired_time"`
7+
Code string `json:"verify_code"`
8+
9+
ActionPermission string `json:"action_permission"`
10+
}
11+
12+
type ShareRecord struct {
13+
ID string `json:"id"`
14+
Code string `json:"verify_code"`
15+
Session ObjectId `json:"session"`
16+
Sharing ObjectId `json:"sharing"`
17+
OrgId string `json:"org_id"`
18+
OrgName string `json:"org_name"`
19+
20+
ActionPermission LabelValue `json:"action_permission"`
21+
22+
Err interface{} `json:"error"`
23+
}
24+
25+
const (
26+
readOnlyPermission = "readonly"
27+
writablePermission = "writable"
28+
)
29+
30+
func (s ShareRecord) Writeable() bool {
31+
return s.ActionPermission.Value == writablePermission
32+
}
33+
34+
type SharingSessionRequest struct {
35+
SessionID string `json:"session"`
36+
ExpireTime int `json:"expired_time"`
37+
Users []string `json:"users"`
38+
ActionPerm string `json:"action_permission"`
39+
}
40+
41+
type SharePostData struct {
42+
ShareId string `json:"sharing"`
43+
Code string `json:"verify_code"`
44+
UserId string `json:"joiner"`
45+
RemoteAddr string `json:"remote_addr"`
46+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package service
2+
3+
import (
4+
"fmt"
5+
6+
"lion/pkg/jms-sdk-go/model"
7+
)
8+
9+
func (s *JMService) CreateShareRoom(data model.SharingSessionRequest) (res model.SharingSession, err error) {
10+
_, err = s.authClient.Post(ShareCreateURL, data, &res)
11+
return
12+
}
13+
14+
func (s *JMService) JoinShareRoom(data model.SharePostData) (res model.ShareRecord, err error) {
15+
_, err = s.authClient.Post(ShareSessionJoinURL, data, &res)
16+
return
17+
}
18+
19+
func (s *JMService) FinishShareRoom(recordId string) (err error) {
20+
reqUrl := fmt.Sprintf(ShareSessionFinishURL, recordId)
21+
_, err = s.authClient.Patch(reqUrl, nil, nil)
22+
return
23+
}

‎pkg/jms-sdk-go/service/url.go‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,9 @@ const (
5151

5252
SuperConnectTokenVirtualAppOptionURL = "/api/v1/authentication/super-connection-token/virtual-app-option/"
5353
)
54+
55+
const (
56+
ShareCreateURL = "/api/v1/terminal/session-sharings/"
57+
ShareSessionJoinURL = "/api/v1/terminal/session-join-records/"
58+
ShareSessionFinishURL = "/api/v1/terminal/session-join-records/%s/finished/"
59+
)

‎pkg/session/message.go‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,8 @@ type MetaMessage struct {
1010
UserId string `json:"user_id"`
1111
User string `json:"user"`
1212
Created string `json:"created"`
13+
14+
TerminalId string `json:"terminal_id"`
15+
Primary bool `json:"primary"`
16+
Writable bool `json:"writable"`
1317
}

‎pkg/session/permisson.go‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ type ActionPermission struct {
1313

1414
EnableUpload bool `json:"enable_upload"`
1515
EnableDownload bool `json:"enable_download"`
16+
EnableShare bool `json:"enable_share"`
1617
}
1718

1819
func NewActionPermission(perm *model.Permission, connectType string) *ActionPermission {
@@ -22,6 +23,7 @@ func NewActionPermission(perm *model.Permission, connectType string) *ActionPerm
2223
EnablePaste: perm.EnablePaste(),
2324
EnableUpload: perm.EnableUpload(),
2425
EnableDownload: perm.EnableDownload(),
26+
EnableShare: perm.EnableShare(),
2527
}
2628
globConfig := config.GlobalConfig
2729
switch connectType {

‎pkg/tunnel/cache.go‎

Lines changed: 79 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ package tunnel
33
import (
44
"sync"
55

6+
"lion/pkg/common"
67
"lion/pkg/guacd"
7-
"lion/pkg/session"
8+
"lion/pkg/logger"
89
)
910

1011
type Tunneler interface {
12+
UUID() string
1113
WriteAndFlush(p []byte) (int, error)
1214
ReadInstruction() (guacd.Instruction, error)
1315
Close() error
@@ -22,6 +24,16 @@ type GuaTunnelCache interface {
2224
GetBySessionId(sid string) *Connection
2325
GetMonitorTunnelerBySessionId(sid string) Tunneler
2426
RemoveMonitorTunneler(sid string, monitorTunnel Tunneler)
27+
28+
GetSessionEventChan(sid string) *EventChan
29+
BroadcastSessionEvent(sid string, event *Event)
30+
RecycleSessionEventChannel(sid string, eventChan *EventChan)
31+
}
32+
33+
type SessionEvent interface {
34+
GetSessionEventChannel(sid string) *EventChan
35+
RecycleSessionEventChannel(sid string, eventChan *EventChan)
36+
BroadcastSessionEvent(sid string, event *Event)
2537
}
2638

2739
var (
@@ -33,27 +45,76 @@ type GuaTunnelCacheManager struct {
3345
GuaTunnelCache
3446
}
3547

36-
type SessionCache struct {
37-
sync.Mutex
38-
Sessions map[string]*session.TunnelSession
48+
type Room struct {
49+
sid string
50+
eventChanMaps map[string]*EventChan
51+
lock sync.Mutex
52+
}
53+
54+
func (r *Room) GetEventChannel(sid string) *EventChan {
55+
r.lock.Lock()
56+
defer r.lock.Unlock()
57+
eventChan := NewEventChan(sid)
58+
r.eventChanMaps[eventChan.id] = eventChan
59+
return eventChan
60+
}
61+
62+
func (r *Room) RecycleEventChannel(eventChan *EventChan) {
63+
r.lock.Lock()
64+
defer r.lock.Unlock()
65+
delete(r.eventChanMaps, eventChan.id)
66+
eventChan.Close()
67+
}
68+
69+
func (r *Room) BroadcastEvent(event *Event) {
70+
r.lock.Lock()
71+
defer r.lock.Unlock()
72+
for _, eventChan := range r.eventChanMaps {
73+
eventChan.SendEvent(event)
74+
}
3975
}
4076

41-
func (g *SessionCache) Add(s *session.TunnelSession) {
42-
g.Lock()
43-
defer g.Unlock()
44-
g.Sessions[s.ID] = s
77+
type EventChan struct {
78+
id string
79+
sid string
80+
eventCh chan *Event
4581
}
4682

47-
func (g *SessionCache) Get(sid string) *session.TunnelSession {
48-
g.Lock()
49-
defer g.Unlock()
50-
return g.Sessions[sid]
83+
func (e *EventChan) GetEventChannel() chan *Event {
84+
return e.eventCh
5185
}
5286

53-
func (g *SessionCache) Pop(sid string) *session.TunnelSession {
54-
g.Lock()
55-
defer g.Unlock()
56-
sess := g.Sessions[sid]
57-
delete(g.Sessions, sid)
58-
return sess
87+
func (e *EventChan) SendEvent(event *Event) {
88+
select {
89+
case e.eventCh <- event:
90+
default:
91+
logger.Errorf("EventChan %s for session %s is full", e.id, e.sid)
92+
}
5993
}
94+
95+
func (e *EventChan) Close() {
96+
close(e.eventCh)
97+
}
98+
99+
func NewEventChan(sid string) *EventChan {
100+
return &EventChan{
101+
id: common.UUID(),
102+
sid: sid,
103+
eventCh: make(chan *Event, 5),
104+
}
105+
}
106+
107+
type Event struct {
108+
Type string
109+
Data []byte
110+
}
111+
112+
const (
113+
ShareJoin = "share_join"
114+
ShareExit = "share_exit"
115+
ShareUsers = "share_users"
116+
117+
ShareRemoveUser = "share_remove_user"
118+
ShareSessionPause = "share_session_pause"
119+
ShareSessionResume = "share_session_resume"
120+
)

0 commit comments

Comments
 (0)