Search code examples
c#google-apigoogle-drive-apigoogle-api-dotnet-client

How do you create a Google API App that uses the drive.file to access only specifically requested files?


I'm writing a C# Desktop app that as part of its job is to add/edit cells in a pre-existing Google Sheet that user has created and supplies the URL of. During development I've used the far more open Sheets.Files and Drive.Files scopes that allow read/write access to everything everywhere.

I am now trying to use the Drive.File scope to restrict the apps access to only the specific Sheet file we will be interacting with. However I am seriously struggling to understand how to, as part of the auth flow, ask the user for access to write to the file.

Previously I was auth'ing with:

        public async Task AuthGoogleSheets(CancellationToken cancellationToken)
        {
            using (var stream = new FileStream(CredentialsFilePath, FileMode.Open, FileAccess.Read))
            {
                _googleCreds = await GoogleWebAuthorizationBroker.AuthorizeAsync(
                    GoogleClientSecrets.FromStream(stream).Secrets,
                    new[] { SheetsService.Scope.Spreadsheets },
                    "user",
                    cancellationToken,
                    new FileDataStore(AuthTokenFilePath));

                await _googleCreds.RefreshTokenAsync(cancellationToken);
            }

            // Create Google Sheets service.
            sheetsService = new SheetsService(new BaseClientService.Initializer()
            {
                HttpClientInitializer = _googleCreds,
                ApplicationName = "myappname",
            });
        }

I had hoped simply adding a LoginHint with the sheet URL would do the job but it hasn't helped. Do I need to use DriveService to send a permission request email? That doesn't sound right to me.


Solution

  • If you check the docs. Drive scopes

    enter image description here

    The Drive.File scope gives you access to files that where created by your application only. For your app to have created it you must have used file.create and used an access token that was created by the client id you have for your app, directly into the users drive account.

    All other scopes give you access to the users full drive account. For example drive.readonly will for example give you full read only access to all of the files on the users google drive account.

    There is no way to limit it without using Drive.File.

    You could use a service account and ask the user to share a folder on their drive account with the service account. This can work but it depends upon your user base, and it will then be up to you to ensure that you know "which" user the folder belongs to. Doing this can lead to confusion and sharing data with the wrong user if your not careful but it depends on your use case.