How to prevent folder creation in macOS FileProviderExtension

I need to prevent folder-creation in certain scenarios. I know I can achieve that via NSFileProviderUserInteractions but that only works when folder creation attempt is done via Finder.

If however, user tries to create a folder in Terminal via mkdir folder1 then createItem callback does get called.

In createItem callback I tried two options:

Option 1

func createItem(basedOn itemTemplate: NSFileProviderItem, fields: NSFileProviderItemFields,
    contents url: URL?, options: NSFileProviderCreateItemOptions = [],
    request: NSFileProviderRequest,
    completionHandler: @escaping (NSFileProviderItem?,
                                  NSFileProviderItemFields, Bool, Error?) -> Void) -> Progress {
    
    let progress = Progress(totalUnitCount: 1)

    if itemTemplate.parentItemIdentifier == .rootContainer || itemTemplate.contentType == .aliasFile ||
               itemTemplate.contentType == .symbolicLink {
        print("Preventing item creation in root level")

        let entry = Entry(
                id: UUID().uuidString.lowercased(),
                type: itemTemplate.contentType == .folder ? Entry.Kind.folder : Entry.Kind.file,
                filename: itemTemplate.filename,
                parentId: NSFileProviderItemIdentifier.trashContainer.rawValue,
                contentType: itemTemplate.contentType!,
                size: itemTemplate.documentSize as! Int,
                creationDate: itemTemplate.creationDate!!,
                modificationDate: itemTemplate.contentModificationDate as? Date,
                lastUsedDate: itemTemplate.lastUsedDate as? Date,
                fileSystemFlags: itemTemplate.fileSystemFlags?.rawValue ?? 4,
                version: nil,
                rootContainerId: nil,
                archived: false
        )
        let item = FileProviderItem(entry: entry)

        print("Returning trashed item")
        completionHandler(item, [], false, nil)
        return progress
    }

    // other code
}

and indeed when creating folder via Finder (with NSFileProviderUserInteractions disabled), folder appears briefly and disappears immediatelly after that.

Option 2

func createItem(basedOn itemTemplate: NSFileProviderItem, fields: NSFileProviderItemFields,
    contents url: URL?, options: NSFileProviderCreateItemOptions = [],
    request: NSFileProviderRequest,
    completionHandler: @escaping (NSFileProviderItem?,
                                  NSFileProviderItemFields, Bool, Error?) -> Void) -> Progress {
    let progress = Progress(totalUnitCount: 1)

    if itemTemplate.parentItemIdentifier == .rootContainer || itemTemplate.contentType == .aliasFile ||
               itemTemplate.contentType == .symbolicLink {
        print("Preventing item creation at root level")

        let error = NSError(
                domain: NSCocoaErrorDomain,
                code: NSFeatureUnsupportedError,
                userInfo: [
                    NSLocalizedDescriptionKey: "Folder creation is not allowed."
                ]
        )

        completionHandler(nil, [], false, error)
        return progress
    }

    // other code
}

The problem is that with both options, when folder is created via Terminal, it stays created. Extension marks the folder with exclamation-mark and attempts to invoke createItem callback a few times before giving up.

My goal is to prevent folder-creation in the first place so that when user tries to create folder in Terminal, he can get an error in respond.

% mkdir folder1
error: folder creation forbidden

Is that possible to achieve with FileProviderExtension?

Replies

Maybe with the capabilities property of NSFileProviderItemProtocol ?

There is a property called allowsAddingSubItems: https://developer.apple.com/documentation/fileprovider/nsfileprovideritemcapabilities

@Stef1205 That's a great advice, but what's weird is that if I report capabilities for folder:

return [.allowsReading, .allowsAddingSubItems]

then renaming is forbidden as expected but also creating new items (ie folders) inside it is also forbidden both in Terminal and Finder. Not sure if it's a bug in FileProviderExtension.