I'm requesting authorization codes using the Google API and specify https://www.googleapis.com/auth/drive.file as the required scope since I'm going to store files on the users drives.
However, when I'm authenticating it says my application requests permission for two scopes, both
View and manage Google Drive files and folders that you have opened or created with this app
and
View metadata for files in your Google Drive
I can verify that I indeed have access to list all files on the drive.
Is the drive.metadata automatically included/required for the scope i'm requesting?
I wish to ask for as few permissions as possible.
Drive v3 scopes
https://www.googleapis.com/auth/drive View and manage the files in your Google Drive
https://www.googleapis.com/auth/drive.appdata View and manage its own configuration data in your Google Drive
https://www.googleapis.com/auth/drive.file View and manage Google Drive files and folders that you have opened or created with this app
https://www.googleapis.com/auth/drive.metadata View and manage metadata of files in your Google Drive
https://www.googleapis.com/auth/drive.metadata.readonly View metadata for files in your Google Drive
https://www.googleapis.com/auth/drive.photos.readonly View the photos, videos and albums in your Google Photos
https://www.googleapis.com/auth/drive.readonly View the files in your Google Drive
https://www.googleapis.com/auth/drive.scripts Modify your Google Apps Script scripts' behavior
You cant view metadata on a file you dont have access to see. Yes you need to be able to see them. Google is smart they know if you want to want to see the metadata your going to have to also need the ability to see the file in question. So yes you are going to need to be able to list it.
Related
I have an internal app (not a published one, only used within our Google Workspace domain) which is a command line tool to update the contents of some Google Sheets. It currently uses the https://www.googleapis.com/auth/drive scope and works fine.
I want to minimize the privileges of the authorization token that this app caches, and by reading the documentation it seems that I should be able to use the https://www.googleapis.com/auth/drive.readonly scope to find the file I want, and also https://www.googleapis.com/auth/drive.file to grant write access to only a specific file.
With the reduced scopes, I am not surprised to get an error like:
appNotAuthorizedToFile: The user has not granted the app 566375348811 write access to the file 1UsItGhBHwRaodHbv5g1LCrSESUZBkskDvKDkbGjREjI
The only relevant documentation talks about integrating apps with Google Drive and using the Drive Picker UI which I expect does this authorization behind the scenes. Since this is an internal command line tool, I really don't want to go that route.
Hence the question:
How do I open a file in a command line application using the https://www.googleapis.com/auth/drive.file scope?
I'm OK even if I need to set some magic metadata on the file to make it accessible.
Update
As I got a couple of responses saying that when using drive.file it is not possible to access files which are not created by the application, I am putting some supporting documentation here to show why I think it is possible:
The API-specific auth info is the first document on the Google Drive API page, and it specifically mentions:
So, when possible, use non-sensitive scopes as they narrow access to
specific functionality needed by an app. In most cases, providing
narrow access means using the
https://www.googleapis.com/auth/drive.file per-file access scope.
Further down the page it mentions:
This scope enables users to select the specific files from Google
Drive, and through the Google Picker, that they want to allow your app
to access.
I understand this to mean that it is possible to open files which were not created by the app, even when using drive.file.
My problem is that the document goes on to explain:
Many apps work with per-file access without any changes. If you are
currently using your own file picker, we recommend switching to the
Google Picker which fully supports the drive.file scope.
Well, since I am using a command line app, I cannot use the Google Picker, so I am asking how to implement my own. I do understand that the picker itself needs to have access to all the files (hence the need for a drive.readonly scope), but to actually be able to write the files, it needs the elevated permission of drive or the more restrictive per-file access of drive.file.
If I simulate an authorization request for drive.file I get a prompt which explains that authorizing the request will grant my app to:
See, edit, create, and delete only the specific Google Drive files you use with this app ℹ️
Clicking on the information icon I get a more verbose explanation which reads like it support opening any file I authorize:
This app wants permission to create new files or change existing files
that you open with this app. Once authorized, the app can:
See these files
Upload and download these files
Delete these files
See the names and emails of people you share these files with
Share and stop sharing these files with others
Organize these files
There may be private information in your Google Drive, like financial
records, medical reports, photos or tax info.
There are also other examples of applications like ZIP Extractor or diagrams.net or Photo Editor which use the drive.file scope (based on the authorization prompt), and which I can use to open and edit files that were not created by them.
I am posting this as an answer, to demonstrate an ugly "workaround" for the issue.
TL;DR: Use a web based frontend to authorize access to files. Once the app is authorized, the command line app inherits the permissions.
More step by step instructions, assuming we already have a working command line project:
Go to https://myaccount.google.com/permissions and revoke all access I have granted to my app.
Follow the instructions at the Drive Picker API to update my current GCP project.
Create an API key. OK to be unrestricted, but I restricted it to https://localhost:9843
Create a new OAuth 2.0 client ID of a "Web application" type (my current one is "Desktop" type and that would not work). Authorize https://localhost:9843 as a JavaScript origin.
Copy the helloworld.html example at the bottom of the Drive Picker API guide which is also on GitHub with the following modifications:
Set developerKey to the API key created above
Set clientId to the new OAuth 2.0 client ID created abovce
Set appId to the numeric project ID of my GCP project
Add 'include_granted_scopes': true to the call to window.gapi.auth.authorize
Update createPicker to make it easier to find the files I want. E.g., set the mime type filter to application/vnd.google-apps.spreadsheet.
Host the example in a browser with ruby -rwebrick/https -e 'WEBrick::HTTPServer.new(:Port => 9843, :DocumentRoot => ".", :SSLEnable => true, :SSLCertName => "CN=localhost", :SSLCertComment => "Autogenerated" ).start'
Now, if my command line app fails to edit a file, I can use https://localhost:9843/helloworld.html to grant access to the file, and my command line app can then edit that file.
If you check the docs for the scope you will find it says.
https://www.googleapis.com/auth/drive.file View and manage Google Drive files and folders that you have opened or created with this app
This gives your app access to files that the app itself created or has previously opened.
You should also know that there is no way to limit authorization to a single file. Authorization is all or not thing.
How do I open a file in a command line application using the https://www.googleapis.com/auth/drive.file scope?
You make sure that the file was created by the app itself. using files.create. If the file was created by any other app the you cant access it using the drive.file scope
There is one note though if you have https://www.googleapis.com/auth/drive.read-only scope and you open that file to read it. the line where it says opened or created with this app implies to me that once you have opended it for read in this app that you would then be able to use it with https://www.googleapis.com/auth/drive.file but its not something I have tried.
Another thing is im not sure what you mean by open the google drive api is a file storage api its not going to let you see the contents of the file your going to have to download it and open it locally. Have you considered going though the Google sheets api if you want to read and write to it programmatically?
ToS states - https://developers.google.com/drive/api/v3/terms:
"The Drive API is not allowed for certain use cases without Google’s express prior written consent, including the following:
Backup of user/app content from developer’s app to Drive."
While on Introduction to Google Drive API we read - https://developers.google.com/drive/api/v3/about-sdk:
"You can use Google Drive API to:
Create a dedicated Drive folder to store your application’s data so that the app cannot access all the user's content stored in Google Drive. See Store application-specific data."
So can I use it to store user data, which it generates while using the app and autosync it like Viber does? It could be .json files, maybe photos.
The application data folder is a special hidden folder that your app can use to store application-specific data, such as configuration files. The application data folder is automatically created when you attempt to create a file in it. Use this folder to store any files that the user shouldn't directly interact with. This folder is only accessible by your application and its contents are hidden from the user and from other Drive apps.
There's a big difference between user/app content from developer’s app and configuration file.
Our app has the ability to upload documents from google drive to our app, or to embed google docs in our app.
Currently, we are looking at using these API scopes:
google docs: https://www.googleapis.com/auth/documents.readonly
"View your Google Docs documents"
google drive: https://www.googleapis.com/auth/drive.readonly
"See and download all your Google Drive files"
However, those scopes give us read access to ALL the user's google drive files and documents. We actually only want access to the files the user selects themselves to share with us. Is there a way to only gain access to user selected files, and not all files? I basically want our scope to be more restricted than those two, both for the user's comfort and privacy, as well as limiting our app potential liability.
I see that this is this scope:
https://www.googleapis.com/auth/drive.file
"View and manage Google Drive files and folders that you have opened or created with this app"
But I only want read access, and don't need the ability to 'manage' anything on the user's drive. I also don't see a parallel for google docs.
Any information, solutions, and/or suggestions are greatly appreciated.
I have an application that needs to upload file to Google Drive via the ordinary Google Drive API. It needs to upload, but it never needs to download anything, list directories, read metadata or anything like that. It basically uses Google Drive as a drop box to store results of some computations.
Because of the principle of least authority, I would like to give this application the authorization to create new files, but not read or modify anything. Is this possible? I cannot see anything like this in this list, so I suspect the answer is no, but would like more informed comments.
By principle of least authority "user/process should have necessities/privileges". A file created by an app is owned(create/modify/delete) by app and no access to rest of resources.
If this definition fits in your scope then use
https://www.googleapis.com/auth/drive.file
"Per-file access to files created or opened by the app"
As stated in Choose Auth Scopes
Auth scopes express the permissions you request users to authorize for your app. While many Drive apps can function with just the required set of scopes, you may need to consider using other available scopes.
As far as I know, you can choose from the list of scopes available for the Drive API, combine them or mix and match if necessary. And, you can also add other scopes if your app requires access to any other Google APIs as given in Google APIs scopes.
To learn more about scopes, you can watch the video of Google engineers discussing related tips and tricks within the given documentation. I hope that helps.
I am creating an app which saves same files on dropBox, in the app folder. all the saved files uploaded by all app users should then be displayed in a table view. the result which I got is that only the user's files are shown, but I would like the data do be synchronized among all app users. I posted a question of this kind on dropbox developer forum and this was the answer:
"The Dropbox API is built to sync files within each specific authorized account, not between all authorized accounts.
If you do need to copy files between accounts, check out the new /copy_ref call:
https://www.dropbox.com/developers/reference/api#copy_ref"
...
"This really depends on the structure/use of your app. If it's just an iOS app, with no server side component, you'll need to build some way for users to send the copy references to each other."
I so tried to understand what the copy ref was, but It isn't very clear. do they mean that I need to build a server like mySql to do this, or can I integrate the ability to share all the data in the app itself??