Allow users to forget rooms

This commit is contained in:
Daniel Wagner-Hall 2015-11-17 17:17:30 -05:00
parent b697a842a5
commit ba26eb3d5d
6 changed files with 81 additions and 4 deletions

View File

@ -207,6 +207,13 @@ class Auth(object):
user_id, room_id user_id, room_id
)) ))
if membership == Membership.LEAVE:
forgot = yield self.store.did_forget(user_id, room_id)
if forgot:
raise AuthError(403, "User %s not in room %s" % (
user_id, room_id
))
defer.returnValue(member) defer.returnValue(member)
@defer.inlineCallbacks @defer.inlineCallbacks

View File

@ -743,6 +743,9 @@ class RoomMemberHandler(BaseHandler):
) )
defer.returnValue((token, public_key, key_validity_url, display_name)) defer.returnValue((token, public_key, key_validity_url, display_name))
def forget(self, user, room_id):
self.store.forget(user.to_string(), room_id)
class RoomListHandler(BaseHandler): class RoomListHandler(BaseHandler):

View File

@ -448,7 +448,7 @@ class RoomMembershipRestServlet(ClientV1RestServlet):
def register(self, http_server): def register(self, http_server):
# /rooms/$roomid/[invite|join|leave] # /rooms/$roomid/[invite|join|leave]
PATTERN = ("/rooms/(?P<room_id>[^/]*)/" PATTERN = ("/rooms/(?P<room_id>[^/]*)/"
"(?P<membership_action>join|invite|leave|ban|kick)") "(?P<membership_action>join|invite|leave|ban|kick|forget)")
register_txn_path(self, PATTERN, http_server) register_txn_path(self, PATTERN, http_server)
@defer.inlineCallbacks @defer.inlineCallbacks
@ -458,6 +458,8 @@ class RoomMembershipRestServlet(ClientV1RestServlet):
allow_guest=True allow_guest=True
) )
effective_membership_action = membership_action
if is_guest and membership_action not in {Membership.JOIN, Membership.LEAVE}: if is_guest and membership_action not in {Membership.JOIN, Membership.LEAVE}:
raise AuthError(403, "Guest access not allowed") raise AuthError(403, "Guest access not allowed")
@ -488,11 +490,13 @@ class RoomMembershipRestServlet(ClientV1RestServlet):
UserID.from_string(state_key) UserID.from_string(state_key)
if membership_action == "kick": if membership_action == "kick":
membership_action = "leave" effective_membership_action = "leave"
elif membership_action == "forget":
effective_membership_action = "leave"
msg_handler = self.handlers.message_handler msg_handler = self.handlers.message_handler
content = {"membership": unicode(membership_action)} content = {"membership": unicode(effective_membership_action)}
if is_guest: if is_guest:
content["kind"] = "guest" content["kind"] = "guest"
@ -509,6 +513,9 @@ class RoomMembershipRestServlet(ClientV1RestServlet):
is_guest=is_guest, is_guest=is_guest,
) )
if membership_action == "forget":
self.handlers.room_member_handler.forget(user, room_id)
defer.returnValue((200, {})) defer.returnValue((200, {}))
def _has_3pid_invite_keys(self, content): def _has_3pid_invite_keys(self, content):

View File

@ -25,7 +25,7 @@ logger = logging.getLogger(__name__)
# Remember to update this number every time a change is made to database # Remember to update this number every time a change is made to database
# schema files, so the users will be informed on server restarts. # schema files, so the users will be informed on server restarts.
SCHEMA_VERSION = 25 SCHEMA_VERSION = 26
dir_path = os.path.abspath(os.path.dirname(__file__)) dir_path = os.path.abspath(os.path.dirname(__file__))

View File

@ -269,3 +269,39 @@ class RoomMemberStore(SQLBaseStore):
ret = len(room_id_lists.pop(0).intersection(*room_id_lists)) > 0 ret = len(room_id_lists.pop(0).intersection(*room_id_lists)) > 0
defer.returnValue(ret) defer.returnValue(ret)
def forget(self, user_id, room_id):
def f(txn):
sql = (
"UPDATE"
" room_memberships"
" SET"
" forgotten = 1"
" WHERE"
" user_id = ?"
" AND"
" room_id = ?"
)
txn.execute(sql, (user_id, room_id))
self.runInteraction("forget_membership", f)
@defer.inlineCallbacks
def did_forget(self, user_id, room_id):
def f(txn):
sql = (
"SELECT"
" COUNT(*)"
"FROM"
" room_memberships"
" WHERE"
" user_id = ?"
" AND"
" room_id = ?"
" AND"
" forgotten = 1"
)
txn.execute(sql, (user_id, room_id))
rows = txn.fetchall()
return rows[0][0]
count = yield self.runInteraction("did_forget_membership", f)
defer.returnValue(count > 0)

View File

@ -0,0 +1,24 @@
/* Copyright 2015 OpenMarket Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Keeps track of what rooms users have left and don't want to be able to
* access again.
*
* If all users on this server have left a room, we can delete the room
* entirely.
*/
ALTER TABLE room_memberships ADD COLUMN forgotten INTEGER(1) DEFAULT 0;