forked from MirrorHub/synapse
Generate guest access token on 3pid invites
This means that following the same link across multiple sessions or devices can re-use the same guest account. Note that this is somewhat of an abuse vector; we can't throw up captchas on this flow, so this is a way of registering ephemeral accounts for spam, whose sign-up we don't rate limit.
This commit is contained in:
parent
869580206d
commit
33300673b7
4 changed files with 91 additions and 0 deletions
|
@ -349,3 +349,18 @@ class RegistrationHandler(BaseHandler):
|
|||
|
||||
def auth_handler(self):
|
||||
return self.hs.get_handlers().auth_handler
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def guest_access_token_for(self, medium, address, inviter_user_id):
|
||||
access_token = yield self.store.get_3pid_guest_access_token(medium, address)
|
||||
if access_token:
|
||||
defer.returnValue(access_token)
|
||||
|
||||
_, access_token = yield self.register(
|
||||
generate_token=True,
|
||||
make_guest=True
|
||||
)
|
||||
access_token = yield self.store.save_or_get_3pid_guest_access_token(
|
||||
medium, address, access_token, inviter_user_id
|
||||
)
|
||||
defer.returnValue(access_token)
|
||||
|
|
|
@ -848,6 +848,13 @@ class RoomMemberHandler(BaseHandler):
|
|||
user.
|
||||
"""
|
||||
|
||||
registration_handler = self.hs.get_handlers().registration_handler
|
||||
guest_access_token = yield registration_handler.guest_access_token_for(
|
||||
medium=medium,
|
||||
address=address,
|
||||
inviter_user_id=inviter_user_id,
|
||||
)
|
||||
|
||||
is_url = "%s%s/_matrix/identity/api/v1/store-invite" % (
|
||||
id_server_scheme, id_server,
|
||||
)
|
||||
|
@ -864,6 +871,7 @@ class RoomMemberHandler(BaseHandler):
|
|||
"sender": inviter_user_id,
|
||||
"sender_display_name": inviter_display_name,
|
||||
"sender_avatar_url": inviter_avatar_url,
|
||||
"guest_access_token": guest_access_token,
|
||||
}
|
||||
)
|
||||
# TODO: Check for success
|
||||
|
|
|
@ -387,3 +387,47 @@ class RegistrationStore(SQLBaseStore):
|
|||
"find_next_generated_user_id",
|
||||
_find_next_generated_user_id
|
||||
)))
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def get_3pid_guest_access_token(self, medium, address):
|
||||
ret = yield self._simple_select_one(
|
||||
"threepid_guest_access_tokens",
|
||||
{
|
||||
"medium": medium,
|
||||
"address": address
|
||||
},
|
||||
["guest_access_token"], True, 'get_3pid_guest_access_token'
|
||||
)
|
||||
if ret:
|
||||
defer.returnValue(ret["guest_access_token"])
|
||||
defer.returnValue(None)
|
||||
|
||||
@defer.inlineCallbacks
|
||||
def save_or_get_3pid_guest_access_token(
|
||||
self, medium, address, access_token, inviter_user_id
|
||||
):
|
||||
"""
|
||||
Gets the 3pid's guest access token if exists, else saves access_token.
|
||||
|
||||
:param medium (str): Medium of the 3pid. Must be "email".
|
||||
:param address (str): 3pid address.
|
||||
:param access_token (str): The access token to persist if none is
|
||||
already persisted.
|
||||
:param inviter_user_id (str): User ID of the inviter.
|
||||
:return (deferred str): Whichever access token is persisted at the end
|
||||
of this function call.
|
||||
"""
|
||||
def insert(txn):
|
||||
txn.execute(
|
||||
"INSERT INTO threepid_guest_access_tokens "
|
||||
"(medium, address, guest_access_token, first_inviter) "
|
||||
"VALUES (?, ?, ?, ?)",
|
||||
(medium, address, access_token, inviter_user_id)
|
||||
)
|
||||
|
||||
try:
|
||||
yield self.runInteraction("save_3pid_guest_access_token", insert)
|
||||
defer.returnValue(access_token)
|
||||
except self.database_engine.module.IntegrityError:
|
||||
ret = yield self.get_3pid_guest_access_token(medium, address)
|
||||
defer.returnValue(ret)
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/* Copyright 2016 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.
|
||||
*/
|
||||
|
||||
-- Stores guest account access tokens generated for unbound 3pids.
|
||||
CREATE TABLE threepid_guest_access_tokens(
|
||||
medium TEXT, -- The medium of the 3pid. Must be "email".
|
||||
address TEXT, -- The 3pid address.
|
||||
guest_access_token TEXT, -- The access token for a guest user for this 3pid.
|
||||
first_inviter TEXT -- User ID of the first user to invite this 3pid to a room.
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX threepid_guest_access_tokens_index ON threepid_guest_access_tokens(medium, address);
|
Loading…
Reference in a new issue