In my opinion you should go with custom web part. Your requirement is fairly simple, but the amount of work to create a custom web part that too with security trimming will surely turn this task into a Mammoth.
You can follow a simple approach.
Set unique permissions on your Doc Lib
|
|
\|/
Create a custom web part to pull folders and show files inside it
The above approach can be achieved via Client Side Object Model
using c#/JavaScript/PowerShell
Step 1: Set unique permissions on the Document Library for groups and users, by breaking role inheritance.
Refer Assigning Folder Permissions with JSOM and SharePoint Item Level Permissions using PowerShell and CSOM
Step 2: Here you create a custom web part which first retrieves all folders from your document library and display it in Tree View, While creating a tree structure we also check if current user has permissions on it or not?
Get Folders: Sample code to get all folders inside a document library, refered from Get all Folders using Javascript client object model
function GetFolders()
{
var context = new SP.ClientContext.get_current();
var web = context.get_web();
var list = web.get_lists().getByTitle('DocumentLibraryName');
var query = SP.CamlQuery.createAllFoldersQuery();
this.allItems = list.getItems(query);
context.load(allItems);
context.executeQueryAsync(Function.createDelegate(this, this.success), Function.createDelegate(this, this.failed));
}
function success()
{
var FolderNames = "";
var ListEnumerator = this.allItems.getEnumerator();
while(ListEnumerator.moveNext())
{
var currentItem = ListEnumerator.get_current();
var _contentType = currentItem.get_fileSystemObjectType();
if(currentItem.get_fileSystemObjectType() == '1')
{
FolderNames += currentItem.get_item('Title')+ '\n';
checkPermission(currentItem.get_item('ID'))
}
}
}
function failed(sender, args)
{
alert("failed. Message:" + args.get_message());
}
Check Permissions on folder: In the success function of Get Folder, you must check whether this current folder has permissions for the current logged in user. For this we call checkPermission(listItem_id)
Refer EffectiveBasePermissions for ListItems
function checkPermission( listItem_id ) {
var spList = context.get_web().get_lists().getByTitle( listTitle );
var spListItem = spList.getItemById( listItem_id );
context.load( spListItem );
context.load( spListItem , 'EffectiveBasePermissions' );
context.executeQueryAsync(
// OnSuccess
function ( sender , args ) {
var listItem_id = spListItem.get_id().toString();
var listItem_Title = spListItem.get_item('Title');
var listItem_AssignedTo_RAW = spListItem.get_item('Assigned_x0020_To');
var listItem_HasEditPerms = spListItem.get_effectiveBasePermissions().has(SP.PermissionKind.editListItems);
ShowFolderInTreeView( listItem_id , listItem_Title , listItem_HasEditPerms );
},
// OnFailure
function ( sender , args ) {
alert('request failed ' + args.get_message() + '\n' + args.get_stackTrace());
}
);
}
On Click of Folder leaf: Now once you have created a tree view of folders, then onclick of each leaf you can call a function which pulls files for that folder. Referred from Get Files from a Folder using JavaScript client object model
function ViewAllFiles()
{
var context = new SP.ClientContext.get_current();
var web = context.get_web();
var list = web.get_lists().getByTitle('Shared Documents');
var query = SP.CamlQuery.createAllItemsQuery();
query.set_folderServerRelativeUrl('/Shared%20Documents/TestFolder');
this.allItems = list.getItems(query);
context.load(allItems, 'Include(Title, ContentType, File)');
context.executeQueryAsync(Function.createDelegate(this, this.success), Function.createDelegate(this, this.failed));
}
function success()
{
var fileUrls = "";
var ListEnumerator = this.allItems.getEnumerator();
while(ListEnumerator.moveNext())
{
var currentItem = ListEnumerator.get_current();
var _contentType = currentItem.get_contentType();
if(_contentType.get_name() != "Folder")
{
var File = currentItem.get_file();
if(File != null)
{
fileUrls += File.get_serverRelativeUrl() + '\n';
}
}
}
alert(fileUrls);
}
function failed(sender, args) {
alert("failed. Message:" + args.get_message());
}