- Backend: callbacks on_publish/on_publish_done, UpdateStreamURL, GetByStreamKey - Nginx-RTMP: config infra, docker-compose service (profil live) - Frontend: stream_url dans LiveStream, HLS.js dans LiveViewPlayer, état Stream terminé - Chat: rate limit send_live_message 1 msg/3s pour rooms live_streams - Env: RTMP_CALLBACK_SECRET, STREAM_HLS_BASE_URL, NGINX_RTMP_HOST - Roadmap v0.10.6 marquée DONE
104 lines
2.7 KiB
Go
104 lines
2.7 KiB
Go
package chat
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/google/uuid"
|
|
"go.uber.org/zap"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type PermissionService struct {
|
|
db *gorm.DB
|
|
logger *zap.Logger
|
|
}
|
|
|
|
func NewPermissionService(db *gorm.DB, logger *zap.Logger) *PermissionService {
|
|
if logger == nil {
|
|
logger = zap.NewNop()
|
|
}
|
|
return &PermissionService{
|
|
db: db,
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
type roomMemberCheck struct {
|
|
Role string `gorm:"column:role"`
|
|
IsMuted bool `gorm:"column:is_muted"`
|
|
}
|
|
|
|
func (p *PermissionService) getMembership(ctx context.Context, userID, roomID uuid.UUID) (*roomMemberCheck, bool) {
|
|
var member roomMemberCheck
|
|
err := p.db.WithContext(ctx).
|
|
Table("room_members").
|
|
Select("role, is_muted").
|
|
Where("user_id = ? AND room_id = ?", userID, roomID).
|
|
First(&member).Error
|
|
if err != nil {
|
|
return nil, false
|
|
}
|
|
return &member, true
|
|
}
|
|
|
|
func (p *PermissionService) CanRead(ctx context.Context, userID, roomID uuid.UUID) bool {
|
|
// GL3-01: Live stream chat — allow read when roomID is a live_streams.id (public)
|
|
var count int64
|
|
if err := p.db.WithContext(ctx).
|
|
Table("live_streams").
|
|
Where("id = ?", roomID).
|
|
Count(&count).Error; err == nil && count > 0 {
|
|
return true
|
|
}
|
|
_, isMember := p.getMembership(ctx, userID, roomID)
|
|
return isMember
|
|
}
|
|
|
|
func (p *PermissionService) CanSend(ctx context.Context, userID, roomID uuid.UUID) bool {
|
|
// GL3-01: Live stream chat — allow send when roomID is a live_streams.id (public)
|
|
var count int64
|
|
if err := p.db.WithContext(ctx).
|
|
Table("live_streams").
|
|
Where("id = ?", roomID).
|
|
Count(&count).Error; err == nil && count > 0 {
|
|
return true
|
|
}
|
|
member, isMember := p.getMembership(ctx, userID, roomID)
|
|
if !isMember {
|
|
return false
|
|
}
|
|
return !member.IsMuted
|
|
}
|
|
|
|
func (p *PermissionService) CanJoin(ctx context.Context, userID, roomID uuid.UUID) bool {
|
|
// GL3-01: Live stream chat — allow join when roomID is a live_streams.id (public)
|
|
var count int64
|
|
if err := p.db.WithContext(ctx).
|
|
Table("live_streams").
|
|
Where("id = ?", roomID).
|
|
Count(&count).Error; err == nil && count > 0 {
|
|
return true
|
|
}
|
|
_, isMember := p.getMembership(ctx, userID, roomID)
|
|
return isMember
|
|
}
|
|
|
|
// IsLiveRoom returns true if roomID is a live_streams.id (F474).
|
|
func (p *PermissionService) IsLiveRoom(ctx context.Context, roomID uuid.UUID) bool {
|
|
var count int64
|
|
if err := p.db.WithContext(ctx).
|
|
Table("live_streams").
|
|
Where("id = ?", roomID).
|
|
Count(&count).Error; err != nil {
|
|
return false
|
|
}
|
|
return count > 0
|
|
}
|
|
|
|
func (p *PermissionService) CanModerate(ctx context.Context, userID, roomID uuid.UUID) bool {
|
|
member, isMember := p.getMembership(ctx, userID, roomID)
|
|
if !isMember {
|
|
return false
|
|
}
|
|
return member.Role == "admin" || member.Role == "moderator" || member.Role == "owner"
|
|
}
|