example-policy.sh raw
1 #!/bin/bash
2
3 # ORLY Policy Script Example
4 # This script demonstrates advanced policy logic including:
5 # - IP address blocking
6 # - Content filtering
7 # - Authentication requirements
8 # - User-specific permissions
9 # - Age validation (complementing built-in age checks)
10
11 # Configuration
12 BLOCKED_IPS=("127.0.0.1" "192.168.1.100")
13 BLOCKED_WORDS=("spam" "scam" "phishing")
14 TRUSTED_USERS=("746573742d7075626b6579" "abcdef1234567890abcdef1234567890abcdef12")
15 ADMIN_USERS=("746573742d7075626b6579")
16
17 # Function to check if IP is blocked
18 is_ip_blocked() {
19 local ip="$1"
20 for blocked_ip in "${BLOCKED_IPS[@]}"; do
21 if [[ "$ip" == "$blocked_ip" ]]; then
22 return 0
23 fi
24 done
25 return 1
26 }
27
28 # Function to check for blocked words
29 contains_blocked_words() {
30 local content="$1"
31 local lower_content=$(echo "$content" | tr '[:upper:]' '[:lower:]')
32
33 for word in "${BLOCKED_WORDS[@]}"; do
34 if [[ "$lower_content" == *"$word"* ]]; then
35 return 0
36 fi
37 done
38 return 1
39 }
40
41 # Function to check if user is trusted
42 is_trusted_user() {
43 local pubkey="$1"
44 for trusted_user in "${TRUSTED_USERS[@]}"; do
45 if [[ "$pubkey" == "$trusted_user" ]]; then
46 return 0
47 fi
48 done
49 return 1
50 }
51
52 # Function to check if user is admin
53 is_admin_user() {
54 local pubkey="$1"
55 for admin_user in "${ADMIN_USERS[@]}"; do
56 if [[ "$pubkey" == "$admin_user" ]]; then
57 return 0
58 fi
59 done
60 return 1
61 }
62
63 # Function to validate event age (additional to built-in checks)
64 validate_event_age() {
65 local created_at="$1"
66 local current_time=$(date +%s)
67 local age=$((current_time - created_at))
68
69 # Additional age validation beyond built-in checks
70 # Reject events older than 7 days for certain kinds
71 if [[ $age -gt 604800 ]]; then
72 return 1
73 fi
74
75 return 0
76 }
77
78 # Main policy logic
79 while IFS= read -r line; do
80 # Parse JSON input
81 event_id=$(echo "$line" | jq -r '.id // empty')
82 pubkey=$(echo "$line" | jq -r '.pubkey // empty')
83 kind=$(echo "$line" | jq -r '.kind // empty')
84 content=$(echo "$line" | jq -r '.content // empty')
85 created_at=$(echo "$line" | jq -r '.created_at // empty')
86 logged_in_pubkey=$(echo "$line" | jq -r '.logged_in_pubkey // empty')
87 ip_address=$(echo "$line" | jq -r '.ip_address // empty')
88
89 # Default to accept
90 action="accept"
91 msg=""
92
93 # Check IP blocking
94 if is_ip_blocked "$ip_address"; then
95 action="reject"
96 msg="IP address blocked"
97 echo "{\"id\":\"$event_id\",\"action\":\"$action\",\"msg\":\"$msg\"}"
98 continue
99 fi
100
101 # Check for blocked words in content
102 if contains_blocked_words "$content"; then
103 action="reject"
104 msg="Content contains blocked words"
105 echo "{\"id\":\"$event_id\",\"action\":\"$action\",\"msg\":\"$msg\"}"
106 continue
107 fi
108
109 # Additional age validation
110 if ! validate_event_age "$created_at"; then
111 action="reject"
112 msg="Event too old (additional validation)"
113 echo "{\"id\":\"$event_id\",\"action\":\"$action\",\"msg\":\"$msg\"}"
114 continue
115 fi
116
117 # Kind-specific rules
118 case "$kind" in
119 "4") # Direct messages
120 # Require authentication for DMs
121 if [[ -z "$logged_in_pubkey" ]]; then
122 action="reject"
123 msg="Authentication required for direct messages"
124 fi
125 ;;
126 "40"|"41"|"42"|"43"|"44") # Channel events
127 # Require authentication for channel events
128 if [[ -z "$logged_in_pubkey" ]]; then
129 action="reject"
130 msg="Authentication required for channel events"
131 fi
132 ;;
133 "9735") # Zap receipts
134 # Only allow trusted users to post zap receipts
135 if ! is_trusted_user "$pubkey"; then
136 action="reject"
137 msg="Only trusted users can post zap receipts"
138 fi
139 ;;
140 esac
141
142 # Admin bypass for certain operations
143 if is_admin_user "$pubkey"; then
144 # Admins can bypass most restrictions
145 action="accept"
146 msg="Admin bypass"
147 fi
148
149 # Output decision
150 echo "{\"id\":\"$event_id\",\"action\":\"$action\",\"msg\":\"$msg\"}"
151
152 done