step 5 (partial): strip dropped packages from production code
Removed all references to dropped packages in non-test code.
Zero dropped imports, store refs, or model types remaining.
Major removals:
- scheduler/ package (entire dir) — tasks moved to extension track
- taskutil/ package (entire dir)
- health/ package (entire dir) — provider/tool health
- sandbox/provider_module.go — provider.complete module
- handlers: workflow_entry, workflow_instances, workflow_forms,
workflow_assignments, workflow_monitor, health_admin (6 files)
- auth/session.go, middleware/session_auth.go
- store/{postgres,sqlite}/sessions.go, tasks.go
Rewrites:
- store/{postgres,sqlite}/health.go — kernel-only Prune
(ws_tickets, rate_limit_counters, stale presence)
- handlers/admin.go: 847→467 lines (stripped provider CRUD)
- handlers/teams.go: 520→411 lines (stripped model listing)
- sandbox/runner.go: removed ProviderResolver
- sandbox/workflow_module.go: 216→83 lines (definition-only)
- main.go: 1579→1325 lines (stripped dropped package init)
- pages/pages.go: stripped channel/session lookups
- events/types.go: stripped chat/channel/workspace event routes
- models: stripped stale types, constants, notification types
Store interface cleanup:
- Removed SessionStore, TaskStore from Stores struct
- Stripped workflow assignment methods from WorkflowStore iface
- Stripped assignment methods from PG+SQLite workflow stores
- Updated testhelper.go table list to kernel-only
Migrations: removed 008_tasks.sql (both dialects)
-9665/+69 lines across 51 files.
This commit is contained in:
@@ -14,43 +14,23 @@ const EveryoneGroupID = "00000000-0000-0000-0000-000000000001"
|
||||
|
||||
// Permission constants — domain.action convention.
|
||||
const (
|
||||
PermModelUse = "model.use" // use models for completion
|
||||
PermModelSelectAny = "model.select_any" // use any enabled model (vs. group allowlist)
|
||||
PermKBRead = "kb.read" // search KBs through personas
|
||||
PermKBWrite = "kb.write" // upload/delete KB documents
|
||||
PermKBCreate = "kb.create" // create new knowledge bases
|
||||
PermChannelCreate = "channel.create" // create group/channel conversations
|
||||
PermChannelInvite = "channel.invite" // invite users to channels
|
||||
PermPersonaCreate = "persona.create" // create new personas
|
||||
PermPersonaManage = "persona.manage" // edit/delete team personas
|
||||
PermWorkflowCreate = "workflow.create" // create workflow definitions (v0.25.0)
|
||||
PermAdminView = "admin.view" // read-only admin panel access
|
||||
PermTokenUnlimited = "token.unlimited" // bypass token budgets
|
||||
PermTaskCreate = "task.create" // create scheduled tasks (v0.27.2)
|
||||
PermTaskAdmin = "task.admin" // manage all tasks, set global task config (v0.27.2)
|
||||
PermTaskAction = "task.action" // create non-LLM action tasks (v0.28.0)
|
||||
PermTaskStarlark = "task.starlark" // create Starlark tasks (pre-positioned for v0.29.0)
|
||||
PermExtensionUse = "extension.use" // use installed extensions
|
||||
PermExtensionInstall = "extension.install" // install/manage extension packages
|
||||
PermWorkflowCreate = "workflow.create" // create workflow definitions
|
||||
PermWorkflowSubmit = "workflow.submit" // submit to public workflows
|
||||
PermAdminView = "admin.view" // read-only admin panel access
|
||||
PermTokenUnlimited = "token.unlimited" // bypass token budgets
|
||||
)
|
||||
|
||||
// AllPermissions is the complete set of valid permission strings.
|
||||
// Used for validation in handlers and rendering checkboxes in admin UI.
|
||||
var AllPermissions = []string{
|
||||
PermModelUse,
|
||||
PermModelSelectAny,
|
||||
PermKBRead,
|
||||
PermKBWrite,
|
||||
PermKBCreate,
|
||||
PermChannelCreate,
|
||||
PermChannelInvite,
|
||||
PermPersonaCreate,
|
||||
PermPersonaManage,
|
||||
PermExtensionUse,
|
||||
PermExtensionInstall,
|
||||
PermWorkflowCreate,
|
||||
PermWorkflowSubmit,
|
||||
PermAdminView,
|
||||
PermTokenUnlimited,
|
||||
PermTaskCreate,
|
||||
PermTaskAdmin,
|
||||
PermTaskAction,
|
||||
PermTaskStarlark,
|
||||
}
|
||||
|
||||
// ── Resolution ──────────────────────────────
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
package auth
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"log"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
|
||||
"switchboard-core/config"
|
||||
"switchboard-core/models"
|
||||
"switchboard-core/store"
|
||||
)
|
||||
|
||||
const sessionCookieName = "sb_session"
|
||||
|
||||
// CreateOrResumeSession looks up or creates a session participant for
|
||||
// an anonymous visitor to a workflow channel.
|
||||
//
|
||||
// Two entry paths:
|
||||
// - Cookie-based (default): random token stored in sb_session cookie
|
||||
// - mTLS-based: cert fingerprint used as stable session identity
|
||||
func CreateOrResumeSession(c *gin.Context, stores store.Stores, channelID string, cfg *config.Config) (*models.SessionParticipant, error) {
|
||||
// Check for existing session cookie
|
||||
token, _ := c.Cookie(sessionCookieName)
|
||||
|
||||
// mTLS mode: use cert fingerprint as stable token
|
||||
if cfg.AuthMode == "mtls" {
|
||||
fp := c.GetHeader("X-SSL-Client-Fingerprint")
|
||||
if fp != "" {
|
||||
token = "mtls:" + fp
|
||||
}
|
||||
}
|
||||
|
||||
// Resume existing session if token matches this channel
|
||||
if token != "" {
|
||||
session, err := stores.Sessions.GetByToken(c.Request.Context(), token)
|
||||
if err == nil && session.ChannelID == channelID {
|
||||
return session, nil
|
||||
}
|
||||
// Token exists but for different channel — fall through to create
|
||||
if err != nil && err != sql.ErrNoRows {
|
||||
log.Printf("[auth/session] warn: GetByToken error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Create new session
|
||||
token = "sess:" + uuid.New().String()
|
||||
displayName, err := generateVisitorName(c.Request.Context(), stores, channelID)
|
||||
if err != nil {
|
||||
displayName = "Visitor"
|
||||
}
|
||||
|
||||
session := &models.SessionParticipant{
|
||||
SessionToken: token,
|
||||
ChannelID: channelID,
|
||||
DisplayName: displayName,
|
||||
}
|
||||
|
||||
// mTLS mode: store fingerprint for team member visibility
|
||||
if cfg.AuthMode == "mtls" {
|
||||
fp := c.GetHeader("X-SSL-Client-Fingerprint")
|
||||
if fp != "" {
|
||||
session.Fingerprint = fp
|
||||
}
|
||||
}
|
||||
|
||||
if err := stores.Sessions.Create(c.Request.Context(), session); err != nil {
|
||||
return nil, fmt.Errorf("create session: %w", err)
|
||||
}
|
||||
|
||||
// Add as channel participant
|
||||
_ = stores.Channels.AddParticipant(c.Request.Context(), &models.ChannelParticipant{
|
||||
ChannelID: channelID,
|
||||
ParticipantType: "session",
|
||||
ParticipantID: session.ID,
|
||||
Role: "visitor",
|
||||
})
|
||||
|
||||
// Set cookie (httponly, secure, 30 day expiry)
|
||||
c.SetCookie(sessionCookieName, token, 60*60*24*30, "/", "", true, true)
|
||||
|
||||
log.Printf("[auth/session] created session %s for channel %s (%s)", session.ID, channelID, displayName)
|
||||
return session, nil
|
||||
}
|
||||
|
||||
// generateVisitorName produces "Visitor #N" based on existing session count.
|
||||
func generateVisitorName(ctx context.Context, stores store.Stores, channelID string) (string, error) {
|
||||
count, err := stores.Sessions.CountForChannel(ctx, channelID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return fmt.Sprintf("Visitor #%d", count+1), nil
|
||||
}
|
||||
Reference in New Issue
Block a user