Exemplo n.º 1
0
    def on_modified(self, event):
        super(HostEventHandler, self).on_modified(event)
        # print event.event_type

        what = 'directory' if event.is_directory else 'file'
        # logging.info("Modified %s: %s", what, event.src_path)
        mylog('$$$$$$$ Modified $$$$$$$$$$ {} $$$$$$$$$$$$$$$$$$$$'.format(event.src_path), '7')
Exemplo n.º 2
0
def do_client_list_files(host_obj, connection, address, msg_obj, client,
                         cloud):
    _log = get_mylog()
    cloudname = cloud.name
    session_id = client.uuid if client is not None else None
    client_uid = client.user_id if client else PUBLIC_USER_ID

    private_data = host_obj.get_private_data(cloud)
    if private_data is None:
        msg = 'Somehow the cloud doesn\'t have a privatedata associated with it'
        err = InvalidStateMessage(msg)
        host_obj.log_client(client, 'ls', cloud, None, 'error')
        send_error_and_close(err, connection)
        return

    # todo: I believe this should be more complicated.
    # Say a person has permission to read some children of the directory,
    # but not the directory itself. ls returns ACCESS_ERROR currently.
    # Perhaps it should return the children it can access?
    # though, is this process recursive? What if I ls "/", but only have access to "/foo/bar/..."?

    rel_path = RelativePath()
    rd = rel_path.from_relative(msg_obj.fpath)
    if not rd.success:
        msg = '{} is not a valid cloud path'.format(msg_obj.fpath)
        err = InvalidStateMessage(msg)
        _log.debug(err)
        send_error_and_close(err, connection)
        host_obj.log_client(client, 'ls', cloud, rel_path, 'error')
        return

    rd = host_obj.client_access_check_or_close(connection, session_id, cloud,
                                               rel_path, READ_ACCESS)
    if rd.success:
        full_path = rel_path.to_absolute(cloud.root_directory)
        if not os.path.exists(full_path):
            resp = FileDoesNotExistErrorMessage()
            host_obj.log_client(client, 'ls', cloud, rel_path, 'error')

        elif not os.path.isdir(full_path):
            mylog(
                'Responding to ClientListFiles with error - {} is a file, not dir.'
                .format(rel_path.to_string()))
            resp = FileIsNotDirErrorMessage()
            host_obj.log_client(client, 'ls', cloud, rel_path, 'error')

        else:
            mylog('Responding successfully to ClientListFiles')
            resp = ListFilesResponseMessage(cloudname, session_id,
                                            rel_path.to_string())
            resp.stat = make_stat_dict(rel_path, private_data, cloud,
                                       client_uid)
            resp.ls = make_ls_array(rel_path, private_data, cloud, client_uid)
            host_obj.log_client(client, 'ls', cloud, rel_path, 'success')

        connection.send_obj(resp)
    else:
        # the access check will send error
        host_obj.log_client(client, 'ls', cloud, rel_path, 'error')
        pass
Exemplo n.º 3
0
    def on_moved(self, event):
        super(HostEventHandler, self).on_moved(event)
        # print event.event_type

        what = 'directory' if event.is_directory else 'file'
        # logging.info("Moved %s: from %s to %s", what, event.src_path,
        #              event.dest_path)
        mylog('$$$$$$$ MOVED $$$$$$$$$$ {} $$$$$$$$$$$$$$$$$$$$'.format(event.src_path), '7')
Exemplo n.º 4
0
def do_client_add_owner(host_obj, connection, address, msg_obj, client, cloud):
    cloudname = cloud.cname()
    session_id = client.uuid if client else None
    client_uid = client.user_id if client else PUBLIC_USER_ID
    new_owner_id = msg_obj.new_user_id
    private_data = host_obj.get_private_data(cloud)
    if private_data is None:
        msg = 'Somehow the cloud doesn\'t have a privatedata associated with it'
        err = InvalidStateMessage(msg)
        mylog(err.message, '31')
        host_obj.log_client(client, 'add-owner', cloud, None, 'error')
        send_error_and_close(err, connection)
        return

    if new_owner_id == PUBLIC_USER_ID:
        msg = 'The public can\'t be a owner of a cloud'
        err = AddOwnerFailureMessage(msg)
        mylog(err.message, '31')
        host_obj.log_client(client, 'add-owner', cloud, None, 'error')
        send_error_and_close(err, connection)
        return
    if not private_data.has_owner(client_uid):
        msg = 'User [{}] is not an owner of the cloud "{}"'.format(
            client_uid, cloudname)
        err = AddOwnerFailureMessage(msg)
        mylog(err.message, '31')
        host_obj.log_client(client, 'add-owner', cloud, None, 'error')
        send_error_and_close(err, connection)
        return
    rd = cloud.get_remote_conn()
    if rd.success:
        remote_conn = rd.data
        request = msg_obj
        # todo:24 too lazy to do now
        remote_conn.send_obj(request)
        response = remote_conn.recv_obj()
        if response.type == ADD_OWNER_SUCCESS:
            rd = Success()
        else:
            rd = Error(response.message)
    if not rd.success:
        msg = 'failed to validate the ADD_OWNER request with the remote, msg={}'.format(
            rd.data)
        err = AddOwnerFailureMessage(msg)
        mylog(err.message, '31')
        host_obj.log_client(client, 'add-owner', cloud, None, 'error')
        send_error_and_close(err, connection)
    else:
        private_data.add_owner(new_owner_id)
        private_data.commit()
        mylog('Added user [{}] to the owners of {}'.format(
            new_owner_id, cloudname))
        # todo:15
        host_obj.log_client(client, 'add-owner', cloud, None, 'success')
        response = AddOwnerSuccessMessage(session_id, new_owner_id,
                                          cloud.uname(), cloudname)
        connection.send_obj(response)
Exemplo n.º 5
0
def client_message_wrapper(
    host_obj,
    connection,
    address,
    msg_obj,
    callback  # type: (HostController, AbstractConnection, object, BaseMessage, Client, Cloud) -> ResultAndData
):
    # type: (HostController, AbstractConnection, object, BaseMessage, ...) -> None
    session_id = msg_obj.sid
    cloudname = msg_obj.cname
    cloud_uname = msg_obj.cloud_uname  # todo:15
    db = host_obj.get_db()

    rd = validate_or_get_client_session(db, session_id, cloud_uname, cloudname)
    if not rd.success:
        response = ClientAuthErrorMessage(rd.data)
        send_error_and_close(response, connection)
        return
    else:
        mylog('valid client session')
        client = rd.data
        cloud = None
        if client is None:
            # The client is the public client. Callers should be prepared to handle
            # the public client case.
            clouds = get_clouds_by_name(db, cloud_uname, cloudname)
            if len(clouds) > 0:
                cloud = clouds[0]
            else:
                err = InvalidStateMessage(
                    'Public client came for {}/{}, but was unable to find it.'.
                    format(cloud_uname, cloudname))
                mylog(err.message, '31')
                send_error_and_close(err, connection)
                return
        else:
            cloud = client.cloud
            mylog('client.cloud={}'.format(client.cloud.full_name()))
            if cloud is None:
                # todo:17 The cloud could have been deleted while a client had it
                err = InvalidStateMessage(
                    'Somehow the client object did not have '
                    'a cloud associated with it.')
                mylog(err.message, '31')
                send_error_and_close(err, connection)
                return

            # refresh the session:
            rd = cloud.get_remote_conn()
            if rd.success:
                refresh = ClientSessionRefreshMessage(session_id)
                rd.data.send_obj(refresh)
                rd.data.close()
            else:
                mylog('Failed to refresh client session.')

        return callback(host_obj, connection, address, msg_obj, client, cloud)
Exemplo n.º 6
0
def do_client_create_link(host_obj, connection, address, msg_obj, client,
                          cloud):
    _log = get_mylog()
    user_id = client.user_id if client else PUBLIC_USER_ID
    session_id = client.uuid if client else None
    rel_path = RelativePath()
    rel_path.from_relative(msg_obj.path)
    _log.debug('Creating a link to {}'.format(rel_path.to_string()))
    private_data = host_obj.get_private_data(cloud)
    if private_data is None:
        msg = 'Somehow the cloud doesn\'t have a privatedata associated with it'
        err = InvalidStateMessage(msg)
        mylog(err.message, '31')
        host_obj.log_client(client, 'link', cloud, rel_path, 'error')
        send_error_and_close(err, connection)
        return Error(msg)

    # how do we want to gate this? Owners only? or sharers only?
    rd = host_obj.client_access_check_or_close(connection, session_id, cloud,
                                               rel_path, SHARE_ACCESS)
    if not rd.success:
        # conn was closed by client_access_check_or_close
        return rd

    # We'll ask the remote to give us a link id
    remote_req = HostReserveLinkRequestMessage(cloud.uname(), cloud.cname())
    rd = cloud.get_remote_conn()
    if not rd.success:
        msg = 'Failed to connect to remote for {}: {}'.format(
            cloud.full_name(), rd.data)
        _log.error(msg)
        host_obj.log_client(client, 'link', cloud, rel_path, 'error')
        connection.send_obj(InvalidStateMessage(msg))
        connection.close()
        return Error(msg)
    remote_conn = rd.data
    _log.debug('Got remote connection')
    remote_conn.send_obj(remote_req)
    remote_resp = remote_conn.recv_obj()
    if remote_resp.type is not HOST_RESERVE_LINK_RESPONSE:
        msg = 'Remote failed to reserve link for us'
        _log.error(msg)
        host_obj.log_client(client, 'link', cloud, rel_path, 'error')
        connection.send_obj(InvalidStateMessage(msg))
        connection.close()
        return Error(msg)
    _log.debug('Got link from remote')
    link_str = remote_resp.link_string
    # Create the link in the private data
    private_data.add_link(rel_path, link_str)
    _log.debug('Committing .nebs to add link {}->{}'.format(
        link_str, rel_path.to_string()))
    private_data.commit()

    resp = ClientCreateLinkResponseMessage(link_str)
    connection.send_obj(resp)
    host_obj.log_client(client, 'link', cloud, rel_path, 'success')
Exemplo n.º 7
0
 def add_owner(self, user_id):
     if not self.has_owner(user_id):
         owners_group = self.get_group(OWNERS_ID)
         if owners_group is not None:
             owners_group.add_user(user_id)
         else:
             mylog(
                 'There is no owners group for this cloud. This is likely a programming error',
                 '31')
Exemplo n.º 8
0
def do_client_stat_files(host_obj, connection, address, msg_obj, client,
                         cloud):
    _log = get_mylog()
    cloudname = cloud.name
    session_id = client.uuid if client is not None else None
    client_uid = client.user_id if client else PUBLIC_USER_ID

    private_data = host_obj.get_private_data(cloud)
    if private_data is None:
        msg = 'Somehow the cloud doesn\'t have a privatedata associated with it'
        err = InvalidStateMessage(msg)
        host_obj.log_client(client, 'stat', cloud, None, 'error')
        send_error_and_close(err, connection)
        return Error(err)

    rel_path = RelativePath()
    rd = rel_path.from_relative(msg_obj.fpath)
    if not rd.success:
        msg = '{} is not a valid cloud path'.format(msg_obj.fpath)
        err = InvalidStateMessage(msg)
        _log.debug(err)
        send_error_and_close(err, connection)
        host_obj.log_client(client, 'stat', cloud, rel_path, 'error')
        return Error(err)

    rd = host_obj.client_access_check_or_close(connection, session_id, cloud,
                                               rel_path, READ_ACCESS)
    if rd.success:
        full_path = rel_path.to_absolute(cloud.root_directory)
        if not os.path.exists(full_path):
            resp = FileDoesNotExistErrorMessage()
            host_obj.log_client(client, 'stat', cloud, rel_path, 'error')

        # elif not os.path.isdir(full_path):
        #     mylog('Responding to ClientListFiles with error - {} is a file, not dir.'.format(rel_path.to_string()))
        #     resp = FileIsNotDirErrorMessage()
        #     host_obj.log_client(client, 'ls', cloud, rel_path, 'error')

        else:
            mylog('Responding successfully to ClientStatFile')
            resp = StatFileResponseMessage(cloudname, session_id,
                                           rel_path.to_string())
            resp.stat = make_stat_dict(rel_path, private_data, cloud,
                                       client_uid)
            # resp.ls = make_ls_array(rel_path, private_data, cloud, client_uid)
            host_obj.log_client(client, 'stat', cloud, rel_path, 'success')

        connection.send_obj(resp)
        return ResultAndData(resp.type == STAT_FILE_RESPONSE, resp)
    else:
        # the access check will send error
        host_obj.log_client(client, 'stat', cloud, rel_path, 'error')
        return rd
Exemplo n.º 9
0
 def write_backend(self, data):
     rd = ResultAndData(False, None)
     try:
         path = self._file_location()
         out_file = open(path, mode='w')
         out_file.write(data)
         out_file.close()
         # mylog('Wrote backend for [{}]"{}"'.format(
         #     self._cloud.my_id_from_remote, self._cloud.name), '32')
         rd = ResultAndData(True, None)
     except IOError, e:
         rd = ResultAndData(False, str(e))
         mylog(str(e))
Exemplo n.º 10
0
def do_client_read_link(host_obj, connection, address, msg_obj, client, cloud):
    _log = get_mylog()
    user_id = client.user_id if client else PUBLIC_USER_ID
    session_id = client.uuid if client else None
    link_str = msg_obj.link_string

    private_data = host_obj.get_private_data(cloud)
    if private_data is None:
        msg = 'Somehow the cloud doesn\'t have a privatedata associated with it'
        err = InvalidStateMessage(msg)
        mylog(err.message, '31')
        host_obj.log_client(client, 'read-link', cloud, link_str, 'error')
        send_error_and_close(err, connection)
        return Error(msg)

    # TODO: how do we handle seperate link permissions here?
    # We're just translating it straight to a normal readfile message

    rd = host_obj.client_link_access_check_or_close(connection, session_id,
                                                    cloud, link_str,
                                                    READ_ACCESS)
    if not rd.success:
        # conn was closed by client_access_check_or_close
        return

    # get the path rom the link
    rel_path = RelativePath()
    path = private_data.get_path_from_link(link_str)
    if path is None:
        msg = 'The link {} is not valid for this cloud'.format(link_str)
        err = LinkDoesNotExistMessage(msg)
        _log.error(err.message)
        host_obj.log_client(client, 'read-link', cloud, link_str, 'error')
        send_error_and_close(err, connection)
        return

    rel_path.from_relative(path)
    # construct a ReadFile message, using the path from the link
    translated = ReadFileRequestMessage(session_id, cloud.uname(),
                                        cloud.cname(), rel_path.to_string())

    return do_client_read_file(host_obj,
                               connection,
                               address,
                               translated,
                               client,
                               cloud,
                               lookup_permissions=False)
Exemplo n.º 11
0
def do_client_get_shared_paths(host_obj, connection, address, msg_obj, client,
                               cloud):
    _log = get_mylog()
    user_id = client.user_id if client else PUBLIC_USER_ID

    private_data = host_obj.get_private_data(cloud)
    if private_data is None:
        msg = 'Somehow the cloud doesn\'t have a privatedata associated with it'
        err = InvalidStateMessage(msg)
        mylog(err.message, '31')
        send_error_and_close(err, connection)
        return

    resp = ClientGetSharedPathsResponseMessage(
        private_data.get_user_permissions(user_id))
    connection.send_obj(resp)
Exemplo n.º 12
0
def do_client_set_link_permissions(host_obj, connection, address, msg_obj,
                                   client, cloud):
    _log = get_mylog()
    user_id = client.user_id if client else PUBLIC_USER_ID
    session_id = client.uuid if client else None
    link_str = msg_obj.link_string
    permissions = msg_obj.permissions

    private_data = host_obj.get_private_data(cloud)
    if private_data is None:
        msg = 'Somehow the cloud doesn\'t have a privatedata associated with it'
        err = InvalidStateMessage(msg)
        mylog(err.message, '31')
        host_obj.log_client(client, 'chmod-link', cloud,
                            RelativeLink(link_str), 'error')
        send_error_and_close(err, connection)
        return Error(msg)

    # get the path from the link
    rel_path = RelativePath()
    path = private_data.get_path_from_link(link_str)
    if path is None:
        msg = 'The link {} is not valid for this cloud'.format(link_str)
        err = LinkDoesNotExistMessage(msg)
        _log.error(err.message)
        host_obj.log_client(client, 'chmod-link', cloud,
                            RelativeLink(link_str), 'error')
        send_error_and_close(err, connection)
        return
    rel_path.from_relative(path)

    # Using the actual file, check if the client has access to share the file.
    rd = host_obj.client_access_check_or_close(connection, session_id, cloud,
                                               rel_path, SHARE_ACCESS)
    if not rd.success:
        return rd

    rd = private_data.set_link_permissions(link_str, permissions)
    if rd.success:
        private_data.commit()
    response = ClientSetLinkPermissionsSuccessMessage(
    ) if rd.success else LinkDoesNotExistMessage()
    host_obj.log_client(client, 'chmod-link', cloud, RelativeLink(link_str),
                        'success' if rd.success else 'error')
    connection.send_obj(response)
Exemplo n.º 13
0
def do_client_get_link_permissions(host_obj, connection, address, msg_obj,
                                   client, cloud):
    _log = get_mylog()
    user_id = client.user_id if client else PUBLIC_USER_ID
    session_id = client.uuid if client else None
    link_str = msg_obj.link_string

    private_data = host_obj.get_private_data(cloud)
    if private_data is None:
        msg = 'Somehow the cloud doesn\'t have a privatedata associated with it'
        err = InvalidStateMessage(msg)
        mylog(err.message, '31')
        # host_obj.log_client(client, 'chown+link', cloud, RelativeLink(link_str), 'error')
        send_error_and_close(err, connection)
        return Error(msg)

    # get the path from the link
    rel_path = RelativePath()
    path = private_data.get_path_from_link(link_str)
    if path is None:
        msg = 'The link {} is not valid for this cloud'.format(link_str)
        err = LinkDoesNotExistMessage(msg)
        _log.error(err.message)
        # host_obj.log_client(client, 'chown+link', cloud, RelativeLink(link_str), 'error')
        send_error_and_close(err, connection)
        return
    rel_path.from_relative(path)

    # TODO: Get the permissions of the backing file too, and OR them with the permissions on the link.
    rd = host_obj.client_access_check_or_close(connection, session_id, cloud,
                                               rel_path, NO_ACCESS)
    if not rd.success:
        return rd
    file_perms = rd.data
    rd = private_data.get_link_full_permissions(link_str)
    if rd.success:
        link_perms = rd.data[0]
        users = rd.data[1]
        response = ClientGetLinkPermissionsResponseMessage(
            link_perms | file_perms, users)
    else:
        response = LinkDoesNotExistMessage()
    # host_obj.log_client(client, 'chown+link', cloud, RelativeLink(link_str), 'success' if rd.success else 'error')
    connection.send_obj(response)
Exemplo n.º 14
0
    def read_json(self, json_string):
        rd = ResultAndData(False, None)
        try:
            json_obj = json.loads(json_string)
            if MAJ_VER_KEY not in json_string:
                raise ValueError

            maj_ver = json_obj[MAJ_VER_KEY]
            if maj_ver == 0:
                rd = self.read_v0(json_obj)
            else:
                message = 'Failed to decode .nebs data with invalid version ' \
                          '{}'.format(maj_ver)
                mylog(message, '31')
                rd = ResultAndData(False, message)

        except ValueError, e:
            mylog('ERROR: Failed to decode json data', '31')
            rd = ResultAndData(False, e)
Exemplo n.º 15
0
def client_link_wrapper(
    host_obj,
    connection,
    address,
    msg_obj,
    callback  # type: (HostController, AbstractConnection, object, BaseMessage, Client, Cloud) -> ResultAndData
):
    # type: (HostController, AbstractConnection, object, BaseMessage, ...) -> None
    session_id = msg_obj.sid
    link_id = msg_obj.link_string
    db = host_obj.get_db()
    _log = get_mylog()
    # Search all of the private datas for one that has the given link.
    clouds = host_obj.find_link_clouds(link_id)
    if len(clouds) < 1:
        err = '{} is not a link on this device'.format(link_id)
        _log.debug(err)
        msg = InvalidStateMessage(err)
        connection.send_obj(msg)
        connection.close()
    cloud = clouds[0]
    # validate that cloud as the one the client was prepped to find
    # TODO: this is very similar to the body of client_message_wrapper
    rd = validate_or_get_client_session(db, session_id, cloud.uname(),
                                        cloud.cname())
    if not rd.success:
        response = ClientAuthErrorMessage(rd.data)
        send_error_and_close(response, connection)
        return
    client = rd.data
    # None is the public user
    if client is not None:
        # refresh the session:
        rd = cloud.get_remote_conn()
        if rd.success:
            refresh = ClientSessionRefreshMessage(session_id)
            rd.data.send_obj(refresh)
            rd.data.close()
        else:
            mylog('Failed to refresh client session.')

    return callback(host_obj, connection, address, msg_obj, client, cloud)
Exemplo n.º 16
0
def handle_client_add_contributor(host_obj, connection, address, msg_obj):
    mylog('handle_client_add_contributor')
    return client_message_wrapper(host_obj, connection, address, msg_obj,
                                  do_client_add_contributor)
Exemplo n.º 17
0
    def add_user_permission(self, new_user_id, rel_path, new_perms):
        # type: (int, RelativePath, int) -> None
        mylog('add_user_permission')
        mylog('{}'.format(self._files))
        rel_path_str = rel_path.to_string()
        if rel_path_str in self._files:
            file_perms = self._files[rel_path_str]
        else:
            # if file_perms is None:
            mylog('Making new FilePermissions object')
            file_perms = FilePermissions(rel_path_str)
        mylog(file_perms.__dict__)

        if new_user_id == PUBLIC_USER_ID:
            file_perms.add_group(PUBLIC_ID, new_perms)
        else:
            file_perms.add_user(new_user_id, new_perms)

        mylog(file_perms.__dict__)
        self._files[rel_path_str] = file_perms
        mylog('{}'.format(self._files))
Exemplo n.º 18
0
 def watch_path(self, cloud_root):
     mylog('Watching path <{}>'.format(cloud_root))
     self.observers[cloud_root] = \
         self.observer.schedule(self.event_handler, cloud_root, recursive=True)
Exemplo n.º 19
0
def handle_client_get_permissions(host_obj, connection, address, msg_obj):
    mylog('handle_client_get_permissions')
    return client_message_wrapper(host_obj, connection, address, msg_obj,
                                  do_client_get_permissions)
Exemplo n.º 20
0
def handle_client_make_directory(host_obj, connection, address, msg_obj):
    mylog('handle_client_make_directory')
    return client_message_wrapper(host_obj, connection, address, msg_obj,
                                  do_client_make_directory)
Exemplo n.º 21
0
def do_client_add_contributor(host_obj, connection, address, msg_obj, client,
                              cloud):
    _log = get_mylog()
    cloudname = cloud.name
    session_id = client.uuid if client else None
    new_user_id = msg_obj.new_user_id
    fpath = msg_obj.fpath
    new_permissions = msg_obj.permissions

    rel_path = RelativePath()
    rd = rel_path.from_relative(fpath)
    if not rd.success:
        msg = '{} is not a valid cloud path'.format(fpath)
        err = InvalidStateMessage(msg)
        _log.debug(err)
        host_obj.log_client(client, 'share', cloud, rel_path, 'error')
        send_error_and_close(err, connection)
        return

    private_data = host_obj.get_private_data(cloud)
    if private_data is None:
        msg = 'Somehow the cloud doesn\'t have a privatedata associated with it'
        err = InvalidStateMessage(msg)
        mylog(err.message, '31')
        send_error_and_close(err, connection)
        host_obj.log_client(client, 'share', cloud, rel_path, 'error')
        return
    rd = host_obj.client_access_check_or_close(connection, session_id, cloud,
                                               rel_path, SHARE_ACCESS)
    if not rd.success:
        # conn was closed by client_access_check_or_close
        return

    perms = rd.data
    if not permissions_are_sufficient(perms, new_permissions):
        msg = 'Client doesn\'t have permission to give to other user'
        err = AddContributorFailureMessage(msg)
        mylog(err.message, '31')
        send_error_and_close(err, connection)
        host_obj.log_client(client, 'share', cloud, rel_path, 'error')
        return
    mylog('Client has sharing permission')
    rd = cloud.get_remote_conn()
    if rd.success:
        remote_conn = rd.data
        request = AddContributorMessage(cloud.my_id_from_remote, new_user_id,
                                        cloud.uname(), cloudname)
        # todo:24 too lazy to do now
        remote_conn.send_obj(request)
        response = remote_conn.recv_obj()
        if response.type == ADD_CONTRIBUTOR_SUCCESS:
            rd = Success()
        else:
            rd = Error(response.message)
    mylog('completed talking to remote, {}'.format(rd))
    if not rd.success:
        msg = 'failed to validate the ADD_ADD_CONTRIBUTOR request with the remote, msg={}'.format(
            rd.data)
        err = AddContributorFailureMessage(msg)
        mylog(err.message, '31')
        host_obj.log_client(client, 'share', cloud, rel_path, 'error')
        send_error_and_close(err, connection)
    else:
        # PrivateData will be able to handle the public_user_id
        private_data.add_user_permission(new_user_id, rel_path,
                                         new_permissions)
        private_data.commit()
        mylog('Added permission {} for user [{}] to file {}:{}'.format(
            new_permissions, new_user_id, cloudname, fpath))
        host_obj.log_client(client, 'share', cloud, rel_path, 'success')
        response = AddContributorSuccessMessage(new_user_id, cloud.uname(),
                                                cloudname)
        connection.send_obj(response)
Exemplo n.º 22
0
def do_client_read_file(host_obj,
                        connection,
                        address,
                        msg_obj,
                        client,
                        cloud,
                        lookup_permissions=True):
    db = host_obj.get_db()
    _log = get_mylog()
    client_uuid = client.uuid if client is not None else None
    # cloud = client.cloud

    cloudname = cloud.name
    requested_file = msg_obj.fpath

    rel_path = RelativePath()
    rd = rel_path.from_relative(requested_file)
    if not rd.success:
        msg = '{} is not a valid cloud path'.format(requested_file)
        err = InvalidStateMessage(msg)
        _log.debug(err)
        send_error_and_close(err, connection)
        host_obj.log_client(client, 'read', cloud, rel_path, 'error')
        return

    requesting_all = requested_file == '/'
    filepath = None
    # if the root is '/', send all of the children of the root
    if requesting_all:
        filepath = cloud.root_directory
        # todo: if they're requesting all, it's definitely a dir,
        # which is an error
    else:
        filepath = rel_path.to_absolute(cloud.root_directory)

    try:
        req_file_stat = os.stat(filepath)
    except Exception:
        err_msg = FileDoesNotExistErrorMessage()
        connection.send_obj(err_msg)
        host_obj.log_client(client, 'read', cloud, rel_path, 'error')
        # connection.close()
        return

    if lookup_permissions:
        rd = host_obj.client_access_check_or_close(connection, client_uuid,
                                                   cloud, rel_path,
                                                   READ_ACCESS)
        if not rd.success:
            host_obj.log_client(client, 'read', cloud, rel_path, 'error')
            return

    req_file_is_dir = S_ISDIR(req_file_stat.st_mode)
    if req_file_is_dir:
        err_msg = FileIsDirErrorMessage()
        connection.send_obj(err_msg)
        host_obj.log_client(client, 'read', cloud, rel_path, 'error')
        # connection.close()
    else:
        # send RFP - ReadFileResponse
        req_file_size = req_file_stat.st_size
        requested_file = open(filepath, 'rb')
        response = ReadFileResponseMessage(client_uuid, rel_path.to_string(),
                                           req_file_size)
        connection.send_obj(response)
        mylog('sent RFRp:{}, now sending file bytes'.format(
            response.serialize()))
        l = 1
        total_len = 0
        num_MB = int(math.floor(req_file_size / (1024 * 1024)))
        transfer_size = 1024 + (10 * 1024 * num_MB)
        num_transfers = 0
        # send file bytes
        while l > 0:
            new_data = requested_file.read(transfer_size)
            sent_len = connection.send_next_data(new_data)
            l = sent_len
            total_len += sent_len
            num_transfers += 1
            if (num_transfers % 127 == 1) and num_transfers >= 1:
                mylog('sent {} blobs of <{}> ({}/{}B total)'.format(
                    num_transfers, filepath, total_len, req_file_size))
                time.sleep(.1)

        mylog('(RFQ)[{}]Sent <{}> data to [{}]'.format(cloud.my_id_from_remote,
                                                       filepath, client.uuid))

        requested_file.close()
        host_obj.log_client(client, 'read', cloud, rel_path, 'success')
    mylog('[{}]bottom of handle_read_file_request(...,{})'.format(
        client.uuid, msg_obj))
Exemplo n.º 23
0
def list_files_handler(host_obj, connection, address, msg_obj):
    mylog('list_files_handler')
    return client_message_wrapper(host_obj, connection, address, msg_obj,
                                  do_client_list_files)