예제 #1
0
def identify_payload(payload):
    """Try to identify whether this is a Diaspora payload.

    Try first public message. Then private message. The check if this is a legacy payload.
    """
    # Private encrypted JSON payload
    try:
        data = json.loads(decode_if_bytes(payload))
        if "encrypted_magic_envelope" in data:
            return True
    except Exception:
        pass
    # Public XML payload
    try:
        xml = etree.fromstring(encode_if_text(payload))
        if xml.tag == MAGIC_ENV_TAG:
            return True
    except Exception:
        pass
    # Legacy XML payload
    try:
        xml = unquote_plus(payload)
        return xml.find('xmlns="%s"' % PROTOCOL_NS) > -1
    except Exception:
        pass
    return False
예제 #2
0
def verify_request_signature(request: RequestType, public_key: Union[str,
                                                                     bytes]):
    """
    Verify HTTP signature in request against a public key.
    """
    key = encode_if_text(public_key)
    date_header = request.headers.get("Date")
    if not date_header:
        raise ValueError("Rquest Date header is missing")

    ts = parse_http_date(date_header)
    dt = datetime.datetime.utcfromtimestamp(ts).replace(tzinfo=pytz.utc)
    delta = datetime.timedelta(seconds=30)
    now = datetime.datetime.utcnow().replace(tzinfo=pytz.utc)
    if dt < now - delta or dt > now + delta:
        raise ValueError("Request Date is too far in future or past")

    HTTPSignatureHeaderAuth.verify(request, key_resolver=lambda **kwargs: key)
예제 #3
0
def identify_request(request: RequestType):
    """Try to identify whether this is a Diaspora request.

    Try first public message. Then private message. The check if this is a legacy payload.
    """
    # Private encrypted JSON payload
    try:
        data = json.loads(decode_if_bytes(request.body))
        if "encrypted_magic_envelope" in data:
            return True
    except Exception:
        pass
    # Public XML payload
    try:
        xml = etree.fromstring(encode_if_text(request.body))
        if xml.tag == MAGIC_ENV_TAG:
            return True
    except Exception:
        pass
    return False
예제 #4
0
    def test_survives_sending_share_if_diaspora_payload_cannot_be_created(
            self, mock_send, share):
        key = get_dummy_private_key()
        share.target_handle = None  # Ensure diaspora payload fails
        recipients = [{
            "endpoint": "https://example.com/receive/public",
            "public": True,
            "protocol": "diaspora",
            "fid": "",
        }, {
            "endpoint": "https://example.tld/receive/public",
            "public": True,
            "protocol": "diaspora",
            "fid": "",
        }, {
            "endpoint": "https://example.net/inbox",
            "fid": "https://example.net/foobar",
            "public": True,
            "protocol": "activitypub",
        }]
        author = UserType(
            private_key=key,
            id="*****@*****.**",
            handle="*****@*****.**",
        )
        handle_send(share, author, recipients)

        # Ensure first call is a public activitypub payload
        args, kwargs = mock_send.call_args_list[0]
        assert args[0] == "https://example.net/inbox"
        assert kwargs['headers'] == {
            'Content-Type':
            'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
        }
        assert encode_if_text(
            "https://www.w3.org/ns/activitystreams#Public") in args[1]

        # Should only be one call
        assert mock_send.call_count == 1
예제 #5
0
    def test_calls_handle_create_payload(self, mock_send, profile):
        key = get_dummy_private_key()
        recipients = [
            {
                "endpoint": "https://127.0.0.1/receive/users/1234",
                "public_key": key.publickey(),
                "public": False,
                "protocol": "diaspora",
                "fid": "",
            },
            {
                "endpoint": "https://example.com/receive/public",
                "public": True,
                "protocol": "diaspora",
                "fid": "",
            },
            {
                "endpoint": "https://example.net/receive/public",
                "public": True,
                "protocol": "diaspora",
                "fid": "",
            },
            # Same twice to ensure one delivery only per unique
            {
                "endpoint": "https://example.net/receive/public",
                "public": True,
                "protocol": "diaspora",
                "fid": "",
            },
            {
                "endpoint": "https://example.net/foobar/inbox",
                "fid": "https://example.net/foobar",
                "public": False,
                "protocol": "activitypub",
            },
            {
                "endpoint": "https://example.net/inbox",
                "fid": "https://example.net/foobar",
                "public": True,
                "protocol": "activitypub",
            }
        ]
        author = UserType(
            private_key=key,
            id="*****@*****.**",
            handle="*****@*****.**",
        )
        handle_send(profile, author, recipients)

        # Ensure first call is a private diaspora payload
        args, kwargs = mock_send.call_args_list[0]
        assert args[0] == "https://127.0.0.1/receive/users/1234"
        assert "aes_key" in args[1]
        assert "encrypted_magic_envelope" in args[1]
        assert kwargs['headers'] == {'Content-Type': 'application/json'}

        # Ensure second call is a private activitypub payload
        args, kwargs = mock_send.call_args_list[1]
        assert args[0] == "https://example.net/foobar/inbox"
        assert kwargs['headers'] == {
            'Content-Type':
            'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
        }
        assert encode_if_text(
            "https://www.w3.org/ns/activitystreams#Public") not in args[1]

        # Ensure third call is a public activitypub payload
        args, kwargs = mock_send.call_args_list[2]
        assert args[0] == "https://example.net/inbox"
        assert kwargs['headers'] == {
            'Content-Type':
            'application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
        }
        assert encode_if_text(
            "https://www.w3.org/ns/activitystreams#Public") in args[1]

        # Ensure diaspora public payloads and recipients, one per unique host
        args3, kwargs3 = mock_send.call_args_list[3]
        args4, kwargs4 = mock_send.call_args_list[4]
        public_endpoints = {args3[0], args4[0]}
        assert public_endpoints == {
            "https://example.net/receive/public",
            "https://example.com/receive/public",
        }
        assert args3[1].startswith("<me:env xmlns:me=")
        assert args4[1].startswith("<me:env xmlns:me=")
        assert kwargs3['headers'] == {
            'Content-Type': 'application/magic-envelope+xml'
        }
        assert kwargs4['headers'] == {
            'Content-Type': 'application/magic-envelope+xml'
        }

        with pytest.raises(IndexError):
            # noinspection PyStatementEffect
            mock_send.call_args_list[5]
예제 #6
0
def test_encode_if_text():
    assert encode_if_text(b"foobar") == b"foobar"
    assert encode_if_text("foobar") == b"foobar"