This commit is contained in:
Anbraten 2024-02-16 17:19:50 +01:00
parent d9c4554108
commit ea06a25d72
5 changed files with 41 additions and 39 deletions

View File

@ -6,26 +6,16 @@ package websocket
import ( import (
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/web" "code.gitea.io/gitea/modules/web"
notify_service "code.gitea.io/gitea/services/notify"
"code.gitea.io/gitea/services/websocket" "code.gitea.io/gitea/services/websocket"
"github.com/olahol/melody"
) )
var m *melody.Melody
func Init(r *web.Route) { func Init(r *web.Route) {
m = melody.New() m := websocket.Init()
r.Any("/-/ws", webSocket)
m.HandleConnect(websocket.HandleConnect)
m.HandleMessage(websocket.HandleMessage)
m.HandleDisconnect(websocket.HandleDisconnect)
notify_service.RegisterNotifier(websocket.NewNotifier(m))
}
func webSocket(ctx *context.Context) { r.Any("/-/ws", func(ctx *context.Context) {
err := m.HandleRequest(ctx.Resp, ctx.Req) err := m.HandleRequest(ctx.Resp, ctx.Req)
if err != nil { if err != nil {
ctx.ServerError("HandleRequest", err) ctx.ServerError("HandleRequest", err)
} }
})
} }

View File

@ -8,33 +8,35 @@ import (
"fmt" "fmt"
issues_model "code.gitea.io/gitea/models/issues" issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/perm"
"code.gitea.io/gitea/models/perm/access"
repo_model "code.gitea.io/gitea/models/repo" repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
user_model "code.gitea.io/gitea/models/user" user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/log"
"github.com/olahol/melody" "github.com/olahol/melody"
) )
func (n *websocketNotifier) filterIssueSessions(repo *repo_model.Repository, issue *issues_model.Issue) []*melody.Session { func (n *websocketNotifier) filterIssueSessions(ctx context.Context, repo *repo_model.Repository, issue *issues_model.Issue) []*melody.Session {
return n.filterSessions(func(s *melody.Session, data *sessionData) bool { return n.filterSessions(func(s *melody.Session, data *sessionData) bool {
// if the user is watching the issue, they will get notifications // if the user is watching the issue, they will get notifications
if !data.isOnURL(fmt.Sprintf("/%s/%s/issues/%d", repo.Owner.Name, repo.Name, issue.Index)) { if !data.isOnURL(fmt.Sprintf("/%s/%s/issues/%d", repo.Owner.Name, repo.Name, issue.Index)) {
return false return false
} }
// if the repo is public, the user will get notifications // if the repo is private, the user will get notifications if they have access to the repo
if !repo.IsPrivate { hasAccess, err := access.HasAccessUnit(ctx, data.user, repo, unit.TypeIssues, perm.AccessModeNone)
return true if err != nil {
log.Error("Failed to check access: %v", err)
return false
} }
// if the repo is private, the user will get notifications if they have access to the repo return hasAccess
// TODO: check if the user has access to the repo
return data.userID == issue.PosterID
}) })
} }
func (n *websocketNotifier) DeleteComment(ctx context.Context, doer *user_model.User, c *issues_model.Comment) { func (n *websocketNotifier) DeleteComment(ctx context.Context, doer *user_model.User, c *issues_model.Comment) {
sessions := n.filterIssueSessions(c.Issue.Repo, c.Issue) sessions := n.filterIssueSessions(ctx, c.Issue.Repo, c.Issue)
for _, s := range sessions { for _, s := range sessions {
msg := fmt.Sprintf(htmxRemoveElement, fmt.Sprintf("#%s", c.HashTag())) msg := fmt.Sprintf(htmxRemoveElement, fmt.Sprintf("#%s", c.HashTag()))

View File

@ -17,7 +17,7 @@ type websocketNotifier struct {
} }
// NewNotifier create a new webhooksNotifier notifier // NewNotifier create a new webhooksNotifier notifier
func NewNotifier(m *melody.Melody) notify_service.Notifier { func newNotifier(m *melody.Melody) notify_service.Notifier {
return &websocketNotifier{ return &websocketNotifier{
m: m, m: m,
rnd: templates.HTMLRenderer(), rnd: templates.HTMLRenderer(),

View File

@ -8,12 +8,13 @@ import (
"net/url" "net/url"
"github.com/olahol/melody" "github.com/olahol/melody"
user_model "code.gitea.io/gitea/models/user"
) )
type sessionData struct { type sessionData struct {
userID int64 user *user_model.User
isSigned bool onURL string
onURL string
} }
func (d *sessionData) isOnURL(_u1 string) bool { func (d *sessionData) isOnURL(_u1 string) bool {

View File

@ -6,12 +6,15 @@ package websocket
import ( import (
"fmt" "fmt"
"github.com/olahol/melody"
"code.gitea.io/gitea/modules/context" "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/json"
notify_service "code.gitea.io/gitea/services/notify"
"github.com/olahol/melody"
) )
var m *melody.Melody
type websocketMessage struct { type websocketMessage struct {
Action string `json:"action"` Action string `json:"action"`
Data string `json:"data"` Data string `json:"data"`
@ -21,14 +24,21 @@ type subscribeMessageData struct {
URL string `json:"url"` URL string `json:"url"`
} }
func HandleConnect(s *melody.Session) { func Init() *melody.Melody {
m = melody.New()
m.HandleConnect(handleConnect)
m.HandleMessage(handleMessage)
m.HandleDisconnect(handleDisconnect)
notify_service.RegisterNotifier(newNotifier(m))
return m
}
func handleConnect(s *melody.Session) {
ctx := context.GetWebContext(s.Request) ctx := context.GetWebContext(s.Request)
data := &sessionData{} data := &sessionData{}
if ctx.IsSigned { if ctx.IsSigned {
data.isSigned = true data.user = ctx.Doer
data.userID = ctx.Doer.ID
} }
s.Set("data", data) s.Set("data", data)
@ -36,7 +46,7 @@ func HandleConnect(s *melody.Session) {
// TODO: handle logouts // TODO: handle logouts
} }
func HandleMessage(s *melody.Session, _msg []byte) { func handleMessage(s *melody.Session, _msg []byte) {
data, err := getSessionData(s) data, err := getSessionData(s)
if err != nil { if err != nil {
return return
@ -67,6 +77,5 @@ func handleSubscribeMessage(data *sessionData, _data any) error {
return nil return nil
} }
func HandleDisconnect(s *melody.Session) { func handleDisconnect(s *melody.Session) {
// TODO: Handle disconnect
} }