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