Ejemplo n.º 1
0
 def perform_vlob_synchronize(self, intent):
     if intent.id in self.vlobs:
         vlob = self.vlobs[intent.id]
         try:
             self.vlob_cache[(intent.id, vlob['version'])] = vlob
         except ValueError:
             pass  # Value too large if cache is disabled
         new_vlob = None
         if vlob['version'] == 1:
             new_vlob = yield Effect(EBackendVlobCreate(vlob['blob'].encode()))
             new_trust_seed = new_vlob.read_trust_seed
             try:
                 self.vlob_cache[(intent.id, vlob['version'])]['read_trust_seed'] = new_trust_seed
             except KeyError:
                 pass
         else:
             yield Effect(EBackendVlobUpdate(
                 intent.id,
                 self.vlobs[intent.id]['write_trust_seed'],
                 self.vlobs[intent.id]['version'],
                 vlob['blob'].encode()))  # TODO encode is correct?
         del self.vlobs[intent.id]
         if new_vlob:
             return {'id': new_vlob.id,
                     'read_trust_seed': new_vlob.read_trust_seed,
                     'write_trust_seed': new_vlob.write_trust_seed}
         else:
             return True
     return False
Ejemplo n.º 2
0
 def perform_user_vlob_update(self, intent):
     id = yield Effect(EGetAuthenticatedUser())
     vlobs = self.vlobs[id]
     if len(vlobs) != intent.version - 1:
         raise UserVlobError('Wrong blob version.')
     vlobs.append(
         UserVlobAtom(id=id, version=intent.version, blob=intent.blob))
     yield Effect(EEvent('user_vlob_updated', id))
Ejemplo n.º 3
0
 def perform_identity_signup(self, intent):
     private_key = generate_asym_key(intent.key_size)
     cipherkey = private_key.export(intent.password)
     pubkey = private_key.pub_key.export()
     # Saving the cipherkey first prevent us from registering a public key
     # then crashing without the corresponding private key saved somewhere
     # TODO: handle compute the hash here instead of in BackendCipherkeyAdd ?
     yield Effect(
         EBackendCipherKeyAdd(intent.id, intent.password, cipherkey))
     yield Effect(EBackendIdentityRegister(intent.id, pubkey))
Ejemplo n.º 4
0
 def perform_identity_unload(self, intent):
     from parsec.core.backend import EBackendReset
     from parsec.core.block import EBlockReset
     if not self.identity:
         raise IdentityNotLoadedError('Identity not loaded')
     # TODO: make block&backend reset event triggered
     yield Effect(EBlockReset())
     yield Effect(EBackendReset())
     yield Effect(EEvent('identity_unloaded', None))
     self.identity = None
Ejemplo n.º 5
0
 def restore(self, version=None):
     if version is None:
         version = self.get_version() - 1
     if version < 1 or version >= self.get_version():
         raise FileError('bad_version', 'Bad version number.')
     yield self.discard()
     vlob = yield Effect(EVlobRead(self.id, self.read_trust_seed, version))
     yield Effect(EVlobUpdate(self.id,
                              self.write_trust_seed,
                              self.version + 1,
                              vlob['blob']))
     self.dirty = True
Ejemplo n.º 6
0
 def discard(self):
     already_synchronized = False
     self.modifications = []
     block_ids = yield self.get_blocks()
     for block_id in block_ids:
         try:
             yield Effect(EBlockDelete(block_id))
         except BlockNotFound:
             already_synchronized = True
     try:
         yield Effect(EVlobDelete(self.id))
     except VlobNotFound:
         already_synchronized = True
     self.dirty = False
     return not already_synchronized
Ejemplo n.º 7
0
def perform_pubkey_get(intent):
    msg = {'id': intent.id}
    ret = yield Effect(BackendCmd('pubkey_get', msg))
    status = ret['status']
    if status != 'ok':
        raise exception_from_status(status)(ret['label'])
    return PubKey(intent.id, from_jsonb64(ret['key']))
Ejemplo n.º 8
0
def perform_group_read(intent):
    msg = {'name': intent.name}
    ret = yield Effect(BackendCmd('group_read', msg))
    status = ret['status']
    if status != 'ok':
        raise exception_from_status(status)(ret['label'])
    return Group(intent.name, ret['admins'], ret['users'])
Ejemplo n.º 9
0
 def perform_vlob_read(self, intent):
     if (intent.id in self.vlobs and
             (not intent.version or intent.version == self.vlobs[intent.id]['version'])):
         # TDOO: remove this mystic 42
         if self.vlobs[intent.id]['read_trust_seed'] == '42':
             self.vlobs[intent.id]['read_trust_seed'] = intent.trust_seed
         assert intent.trust_seed == self.vlobs[intent.id]['read_trust_seed']
         return {'id': intent.id,
                 'blob': self.vlobs[intent.id]['blob'],
                 'version': self.vlobs[intent.id]['version']}
     else:
         if intent.version is not None:
             try:
                 cached_vlob = self.vlob_cache[(intent.id, intent.version)]
                 assert intent.trust_seed == cached_vlob['read_trust_seed']
                 vlob = {'id': intent.id, 'blob': cached_vlob['blob'], 'version': intent.version}
                 return vlob
             except KeyError:
                 pass  # cache miss
         vlob = yield Effect(EBackendVlobRead(intent.id, intent.trust_seed, intent.version))
         vlob = {'id': vlob.id, 'blob': vlob.blob.decode(), 'version': vlob.version}
         try:
             cached_vlob = {'id': intent.id,
                            'read_trust_seed': intent.trust_seed,
                            'version': intent.version,
                            'blob': vlob['blob']}
             self.vlob_cache[(intent.id, intent.version)] = cached_vlob
         except ValueError:
             pass  # Value too large if cache is disabled
         return vlob
Ejemplo n.º 10
0
 def stat(self):
     version = self.get_version()
     vlob = yield Effect(EVlobRead(self.id, self.read_trust_seed, version))
     encrypted_blob = vlob['blob']
     encrypted_blob = from_jsonb64(encrypted_blob)
     blob = self.encryptor.decrypt(encrypted_blob)
     blob = ejson_loads(blob.decode())
     size = 0
     for blocks_and_key in blob:
         for block in blocks_and_key['blocks']:
             size += block['size']
     for modification in self.modifications:
         if modification[0] == self.write:
             end_offset = modification[2] + len(modification[1])
             if size < end_offset:
                 size = end_offset
         elif modification[0] == self.truncate:
             if size > modification[1]:
                 size = modification[1]
         else:
             raise NotImplementedError()
     # TODO don't provide atime field if we don't know it?
     # TODO real date
     return {
         'id': self.id,
         'type': 'file',
         'created': '2012-01-01T00:00:00',
         'updated': '2012-01-01T00:00:00',
         'size': size,
         'version': vlob['version']
     }
Ejemplo n.º 11
0
def api_identity_info(msg):
    UnknownCheckedSchema().load(msg)
    try:
        identity = yield Effect(EIdentityGet())
        return {'status': 'ok', 'loaded': True, 'id': identity.id}
    except IdentityNotLoadedError:
        return {'status': 'ok', 'loaded': False, 'id': None}
Ejemplo n.º 12
0
 async def periodic_synchronization(self, app):
     # TODO: find a better way to do this than using asyncio_perform...
     while True:
         await asyncio.sleep(self.synchronization_idle_interval)
         if (arrow.utcnow().timestamp - self.last_modified.timestamp >
                 self.synchronization_idle_interval):
             await asyncio_perform(
                 app.components.get_dispatcher(), Effect(fs.ESynchronize()))
Ejemplo n.º 13
0
def api_user_vlob_read(msg):
    msg = cmd_READ_Schema().load(msg)
    atom = yield Effect(EUserVlobRead(**msg))
    return {
        'status': 'ok',
        'blob': to_jsonb64(atom.blob),
        'version': atom.version
    }
Ejemplo n.º 14
0
 def commit(self):
     yield self.flush()
     block_ids = yield self.get_blocks()
     for block_id in block_ids:
         yield Effect(EBlockSynchronize(block_id))
     new_vlob = yield Effect(EVlobSynchronize(self.id))
     if new_vlob:
         if new_vlob is not True:
             del File.files[self.id]
             self.id = new_vlob['id']
             self.read_trust_seed = new_vlob['read_trust_seed']
             self.write_trust_seed = new_vlob['write_trust_seed']
             new_vlob = self.get_vlob()
             File.files[self.id] = self
         self.version += 1
     self.dirty = False
     return new_vlob
Ejemplo n.º 15
0
 def reencrypt(self):
     yield self.flush()
     version = self.get_version()
     old_vlob = yield Effect(EVlobRead(self.id, self.read_trust_seed, version))
     old_blob = old_vlob['blob']
     old_encrypted_blob = from_jsonb64(old_blob)
     new_blob = self.encryptor.decrypt(old_encrypted_blob)
     self.encryptor = generate_sym_key()
     new_encrypted_blob = self.encryptor.encrypt(new_blob)
     new_encrypted_blob = to_jsonb64(new_encrypted_blob)
     new_vlob = yield Effect(EVlobCreate(new_encrypted_blob))
     del File.files[self.id]
     self.id = new_vlob['id']
     self.read_trust_seed = new_vlob['read_trust_seed']
     self.write_trust_seed = new_vlob['write_trust_seed']
     File.files[self.id] = self
     self.dirty = True
Ejemplo n.º 16
0
def perform_user_vlob_read(intent):
    msg = {}
    if intent.version is not None:
        msg['version'] = intent.version
    ret = yield Effect(BackendCmd('user_vlob_read', msg))
    status = ret['status']
    if status != 'ok':
        raise exception_from_status(status)(ret['label'])
    return UserVlobAtom(ret['version'], from_jsonb64(ret['blob']))
Ejemplo n.º 17
0
def api_group_read(msg):
    msg = cmd_READ_Schema().load(msg)
    group = yield Effect(EGroupRead(**msg))
    return {
        'status': 'ok',
        'name': group.name,
        'admins': list(group.admins),
        'users': list(group.users)
    }
Ejemplo n.º 18
0
 def load(cls, id, key, read_trust_seed, write_trust_seed, version=None):
     if id in File.files:
         return File.files[id]
     self = File()
     self.id = id
     self.read_trust_seed = read_trust_seed
     self.write_trust_seed = write_trust_seed
     self.encryptor = load_sym_key(from_jsonb64(key))
     vlob = yield Effect(EVlobRead(self.id, self.read_trust_seed, version))
     self.version = vlob['version']
     self.dirty = False
     vlob_list = yield Effect(EVlobList())
     if vlob['id'] in vlob_list:
         self.dirty = True
         self.version -= 1
     self.modifications = []
     File.files[self.id] = self
     return self