package ws import ( "errors" "fmt" "silk-server-go/internal/model" "gorm.io/gorm" ) // DeviceAuthorizer 校验用户是否有权读取指定设备。 type DeviceAuthorizer interface { CanReadDevice(userID, deviceKey string) (bool, error) } // DBDeviceAuthorizer 使用 RBAC + 组织/房间归属判断设备读取权。 type DBDeviceAuthorizer struct { db *gorm.DB } func NewDBDeviceAuthorizer(db *gorm.DB) *DBDeviceAuthorizer { return &DBDeviceAuthorizer{db: db} } func (a *DBDeviceAuthorizer) CanReadDevice(userID, deviceKey string) (bool, error) { if deviceKey == "" { return false, nil } var user model.User if err := a.db.Where("id = ?", userID).First(&user).Error; err != nil { return false, err } if user.Role == model.RoleAdmin { return true, nil } var roleCount int64 err := a.db.Table("role_permissions"). Joins("JOIN permissions ON permissions.id = role_permissions.permission_id"). Where("role_permissions.role = ? AND permissions.code = ?", user.Role, "device:read"). Count(&roleCount).Error if err != nil { return false, err } if roleCount == 0 { return false, nil } var device model.Device if err := a.db.Where("device_key = ?", deviceKey).First(&device).Error; err != nil { return false, err } var roomCount int64 err = a.db.Table("rooms"). Joins("JOIN organization_members om ON om.organization_id = rooms.org_id"). Where("rooms.id = ? AND om.user_id = ?", device.RoomID, userID). Count(&roomCount).Error return roomCount > 0, err } func (h *Hub) authorizeSubscription(userID, deviceKey string) error { if h.authorizer == nil { return errors.New("device authorizer not configured") } ok, err := h.authorizer.CanReadDevice(userID, deviceKey) if err != nil { return err } if !ok { return fmt.Errorf("device subscription denied: %s", deviceKey) } return nil }