Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Write permission is required to read SharePoint folders #1583

Closed
1 task done
ianleeder opened this issue Nov 27, 2024 · 4 comments
Closed
1 task done

Write permission is required to read SharePoint folders #1583

ianleeder opened this issue Nov 27, 2024 · 4 comments

Comments

@ianleeder
Copy link

Category

  • Bug

Describe the bug

I'm not sure if this will be a PnP bug, or a SharePoint API. But if I attempt to list folders using an App Registration that only has permission Sites.Read.All I get the following 403 error:

2024-11-27 14:22:01.5375|Error|SharePoint.SharePointServiceLayer.Test|Unhandled exception! |HttpResponseCode: 403
Code: System.UnauthorizedAccessException
Message: Access denied.
ClientRequestId: 0bdd67a1-4050-4000-307d-ec5f4dbc24ae
SPClientServiceRequestDuration: 15
X-SharePointHealthScore: 1
X-SP-SERVERSTATE: ReadOnly=0

PnP.Core.SharePointRestServiceException: SharePoint Rest service exception
   at PnP.Core.Services.BatchClient.ExecuteSharePointRestInteractiveAsync(Batch batch)
   at PnP.Core.Services.BatchClient.ExecuteSharePointRestBatchAsync(Batch batch)
   at PnP.Core.Services.BatchClient.ExecuteBatch(Batch batch)
   at PnP.Core.Services.PnPContext.ExecuteAsync(Boolean throwOnError)
   at PnP.Core.QueryModel.DataModelQueryService`1.ExecuteQueryAsync(Type expressionType, ODataQuery`1 query, CancellationToken token)
   at PnP.Core.QueryModel.BaseQueryProvider.GetAsyncEnumerable[TResult](Expression expression, CancellationToken token)+MoveNext()
   at PnP.Core.QueryModel.BaseQueryProvider.GetAsyncEnumerable[TResult](Expression expression, CancellationToken token)+System.Threading.Tasks.Sources.IValueTaskSource<System.Boolean>.GetResult()
   at PnP.Core.QueryModel.QueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
   at PnP.Core.QueryModel.QueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)
   at SharePoint.SharePointServiceLayer.ListFiles() in /workspace/src/SharePoint/SharePointServiceLayer.cs:line 60
   at SharePoint.SharePointServiceLayer.Test() in /workspace/src/SharePoint/SharePointServiceLayer.cs:line 22

Reading lists with read-only works fine, and reading folders with read-write works.

Sites.Read.All Sites.ReadWrite.All
var lists = await context.Web.Lists.ToListAsync();
var folders = await context.Web.Folders.ToListAsync();

Steps to reproduce

  1. Use a certificate to authenticate to an App Registration
  2. Grant the App Registration the SharePoint permission Sites.Read.All
  3. Run the following code snippet:
    var folders = await context.Web.Folders.ToListAsync();

Expected behavior

Given that I am only reading folders from SharePoint, I expect to be able to do this with read-only permission. If this is not possible for some technical reason, I expect that it is clearly and boldly indicated in the documentation, and in the exception.

Environment details (development & target environment)

  • SDK version: 1.14.0
  • OS: Docker devcontainer mcr.microsoft.com/devcontainers/dotnet:8.0 based on Debian 12.7
  • SDK used in: Class library accessed by a Console App.
  • Framework: .NET Core 8.0.403
  • Browser(s): N/A
  • Tooling: VS Code
  • Additional details: N/A
@ianleeder
Copy link
Author

ianleeder commented Nov 27, 2024

I'm still trying to wrap my head around the SDK and the models, and I may have misunderstood Folders. But I still don't think I should be getting a 403 when reading with read-only access.

@maximkol
Copy link

@ianleeder It is not an issue with the PnP Core SDK. That's how the SharePoint works, I believe. Web.Folders contains a lot of system folders, which seem to be unavailable with just Read access level.

I would say it's quite an unusual use case to load Web.Folders. If you could explain what you are trying to achieve, I might be able to help you move in the right direction. Maybe you want to get all folders in a specific library, or all libraries?

@ianleeder
Copy link
Author

ianleeder commented Jan 27, 2025

Correct @maximkol, I was attempting to look for a specific folder that existed in a library. I've since worked out that I need to load lists, then get the folders in the list. My code is working now.

It was unclear for someone new to the SDK that Web.Folders is not the correct way to load library folders. Apparently libraries are "lists", so you need to load a list first, then iterate the list folders. Honestly I'm still not clear on what Web.Folders is, but my code is working so I've moved on to a new project.

I still think there should be some sort of documentation to indicate better that library folders are not folders, and that you require write access to read folders.

@pschaeflein
Copy link

Unless you have specific requirements for the SPFolder object, you will likely find all you need in the Microsoft Graph API:
https://learn.microsoft.com/en-us/graph/api/resources/onedrive?view=graph-rest-1.0

The behavior of Graph (and its URL segmenting) might align better with you understanding. (And, folders can be read using a Read permissions).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants