def removeBinding(self, threepid, mxid): """ Removes the binding between a given 3PID and a given MXID. :param threepid: The 3PID of the binding to remove. :type threepid: dict[unicode, unicode] :param mxid: The MXID of the binding to remove. :type mxid: unicode """ localAssocStore = LocalAssociationStore(self.sydent) localAssocStore.removeAssociation(threepid, mxid) self.sydent.pusher.doLocalPush()
def getSignedAssociationsAfterId(self, afterId, limit): assocs = {} localAssocStore = LocalAssociationStore(self.sydent) (localAssocs, maxId) = localAssocStore.getAssociationsAfterId(afterId, limit) signer = Signer(self.sydent) for localId in localAssocs: sgAssoc = signer.signedThreePidAssociation(localAssocs[localId]) assocs[localId] = sgAssoc return (assocs, maxId)
def removeBinding(self, threepid: Dict[str, str], mxid: str) -> None: """ Removes the binding between a given 3PID and a given MXID. :param threepid: The 3PID of the binding to remove. :param mxid: The MXID of the binding to remove. """ # ensure we are casefolding email addresses threepid["address"] = normalise_address(threepid["address"], threepid["medium"]) localAssocStore = LocalAssociationStore(self.sydent) localAssocStore.removeAssociation(threepid, mxid) self.sydent.pusher.doLocalPush()
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() assocSigner = AssociationSigner(self.sydent) sgassoc = assocSigner.signedThreePidAssociation(assoc) 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 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 removeBinding(self, threepid, mxid): localAssocStore = LocalAssociationStore(self.sydent) localAssocStore.removeAssociation(threepid, mxid) self.sydent.pusher.doLocalPush()
def __init__(self, sydent: "Sydent") -> None: self.sydent = sydent self.pushing = False self.peerStore = PeerStore(self.sydent) self.local_assoc_store = LocalAssociationStore(self.sydent)
class Pusher: def __init__(self, sydent: "Sydent") -> None: self.sydent = sydent self.pushing = False self.peerStore = PeerStore(self.sydent) self.local_assoc_store = LocalAssociationStore(self.sydent) def setup(self) -> None: cb = twisted.internet.task.LoopingCall(Pusher.scheduledPush, self) cb.clock = self.sydent.reactor cb.start(10.0) def doLocalPush(self) -> None: """ Synchronously push local associations to this server (ie. copy them to globals table) The local server is essentially treated the same as any other peer except we don't do the network round-trip and this function can be used so the association goes into the global table before the http call returns (so clients know it will be available on at least the same ID server they used) """ localPeer = LocalPeer(self.sydent) signedAssocs, _ = self.local_assoc_store.getSignedAssociationsAfterId( localPeer.lastId, None ) localPeer.pushUpdates(signedAssocs) def scheduledPush(self) -> "defer.Deferred[List[Tuple[bool, None]]]": """Push pending updates to all known remote peers. To be called regularly. :returns a deferred.DeferredList of defers, one per peer we're pushing to that will resolve when pushing to that peer has completed, successfully or otherwise """ peers = self.peerStore.getAllPeers() # Push to all peers in parallel dl = [] for p in peers: dl.append(defer.ensureDeferred(self._push_to_peer(p))) return defer.DeferredList(dl) async def _push_to_peer(self, p: "RemotePeer") -> None: """ For a given peer, retrieves the list of associations that were created since the last successful push to this peer (limited to ASSOCIATIONS_PUSH_LIMIT) and sends them. :param p: The peer to send associations to. """ logger.debug("Looking for updates to push to %s", p.servername) # Check if a push operation is already active. If so, don't start another if p.is_being_pushed_to: logger.debug( "Waiting for %s to finish pushing...", p.replication_url_origin ) return p.is_being_pushed_to = True try: # Push associations ( assocs, latest_assoc_id, ) = self.local_assoc_store.getSignedAssociationsAfterId( p.lastSentVersion, ASSOCIATIONS_PUSH_LIMIT ) # If there are no updates left to send, break the loop if not assocs: return logger.info( "Pushing %d updates to %s", len(assocs), p.replication_url_origin ) result = await p.pushUpdates(assocs) self.peerStore.setLastSentVersionAndPokeSucceeded( p.servername, latest_assoc_id, time_msec() ) logger.info( "Pushed updates to %s with result %d %s", p.replication_url_origin, result.code, result.phrase, ) except Exception: logger.exception("Error pushing updates to %s", p.replication_url_origin) finally: # Whether pushing completed or an error occurred, signal that pushing has finished p.is_being_pushed_to = False
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