I want my C# console app to be able to upload files using a service account to a Google shared drive as well as download / delete these files when logging in to the Google web UI under my personal account. It is my understanding that an oauth account is not necessary and I can do this with only a service account.
Thus far, I have:
The console app can upload files and get a list of files that it uploaded but cannot see the shared folder or files that are shared to the service account email.
Google Shared Drive and permissions
This will get a Google Drive Service successfully but I think the problem may be in the impersonation / delegation.
private DriveService GetDriveService()
{
// Load the Service Account JSON key file
string rootDirectory = Environment.CurrentDirectory;
string keyFilePath = rootDirectory + "\\mykey.json";
ServiceAccountCredential? credential;
using (var stream = new FileStream(keyFilePath, FileMode.Open, FileAccess.Read))
{
credential = GoogleCredential.FromStream(stream)
.CreateScoped(DriveService.Scope.Drive)
.CreateWithUser("[email protected]") // Specifying the user to impersonate
.UnderlyingCredential as ServiceAccountCredential;
}
// Specify the scopes required
var scopes = new[] { DriveService.Scope.DriveFile };
// Create a delegated credential
if (credential == null) throw new ArgumentNullException(nameof(credential));
var delegatedCredential = new ServiceAccountCredential(new ServiceAccountCredential.Initializer(credential.Id)
{
Key = credential.Key,
Scopes = scopes
});
// Create the Drive service
var driveService = new DriveService(new BaseClientService.Initializer
{
HttpClientInitializer = delegatedCredential,
ApplicationName = "ServerTools"
});
return driveService;
}
This code will successfully get a list of files that were uploaded by the console app but they don't show up in the Web UI.
public List<string> GetFileList()
{
var request = _driveService.Files.List();
request.Fields = "nextPageToken, files(id, name)";
var files = request.Execute().Files;
return files.Select(x => x.Name).ToList();
}
This code will not return any folders even though a shared drive is created and the service account is a manager
private List<string>? GetFolders()
{
FilesResource.ListRequest listRequest = _driveService.Files.List();
listRequest.Q = "mimeType='application/vnd.google-apps.folder'";
listRequest.Fields = "nextPageToken, files(id, name)";
// List files.
IList<Google.Apis.Drive.v3.Data.File> files = listRequest.Execute().Files;
return files.Select(x => x.Name).ToList();
}
This feels like a configuration issue but I have run out of places to look. Thanks in advance!
Although I'm not sure whether I could correctly understand your question, how about the following modification? Please modify your bottom script as follows.
FilesResource.ListRequest listRequest = _driveService.Files.List();
listRequest.Q = "mimeType='application/vnd.google-apps.folder'";
listRequest.Fields = "nextPageToken, files(id, name)";
FilesResource.ListRequest listRequest = _driveService.Files.List();
listRequest.Q = "mimeType='application/vnd.google-apps.folder'";
listRequest.Fields = "nextPageToken, files(id, name)";
listRequest.Corpora = "allDrives"; // Added
listRequest.SupportsAllDrives = true; // Added
listRequest.IncludeItemsFromAllDrives = true; // Added
// listRequest.PageSize = 1000; // Add this if you want.