Changeset 0.24.3 (#159)
This commit is contained in:
@@ -194,6 +194,10 @@ func (h *CompletionHandler) Complete(c *gin.Context) {
|
||||
}
|
||||
|
||||
channelID := req.ChannelID
|
||||
if channelID == "" {
|
||||
// v0.24.3: Workflow API routes have channel in URL param
|
||||
channelID = c.Param("id")
|
||||
}
|
||||
if channelID == "" {
|
||||
c.JSON(http.StatusBadRequest, gin.H{"error": "channel_id is required"})
|
||||
return
|
||||
@@ -201,13 +205,25 @@ func (h *CompletionHandler) Complete(c *gin.Context) {
|
||||
|
||||
userID := getUserID(c)
|
||||
|
||||
// Verify participation: check channel_participants first, fall back to
|
||||
// legacy channels.user_id ownership for direct channels.
|
||||
isParticipant, _ := h.stores.Channels.IsParticipant(c.Request.Context(), channelID, "user", userID)
|
||||
if !isParticipant {
|
||||
if !userOwnsChannel(c, channelID, userID) {
|
||||
// v0.24.3: Session participants are pre-validated by AuthOrSession middleware
|
||||
if isSessionAuth(c) {
|
||||
if !sessionCanAccessChannel(c, channelID) {
|
||||
c.JSON(http.StatusForbidden, gin.H{"error": "session not authorized for this channel"})
|
||||
return
|
||||
}
|
||||
// Use session_id as effective identity for cursor/participant tracking.
|
||||
// persistMessage will record participant_type=user with this ID —
|
||||
// acceptable for v0.24.3; v0.25.0 can refine to participant_type=session.
|
||||
userID = c.GetString("session_id")
|
||||
} else {
|
||||
// Verify participation: check channel_participants first, fall back to
|
||||
// legacy channels.user_id ownership for direct channels.
|
||||
isParticipant, _ := h.stores.Channels.IsParticipant(c.Request.Context(), channelID, "user", userID)
|
||||
if !isParticipant {
|
||||
if !userOwnsChannel(c, channelID, userID) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ── ai_mode guard (v0.23.1) ────────────────────────────────────────────────
|
||||
@@ -630,8 +646,10 @@ func (h *CompletionHandler) Complete(c *gin.Context) {
|
||||
// Budget enforcement and model allowlist only apply when the request draws
|
||||
// from a team or global provider. BYOK (personal scope) is the user's money
|
||||
// — no ceiling applies.
|
||||
// v0.24.3: Session participants bypass user-level budget/allowlist checks.
|
||||
// They use the workflow channel's allocated resources.
|
||||
role, _ := c.Get("role")
|
||||
if role != "admin" && providerScope != "personal" {
|
||||
if role != "admin" && providerScope != "personal" && !isSessionAuth(c) {
|
||||
// Token budget
|
||||
if h.stores.Usage != nil {
|
||||
budget, err := auth.ResolveTokenBudget(c.Request.Context(), h.stores, userID)
|
||||
|
||||
Reference in New Issue
Block a user