Пример #1
0
def login_with_token(client: GMatrixClient, user_id: str,
                     access_token: str) -> Optional[User]:
    """Reuse an existing authentication code.

    If this succeeds it means the user has logged in the past, so we assume the
    display name is properly set and that there may be rooms open from past
    executions.
    """
    client.set_access_token(user_id=user_id, token=access_token)

    try:
        # Test the credentials. Any API that requries authentication
        # would be enough.
        client.api.get_devices()
    except MatrixRequestError as ex:
        log.debug(
            "Couldn't use previous login credentials",
            node=node_address_from_userid(client.user_id),
            prev_user_id=user_id,
            _exception=ex,
        )
        return None

    log.debug(
        "Success. Valid previous credentials",
        node=node_address_from_userid(client.user_id),
        user_id=user_id,
    )
    return client.get_user(client.user_id)
Пример #2
0
def _check_previous_login(client: GMatrixClient,
                          prev_user_id: str = None,
                          prev_access_token: str = None,
                          base_username: str = None,
                          server_name: str = None):

    # log.info("User: "******"Access Token: " + prev_access_token)

    _match_user = re.match(
        f"^@{re.escape(base_username)}.*:{re.escape(server_name)}$",
        prev_user_id or "")
    if _match_user:  # same user as before
        assert prev_user_id is not None
        log.info("Trying previous user login", user_id=prev_user_id)
        client.set_access_token(user_id=prev_user_id, token=prev_access_token)

        try:
            client.api.get_devices()
        except MatrixRequestError as ex:
            log.debug(
                "Couldn't use previous login credentials, discarding",
                prev_user_id=prev_user_id,
                _exception=ex,
            )
        else:
            prev_sync_limit = client.set_sync_limit(0)
            client._sync()  # initial_sync
            client.set_sync_limit(prev_sync_limit)
            log.info("Success. Valid previous credentials",
                     user_id=prev_user_id)
            return client.get_user(client.user_id)
    elif prev_user_id:
        log.debug(
            "Different server or account, discarding",
            prev_user_id=prev_user_id,
            current_address=base_username,
            current_server=server_name,
        )
Пример #3
0
def login_or_register(
    client: GMatrixClient,
    signer: Signer,
    prev_user_id: str = None,
    prev_access_token: str = None,
) -> User:
    """Login to a Raiden matrix server with password and displayname proof-of-keys

    - Username is in the format: 0x<eth_address>(.<suffix>)?, where the suffix is not required,
    but a deterministic (per-account) random 8-hex string to prevent DoS by other users registering
    our address
    - Password is the signature of the server hostname, verified by the server to prevent account
    creation spam
    - Displayname currently is the signature of the whole user_id (including homeserver), to be
    verified by other peers. May include in the future other metadata such as protocol version

    Params:
        client: GMatrixClient instance configured with desired homeserver
        signer: raiden.utils.signer.Signer instance for signing password and displayname
        prev_user_id: (optional) previous persisted client.user_id. Must match signer's account
        prev_access_token: (optional) previous persistend client.access_token for prev_user_id
    Returns:
        Own matrix_client.User
    """
    server_url = client.api.base_url
    server_name = urlparse(server_url).netloc

    base_username = to_normalized_address(signer.address)
    _match_user = re.match(
        f'^@{re.escape(base_username)}.*:{re.escape(server_name)}$',
        prev_user_id or '',
    )
    if _match_user:  # same user as before
        log.debug('Trying previous user login', user_id=prev_user_id)
        client.set_access_token(user_id=prev_user_id, token=prev_access_token)

        try:
            client.api.get_devices()
        except MatrixRequestError as ex:
            log.debug(
                'Couldn\'t use previous login credentials, discarding',
                prev_user_id=prev_user_id,
                _exception=ex,
            )
        else:
            prev_sync_limit = client.set_sync_limit(0)
            client._sync()  # initial_sync
            client.set_sync_limit(prev_sync_limit)
            log.debug('Success. Valid previous credentials',
                      user_id=prev_user_id)
            return client.get_user(client.user_id)
    elif prev_user_id:
        log.debug(
            'Different server or account, discarding',
            prev_user_id=prev_user_id,
            current_address=base_username,
            current_server=server_name,
        )

    # password is signed server address
    password = encode_hex(signer.sign(server_name.encode()))
    rand = None
    # try login and register on first 5 possible accounts
    for i in range(JOIN_RETRIES):
        username = base_username
        if i:
            if not rand:
                rand = Random(
                )  # deterministic, random secret for username suffixes
                # initialize rand for seed (which requires a signature) only if/when needed
                rand.seed(int.from_bytes(signer.sign(b'seed')[-32:], 'big'))
            username = f'{username}.{rand.randint(0, 0xffffffff):08x}'

        try:
            client.login(username, password, sync=False)
            prev_sync_limit = client.set_sync_limit(0)
            client._sync()  # when logging, do initial_sync with limit=0
            client.set_sync_limit(prev_sync_limit)
            log.debug(
                'Login',
                homeserver=server_name,
                server_url=server_url,
                username=username,
            )
            break
        except MatrixRequestError as ex:
            if ex.code != 403:
                raise
            log.debug(
                'Could not login. Trying register',
                homeserver=server_name,
                server_url=server_url,
                username=username,
            )
            try:
                client.register_with_password(username, password)
                log.debug(
                    'Register',
                    homeserver=server_name,
                    server_url=server_url,
                    username=username,
                )
                break
            except MatrixRequestError as ex:
                if ex.code != 400:
                    raise
                log.debug('Username taken. Continuing')
                continue
    else:
        raise ValueError('Could not register or login!')

    name = encode_hex(signer.sign(client.user_id.encode()))
    user = client.get_user(client.user_id)
    user.set_display_name(name)
    return user