Today’s Gotcha was on of our sites was failing to upload files. The webpage has an upload button, it posts the file to an api server, which then uses a service account to push that file to the appropriate directory on Google Drive. Today, the upload feature stopped working, giving us an error that said the account was over it’s limit.
Well, this company has hundreds of terabytes of space. All the accounts share it, so that seemed unlikely. Moreover, we could drag the same file into Google Drive directly with no error. After some research, we discovered that the service account is not part of the “business”, but rather its own account …. with its own limits: 15GB.
What’s worse, you can’t just approve more. So that meant we had to do a hot-fix ASAP.
It seems there are 2 solutions:
1. You can have the service account upload the files and then transfer ownership to an account within the domain.
2. You can have the service account impersonate an account within the domain.
Both options have some gotchas. The Transfer of ownership means that you actually “are” leveraging that 15gb storage space of the service account. Now, it’s unlikely that we’ll actually have 15GB come in all at once, but if the transfer of ownership doesn’t work due to some bug or something, then that file will remain in the account. And, over time, that account will get to the point where someone will be uploading a big 1gb file and get rejected because there wasn’t enough space to put it on google before we transfered it. And, we all know that bugs happen and things break. I’d only feel comfortable if we ran some kind of regular sweep to double check.
The next option, impersonation, has it’s own issues. In reality, the biggest problem is security. You need to give the service account “Domain Wide Delegation” of authority. (https://admin.google.com/ac/owl/domainwidedelegation)
Not in the cloud console where API work is normally done, but in the admin module, you’ll see where you can add and edit the scopes of permissions for your service account. In my case, we already had email and google calendar. We needed to add “https://www.googleapis.com/auth/drive” as a scope and only after doing that would we be allowed to impersonate a user when they upload a file.
Now, when you add that service account to the Google Admin Domain Delegation page, remember, you’ll need the email and the Unique ID for that account.
Ok, so that’s out of the way. That will save you a lot of “Why the F doesn’t this work???” down the road when your code is perfect and the error makes not sense.
I’m going to cut and paste in some of our code, but I’ll clean it up a bit, so don’t count on it working
We initialize and maintain the DriveService variable like this. What we’re doing is sending the service account credentials as part of the initializer. You’ll note that we don’t “reinitialize” it after it’s been made, so the “gotcha” here is that if you want to decide to use a different user every time then you need to reinitialize it every time, because the user account impersonated is in the credential inside the service.
Obviously, before you push to production, you’d put these keys in a secure place, and use variables, but while banging this out, here’s what I clipped together. Now that the account has domain access to GoogleDrive, you can actually impersonate ANYBODY IN THE DOMAIN.
From here on out, you can follow any of 10000 how-to posts on working with google drive via service accounts, but THIS is a gotcha you need to be aware of.
What we did was to create a new account named for the application and simply impersonated that account. There is talk of impersonating the user doing the upload, so it would show their name, but there is the problem there is actually permissions. If you are building a system that is designed to ensure data is maintained in an organized fashion, but the client insists that some users should be allowed to just bumble around in google drive whenever they want, then we need to at least make it impossible for beginner users and general data-entry people to not be allowed into the drive directly. So, if they didn’t have permission to load a file to a job folder in google drive, then the service account impersonating them would fail.
good luck!