44package websocket
55
66import (
7+ goContext "context"
8+ "fmt"
9+
10+ "code.gitea.io/gitea/models/perm"
11+ "code.gitea.io/gitea/models/perm/access"
12+ "code.gitea.io/gitea/models/unit"
713 "code.gitea.io/gitea/modules/json"
14+ "code.gitea.io/gitea/modules/log"
815 "code.gitea.io/gitea/services/context"
916 notify_service "code.gitea.io/gitea/services/notify"
17+ "code.gitea.io/gitea/services/pubsub"
1018
1119 "github.com/mitchellh/mapstructure"
1220 "github.com/olahol/melody"
@@ -20,19 +28,26 @@ type websocketMessage struct {
2028}
2129
2230type subscribeMessageData struct {
23- URL string `json:"url "`
31+ Repo string `json:"repo "`
2432}
2533
2634func Init () * melody.Melody {
2735 m = melody .New ()
28- m .HandleConnect (handleConnect )
29- m .HandleMessage (handleMessage )
36+ hub := & hub {
37+ pubsub : pubsub .NewMemory (),
38+ }
39+ m .HandleConnect (hub .handleConnect )
40+ m .HandleMessage (hub .handleMessage )
3041 m .HandleDisconnect (handleDisconnect )
3142 notify_service .RegisterNotifier (newNotifier (m ))
3243 return m
3344}
3445
35- func handleConnect (s * melody.Session ) {
46+ type hub struct {
47+ pubsub pubsub.Broker
48+ }
49+
50+ func (h * hub ) handleConnect (s * melody.Session ) {
3651 ctx := context .GetWebContext (s .Request )
3752
3853 data := & sessionData {}
@@ -45,7 +60,7 @@ func handleConnect(s *melody.Session) {
4560 // TODO: handle logouts
4661}
4762
48- func handleMessage (s * melody.Session , _msg []byte ) {
63+ func ( h * hub ) handleMessage (s * melody.Session , _msg []byte ) {
4964 data , err := getSessionData (s )
5065 if err != nil {
5166 return
@@ -59,21 +74,42 @@ func handleMessage(s *melody.Session, _msg []byte) {
5974
6075 switch msg .Action {
6176 case "subscribe" :
62- err := handleSubscribeMessage (data , msg .Data )
77+ err := h . handleSubscribeMessage (s , data , msg .Data )
6378 if err != nil {
6479 return
6580 }
6681 }
6782}
6883
69- func handleSubscribeMessage (data * sessionData , _data any ) error {
84+ func ( h * hub ) handleSubscribeMessage (s * melody. Session , data * sessionData , _data any ) error {
7085 msgData := & subscribeMessageData {}
7186 err := mapstructure .Decode (_data , & msgData )
7287 if err != nil {
7388 return err
7489 }
7590
76- data .onURL = msgData .URL
91+ ctx := goContext .Background () // TODO: use proper context
92+ h .pubsub .Subscribe (ctx , msgData .Repo , func (msg pubsub.Message ) {
93+ if data .user != nil {
94+ return
95+ }
96+
97+ // TODO: check permissions
98+ hasAccess , err := access .HasAccessUnit (ctx , data .user , repo , unit .TypeIssues , perm .AccessModeRead )
99+ if err != nil {
100+ log .Error ("Failed to check access: %v" , err )
101+ return
102+ }
103+
104+ if ! hasAccess {
105+ return
106+ }
107+
108+ // TODO: check the actual data received from pubsub and send it correctly to the client
109+ d := fmt .Sprintf (htmxRemoveElement , fmt .Sprintf ("#%s" , c .HashTag ()))
110+ _ = s .Write ([]byte (d ))
111+ })
112+
77113 return nil
78114}
79115
0 commit comments