managed-acl.go raw
1 //go:build !(js && wasm)
2
3 package database
4
5 import (
6 "bytes"
7 "encoding/json"
8 "fmt"
9 "time"
10
11 "github.com/dgraph-io/badger/v4"
12 )
13
14 // ManagedACLConfig represents the configuration for managed ACL mode
15 type ManagedACLConfig struct {
16 RelayName string `json:"relay_name"`
17 RelayDescription string `json:"relay_description"`
18 RelayIcon string `json:"relay_icon"`
19 }
20
21 // BannedPubkey represents a banned public key entry
22 type BannedPubkey struct {
23 Pubkey string `json:"pubkey"`
24 Reason string `json:"reason,omitempty"`
25 Added time.Time `json:"added"`
26 }
27
28 // AllowedPubkey represents an allowed public key entry
29 type AllowedPubkey struct {
30 Pubkey string `json:"pubkey"`
31 Reason string `json:"reason,omitempty"`
32 Added time.Time `json:"added"`
33 }
34
35 // BannedEvent represents a banned event entry
36 type BannedEvent struct {
37 ID string `json:"id"`
38 Reason string `json:"reason,omitempty"`
39 Added time.Time `json:"added"`
40 }
41
42 // AllowedEvent represents an allowed event entry
43 type AllowedEvent struct {
44 ID string `json:"id"`
45 Reason string `json:"reason,omitempty"`
46 Added time.Time `json:"added"`
47 }
48
49 // BlockedIP represents a blocked IP address entry
50 type BlockedIP struct {
51 IP string `json:"ip"`
52 Reason string `json:"reason,omitempty"`
53 Added time.Time `json:"added"`
54 }
55
56 // AllowedKind represents an allowed event kind
57 type AllowedKind struct {
58 Kind int `json:"kind"`
59 Added time.Time `json:"added"`
60 }
61
62 // EventNeedingModeration represents an event that needs moderation
63 type EventNeedingModeration struct {
64 ID string `json:"id"`
65 Reason string `json:"reason,omitempty"`
66 Added time.Time `json:"added"`
67 }
68
69 // ManagedACL database operations
70 type ManagedACL struct {
71 *D
72 }
73
74 // NewManagedACL creates a new ManagedACL instance
75 func NewManagedACL(db *D) *ManagedACL {
76 return &ManagedACL{D: db}
77 }
78
79 // SaveBannedPubkey saves a banned pubkey to the database
80 func (m *ManagedACL) SaveBannedPubkey(pubkey string, reason string) error {
81 return m.Update(func(txn *badger.Txn) error {
82 key := m.getBannedPubkeyKey(pubkey)
83 banned := BannedPubkey{
84 Pubkey: pubkey,
85 Reason: reason,
86 Added: time.Now(),
87 }
88 data, err := json.Marshal(banned)
89 if err != nil {
90 return err
91 }
92 return txn.Set(key, data)
93 })
94 }
95
96 // RemoveBannedPubkey removes a banned pubkey from the database
97 func (m *ManagedACL) RemoveBannedPubkey(pubkey string) error {
98 return m.Update(func(txn *badger.Txn) error {
99 key := m.getBannedPubkeyKey(pubkey)
100 return txn.Delete(key)
101 })
102 }
103
104 // ListBannedPubkeys returns all banned pubkeys
105 func (m *ManagedACL) ListBannedPubkeys() ([]BannedPubkey, error) {
106 var banned []BannedPubkey
107 return banned, m.View(func(txn *badger.Txn) error {
108 prefix := m.getBannedPubkeyPrefix()
109 it := txn.NewIterator(badger.IteratorOptions{Prefix: prefix})
110 defer it.Close()
111
112 for it.Rewind(); it.Valid(); it.Next() {
113 item := it.Item()
114 val, err := item.ValueCopy(nil)
115 if err != nil {
116 continue
117 }
118 var bannedPubkey BannedPubkey
119 if err := json.Unmarshal(val, &bannedPubkey); err != nil {
120 continue
121 }
122 banned = append(banned, bannedPubkey)
123 }
124 return nil
125 })
126 }
127
128 // SaveAllowedPubkey saves an allowed pubkey to the database
129 func (m *ManagedACL) SaveAllowedPubkey(pubkey string, reason string) error {
130 return m.Update(func(txn *badger.Txn) error {
131 key := m.getAllowedPubkeyKey(pubkey)
132 allowed := AllowedPubkey{
133 Pubkey: pubkey,
134 Reason: reason,
135 Added: time.Now(),
136 }
137 data, err := json.Marshal(allowed)
138 if err != nil {
139 return err
140 }
141 return txn.Set(key, data)
142 })
143 }
144
145 // RemoveAllowedPubkey removes an allowed pubkey from the database
146 func (m *ManagedACL) RemoveAllowedPubkey(pubkey string) error {
147 return m.Update(func(txn *badger.Txn) error {
148 key := m.getAllowedPubkeyKey(pubkey)
149 return txn.Delete(key)
150 })
151 }
152
153 // ListAllowedPubkeys returns all allowed pubkeys
154 func (m *ManagedACL) ListAllowedPubkeys() ([]AllowedPubkey, error) {
155 var allowed []AllowedPubkey
156 return allowed, m.View(func(txn *badger.Txn) error {
157 prefix := m.getAllowedPubkeyPrefix()
158 it := txn.NewIterator(badger.IteratorOptions{Prefix: prefix})
159 defer it.Close()
160
161 for it.Rewind(); it.Valid(); it.Next() {
162 item := it.Item()
163 val, err := item.ValueCopy(nil)
164 if err != nil {
165 continue
166 }
167 var allowedPubkey AllowedPubkey
168 if err := json.Unmarshal(val, &allowedPubkey); err != nil {
169 continue
170 }
171 allowed = append(allowed, allowedPubkey)
172 }
173 return nil
174 })
175 }
176
177 // SaveBannedEvent saves a banned event to the database
178 func (m *ManagedACL) SaveBannedEvent(eventID string, reason string) error {
179 return m.Update(func(txn *badger.Txn) error {
180 key := m.getBannedEventKey(eventID)
181 banned := BannedEvent{
182 ID: eventID,
183 Reason: reason,
184 Added: time.Now(),
185 }
186 data, err := json.Marshal(banned)
187 if err != nil {
188 return err
189 }
190 return txn.Set(key, data)
191 })
192 }
193
194 // RemoveBannedEvent removes a banned event from the database
195 func (m *ManagedACL) RemoveBannedEvent(eventID string) error {
196 return m.Update(func(txn *badger.Txn) error {
197 key := m.getBannedEventKey(eventID)
198 return txn.Delete(key)
199 })
200 }
201
202 // ListBannedEvents returns all banned events
203 func (m *ManagedACL) ListBannedEvents() ([]BannedEvent, error) {
204 var banned []BannedEvent
205 return banned, m.View(func(txn *badger.Txn) error {
206 prefix := m.getBannedEventPrefix()
207 it := txn.NewIterator(badger.IteratorOptions{Prefix: prefix})
208 defer it.Close()
209
210 for it.Rewind(); it.Valid(); it.Next() {
211 item := it.Item()
212 val, err := item.ValueCopy(nil)
213 if err != nil {
214 continue
215 }
216 var bannedEvent BannedEvent
217 if err := json.Unmarshal(val, &bannedEvent); err != nil {
218 continue
219 }
220 banned = append(banned, bannedEvent)
221 }
222 return nil
223 })
224 }
225
226 // SaveAllowedEvent saves an allowed event to the database
227 func (m *ManagedACL) SaveAllowedEvent(eventID string, reason string) error {
228 return m.Update(func(txn *badger.Txn) error {
229 key := m.getAllowedEventKey(eventID)
230 allowed := AllowedEvent{
231 ID: eventID,
232 Reason: reason,
233 Added: time.Now(),
234 }
235 data, err := json.Marshal(allowed)
236 if err != nil {
237 return err
238 }
239 return txn.Set(key, data)
240 })
241 }
242
243 // RemoveAllowedEvent removes an allowed event from the database
244 func (m *ManagedACL) RemoveAllowedEvent(eventID string) error {
245 return m.Update(func(txn *badger.Txn) error {
246 key := m.getAllowedEventKey(eventID)
247 return txn.Delete(key)
248 })
249 }
250
251 // ListAllowedEvents returns all allowed events
252 func (m *ManagedACL) ListAllowedEvents() ([]AllowedEvent, error) {
253 var allowed []AllowedEvent
254 return allowed, m.View(func(txn *badger.Txn) error {
255 prefix := m.getAllowedEventPrefix()
256 it := txn.NewIterator(badger.IteratorOptions{Prefix: prefix})
257 defer it.Close()
258
259 for it.Rewind(); it.Valid(); it.Next() {
260 item := it.Item()
261 val, err := item.ValueCopy(nil)
262 if err != nil {
263 continue
264 }
265 var allowedEvent AllowedEvent
266 if err := json.Unmarshal(val, &allowedEvent); err != nil {
267 continue
268 }
269 allowed = append(allowed, allowedEvent)
270 }
271 return nil
272 })
273 }
274
275 // SaveBlockedIP saves a blocked IP to the database
276 func (m *ManagedACL) SaveBlockedIP(ip string, reason string) error {
277 return m.Update(func(txn *badger.Txn) error {
278 key := m.getBlockedIPKey(ip)
279 blocked := BlockedIP{
280 IP: ip,
281 Reason: reason,
282 Added: time.Now(),
283 }
284 data, err := json.Marshal(blocked)
285 if err != nil {
286 return err
287 }
288 return txn.Set(key, data)
289 })
290 }
291
292 // RemoveBlockedIP removes a blocked IP from the database
293 func (m *ManagedACL) RemoveBlockedIP(ip string) error {
294 return m.Update(func(txn *badger.Txn) error {
295 key := m.getBlockedIPKey(ip)
296 return txn.Delete(key)
297 })
298 }
299
300 // ListBlockedIPs returns all blocked IPs
301 func (m *ManagedACL) ListBlockedIPs() ([]BlockedIP, error) {
302 var blocked []BlockedIP
303 return blocked, m.View(func(txn *badger.Txn) error {
304 prefix := m.getBlockedIPPrefix()
305 it := txn.NewIterator(badger.IteratorOptions{Prefix: prefix})
306 defer it.Close()
307
308 for it.Rewind(); it.Valid(); it.Next() {
309 item := it.Item()
310 val, err := item.ValueCopy(nil)
311 if err != nil {
312 continue
313 }
314 var blockedIP BlockedIP
315 if err := json.Unmarshal(val, &blockedIP); err != nil {
316 continue
317 }
318 blocked = append(blocked, blockedIP)
319 }
320 return nil
321 })
322 }
323
324 // SaveAllowedKind saves an allowed kind to the database
325 func (m *ManagedACL) SaveAllowedKind(kind int) error {
326 return m.Update(func(txn *badger.Txn) error {
327 key := m.getAllowedKindKey(kind)
328 allowed := AllowedKind{
329 Kind: kind,
330 Added: time.Now(),
331 }
332 data, err := json.Marshal(allowed)
333 if err != nil {
334 return err
335 }
336 return txn.Set(key, data)
337 })
338 }
339
340 // RemoveAllowedKind removes an allowed kind from the database
341 func (m *ManagedACL) RemoveAllowedKind(kind int) error {
342 return m.Update(func(txn *badger.Txn) error {
343 key := m.getAllowedKindKey(kind)
344 return txn.Delete(key)
345 })
346 }
347
348 // ListAllowedKinds returns all allowed kinds
349 func (m *ManagedACL) ListAllowedKinds() ([]int, error) {
350 var kinds []int
351 return kinds, m.View(func(txn *badger.Txn) error {
352 prefix := m.getAllowedKindPrefix()
353 it := txn.NewIterator(badger.IteratorOptions{Prefix: prefix})
354 defer it.Close()
355
356 for it.Rewind(); it.Valid(); it.Next() {
357 item := it.Item()
358 val, err := item.ValueCopy(nil)
359 if err != nil {
360 continue
361 }
362 var allowedKind AllowedKind
363 if err := json.Unmarshal(val, &allowedKind); err != nil {
364 continue
365 }
366 kinds = append(kinds, allowedKind.Kind)
367 }
368 return nil
369 })
370 }
371
372 // SaveEventNeedingModeration saves an event that needs moderation
373 func (m *ManagedACL) SaveEventNeedingModeration(eventID string, reason string) error {
374 return m.Update(func(txn *badger.Txn) error {
375 key := m.getEventNeedingModerationKey(eventID)
376 event := EventNeedingModeration{
377 ID: eventID,
378 Reason: reason,
379 Added: time.Now(),
380 }
381 data, err := json.Marshal(event)
382 if err != nil {
383 return err
384 }
385 return txn.Set(key, data)
386 })
387 }
388
389 // RemoveEventNeedingModeration removes an event from moderation queue
390 func (m *ManagedACL) RemoveEventNeedingModeration(eventID string) error {
391 return m.Update(func(txn *badger.Txn) error {
392 key := m.getEventNeedingModerationKey(eventID)
393 return txn.Delete(key)
394 })
395 }
396
397 // ListEventsNeedingModeration returns all events needing moderation
398 func (m *ManagedACL) ListEventsNeedingModeration() ([]EventNeedingModeration, error) {
399 var events []EventNeedingModeration
400 return events, m.View(func(txn *badger.Txn) error {
401 prefix := m.getEventNeedingModerationPrefix()
402 it := txn.NewIterator(badger.IteratorOptions{Prefix: prefix})
403 defer it.Close()
404
405 for it.Rewind(); it.Valid(); it.Next() {
406 item := it.Item()
407 val, err := item.ValueCopy(nil)
408 if err != nil {
409 continue
410 }
411 var event EventNeedingModeration
412 if err := json.Unmarshal(val, &event); err != nil {
413 continue
414 }
415 events = append(events, event)
416 }
417 return nil
418 })
419 }
420
421 // SaveRelayConfig saves relay configuration
422 func (m *ManagedACL) SaveRelayConfig(config ManagedACLConfig) error {
423 return m.Update(func(txn *badger.Txn) error {
424 key := m.getRelayConfigKey()
425 data, err := json.Marshal(config)
426 if err != nil {
427 return err
428 }
429 return txn.Set(key, data)
430 })
431 }
432
433 // GetRelayConfig returns relay configuration
434 func (m *ManagedACL) GetRelayConfig() (ManagedACLConfig, error) {
435 var config ManagedACLConfig
436 return config, m.View(func(txn *badger.Txn) error {
437 key := m.getRelayConfigKey()
438 item, err := txn.Get(key)
439 if err != nil {
440 if err == badger.ErrKeyNotFound {
441 // Return default config
442 config = ManagedACLConfig{
443 RelayName: "Managed Relay",
444 RelayDescription: "A managed Nostr relay",
445 RelayIcon: "",
446 }
447 return nil
448 }
449 return err
450 }
451 val, err := item.ValueCopy(nil)
452 if err != nil {
453 return err
454 }
455 return json.Unmarshal(val, &config)
456 })
457 }
458
459 // Check if a pubkey is banned
460 func (m *ManagedACL) IsPubkeyBanned(pubkey string) (bool, error) {
461 var banned bool
462 return banned, m.View(func(txn *badger.Txn) error {
463 key := m.getBannedPubkeyKey(pubkey)
464 _, err := txn.Get(key)
465 if err == badger.ErrKeyNotFound {
466 banned = false
467 return nil
468 }
469 if err != nil {
470 return err
471 }
472 banned = true
473 return nil
474 })
475 }
476
477 // Check if a pubkey is explicitly allowed
478 func (m *ManagedACL) IsPubkeyAllowed(pubkey string) (bool, error) {
479 var allowed bool
480 return allowed, m.View(func(txn *badger.Txn) error {
481 key := m.getAllowedPubkeyKey(pubkey)
482 _, err := txn.Get(key)
483 if err == badger.ErrKeyNotFound {
484 allowed = false
485 return nil
486 }
487 if err != nil {
488 return err
489 }
490 allowed = true
491 return nil
492 })
493 }
494
495 // Check if an event is banned
496 func (m *ManagedACL) IsEventBanned(eventID string) (bool, error) {
497 var banned bool
498 return banned, m.View(func(txn *badger.Txn) error {
499 key := m.getBannedEventKey(eventID)
500 _, err := txn.Get(key)
501 if err == badger.ErrKeyNotFound {
502 banned = false
503 return nil
504 }
505 if err != nil {
506 return err
507 }
508 banned = true
509 return nil
510 })
511 }
512
513 // Check if an event is explicitly allowed
514 func (m *ManagedACL) IsEventAllowed(eventID string) (bool, error) {
515 var allowed bool
516 return allowed, m.View(func(txn *badger.Txn) error {
517 key := m.getAllowedEventKey(eventID)
518 _, err := txn.Get(key)
519 if err == badger.ErrKeyNotFound {
520 allowed = false
521 return nil
522 }
523 if err != nil {
524 return err
525 }
526 allowed = true
527 return nil
528 })
529 }
530
531 // Check if an IP is blocked
532 func (m *ManagedACL) IsIPBlocked(ip string) (bool, error) {
533 var blocked bool
534 return blocked, m.View(func(txn *badger.Txn) error {
535 key := m.getBlockedIPKey(ip)
536 _, err := txn.Get(key)
537 if err == badger.ErrKeyNotFound {
538 blocked = false
539 return nil
540 }
541 if err != nil {
542 return err
543 }
544 blocked = true
545 return nil
546 })
547 }
548
549 // Check if a kind is allowed
550 func (m *ManagedACL) IsKindAllowed(kind int) (bool, error) {
551 var allowed bool
552 return allowed, m.View(func(txn *badger.Txn) error {
553 key := m.getAllowedKindKey(kind)
554 _, err := txn.Get(key)
555 if err == badger.ErrKeyNotFound {
556 allowed = false
557 return nil
558 }
559 if err != nil {
560 return err
561 }
562 allowed = true
563 return nil
564 })
565 }
566
567 // Key generation methods
568 func (m *ManagedACL) getBannedPubkeyKey(pubkey string) []byte {
569 buf := new(bytes.Buffer)
570 buf.WriteString("MANAGED_ACL_BANNED_PUBKEY_")
571 buf.WriteString(pubkey)
572 return buf.Bytes()
573 }
574
575 func (m *ManagedACL) getBannedPubkeyPrefix() []byte {
576 return []byte("MANAGED_ACL_BANNED_PUBKEY_")
577 }
578
579 func (m *ManagedACL) getAllowedPubkeyKey(pubkey string) []byte {
580 buf := new(bytes.Buffer)
581 buf.WriteString("MANAGED_ACL_ALLOWED_PUBKEY_")
582 buf.WriteString(pubkey)
583 return buf.Bytes()
584 }
585
586 func (m *ManagedACL) getAllowedPubkeyPrefix() []byte {
587 return []byte("MANAGED_ACL_ALLOWED_PUBKEY_")
588 }
589
590 func (m *ManagedACL) getBannedEventKey(eventID string) []byte {
591 buf := new(bytes.Buffer)
592 buf.WriteString("MANAGED_ACL_BANNED_EVENT_")
593 buf.WriteString(eventID)
594 return buf.Bytes()
595 }
596
597 func (m *ManagedACL) getBannedEventPrefix() []byte {
598 return []byte("MANAGED_ACL_BANNED_EVENT_")
599 }
600
601 func (m *ManagedACL) getAllowedEventKey(eventID string) []byte {
602 buf := new(bytes.Buffer)
603 buf.WriteString("MANAGED_ACL_ALLOWED_EVENT_")
604 buf.WriteString(eventID)
605 return buf.Bytes()
606 }
607
608 func (m *ManagedACL) getAllowedEventPrefix() []byte {
609 return []byte("MANAGED_ACL_ALLOWED_EVENT_")
610 }
611
612 func (m *ManagedACL) getBlockedIPKey(ip string) []byte {
613 buf := new(bytes.Buffer)
614 buf.WriteString("MANAGED_ACL_BLOCKED_IP_")
615 buf.WriteString(ip)
616 return buf.Bytes()
617 }
618
619 func (m *ManagedACL) getBlockedIPPrefix() []byte {
620 return []byte("MANAGED_ACL_BLOCKED_IP_")
621 }
622
623 func (m *ManagedACL) getAllowedKindKey(kind int) []byte {
624 buf := new(bytes.Buffer)
625 buf.WriteString("MANAGED_ACL_ALLOWED_KIND_")
626 buf.WriteString(fmt.Sprintf("%d", kind))
627 return buf.Bytes()
628 }
629
630 func (m *ManagedACL) getAllowedKindPrefix() []byte {
631 return []byte("MANAGED_ACL_ALLOWED_KIND_")
632 }
633
634 func (m *ManagedACL) getEventNeedingModerationKey(eventID string) []byte {
635 buf := new(bytes.Buffer)
636 buf.WriteString("MANAGED_ACL_MODERATION_")
637 buf.WriteString(eventID)
638 return buf.Bytes()
639 }
640
641 func (m *ManagedACL) getEventNeedingModerationPrefix() []byte {
642 return []byte("MANAGED_ACL_MODERATION_")
643 }
644
645 func (m *ManagedACL) getRelayConfigKey() []byte {
646 return []byte("MANAGED_ACL_RELAY_CONFIG")
647 }
648