def setUp(self): # Create a new sydent self.sydent = make_sydent() # Create a fake peer to replicate to. peer_public_key_base64 = "+vB8mTaooD/MA8YYZM8t9+vnGhP1937q2icrqPV9JTs" # Inject our fake peer into the database. cur = self.sydent.db.cursor() cur.execute( "INSERT INTO peers (name, port, lastSentVersion, active) VALUES (?, ?, ?, ?)", ("fake.server", 1234, 0, 1), ) cur.execute( "INSERT INTO peer_pubkeys (peername, alg, key) VALUES (?, ?, ?)", ("fake.server", "ed25519", peer_public_key_base64), ) self.sydent.db.commit() # Build some fake associations. self.assocs = [] assoc_count = 150 for i in range(assoc_count): assoc = ThreepidAssociation( medium="email", address="*****@*****.**" % i, lookup_hash=None, mxid="@bob%d:example.com" % i, ts=(i * 10000), not_before=0, not_after=99999999999, ) self.assocs.append(assoc)
def getAssociationsAfterId(self, afterId, limit): cur = self.sydent.db.cursor() if afterId is None: afterId = -1 q = "select id, medium, address, lookup_hash, mxid, ts, notBefore, notAfter from " \ "local_threepid_associations " \ "where id > ? order by id asc" if limit is not None: q += " limit ?" res = cur.execute(q, (afterId, limit)) else: # No no, no no no no, no no no no, no no, there's no limit. res = cur.execute(q, (afterId, )) maxId = None assocs = {} for row in res.fetchall(): assoc = ThreepidAssociation(row[1], row[2], row[3], row[4], row[5], row[6], row[7]) assocs[row[0]] = assoc maxId = row[0] return (assocs, maxId)
def addBinding(self, medium, address, mxid): """Binds the given 3pid to the given mxid. It's assumed that we have somehow validated that the given user owns the given 3pid Args: medium (str): the type of 3pid address (str): the 3pid mxid (str): the mxid to bind it to """ localAssocStore = LocalAssociationStore(self.sydent) createdAt = time_msec() expires = createdAt + ThreepidBinder.THREEPID_ASSOCIATION_LIFETIME_MS assoc = ThreepidAssociation(medium, address, mxid, createdAt, createdAt, expires) localAssocStore.addOrUpdateAssociation(assoc) self.sydent.pusher.doLocalPush() joinTokenStore = JoinTokenStore(self.sydent) pendingJoinTokens = joinTokenStore.getTokens(medium, address) invites = [] for token in pendingJoinTokens: token["mxid"] = mxid token["signed"] = { "mxid": mxid, "token": token["token"], } token["signed"] = signedjson.sign.sign_json( token["signed"], self.sydent.server_name, self.sydent.keyring.ed25519) invites.append(token) if invites: assoc.extra_fields["invites"] = invites joinTokenStore.markTokensAsSent(medium, address) signer = Signer(self.sydent) sgassoc = signer.signedThreePidAssociation(assoc) self._notify(sgassoc, 0) return sgassoc
def addBinding(self, medium, address, mxid): """Binds the given 3pid to the given mxid. It's assumed that we have somehow validated that the given user owns the given 3pid Args: medium (str): the type of 3pid address (str): the 3pid mxid (str): the mxid to bind it to """ localAssocStore = LocalAssociationStore(self.sydent) createdAt = time_msec() expires = createdAt + ThreepidBinder.THREEPID_ASSOCIATION_LIFETIME_MS assoc = ThreepidAssociation(medium, address, mxid, createdAt, createdAt, expires) localAssocStore.addOrUpdateAssociation(assoc) self.sydent.pusher.doLocalPush() joinTokenStore = JoinTokenStore(self.sydent) pendingJoinTokens = joinTokenStore.getTokens(medium, address) invites = [] for token in pendingJoinTokens: token["mxid"] = mxid token["signed"] = { "mxid": mxid, "token": token["token"], } token["signed"] = signedjson.sign.sign_json(token["signed"], self.sydent.server_name, self.sydent.keyring.ed25519) invites.append(token) if invites: assoc.extra_fields["invites"] = invites joinTokenStore.markTokensAsSent(medium, address) signer = Signer(self.sydent) sgassoc = signer.signedThreePidAssociation(assoc) self._notify(sgassoc, 0) return sgassoc
def addBinding(self, valSessionId, clientSecret, mxid): valSessionStore = ThreePidValSessionStore(self.sydent) localAssocStore = LocalAssociationStore(self.sydent) s = valSessionStore.getValidatedSession(valSessionId, clientSecret) createdAt = time_msec() expires = createdAt + ThreepidBinder.THREEPID_ASSOCIATION_LIFETIME_MS assoc = ThreepidAssociation(s.medium, s.address, mxid, createdAt, createdAt, expires) localAssocStore.addOrUpdateAssociation(assoc) self.sydent.pusher.doLocalPush() joinTokenStore = JoinTokenStore(self.sydent) pendingJoinTokens = joinTokenStore.getTokens(s.medium, s.address) invites = [] for token in pendingJoinTokens: token["mxid"] = mxid token["signed"] = { "mxid": mxid, "token": token["token"], } token["signed"] = signedjson.sign.sign_json( token["signed"], self.sydent.server_name, self.sydent.keyring.ed25519) invites.append(token) if invites: assoc.extra_fields["invites"] = invites joinTokenStore.markTokensAsSent(s.medium, s.address) assocSigner = AssociationSigner(self.sydent) sgassoc = assocSigner.signedThreePidAssociation(assoc) self._notify(sgassoc, 0) return sgassoc
def addBinding(self, valSessionId, clientSecret, mxid): valSessionStore = ThreePidValSessionStore(self.sydent) localAssocStore = LocalAssociationStore(self.sydent) s = valSessionStore.getValidatedSession(valSessionId, clientSecret) createdAt = time_msec() expires = createdAt + ThreepidBinder.THREEPID_ASSOCIATION_LIFETIME_MS assoc = ThreepidAssociation(s.medium, s.address, mxid, createdAt, createdAt, expires) localAssocStore.addOrUpdateAssociation(assoc) self.sydent.pusher.doLocalPush() joinTokenStore = JoinTokenStore(self.sydent) pendingJoinTokens = joinTokenStore.getTokens(s.medium, s.address) invites = [] for token in pendingJoinTokens: token["mxid"] = mxid token["signed"] = { "mxid": mxid, "token": token["token"], } token["signed"] = signedjson.sign.sign_json(token["signed"], self.sydent.server_name, self.sydent.keyring.ed25519) invites.append(token) if invites: assoc.extra_fields["invites"] = invites joinTokenStore.markTokensAsSent(s.medium, s.address) assocSigner = AssociationSigner(self.sydent) sgassoc = assocSigner.signedThreePidAssociation(assoc) self._notify(sgassoc, 0) return sgassoc
def getAssociationsAfterId( self, afterId: Optional[int], limit: Optional[int] = None ) -> Tuple[Dict[int, ThreepidAssociation], Optional[int]]: """ Retrieves every association after the given ID. :param afterId: The ID after which to retrieve associations. :param limit: The maximum number of associations to retrieve, or None if no limit. :return: The retrieved associations (in a dict[id, assoc]), and the highest ID retrieved (or None if no ID thus no association was retrieved). """ cur = self.sydent.db.cursor() if afterId is None: afterId = -1 q = ( "select id, medium, address, lookup_hash, mxid, ts, notBefore, notAfter from " "local_threepid_associations " "where id > ? order by id asc") if limit is not None: q += " limit ?" res = cur.execute(q, (afterId, limit)) else: # No no, no no no no, no no no no, no no, there's no limit. res = cur.execute(q, (afterId, )) maxId = None assocs = {} row: Tuple[int, str, str, Optional[str], Optional[str], Optional[int], Optional[int], Optional[int], ] for row in res.fetchall(): assoc = ThreepidAssociation(row[1], row[2], row[3], row[4], row[5], row[6], row[7]) assocs[row[0]] = assoc maxId = row[0] return assocs, maxId
def addBinding(self, medium, address, mxid): """ Binds the given 3pid to the given mxid. It's assumed that we have somehow validated that the given user owns the given 3pid :param medium: The medium of the 3PID to bind. :type medium: unicode :param address: The address of the 3PID to bind. :type address: unicode :param mxid: The MXID to bind the 3PID to. :type mxid: unicode :return: The signed association. :rtype: dict[str, any] """ localAssocStore = LocalAssociationStore(self.sydent) # Fill out the association details createdAt = time_msec() expires = createdAt + ThreepidBinder.THREEPID_ASSOCIATION_LIFETIME_MS # Hash the medium + address and store that hash for the purposes of # later lookups str_to_hash = u' '.join( [address, medium, self.hashing_store.get_lookup_pepper()], ) lookup_hash = sha256_and_url_safe_base64(str_to_hash) assoc = ThreepidAssociation( medium, address, lookup_hash, mxid, createdAt, createdAt, expires, ) localAssocStore.addOrUpdateAssociation(assoc) self.sydent.pusher.doLocalPush() joinTokenStore = JoinTokenStore(self.sydent) pendingJoinTokens = joinTokenStore.getTokens(medium, address) invites = [] for token in pendingJoinTokens: token["mxid"] = mxid token["signed"] = { "mxid": mxid, "token": token["token"], } token["signed"] = signedjson.sign.sign_json( token["signed"], self.sydent.server_name, self.sydent.keyring.ed25519) invites.append(token) if invites: assoc.extra_fields["invites"] = invites joinTokenStore.markTokensAsSent(medium, address) signer = Signer(self.sydent) sgassoc = signer.signedThreePidAssociation(assoc) self._notify(sgassoc, 0) return sgassoc
def addBinding(self, medium: str, address: str, mxid: str) -> Dict[str, Any]: """ Binds the given 3pid to the given mxid. It's assumed that we have somehow validated that the given user owns the given 3pid :param medium: The medium of the 3PID to bind. :param address: The address of the 3PID to bind. :param mxid: The MXID to bind the 3PID to. :return: The signed association. """ # ensure we casefold email address before storing normalised_address = normalise_address(address, medium) localAssocStore = LocalAssociationStore(self.sydent) # Fill out the association details createdAt = time_msec() expires = createdAt + ThreepidBinder.THREEPID_ASSOCIATION_LIFETIME_MS # Hash the medium + address and store that hash for the purposes of # later lookups lookup_pepper = self.hashing_store.get_lookup_pepper() assert lookup_pepper is not None str_to_hash = " ".join([normalised_address, medium, lookup_pepper], ) lookup_hash = sha256_and_url_safe_base64(str_to_hash) assoc = ThreepidAssociation( medium, normalised_address, lookup_hash, mxid, createdAt, createdAt, expires, ) localAssocStore.addOrUpdateAssociation(assoc) self.sydent.pusher.doLocalPush() joinTokenStore = JoinTokenStore(self.sydent) pendingJoinTokens = joinTokenStore.getTokens(medium, normalised_address) invites = [] # Widen the value type to Any: we're going to set the signed key # to point to a dict, but pendingJoinTokens yields Dict[str, str] token: Dict[str, Any] for token in pendingJoinTokens: token["mxid"] = mxid presigned = { "mxid": mxid, "token": token["token"], } token["signed"] = signedjson.sign.sign_json( presigned, self.sydent.config.general.server_name, self.sydent.keyring.ed25519, ) invites.append(token) if invites: assoc.extra_fields["invites"] = invites joinTokenStore.markTokensAsSent(medium, normalised_address) signer = Signer(self.sydent) sgassoc = signer.signedThreePidAssociation(assoc) defer.ensureDeferred(self._notify(sgassoc, 0)) return sgassoc