Пример #1
0
def browse():
    from_path = request.args.get('path', '')
    if from_path == '':
        from_path = os.path.sep

    # #2475 Default this in case of error in get_directory_listing()
    directory_info = DirectoryInfo(from_path)

    db_session = data_engine.db_get_session()
    db_committed = False
    try:
        directory_info = get_directory_listing(from_path, True)

        # Auto-populate the folders database
        db_folder = auto_sync_folder(
            from_path,
            data_engine,
            task_engine,
            _db_session=db_session
        )
        db_session.commit()
        db_committed = True

        if db_folder is not None:
            # Require view permission or file admin
            permissions_engine.ensure_folder_permitted(
                db_folder,
                FolderPermission.ACCESS_VIEW,
                get_session_user()
            )

        # Remember last path for the Browse and Upload menus
        if directory_info.exists() and db_folder:
            session['last_browse_path'] = from_path

        return render_template(
            'list.html',
            formats=image_engine.get_image_formats(),
            pathsep=os.path.sep,
            timezone=get_timezone_code(),
            directory_info=directory_info,
            folder_name=filepath_filename(from_path),
            db_info=db_folder,
            db_parent_info=db_folder.parent if db_folder else None,
            STATUS_ACTIVE=Folder.STATUS_ACTIVE
        )
    except Exception as e:
        log_security_error(e, request)
        if app.config['DEBUG']:
            raise
        return render_template(
            'list.html',
            directory_info=directory_info,
            err_msg='This folder cannot be viewed: ' + str(e)
        )
    finally:
        try:
            if not db_committed:
                db_session.rollback()
        finally:
            db_session.close()
Пример #2
0
def folder_browse():
    from_path = request.args.get('path', '')
    show_files = request.args.get('show_files', '')
    embed = request.args.get('embed', '')
    msg = request.args.get('msg', '')
    if from_path == '':
        from_path = os.path.sep

    db_session = data_engine.db_get_session()
    db_committed = False
    try:
        # This also checks for path existence
        folder_list = get_directory_listing(from_path, True)

        # Auto-populate the folders database
        db_folder = auto_sync_folder(
            from_path,
            data_engine,
            task_engine,
            _db_session=db_session
        )
        db_session.commit()
        db_committed = True

        # Should never happen
        if db_folder is None:
            raise DoesNotExistError(from_path)

        # Require view permission or file admin
        permissions_engine.ensure_folder_permitted(
            db_folder,
            FolderPermission.ACCESS_VIEW,
            get_session_user()
        )

        return render_template(
            'folder_list.html',
            formats=image_engine.get_image_formats(),
            embed=embed,
            msg=msg,
            name=filepath_filename(from_path),
            path=from_path,
            pathsep=os.path.sep,
            parent_path=filepath_parent(from_path),
            folder_list=folder_list,
            show_files=show_files,
            db_info=db_folder,
            db_parent_info=db_folder.parent,
            STATUS_ACTIVE=Folder.STATUS_ACTIVE
        )
    except Exception as e:
        log_security_error(e, request)
        if app.config['DEBUG']:
            raise
        return render_template(
            'folder_list.html',
            embed=embed,
            msg=msg,
            name=filepath_filename(from_path),
            path=from_path,
            err_msg='This folder cannot be viewed: ' + str(e)
        )
    finally:
        try:
            if not db_committed:
                db_session.rollback()
        finally:
            db_session.close()
Пример #3
0
    def calculate_folder_permissions(self, folder, user=None, folder_must_exist=True):
        """
        Returns an integer indicating the highest access level that is permitted
        for a folder, based on all a user's groups. This value will be returned
        from cache if possible.

        The folder parameter can be either a Folder object or a folder path.
        If user is None, the anonymous user's permissions are checked, using
        the Public group.
        If folder_must_exist is False, the folder parameter can be a path that
        does not yet exist (access will be calculated for the nearest existing
        path).

        Raises a ValueError if folder is None.
        Raises a DoesNotExistError if folder_must_exist is True but the folder
        is an invalid path, or if a user is provided but is not a valid user.
        """
        if folder is None:
            raise ValueError('Empty folder provided for permissions checking')

        folder_path = self._normalize_path(
            folder.path if hasattr(folder, 'path') else folder
        )

        # Periodically ensure our data is up to date
        self._check_data_version()
        # Note this now in case another thread changes it mid-flow further on
        current_version = self._fp_data_version

        # Try the cache first
        if user is None:
            cache_val = self._public_fp_cache.get(folder_path)
        else:
            cache_val = self._cache.raw_get(
                self._get_cache_key(user, folder_path),
                integrity_check=True
            )
        # Cache entries are (value, version)
        if cache_val and cache_val[1] == current_version:
            return cache_val[0]

        #     We need to (re)calculate the folder access
        # !!! Also update _trace_folder_permissions() if changing this !!!
        db_session = self._db.db_get_session()
        db_commit = False
        try:
            # Get the folder and public group objects
            db_folder = db_session.merge(folder, load=False) if hasattr(folder, 'path') else \
                        auto_sync_folder(folder, self._db, self._tasks, _db_session=db_session)
            db_public_group = self._db.get_group(
                group_id=Group.ID_PUBLIC,
                load_users=False,
                _db_session=db_session
            )
            # Handle non-existent folder
            if db_folder is None and not folder_must_exist:
                db_folder = _get_nearest_parent_folder(folder_path, self._db, db_session)
            # Hopefully won't need these
            if db_folder is None:
                raise DoesNotExistError(folder_path)
            if db_public_group is None:
                raise DoesNotExistError('Public group')

            # Get the Public group access
            public_permission = self._db.get_nearest_folder_permission(
                db_folder,
                db_public_group,
                _db_session=db_session
            )
            if public_permission is None:
                # Hopefully never get here
                self._logger.error('No root folder permission found for the Public group')
                public_permission = FolderPermission(
                    db_folder, db_public_group, FolderPermission.ACCESS_NONE
                )

            if user is None:
                # Debug log only
                if self._settings['DEBUG']:
                    self._logger.debug(
                        'Public access to folder ' + folder_path +
                        ' is ' + str(public_permission)
                    )
                # Add result to cache and return it
                self._public_fp_cache.set(
                    folder_path,
                    (public_permission.access, current_version)
                )
                db_commit = True
                return public_permission.access
            else:
                db_user = user if self._db.attr_is_loaded(user, 'groups') else \
                          self._db.get_user(user.id, load_groups=True, _db_session=db_session)
                # Hopefully won't need this
                if db_user is None:
                    raise DoesNotExistError('User %d' % user.id)

                # Look at access for each of the user's groups
                final_access = FolderPermission.ACCESS_NONE
                for db_user_group in db_user.groups:
                    g_permission = self._db.get_nearest_folder_permission(
                        db_folder,
                        db_user_group,
                        _db_session=db_session
                    )
                    # The final access = the highest level from all the groups
                    if g_permission is not None and g_permission.access > final_access:
                        final_access = g_permission.access
                        # Fast path
                        if final_access == FolderPermission.ACCESS_ALL:
                            break
                # Use the public group access as a fallback
                if public_permission.access > final_access:
                    final_access = public_permission.access
                # Debug log only
                if self._settings['DEBUG']:
                    self._logger.debug(
                        str(user) + '\'s access to folder ' + folder_path +
                        ' is ' + str(final_access)
                    )
                # Add result to cache and return it
                self._cache.raw_put(
                    self._get_cache_key(user, folder_path),
                    (final_access, current_version),
                    PermissionsManager.USER_PERMISSIONS_TIMEOUT,
                    integrity_check=True
                )
                db_commit = True
                return final_access

        finally:
            try:
                if db_commit:
                    db_session.commit()
                else:
                    db_session.rollback()
            finally:
                db_session.close()