statestore.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  1. package appservice
  2. import (
  3. "maunium.net/go/gomatrix"
  4. "strings"
  5. "sync"
  6. )
  7. type StateStore interface {
  8. IsRegistered(userID string) bool
  9. MarkRegistered(userID string)
  10. IsInRoom(roomID, userID string) bool
  11. SetMembership(roomID, userID, membership string)
  12. SetPowerLevels(roomID string, levels *gomatrix.PowerLevels)
  13. GetPowerLevels(roomID string) *gomatrix.PowerLevels
  14. GetPowerLevel(roomID, userID string) int
  15. GetPowerLevelRequirement(roomID string, eventType gomatrix.EventType, isState bool) int
  16. HasPowerLevel(roomID, userID string, eventType gomatrix.EventType, isState bool) bool
  17. }
  18. func (as *AppService) UpdateState(evt *gomatrix.Event) {
  19. switch evt.Type {
  20. case gomatrix.StateMember:
  21. as.StateStore.SetMembership(evt.RoomID, evt.GetStateKey(), evt.Content.Membership)
  22. }
  23. }
  24. type BasicStateStore struct {
  25. registrationsLock sync.RWMutex `json:"-"`
  26. Registrations map[string]bool `json:"registrations"`
  27. membershipsLock sync.RWMutex `json:"-"`
  28. Memberships map[string]map[string]string `json:"memberships"`
  29. powerLevelsLock sync.RWMutex `json:"-"`
  30. PowerLevels map[string]*gomatrix.PowerLevels `json:"power_levels"`
  31. }
  32. func NewBasicStateStore() *BasicStateStore {
  33. return &BasicStateStore{
  34. Registrations: make(map[string]bool),
  35. Memberships: make(map[string]map[string]string),
  36. PowerLevels: make(map[string]*gomatrix.PowerLevels),
  37. }
  38. }
  39. func (store *BasicStateStore) IsRegistered(userID string) bool {
  40. store.registrationsLock.RLock()
  41. registered, ok := store.Registrations[userID]
  42. store.registrationsLock.RUnlock()
  43. return ok && registered
  44. }
  45. func (store *BasicStateStore) MarkRegistered(userID string) {
  46. store.registrationsLock.Lock()
  47. store.Registrations[userID] = true
  48. store.registrationsLock.Unlock()
  49. }
  50. func (store *BasicStateStore) GetRoomMemberships(roomID string) map[string]string {
  51. store.membershipsLock.RLock()
  52. memberships, ok := store.Memberships[roomID]
  53. store.membershipsLock.RUnlock()
  54. if !ok {
  55. memberships = make(map[string]string)
  56. store.membershipsLock.Lock()
  57. store.Memberships[roomID] = memberships
  58. store.membershipsLock.Unlock()
  59. }
  60. return memberships
  61. }
  62. func (store *BasicStateStore) GetMembership(roomID, userID string) string {
  63. store.membershipsLock.RLock()
  64. membership, ok := store.GetRoomMemberships(roomID)[userID]
  65. store.membershipsLock.RUnlock()
  66. if !ok {
  67. return "leave"
  68. }
  69. return membership
  70. }
  71. func (store *BasicStateStore) IsInRoom(roomID, userID string) bool {
  72. return store.GetMembership(roomID, userID) == "join"
  73. }
  74. func (store *BasicStateStore) SetMembership(roomID, userID, membership string) {
  75. store.membershipsLock.Lock()
  76. memberships, ok := store.Memberships[roomID]
  77. if !ok {
  78. store.Memberships[roomID] = map[string]string{
  79. userID: strings.ToLower(membership),
  80. }
  81. } else {
  82. memberships[userID] = strings.ToLower(membership)
  83. }
  84. store.membershipsLock.Unlock()
  85. }
  86. func (store *BasicStateStore) SetPowerLevels(roomID string, levels *gomatrix.PowerLevels) {
  87. store.powerLevelsLock.Lock()
  88. store.PowerLevels[roomID] = levels
  89. store.powerLevelsLock.Unlock()
  90. }
  91. func (store *BasicStateStore) GetPowerLevels(roomID string) (levels *gomatrix.PowerLevels) {
  92. store.powerLevelsLock.RLock()
  93. levels, _ = store.PowerLevels[roomID]
  94. store.powerLevelsLock.RUnlock()
  95. return
  96. }
  97. func (store *BasicStateStore) GetPowerLevel(roomID, userID string) int {
  98. return store.GetPowerLevels(roomID).GetUserLevel(userID)
  99. }
  100. func (store *BasicStateStore) GetPowerLevelRequirement(roomID string, eventType gomatrix.EventType, isState bool) int {
  101. levels := store.GetPowerLevels(roomID)
  102. switch eventType {
  103. case "kick":
  104. return levels.Kick()
  105. case "invite":
  106. return levels.Invite()
  107. case "redact":
  108. return levels.Redact()
  109. }
  110. return levels.GetEventLevel(eventType, isState)
  111. }
  112. func (store *BasicStateStore) HasPowerLevel(roomID, userID string, eventType gomatrix.EventType, isState bool) bool {
  113. return store.GetPowerLevel(roomID, userID) >= store.GetPowerLevelRequirement(roomID, eventType, isState)
  114. }