Beispiel #1
0
def get_client_and_key(username, password):
    fxa_client = FxAClient()

    pickle_filename = username + '.pickle'
    prev_session = None
    try:
        prev_session = pickle.load(open(pickle_filename, 'rb'))
    except Exception:
        pass

    if prev_session:
        session = FxASession(fxa_client, username,
                             quick_stretch_password(username, password),
                             prev_session.uid,
                             prev_session.token)
        session.keys = prev_session.keys
        session.check_session_status()
    else:
        session = fxa_client.login(username, password, keys=True)
        session.fetch_keys()

    pickle.dump(session, open(pickle_filename, 'wb'))

    bid_assertion_args = get_browserid_assertion(session)
    client = SyncClient(*bid_assertion_args)

    sync_keys = KeyBundle.fromMasterKey(
        session.keys[1],
        b"identity.mozilla.com/picl/v1/oldsync")

    # Fetch the sync bundle keys out of storage.
    # They're encrypted with the account-level key.
    keys = decrypt_payload(client.get_record('crypto', 'keys')['payload'],
                           sync_keys)

    # There's some provision for using separate key bundles
    # for separate collections
    # but I haven't bothered digging through to see what that's about because
    # it doesn't seem to be in use, at least on my account.
    if keys["collections"]:
        raise RuntimeError("no support for per-collection key bundles")

    bulk_keys = KeyBundle(base64.b64decode(keys["default"][0]),
                          base64.b64decode(keys["default"][1]))
    return (client, bulk_keys)
def upload_passwords_data(passdata, assertion, kB):
    """
    Upload the passdata passwords to the Firefox Account
    :param passdata: The list of formated Firefox compatible password data
    :param assertion:
    :param kB:
    :return:
    """
    # Connect to sync.
    xcs = hexlify(hashlib.sha256(kB).digest()[:16])
    client = SyncClient(assertion, xcs)
    # Fetch /crypto/keys.
    raw_sync_key = fxa.crypto.derive_key(kB, "oldsync", 64)
    root_key_bundle = KeyBundle(
        raw_sync_key[:32],
        raw_sync_key[32:],
    )
    keys_bso = client.get_record("crypto", "keys")
    keys = root_key_bundle.decrypt_bso(keys_bso)
    default_key_bundle = KeyBundle(
        base64.b64decode(keys["default"][0]),
        base64.b64decode(keys["default"][1]),
    )
    for data in tqdm(passdata):
        encrypted_data = default_key_bundle.encrypt_bso(data)
        assert default_key_bundle.decrypt_bso(encrypted_data) == data
        client.put_record("passwords", encrypted_data)
    logging.debug("Synced password records: %d" %
                  len(client.get_records("passwords")))
    logging.info("Done!")
Beispiel #3
0
    def setUp(self):
        super(ClientHTTPCallsTest, self).setUp()
        self.client = SyncClient(
            hashalg=mock.sentinel.hashalg,
            id=mock.sentinel.id,
            key=mock.sentinel.key,
            uid=mock.sentinel.uid,
            api_endpoint=mock.sentinel.api_endpoint
        )

        # Mock the request method of the client, since we'll use
        # it to make sure the correct requests are made.
        self.client._request = mock.MagicMock()
Beispiel #4
0
class ClientHTTPCallsTest(unittest.TestCase):
    def setUp(self):
        super(ClientHTTPCallsTest, self).setUp()
        self.client = SyncClient(
            hashalg=mock.sentinel.hashalg,
            id=mock.sentinel.id,
            key=mock.sentinel.key,
            uid=mock.sentinel.uid,
            api_endpoint=mock.sentinel.api_endpoint
        )

        # Mock the request method of the client, since we'll use
        # it to make sure the correct requests are made.
        self.client._request = mock.MagicMock()

    def test_info_collection(self):
        self.client.info_collections()
        self.client._request.assert_called_with('get', '/info/collections')

    def test_info_collection_can_receive_requests_parameters(self):
        self.client.info_collections(headers=mock.sentinel.headers)
        self.client._request.assert_called_with('get', '/info/collections',
                                                headers=mock.sentinel.headers)

    def test_info_quota(self):
        self.client.info_quota()
        self.client._request.assert_called_with('get', '/info/quota')

    def test_info_quota_can_receive_requests_parameters(self):
        self.client.info_quota(headers=mock.sentinel.headers)
        self.client._request.assert_called_with('get', '/info/quota',
                                                headers=mock.sentinel.headers)

    def test_collection_usage(self):
        self.client.get_collection_usage()
        self.client._request.assert_called_with(
            'get', '/info/collection_usage')

    def test_collection_usage_can_receive_requests_parameters(self):
        self.client.get_collection_usage(headers=mock.sentinel.headers)
        self.client._request.assert_called_with(
            'get', '/info/collection_usage', headers=mock.sentinel.headers)

    def test_collection_counts(self):
        self.client.get_collection_counts()
        self.client._request.assert_called_with(
            'get', '/info/collection_counts')

    def test_collection_counts_can_receive_requests_parameters(self):
        self.client.get_collection_counts(headers=mock.sentinel.headers)
        self.client._request.assert_called_with(
            'get', '/info/collection_counts', headers=mock.sentinel.headers)

    def test_delete_all_records(self):
        self.client.delete_all_records()
        self.client._request.assert_called_with(
            'delete', '/')

    def test_delete_all_records_can_receive_requests_parameters(self):
        self.client.delete_all_records(headers=mock.sentinel.headers)
        self.client._request.assert_called_with(
            'delete', '/', headers=mock.sentinel.headers)

    def test_get_records_sets_full_by_default(self):
        self.client.get_records('mycollection')
        self.client._request.assert_called_with(
            'get', '/storage/mycollection',
            params={'full': True})

    def test_get_records_lowers_the_collection_name(self):
        self.client.get_records('myCollection')
        self.client._request.assert_called_with(
            'get', '/storage/mycollection',
            params={'full': True})

    def test_get_records_handles_ids(self):
        self.client.get_records('myCollection', ids=(1, 3))
        self.client._request.assert_called_with(
            'get', '/storage/mycollection',
            params={'full': True, 'ids': '1,3'})

    def test_get_records_handles_full(self):
        self.client.get_records('mycollection', full=False)
        self.client._request.assert_called_with(
            'get', '/storage/mycollection',
            params={})

    def test_get_records_handles_newer(self):
        self.client.get_records('mycollection', newer='newer')
        self.client._request.assert_called_with(
            'get', '/storage/mycollection',
            params={'newer': 'newer', 'full': True})

    def test_get_records_handles_limit(self):
        self.client.get_records('mycollection', limit='limit')
        self.client._request.assert_called_with(
            'get', '/storage/mycollection',
            params={'limit': 'limit', 'full': True})

    def test_get_records_handles_offset(self):
        self.client.get_records('mycollection', offset='offset')
        self.client._request.assert_called_with(
            'get', '/storage/mycollection',
            params={'offset': 'offset', 'full': True})

    def test_get_records_handles_sort_by_newest(self):
        self.client.get_records('mycollection', sort='newest')
        self.client._request.assert_called_with(
            'get', '/storage/mycollection',
            params={'sort': 'newest', 'full': True})

    def test_get_records_handles_sort_by_oldest(self):
        self.client.get_records('mycollection', sort='oldest')
        self.client._request.assert_called_with(
            'get', '/storage/mycollection',
            params={'sort': 'oldest', 'full': True})

    def test_get_records_handles_sort_by_index(self):
        self.client.get_records('mycollection', sort='index')
        self.client._request.assert_called_with(
            'get', '/storage/mycollection',
            params={'sort': 'index', 'full': True})

    def test_get_records_ignore_sort_by_invalid(self):
        self.client.get_records('mycollection', sort='invalid')
        self.client._request.assert_called_with(
            'get', '/storage/mycollection',
            params={'full': True})

    def test_get_record(self):
        self.client.get_record('myCollection', 1234)
        self.client._request.assert_called_with(
            'get', '/storage/mycollection/1234')

    def test_get_record_can_receive_requests_parameters(self):
        self.client.get_record('myCollection', 1234,
                               headers=mock.sentinel.headers)
        self.client._request.assert_called_with(
            'get', '/storage/mycollection/1234',
            headers=mock.sentinel.headers)

    def test_delete_record(self):
        self.client.delete_record('myCollection', 1234)
        self.client._request.assert_called_with(
            'delete', '/storage/mycollection/1234')

    def test_delete_record_can_receive_requests_parameters(self):
        self.client.delete_record('myCollection', 1234,
                                  headers=mock.sentinel.headers)
        self.client._request.assert_called_with(
            'delete', '/storage/mycollection/1234',
            headers=mock.sentinel.headers)

    def test_put_record(self):
        record = {'id': 1234, 'foo': 'bar'}
        self.client.put_record('myCollection', record)
        self.client._request.assert_called_with(
            'put', '/storage/mycollection/1234',
            data='{"foo": "bar"}',
            headers={'Content-Type': 'application/json; charset=utf-8'})

    def test_put_record_handle_json_string_parameter(self):
        record = '{"id": 1234, "foo": "bar"}'
        self.client.put_record('myCollection', record)
        self.client._request.assert_called_with(
            'put', '/storage/mycollection/1234',
            data='{"foo": "bar"}',
            headers={'Content-Type': 'application/json; charset=utf-8'})

    def test_put_record_can_receive_requests_parameters(self):
        record = {'id': 1234, 'foo': 'bar'}
        self.client.put_record('myCollection', record,
                               headers={'Sentinel': 'true'})
        self.client._request.assert_called_with(
            'put', '/storage/mycollection/1234',
            data='{"foo": "bar"}',
            headers={'Content-Type': 'application/json; charset=utf-8',
                     'Sentinel': 'true'})

    def test_put_record_doesnt_modify_the_passed_object(self):
        record = {'id': 1234, 'foo': 'bar'}
        self.client.put_record('myCollection', record)
        assert 'id' in record.keys()

    def test_post_records(self):
        # For now, this does nothing.
        records = [{'id': idx, 'foo': 'foo'} for idx in range(1, 10)]
        self.client.post_records("myCollection", records)
Beispiel #5
0
 def _get_client(self, api_endpoint='http://example.org/', **kwargs):
     client = SyncClient("bid_assertion", "client_state", **kwargs)
     client.api_endpoint = api_endpoint
     client.auth = mock.sentinel.auth
     return client