test_mau.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. # -*- coding: utf-8 -*-
  2. # Copyright 2018 New Vector Ltd
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License");
  5. # you may not use this file except in compliance with the License.
  6. # You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. """Tests REST events for /rooms paths."""
  16. import json
  17. from mock import Mock
  18. from synapse.api.constants import LoginType
  19. from synapse.api.errors import Codes, HttpResponseException, SynapseError
  20. from synapse.rest.client.v2_alpha import register, sync
  21. from tests import unittest
  22. class TestMauLimit(unittest.HomeserverTestCase):
  23. servlets = [register.register_servlets, sync.register_servlets]
  24. def make_homeserver(self, reactor, clock):
  25. self.hs = self.setup_test_homeserver(
  26. "red",
  27. http_client=None,
  28. federation_client=Mock(),
  29. )
  30. self.store = self.hs.get_datastore()
  31. self.hs.config.registrations_require_3pid = []
  32. self.hs.config.enable_registration_captcha = False
  33. self.hs.config.recaptcha_public_key = []
  34. self.hs.config.limit_usage_by_mau = True
  35. self.hs.config.hs_disabled = False
  36. self.hs.config.max_mau_value = 2
  37. self.hs.config.mau_trial_days = 0
  38. self.hs.config.server_notices_mxid = "@server:red"
  39. self.hs.config.server_notices_mxid_display_name = None
  40. self.hs.config.server_notices_mxid_avatar_url = None
  41. self.hs.config.server_notices_room_name = "Test Server Notice Room"
  42. return self.hs
  43. def test_simple_deny_mau(self):
  44. # Create and sync so that the MAU counts get updated
  45. token1 = self.create_user("kermit1")
  46. self.do_sync_for_user(token1)
  47. token2 = self.create_user("kermit2")
  48. self.do_sync_for_user(token2)
  49. # We've created and activated two users, we shouldn't be able to
  50. # register new users
  51. with self.assertRaises(SynapseError) as cm:
  52. self.create_user("kermit3")
  53. e = cm.exception
  54. self.assertEqual(e.code, 403)
  55. self.assertEqual(e.errcode, Codes.RESOURCE_LIMIT_EXCEEDED)
  56. def test_allowed_after_a_month_mau(self):
  57. # Create and sync so that the MAU counts get updated
  58. token1 = self.create_user("kermit1")
  59. self.do_sync_for_user(token1)
  60. token2 = self.create_user("kermit2")
  61. self.do_sync_for_user(token2)
  62. # Advance time by 31 days
  63. self.reactor.advance(31 * 24 * 60 * 60)
  64. self.store.reap_monthly_active_users()
  65. self.reactor.advance(0)
  66. # We should be able to register more users
  67. token3 = self.create_user("kermit3")
  68. self.do_sync_for_user(token3)
  69. def test_trial_delay(self):
  70. self.hs.config.mau_trial_days = 1
  71. # We should be able to register more than the limit initially
  72. token1 = self.create_user("kermit1")
  73. self.do_sync_for_user(token1)
  74. token2 = self.create_user("kermit2")
  75. self.do_sync_for_user(token2)
  76. token3 = self.create_user("kermit3")
  77. self.do_sync_for_user(token3)
  78. # Advance time by 2 days
  79. self.reactor.advance(2 * 24 * 60 * 60)
  80. # Two users should be able to sync
  81. self.do_sync_for_user(token1)
  82. self.do_sync_for_user(token2)
  83. # But the third should fail
  84. with self.assertRaises(SynapseError) as cm:
  85. self.do_sync_for_user(token3)
  86. e = cm.exception
  87. self.assertEqual(e.code, 403)
  88. self.assertEqual(e.errcode, Codes.RESOURCE_LIMIT_EXCEEDED)
  89. # And new registrations are now denied too
  90. with self.assertRaises(SynapseError) as cm:
  91. self.create_user("kermit4")
  92. e = cm.exception
  93. self.assertEqual(e.code, 403)
  94. self.assertEqual(e.errcode, Codes.RESOURCE_LIMIT_EXCEEDED)
  95. def test_trial_users_cant_come_back(self):
  96. self.hs.config.mau_trial_days = 1
  97. # We should be able to register more than the limit initially
  98. token1 = self.create_user("kermit1")
  99. self.do_sync_for_user(token1)
  100. token2 = self.create_user("kermit2")
  101. self.do_sync_for_user(token2)
  102. token3 = self.create_user("kermit3")
  103. self.do_sync_for_user(token3)
  104. # Advance time by 2 days
  105. self.reactor.advance(2 * 24 * 60 * 60)
  106. # Two users should be able to sync
  107. self.do_sync_for_user(token1)
  108. self.do_sync_for_user(token2)
  109. # Advance by 2 months so everyone falls out of MAU
  110. self.reactor.advance(60 * 24 * 60 * 60)
  111. self.store.reap_monthly_active_users()
  112. self.reactor.advance(0)
  113. # We can create as many new users as we want
  114. token4 = self.create_user("kermit4")
  115. self.do_sync_for_user(token4)
  116. token5 = self.create_user("kermit5")
  117. self.do_sync_for_user(token5)
  118. token6 = self.create_user("kermit6")
  119. self.do_sync_for_user(token6)
  120. # users 2 and 3 can come back to bring us back up to MAU limit
  121. self.do_sync_for_user(token2)
  122. self.do_sync_for_user(token3)
  123. # New trial users can still sync
  124. self.do_sync_for_user(token4)
  125. self.do_sync_for_user(token5)
  126. self.do_sync_for_user(token6)
  127. # But old user cant
  128. with self.assertRaises(SynapseError) as cm:
  129. self.do_sync_for_user(token1)
  130. e = cm.exception
  131. self.assertEqual(e.code, 403)
  132. self.assertEqual(e.errcode, Codes.RESOURCE_LIMIT_EXCEEDED)
  133. def test_tracked_but_not_limited(self):
  134. self.hs.config.max_mau_value = 1 # should not matter
  135. self.hs.config.limit_usage_by_mau = False
  136. self.hs.config.mau_stats_only = True
  137. # Simply being able to create 2 users indicates that the
  138. # limit was not reached.
  139. token1 = self.create_user("kermit1")
  140. self.do_sync_for_user(token1)
  141. token2 = self.create_user("kermit2")
  142. self.do_sync_for_user(token2)
  143. # We do want to verify that the number of tracked users
  144. # matches what we want though
  145. count = self.store.get_monthly_active_count()
  146. self.reactor.advance(100)
  147. self.assertEqual(2, self.successResultOf(count))
  148. def create_user(self, localpart):
  149. request_data = json.dumps(
  150. {
  151. "username": localpart,
  152. "password": "monkey",
  153. "auth": {"type": LoginType.DUMMY},
  154. }
  155. )
  156. request, channel = self.make_request("POST", "/register", request_data)
  157. self.render(request)
  158. if channel.code != 200:
  159. raise HttpResponseException(
  160. channel.code, channel.result["reason"], channel.result["body"]
  161. ).to_synapse_error()
  162. access_token = channel.json_body["access_token"]
  163. return access_token
  164. def do_sync_for_user(self, token):
  165. request, channel = self.make_request(
  166. "GET", "/sync", access_token=token
  167. )
  168. self.render(request)
  169. if channel.code != 200:
  170. raise HttpResponseException(
  171. channel.code, channel.result["reason"], channel.result["body"]
  172. ).to_synapse_error()