示例#1
0
 def _do_create_revision_from_another_supplier(self, another_revision,
                                               another_suppliers,
                                               another_ecc_map):
     local_customer_meta_info = contactsdb.get_customer_meta_info(
         self.customer_idurl)
     possible_position = local_customer_meta_info.get('position', -1) or -1
     if possible_position >= 0:
         try:
             another_suppliers[possible_position] = my_id.getLocalIDURL()
         except:
             lg.exc()
         contactsdb.add_customer_meta_info(
             self.customer_idurl, {
                 'ecc_map': another_ecc_map,
                 'position': possible_position,
                 'family_snapshot': another_suppliers,
             })
     return {
         'revision': int(another_revision),
         'publisher_idurl':
         my_id.getLocalIDURL(),  # I will be a publisher of that revision
         'suppliers': another_suppliers,
         'ecc_map': another_ecc_map,
         'customer_idurl': self.customer_idurl,
     }
示例#2
0
 def _on_incoming_supplier_position(self, inp):
     # this packet came from the customer, a godfather of the family ;)))
     incoming_packet = inp['packet']
     try:
         ecc_map = inp['customer_ecc_map']
         supplier_idurl = inp['supplier_idurl']
         supplier_position = inp['supplier_position']
         family_snapshot = inp.get('family_snapshot') or []
     except:
         lg.exc()
         return None
     if supplier_idurl != my_id.getLocalIDURL():
         return p2p_service.SendFail(
             incoming_packet,
             'contacts packet with supplier position not addressed to me')
     try:
         _existing_position = self.my_info['suppliers'].index(
             supplier_idurl)
     except:
         _existing_position = -1
     contactsdb.add_customer_meta_info(
         self.customer_idurl, {
             'ecc_map': ecc_map,
             'position': supplier_position,
             'family_snapshot': family_snapshot,
         })
     if _Debug:
         lg.out(
             _DebugLevel,
             'family_member._on_incoming_supplier_position stored new meta info for customer %s:\n'
             % self.customer_idurl)
         lg.out(
             _DebugLevel,
             '    ecc_map=%s position=%s family_snapshot=%s' % (
                 ecc_map,
                 supplier_position,
                 family_snapshot,
             ))
     return p2p_service.SendAck(incoming_packet)
示例#3
0
 def request(self, json_payload, newpacket, info):
     from twisted.internet import reactor  # @UnresolvedImport
     from logs import lg
     from main import events
     from crypt import my_keys
     from p2p import p2p_service
     from contacts import contactsdb
     from storage import accounting
     from userid import global_id
     customer_idurl = newpacket.OwnerID
     customer_id = global_id.UrlToGlobalID(customer_idurl)
     bytes_for_customer = 0
     try:
         bytes_for_customer = int(json_payload['needed_bytes'])
     except:
         lg.warn("wrong payload" % newpacket.Payload)
         return p2p_service.SendFail(newpacket, 'wrong payload')
     try:
         customer_public_key = json_payload['customer_public_key']
         customer_public_key_id = customer_public_key['key_id']
     except:
         customer_public_key = None
         customer_public_key_id = None
     data_owner_idurl = None
     target_customer_idurl = None
     family_position = json_payload.get('position')
     ecc_map = json_payload.get('ecc_map')
     family_snapshot = json_payload.get('family_snapshot')
     key_id = json_payload.get('key_id')
     target_customer_id = json_payload.get('customer_id')
     if key_id:
         # this is a request from external user to access shared data stored by one of my customers
         # this is "second" customer requesting data from "first" customer
         if not key_id or not my_keys.is_valid_key_id(key_id):
             lg.warn('missed or invalid key id')
             return p2p_service.SendFail(newpacket, 'invalid key id')
         target_customer_idurl = global_id.GlobalUserToIDURL(
             target_customer_id)
         if not contactsdb.is_customer(target_customer_idurl):
             lg.warn("target user %s is not a customer" %
                     target_customer_id)
             return p2p_service.SendFail(newpacket, 'not a customer')
         if target_customer_idurl == customer_idurl:
             lg.warn('customer %s requesting shared access to own files' %
                     customer_idurl)
             return p2p_service.SendFail(newpacket, 'invalid case')
         if not my_keys.is_key_registered(key_id):
             lg.warn('key not registered: %s' % key_id)
             p2p_service.SendFail(newpacket, 'key not registered')
             return False
         data_owner_idurl = my_keys.split_key_id(key_id)[1]
         if data_owner_idurl != target_customer_idurl and data_owner_idurl != customer_idurl:
             # pretty complex scenario:
             # external customer requesting access to data which belongs not to that customer
             # this is "third" customer accessing data belongs to "second" customer
             # TODO: for now just stop it
             lg.warn(
                 'under construction, key_id=%s customer_idurl=%s target_customer_idurl=%s'
                 % (
                     key_id,
                     customer_idurl,
                     target_customer_idurl,
                 ))
             p2p_service.SendFail(newpacket, 'under construction')
             return False
         # do not create connection with that customer, only accept the request
         lg.info(
             'external customer %s requested access to shared data at %s' %
             (
                 customer_id,
                 key_id,
             ))
         return p2p_service.SendAck(newpacket, 'accepted')
     # key_id is not present in the request:
     # this is a request to connect new customer (or reconnect existing one) to that supplier
     if not bytes_for_customer or bytes_for_customer < 0:
         lg.warn("wrong payload : %s" % newpacket.Payload)
         return p2p_service.SendFail(newpacket, 'wrong storage value')
     current_customers = contactsdb.customers()
     if accounting.check_create_customers_quotas():
         lg.out(6, 'service_supplier.request created a new space file')
     space_dict = accounting.read_customers_quotas()
     try:
         free_bytes = int(space_dict[b'free'])
     except:
         lg.exc()
         return p2p_service.SendFail(newpacket, 'broken space file')
     if (customer_idurl not in current_customers
             and customer_idurl in list(space_dict.keys())):
         lg.warn("broken space file")
         return p2p_service.SendFail(newpacket, 'broken space file')
     if (customer_idurl in current_customers
             and customer_idurl not in list(space_dict.keys())):
         lg.warn("broken customers file")
         return p2p_service.SendFail(newpacket, 'broken customers file')
     if customer_idurl in current_customers:
         free_bytes += int(space_dict.get(customer_idurl, 0))
         space_dict[b'free'] = free_bytes
         current_customers.remove(customer_idurl)
         space_dict.pop(customer_idurl)
         new_customer = False
     else:
         new_customer = True
     lg.out(
         8, '    new_customer=%s current_allocated_bytes=%s' % (
             new_customer,
             space_dict.get(customer_idurl),
         ))
     from supplier import local_tester
     if free_bytes <= bytes_for_customer:
         contactsdb.update_customers(current_customers)
         contactsdb.remove_customer_meta_info(customer_idurl)
         contactsdb.save_customers()
         accounting.write_customers_quotas(space_dict)
         if customer_public_key_id:
             my_keys.erase_key(customer_public_key_id)
         reactor.callLater(
             0, local_tester.TestUpdateCustomers)  # @UndefinedVariable
         if new_customer:
             lg.out(
                 8,
                 "    NEW CUSTOMER: DENIED !!!!!!!!!!!    not enough space available"
             )
             events.send('new-customer-denied', dict(idurl=customer_idurl))
         else:
             lg.out(
                 8,
                 "    OLD CUSTOMER: DENIED !!!!!!!!!!!    not enough space available"
             )
             events.send('existing-customer-denied',
                         dict(idurl=customer_idurl))
         return p2p_service.SendAck(newpacket, 'deny')
     space_dict[b'free'] = free_bytes - bytes_for_customer
     current_customers.append(customer_idurl)
     space_dict[customer_idurl] = bytes_for_customer
     contactsdb.update_customers(current_customers)
     contactsdb.save_customers()
     contactsdb.add_customer_meta_info(
         customer_idurl, {
             'ecc_map': ecc_map,
             'position': family_position,
             'family_snapshot': family_snapshot,
         })
     accounting.write_customers_quotas(space_dict)
     if customer_public_key_id:
         my_keys.erase_key(customer_public_key_id)
         try:
             if not my_keys.is_key_registered(customer_public_key_id):
                 key_id, key_object = my_keys.read_key_info(
                     customer_public_key)
                 if not my_keys.register_key(key_id, key_object):
                     lg.err('failed to register customer public key')
         except:
             lg.exc()
     else:
         lg.warn('customer public key was not provided in the request')
     reactor.callLater(
         0, local_tester.TestUpdateCustomers)  # @UndefinedVariable
     if new_customer:
         lg.out(
             8,
             "    NEW CUSTOMER: ACCEPTED   %s family_position=%s ecc_map=%s allocated_bytes=%s"
             %
             (customer_idurl, family_position, ecc_map, bytes_for_customer))
         lg.out(
             8,
             "        family_snapshot=%r !!!!!!!!!!!!!!" % family_snapshot,
         )
         events.send(
             'new-customer-accepted',
             dict(
                 idurl=customer_idurl,
                 allocated_bytes=bytes_for_customer,
                 ecc_map=ecc_map,
                 position=family_position,
                 family_snapshot=family_snapshot,
                 key_id=customer_public_key_id,
             ))
     else:
         lg.out(
             8,
             "    OLD CUSTOMER: ACCEPTED  %s family_position=%s ecc_map=%s allocated_bytes=%s"
             %
             (customer_idurl, family_position, ecc_map, bytes_for_customer))
         lg.out(
             8,
             "        family_snapshot=%r !!!!!!!!!!!!!!" % family_snapshot)
         events.send(
             'existing-customer-accepted',
             dict(
                 idurl=customer_idurl,
                 allocated_bytes=bytes_for_customer,
                 ecc_map=ecc_map,
                 position=family_position,
                 key_id=customer_public_key_id,
                 family_snapshot=family_snapshot,
             ))
     return p2p_service.SendAck(newpacket, 'accepted')