| 1588 | |
| 1589 | |
| 1590 | def load_records_in_shared_folder(params, shared_folder_uid, record_uids=None): |
| 1591 | # type: (KeeperParams, str, Optional[Iterable[str]]) -> None |
| 1592 | |
| 1593 | if shared_folder_uid not in params.shared_folder_cache: |
| 1594 | raise Exception(f'Shared folder \"{shared_folder_uid}\" is not loaded.') |
| 1595 | shared_folder = params.shared_folder_cache[shared_folder_uid] |
| 1596 | shared_folder_key = shared_folder['shared_folder_key_unencrypted'] |
| 1597 | record_keys = {} # type: Dict[str, bytes] |
| 1598 | for rk in shared_folder.get('records', []): |
| 1599 | record_uid = rk.get('record_uid') |
| 1600 | try: |
| 1601 | key = utils.base64_url_decode(rk['record_key']) |
| 1602 | if len(key) == 60: |
| 1603 | record_key = crypto.decrypt_aes_v2(key, shared_folder_key) |
| 1604 | else: |
| 1605 | record_key = crypto.decrypt_aes_v1(key, shared_folder_key) |
| 1606 | record_keys[record_uid] = record_key |
| 1607 | except Exception as e: |
| 1608 | logging.debug('Cannot decrypt record \"%s\" key: %s', record_uid, e) |
| 1609 | |
| 1610 | if record_uids: |
| 1611 | record_set = set(record_uids) |
| 1612 | record_set.intersection_update(record_keys.keys()) |
| 1613 | else: |
| 1614 | record_set = set(record_keys.keys()) |
| 1615 | record_set.difference_update(params.record_cache.keys()) |
| 1616 | |
| 1617 | while len(record_set) > 0: |
| 1618 | rq = record_pb2.GetRecordDataWithAccessInfoRequest() |
| 1619 | rq.clientTime = utils.current_milli_time() |
| 1620 | rq.recordDetailsInclude = record_pb2.DATA_PLUS_SHARE |
| 1621 | for uid in record_set: |
| 1622 | try: |
| 1623 | rq.recordUid.append(utils.base64_url_decode(uid)) |
| 1624 | except Exception as e: |
| 1625 | logging.debug('Incorrect record UID \"%s\": %s', uid, e) |
| 1626 | record_set.clear() |
| 1627 | |
| 1628 | rs = communicate_rest(params, rq, 'vault/get_records_details', rs_type=record_pb2.GetRecordDataWithAccessInfoResponse) |
| 1629 | for record_info in rs.recordDataWithAccessInfo: |
| 1630 | record_uid = utils.base64_url_encode(record_info.recordUid) |
| 1631 | record_data = record_info.recordData |
| 1632 | try: |
| 1633 | if record_data.ownerRecordUid and record_data.encryptedLinkedRecordKey: |
| 1634 | owner_id = utils.base64_url_encode(record_data.ownerRecordUid) |
| 1635 | if owner_id in record_keys: |
| 1636 | record_keys[record_uid] = crypto.decrypt_aes_v2(record_data.encryptedLinkedRecordKey, record_keys[owner_id]) |
| 1637 | |
| 1638 | if record_uid not in record_keys: |
| 1639 | continue |
| 1640 | |
| 1641 | record_key = record_keys[record_uid] |
| 1642 | version = record_data.version |
| 1643 | record = { |
| 1644 | 'record_uid': record_uid, |
| 1645 | 'revision': record_data.revision, |
| 1646 | 'version': version, |
| 1647 | 'shared': record_data.shared, |