From b58b91cd149a9a6cebc9adf539a74136bd1e0a72 Mon Sep 17 00:00:00 2001 From: mleku Date: Sun, 14 Dec 2025 18:36:04 +0100 Subject: [PATCH] Add ORLY_POLICY_PATH for custom policy file location MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add ORLY_POLICY_PATH environment variable to configure custom policy file path, overriding the default ~/.config/ORLY/policy.json location - Enforce ABSOLUTE paths only - relay panics on startup if relative path is provided, preventing common misconfiguration errors - Update PolicyManager to store and expose configPath for hot-reload saves - Add ConfigPath() method to P struct delegating to internal PolicyManager - Update NewWithManager() signature to accept optional custom path parameter - Add BUG_REPORTS_AND_FEATURE_REQUEST_PROTOCOL.md with issue submission guidelines requiring environment details, reproduction steps, and logs - Update README.md with system requirements (500MB minimum memory) and link to bug report protocol - Update CLAUDE.md and README.md documentation for new ORLY_POLICY_PATH Files modified: - app/config/config.go: Add PolicyPath config field - pkg/policy/policy.go: Add configPath storage and validation - app/handle-policy-config.go: Use policyManager.ConfigPath() - app/main.go: Pass cfg.PolicyPath to NewWithManager - pkg/policy/*_test.go: Update test calls with new parameter - BUG_REPORTS_AND_FEATURE_REQUEST_PROTOCOL.md: New file - README.md, CLAUDE.md: Documentation updates 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- .claude/settings.local.json | 3 +- BUG_REPORTS_AND_FEATURE_REQUEST_PROTOCOL.md | 254 ++++++++++++++++++ CLAUDE.md | 7 +- README.md | 22 +- app/config/config.go | 3 +- app/handle-policy-config.go | 6 +- app/handle_policy_config_test.go | 2 +- app/main.go | 2 +- .../POLICY_BUG_FIX_SUMMARY.md | 0 go.sum | 4 +- pkg/policy/bug_reproduction_test.go | 2 +- pkg/policy/follows_test.go | 2 +- pkg/policy/hotreload_test.go | 2 +- pkg/policy/policy.go | 40 ++- pkg/policy/policy_test.go | 2 +- pkg/policy/tag_validation_test.go | 2 +- pkg/version/version | 2 +- 17 files changed, 335 insertions(+), 20 deletions(-) create mode 100644 BUG_REPORTS_AND_FEATURE_REQUEST_PROTOCOL.md rename POLICY_BUG_FIX_SUMMARY.md => docs/POLICY_BUG_FIX_SUMMARY.md (100%) diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 2eddf0a..2439ddb 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -116,7 +116,8 @@ "WebFetch(domain:eylenburg.github.io)", "Bash(go run -exec '' -c 'package main; import \"\"git.mleku.dev/mleku/nostr/utils/normalize\"\"; import \"\"fmt\"\"; func main() { fmt.Println(string(normalize.URL([]byte(\"\"relay.example.com:3334\"\")))); fmt.Println(string(normalize.URL([]byte(\"\"relay.example.com:443\"\")))); fmt.Println(string(normalize.URL([]byte(\"\"ws://relay.example.com:3334\"\")))); fmt.Println(string(normalize.URL([]byte(\"\"wss://relay.example.com:3334\"\")))) }')", "Bash(go run:*)", - "Bash(git commit -m \"$(cat <<''EOF''\nFix NIP-11 fetch URL scheme conversion for non-proxied relays\n\n- Convert wss:// to https:// and ws:// to http:// before fetching NIP-11\n documents, fixing failures for users not using HTTPS upgrade proxies\n- The fetchNIP11 function was using WebSocket URLs directly for HTTP\n requests, causing scheme mismatch errors\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude Opus 4.5 \nEOF\n)\")" + "Bash(git commit -m \"$(cat <<''EOF''\nFix NIP-11 fetch URL scheme conversion for non-proxied relays\n\n- Convert wss:// to https:// and ws:// to http:// before fetching NIP-11\n documents, fixing failures for users not using HTTPS upgrade proxies\n- The fetchNIP11 function was using WebSocket URLs directly for HTTP\n requests, causing scheme mismatch errors\n\n🤖 Generated with [Claude Code](https://claude.com/claude-code)\n\nCo-Authored-By: Claude Opus 4.5 \nEOF\n)\")", + "Bash(/tmp/orly help:*)" ], "deny": [], "ask": [] diff --git a/BUG_REPORTS_AND_FEATURE_REQUEST_PROTOCOL.md b/BUG_REPORTS_AND_FEATURE_REQUEST_PROTOCOL.md new file mode 100644 index 0000000..0269e13 --- /dev/null +++ b/BUG_REPORTS_AND_FEATURE_REQUEST_PROTOCOL.md @@ -0,0 +1,254 @@ +# Feature Request and Bug Report Protocol + +This document describes how to submit effective bug reports and feature requests for ORLY relay. Following these guidelines helps maintainers understand and resolve issues quickly. + +## Before Submitting + +1. **Search existing issues** - Your issue may already be reported or discussed +2. **Check documentation** - Review `CLAUDE.md`, `docs/`, and `pkg/*/README.md` files +3. **Verify with latest version** - Ensure the issue exists in the current release +4. **Test with default configuration** - Rule out configuration-specific problems + +## Bug Reports + +### Required Information + +**Title**: Concise summary of the problem +- Good: "Kind 3 events with 8000+ follows truncated on save" +- Bad: "Events not saving" or "Bug in database" + +**Environment**: +``` +ORLY version: (output of ./orly version) +OS: (e.g., Ubuntu 24.04, macOS 14.2) +Go version: (output of go version) +Database backend: (badger/neo4j/wasmdb) +``` + +**Configuration** (relevant settings only): +```bash +ORLY_DB_TYPE=badger +ORLY_POLICY_ENABLED=true +# Include any non-default settings +``` + +**Steps to Reproduce**: +1. Start relay with configuration X +2. Connect client and send event Y +3. Query for event with filter Z +4. Observe error/unexpected behavior + +**Expected Behavior**: What should happen + +**Actual Behavior**: What actually happens + +**Logs**: Include relevant log output with `ORLY_LOG_LEVEL=debug` or `trace` + +### Minimal Reproduction + +The most effective bug reports include a minimal reproduction case: + +```bash +# Example: Script that demonstrates the issue +export ORLY_LOG_LEVEL=debug +./orly & +sleep 2 + +# Send problematic event +echo '["EVENT", {...}]' | websocat ws://localhost:3334 + +# Show the failure +echo '["REQ", "test", {"kinds": [1]}]' | websocat ws://localhost:3334 +``` + +Or provide a failing test case: + +```go +func TestReproduceBug(t *testing.T) { + // Setup + db := setupTestDB(t) + + // This should work but fails + event := createTestEvent(kind, content) + err := db.SaveEvent(ctx, event) + require.NoError(t, err) + + // Query returns unexpected result + results, err := db.QueryEvents(ctx, filter) + assert.Len(t, results, 1) // Fails: got 0 +} +``` + +## Feature Requests + +### Required Information + +**Title**: Clear description of the feature +- Good: "Add WebSocket compression support (permessage-deflate)" +- Bad: "Make it faster" or "New feature idea" + +**Problem Statement**: What problem does this solve? +``` +Currently, clients with high-latency connections experience slow sync times +because event data is transmitted uncompressed. A typical session transfers +50MB of JSON that could be reduced to ~10MB with compression. +``` + +**Proposed Solution**: How should it work? +``` +Add optional permessage-deflate WebSocket extension support: +- New config: ORLY_WS_COMPRESSION=true +- Negotiate compression during WebSocket handshake +- Apply to messages over configurable threshold (default 1KB) +``` + +**Use Case**: Who benefits and how? +``` +- Mobile clients on cellular connections +- Users syncing large follow lists +- Relays with bandwidth constraints +``` + +**Alternatives Considered** (optional): +``` +- Application-level compression: Rejected because it requires client changes +- HTTP/2: Not applicable for WebSocket connections +``` + +### Implementation Notes (optional) + +If you have implementation ideas: + +``` +Suggested approach: +1. Add compression config to app/config/config.go +2. Modify gorilla/websocket upgrader in app/handle-websocket.go +3. Add compression threshold check before WriteMessage() + +Reference: gorilla/websocket has built-in permessage-deflate support +``` + +## What Makes Reports Effective + +**Do**: +- Be specific and factual +- Include version numbers and exact error messages +- Provide reproducible steps +- Attach relevant logs (redact sensitive data) +- Link to related issues or discussions +- Respond to follow-up questions promptly + +**Avoid**: +- Vague descriptions ("it doesn't work") +- Multiple unrelated issues in one report +- Assuming the cause without evidence +- Demanding immediate fixes +- Duplicating existing issues + +## Issue Labels + +When applicable, suggest appropriate labels: + +| Label | Use When | +|-------|----------| +| `bug` | Something isn't working as documented | +| `enhancement` | New feature or improvement | +| `performance` | Speed or resource usage issue | +| `documentation` | Docs are missing or incorrect | +| `question` | Clarification needed (not a bug) | +| `good first issue` | Suitable for new contributors | + +## Response Expectations + +- **Acknowledgment**: Within a few days +- **Triage**: Issue labeled and prioritized +- **Resolution**: Depends on complexity and priority + +Complex features may require discussion before implementation. Bug fixes for critical issues are prioritized. + +## Following Up + +If your issue hasn't received attention: + +1. **Check issue status** - It may be labeled or assigned +2. **Add new information** - If you've discovered more details +3. **Politely bump** - A single follow-up comment after 2 weeks is appropriate +4. **Consider contributing** - PRs that fix bugs or implement features are welcome + +## Contributing Fixes + +If you want to fix a bug or implement a feature yourself: + +1. Comment on the issue to avoid duplicate work +2. Follow the coding patterns in `CLAUDE.md` +3. Include tests for your changes +4. Keep PRs focused on a single issue +5. Reference the issue number in your PR + +## Security Issues + +**Do not report security vulnerabilities in public issues.** + +For security-sensitive bugs: +- Contact maintainers directly +- Provide detailed reproduction steps privately +- Allow reasonable time for a fix before disclosure + +## Examples + +### Good Bug Report + +```markdown +## WebSocket disconnects after 60 seconds of inactivity + +**Environment**: +- ORLY v0.34.5 +- Ubuntu 22.04 +- Go 1.25.3 +- Badger backend + +**Steps to Reproduce**: +1. Connect to relay: `websocat ws://localhost:3334` +2. Send subscription: `["REQ", "test", {"kinds": [1], "limit": 1}]` +3. Wait 60 seconds without sending messages +4. Observe connection closed + +**Expected**: Connection remains open (Nostr relays should maintain persistent connections) + +**Actual**: Connection closed with code 1000 after exactly 60 seconds + +**Logs** (ORLY_LOG_LEVEL=debug): +``` +1764783029014485🔎 client timeout, closing connection /app/handle-websocket.go:142 +``` + +**Possible Cause**: May be related to read deadline not being extended on subscription activity +``` + +### Good Feature Request + +```markdown +## Add rate limiting per pubkey + +**Problem**: +A single pubkey can flood the relay with events, consuming storage and +bandwidth. Currently there's no way to limit per-author submission rate. + +**Proposed Solution**: +Add configurable rate limiting: +```bash +ORLY_RATE_LIMIT_EVENTS_PER_MINUTE=60 +ORLY_RATE_LIMIT_BURST=10 +``` + +When exceeded, return OK false with "rate-limited" message per NIP-20. + +**Use Case**: +- Public relays protecting against spam +- Community relays with fair-use policies +- Paid relays enforcing subscription tiers + +**Alternatives Considered**: +- IP-based limiting: Ineffective because users share IPs and use VPNs +- Global limiting: Punishes all users for one bad actor +``` diff --git a/CLAUDE.md b/CLAUDE.md index 4fe370b..b7b7efe 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -147,6 +147,10 @@ export ORLY_SPROCKET_ENABLED=true # Enable policy system export ORLY_POLICY_ENABLED=true +# Custom policy file path (MUST be ABSOLUTE path starting with /) +# Default: ~/.config/ORLY/policy.json (or ~/.config/{ORLY_APP_NAME}/policy.json) +# export ORLY_POLICY_PATH=/etc/orly/policy.json + # Database backend selection (badger, neo4j, or wasmdb) export ORLY_DB_TYPE=badger @@ -270,7 +274,8 @@ export ORLY_AUTH_TO_WRITE=false # Require auth only for writes - `none.go` - Open relay (no restrictions) **`pkg/policy/`** - Event filtering and validation policies -- Policy configuration loaded from `~/.config/ORLY/policy.json` +- Policy configuration loaded from `~/.config/ORLY/policy.json` by default +- Custom path via `ORLY_POLICY_PATH` (MUST be absolute path starting with `/`) - Per-kind size limits, age restrictions, custom scripts - **Write-Only Validation**: Size, age, tag, and expiry validations apply ONLY to write operations - **Read-Only Filtering**: `read_allow`, `read_deny`, `privileged` apply ONLY to read operations diff --git a/README.md b/README.md index 4480a0c..b931fbf 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # next.orly.dev +--- + ![orly.dev](./docs/orly.png) ![Version v0.24.1](https://img.shields.io/badge/version-v0.24.1-blue.svg) @@ -10,6 +12,19 @@ zap me: �mlekudev@getalby.com follow me on [nostr](https://jumble.social/users/npub1fjqqy4a93z5zsjwsfxqhc2764kvykfdyttvldkkkdera8dr78vhsmmleku) +## ⚠️ Bug Reports & Feature Requests + +**Bug reports and feature requests that do not follow the protocol will not be accepted.** + +Before submitting any issue, you must read and follow [BUG_REPORTS_AND_FEATURE_REQUEST_PROTOCOL.md](./BUG_REPORTS_AND_FEATURE_REQUEST_PROTOCOL.md). + +Requirements: +- **Bug reports**: Include environment details, reproduction steps, expected/actual behavior, and logs +- **Feature requests**: Include problem statement, proposed solution, and use cases +- **Both**: Search existing issues first, verify with latest version, provide minimal reproduction + +Issues missing required information will be closed without review. + ## ⚠️ System Requirements > **IMPORTANT: ORLY requires a minimum of 500MB of free memory to operate.** @@ -217,7 +232,12 @@ ORLY includes a comprehensive policy system for fine-grained control over event ```bash export ORLY_POLICY_ENABLED=true -# Create policy file at ~/.config/ORLY/policy.json +# Default policy file: ~/.config/ORLY/policy.json + +# OPTIONAL: Use a custom policy file location +# WARNING: ORLY_POLICY_PATH MUST be an ABSOLUTE path (starting with /) +# Relative paths will be REJECTED and the relay will fail to start +export ORLY_POLICY_PATH=/etc/orly/policy.json ``` For detailed configuration and examples, see the [Policy Usage Guide](docs/POLICY_USAGE_GUIDE.md). diff --git a/app/config/config.go b/app/config/config.go index 61de5a9..e18869e 100644 --- a/app/config/config.go +++ b/app/config/config.go @@ -82,7 +82,8 @@ type C struct { DirectorySpiderInterval time.Duration `env:"ORLY_DIRECTORY_SPIDER_INTERVAL" default:"24h" usage:"how often to run directory spider"` DirectorySpiderMaxHops int `env:"ORLY_DIRECTORY_SPIDER_HOPS" default:"3" usage:"maximum hops for relay discovery from seed users"` - PolicyEnabled bool `env:"ORLY_POLICY_ENABLED" default:"false" usage:"enable policy-based event processing (configuration found in $HOME/.config/ORLY/policy.json)"` + PolicyEnabled bool `env:"ORLY_POLICY_ENABLED" default:"false" usage:"enable policy-based event processing (default config: $HOME/.config/ORLY/policy.json)"` + PolicyPath string `env:"ORLY_POLICY_PATH" usage:"ABSOLUTE path to policy configuration file (MUST start with /); overrides default location; relative paths are rejected"` // NIP-43 Relay Access Metadata and Requests NIP43Enabled bool `env:"ORLY_NIP43_ENABLED" default:"false" usage:"enable NIP-43 relay access metadata and invite system"` diff --git a/app/handle-policy-config.go b/app/handle-policy-config.go index f41c0c2..9569567 100644 --- a/app/handle-policy-config.go +++ b/app/handle-policy-config.go @@ -3,9 +3,7 @@ package app import ( "bytes" "fmt" - "path/filepath" - "github.com/adrg/xdg" "lol.mleku.dev/log" "git.mleku.dev/mleku/nostr/encoders/event" "git.mleku.dev/mleku/nostr/encoders/filter" @@ -76,8 +74,8 @@ func (l *Listener) HandlePolicyConfigUpdate(ev *event.E) error { log.I.F("policy config validation passed") - // Get config path for saving - configPath := filepath.Join(xdg.ConfigHome, l.Config.AppName, "policy.json") + // Get config path for saving (uses custom path if set, otherwise default) + configPath := l.policyManager.ConfigPath() // 3. Pause ALL message processing (lock mutex) // Note: We need to release the RLock first (which caller holds), then acquire exclusive Lock diff --git a/app/handle_policy_config_test.go b/app/handle_policy_config_test.go index 7bfd537..a006d57 100644 --- a/app/handle_policy_config_test.go +++ b/app/handle_policy_config_test.go @@ -74,7 +74,7 @@ func setupPolicyTestListener(t *testing.T, policyAdminHex string) (*Listener, *d } // Create policy manager - now config file exists at XDG path - policyManager := policy.NewWithManager(ctx, cfg.AppName, cfg.PolicyEnabled) + policyManager := policy.NewWithManager(ctx, cfg.AppName, cfg.PolicyEnabled, "") server := &Server{ Ctx: ctx, diff --git a/app/main.go b/app/main.go index d87e156..d54cceb 100644 --- a/app/main.go +++ b/app/main.go @@ -87,7 +87,7 @@ func Run( l.sprocketManager = NewSprocketManager(ctx, cfg.AppName, cfg.SprocketEnabled) // Initialize policy manager - l.policyManager = policy.NewWithManager(ctx, cfg.AppName, cfg.PolicyEnabled) + l.policyManager = policy.NewWithManager(ctx, cfg.AppName, cfg.PolicyEnabled, cfg.PolicyPath) // Merge policy-defined owners with environment-defined owners // This allows cloud deployments to add owners via policy.json when env vars cannot be modified diff --git a/POLICY_BUG_FIX_SUMMARY.md b/docs/POLICY_BUG_FIX_SUMMARY.md similarity index 100% rename from POLICY_BUG_FIX_SUMMARY.md rename to docs/POLICY_BUG_FIX_SUMMARY.md diff --git a/go.sum b/go.sum index 4c26060..0447612 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,5 @@ -git.mleku.dev/mleku/nostr v1.0.8 h1:YYREdIxobEqYkzxQ7/5ALACPzLkiHW+CTira+VvSQZk= -git.mleku.dev/mleku/nostr v1.0.8/go.mod h1:iYTlg2WKJXJ0kcsM6QBGOJ0UDiJidMgL/i64cHyPjZc= +git.mleku.dev/mleku/nostr v1.0.9 h1:aiN0ihnXzEpboXjW4u8qr5XokLQqg4P0XSZ1Y273qM0= +git.mleku.dev/mleku/nostr v1.0.9/go.mod h1:iYTlg2WKJXJ0kcsM6QBGOJ0UDiJidMgL/i64cHyPjZc= github.com/BurntSushi/toml v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg= github.com/BurntSushi/toml v1.5.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= github.com/ImVexed/fasturl v0.0.0-20230304231329-4e41488060f3 h1:ClzzXMDDuUbWfNNZqGeYq4PnYOlwlOVIvSyNaIy0ykg= diff --git a/pkg/policy/bug_reproduction_test.go b/pkg/policy/bug_reproduction_test.go index 22bd036..39a6af9 100644 --- a/pkg/policy/bug_reproduction_test.go +++ b/pkg/policy/bug_reproduction_test.go @@ -96,7 +96,7 @@ func TestBugReproduction_WithPolicyManager(t *testing.T) { // Create policy with manager (enabled) ctx := context.Background() - policy := NewWithManager(ctx, "ORLY", true) + policy := NewWithManager(ctx, "ORLY", true, "") // Load policy from file if err := policy.LoadFromFile(policyPath); err != nil { diff --git a/pkg/policy/follows_test.go b/pkg/policy/follows_test.go index 05b5517..2b847e5 100644 --- a/pkg/policy/follows_test.go +++ b/pkg/policy/follows_test.go @@ -31,7 +31,7 @@ func setupTestPolicy(t *testing.T, appName string) (*P, func()) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - policy := NewWithManager(ctx, appName, true) + policy := NewWithManager(ctx, appName, true, "") if policy == nil { cancel() os.RemoveAll(configDir) diff --git a/pkg/policy/hotreload_test.go b/pkg/policy/hotreload_test.go index d55011c..f8cf931 100644 --- a/pkg/policy/hotreload_test.go +++ b/pkg/policy/hotreload_test.go @@ -29,7 +29,7 @@ func setupHotreloadTestPolicy(t *testing.T, appName string) (*P, func()) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - policy := NewWithManager(ctx, appName, true) + policy := NewWithManager(ctx, appName, true, "") if policy == nil { cancel() os.RemoveAll(configDir) diff --git a/pkg/policy/policy.go b/pkg/policy/policy.go index 31800e2..f7af4c1 100644 --- a/pkg/policy/policy.go +++ b/pkg/policy/policy.go @@ -514,12 +514,19 @@ type PolicyManager struct { ctx context.Context cancel context.CancelFunc configDir string + configPath string // Path to policy.json file scriptPath string // Default script path for backward compatibility enabled bool mutex sync.RWMutex runners map[string]*ScriptRunner // Map of script path -> runner } +// ConfigPath returns the path to the policy configuration file. +// This is used by hot-reload handlers to know where to save updated policy. +func (pm *PolicyManager) ConfigPath() string { + return pm.configPath +} + // P represents a complete policy configuration for a Nostr relay. // It defines access control rules, kind filtering, and default behavior. // Policies are evaluated in order: global rules, kind filtering, specific rules, then default policy. @@ -695,6 +702,15 @@ func (p *P) IsEnabled() bool { return p != nil && p.manager != nil && p.manager.IsEnabled() } +// ConfigPath returns the path to the policy configuration file. +// Delegates to the internal PolicyManager. +func (p *P) ConfigPath() string { + if p == nil || p.manager == nil { + return "" + } + return p.manager.ConfigPath() +} + // getDefaultPolicyAction returns true if the default policy is "allow", false if "deny" func (p *P) getDefaultPolicyAction() (allowed bool) { switch p.DefaultPolicy { @@ -711,10 +727,29 @@ func (p *P) getDefaultPolicyAction() (allowed bool) { // NewWithManager creates a new policy with a policy manager for script execution. // It initializes the policy manager, loads configuration from files, and starts // background processes for script management and periodic health checks. -func NewWithManager(ctx context.Context, appName string, enabled bool) *P { +// +// The customPolicyPath parameter allows overriding the default policy file location. +// If empty, uses the default path: $HOME/.config/{appName}/policy.json +// If provided, it MUST be an absolute path (starting with /) or the function will panic. +func NewWithManager(ctx context.Context, appName string, enabled bool, customPolicyPath string) *P { configDir := filepath.Join(xdg.ConfigHome, appName) scriptPath := filepath.Join(configDir, "policy.sh") - configPath := filepath.Join(configDir, "policy.json") + + // Determine the policy config path + var configPath string + if customPolicyPath != "" { + // Validate that custom path is absolute + if !filepath.IsAbs(customPolicyPath) { + panic(fmt.Sprintf("FATAL: ORLY_POLICY_PATH must be an ABSOLUTE path (starting with /), got: %q", customPolicyPath)) + } + configPath = customPolicyPath + // Update configDir to match the custom path's directory for script resolution + configDir = filepath.Dir(customPolicyPath) + scriptPath = filepath.Join(configDir, "policy.sh") + log.I.F("using custom policy path: %s", configPath) + } else { + configPath = filepath.Join(configDir, "policy.json") + } ctx, cancel := context.WithCancel(ctx) @@ -722,6 +757,7 @@ func NewWithManager(ctx context.Context, appName string, enabled bool) *P { ctx: ctx, cancel: cancel, configDir: configDir, + configPath: configPath, scriptPath: scriptPath, enabled: enabled, runners: make(map[string]*ScriptRunner), diff --git a/pkg/policy/policy_test.go b/pkg/policy/policy_test.go index ea532f0..d2740ba 100644 --- a/pkg/policy/policy_test.go +++ b/pkg/policy/policy_test.go @@ -825,7 +825,7 @@ func TestNewWithManager(t *testing.T) { // Test with disabled policy (doesn't require policy.json file) t.Run("disabled policy", func(t *testing.T) { enabled := false - policy := NewWithManager(ctx, appName, enabled) + policy := NewWithManager(ctx, appName, enabled, "") if policy == nil { t.Fatal("Expected policy but got nil") diff --git a/pkg/policy/tag_validation_test.go b/pkg/policy/tag_validation_test.go index f39296d..a8afae1 100644 --- a/pkg/policy/tag_validation_test.go +++ b/pkg/policy/tag_validation_test.go @@ -31,7 +31,7 @@ func setupTagValidationTestPolicy(t *testing.T, appName string) (*P, func()) { ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - policy := NewWithManager(ctx, appName, true) + policy := NewWithManager(ctx, appName, true, "") if policy == nil { cancel() os.RemoveAll(configDir) diff --git a/pkg/version/version b/pkg/version/version index a1a5a34..61da1d2 100644 --- a/pkg/version/version +++ b/pkg/version/version @@ -1 +1 @@ -v0.35.2 \ No newline at end of file +v0.35.3 \ No newline at end of file