I have created a little upload UI which I include in a Google Sites page. It let's a user upload a document. Since the script is published it runs under my account and the uploaded file is uploaded to my google drive. I can from apps script add the person that uploaded the file as an editor, but what I would like to do is make them the owner of a file. (from apps script you can do a .getOwner() on a file... but not a .setOwner() ..... does anyone know a workaround?
Unfortunately changing the owner of a file isn't supported in Apps Script. Issue 74 is a feature request to add this ability, and if you star the issue you'll show your support for the feature and get notified of updates.
------EDITED------
Now there is a handy method called setOwner, which can be found here: https://developers.google.com/apps-script/reference/drive/file#setOwner(User)
There's also the possibility to pass the new owner's email address instead of the User object, which is even more handy in some cases: https://developers.google.com/apps-script/reference/drive/file#setOwner(String)
Updated 12 Sep 2016:
This code uses a service account that's been granted Google Apps Domain-Wide Delegation of Authority. This lets you change the owner of any file owned by any user on the domain. This code uses the Google apps-script-oauth2 library by Eric Koleda.
var PRIVATE_KEY = PropertiesService.getScriptProperties().getProperty('PRIVATE_KEY');
var CLIENT_EMAIL = PropertiesService.getScriptProperties().getProperty('CLIENT_EMAIL');
/**
* Transfers ownership of a file or folder to another account on the domain.
*
* @param {String} fileId The id of the file or folder
* @param {String} ownerEmail The email address of the new owner.
*/
function transferOwnership(fileId, ownerEmail) {
var file = DriveApp.getFileById(fileId);
var currentOwnerEmail = file.getOwner().getEmail(); //the user that we need to impersonate
var service = getService(currentOwnerEmail);
if (service.hasAccess()) {
var url = 'https://www.googleapis.com/drive/v2/files/' + fileId + '/permissions';
var payload = {value: ownerEmail,
type: 'user',
role: 'owner'};
var options = {method: "post",
contentType: "application/json",
headers : {
Authorization: 'Bearer ' + service.getAccessToken()
},
payload: JSON.stringify(payload)//,
,muteHttpExceptions: true
};
//debugger;
//throw 'test my errors';
var response = UrlFetchApp.fetch(url, options);
if (response.getResponseCode() === 200 ||
(response.getResponseCode() === 400 && response.getContentText().indexOf('were successfully shared'))
) {
return response.getContentText();
}
if (response.getResponseCode() === 401 && response.getContentText().indexOf('Invalid Credentials')) {
throw 'Unable to transfer ownership from owner ' + currentOwnerEmail + ' ... ' +
'Please make sure the file\'s owner has a Google Apps license (and not a Google Apps Vault - Former Employee license) and try again.';
}
throw response.getContentText();
} else {
throw service.getLastError();
}
}
/**
* Reset the authorization state, so that it can be re-tested.
*/
function reset() {
var service = getService();
service.reset();
}
/**
* Configures the service.
*/
function getService(userEmail) {
return OAuth2.createService('GoogleDrive:' + userEmail)
// Set the endpoint URL.
.setTokenUrl('https://accounts.google.com/o/oauth2/token')
// Set the private key and issuer.
.setPrivateKey(PRIVATE_KEY)
.setIssuer(CLIENT_EMAIL)
// Set the name of the user to impersonate. This will only work for
// Google Apps for Work/EDU accounts whose admin has setup domain-wide
// delegation:
// https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority
.setSubject(userEmail)
// Set the property store where authorized tokens should be persisted.
.setPropertyStore(PropertiesService.getScriptProperties())
// Set the scope. This must match one of the scopes configured during the
// setup of domain-wide delegation.
.setScope('https://www.googleapis.com/auth/drive');
}
Old answer (obsolete now as the Document List API is deprecated):
You can achieve this in Google Apps Script by accessing the Document List API using the raw atom xml protocol. You need to be a super admin of the domain. Here's an example that works for me:
/**
* Change Owner of a file or folder
* Run this as admin and authorise first in the script editor.
*/
function changeOwner(newOwnerEmail, fileOrFolderId){
var file = DocsList.getFileById(fileOrFolderId);
var oldOwnerEmail = file.getOwner().getEmail();
if (oldOwnerEmail === newOwnerEmail) {
return;
}
file.removeEditor(newOwnerEmail);
var base = 'https://docs.google.com/feeds/';
var fetchArgs = googleOAuth_('docs', base);
fetchArgs.method = 'POST';
var rawXml = "<entry xmlns='http://www.w3.org/2005/Atom' xmlns:gAcl='http://schemas.google.com/acl/2007'>"
+"<category scheme='http://schemas.google.com/g/2005#kind' "
+"term='http://schemas.google.com/acl/2007#accessRule'/>"
+"<gAcl:role value='owner'/>"
+"<gAcl:scope type='user' value='"+newOwnerEmail+"'/>"
+"</entry>";
fetchArgs.payload = rawXml;
fetchArgs.contentType = 'application/atom+xml';
var url = base + encodeURIComponent(oldOwnerEmail) + '/private/full/'+fileOrFolderId+'/acl?v=3&alt=json';
var content = UrlFetchApp.fetch(url, fetchArgs).getContentText();
}
//Google oAuth
function googleOAuth_(name,scope) {
var oAuthConfig = UrlFetchApp.addOAuthService(name);
oAuthConfig.setRequestTokenUrl("https://www.google.com/accounts/OAuthGetRequestToken?scope="+scope);
oAuthConfig.setAuthorizationUrl("https://www.google.com/accounts/OAuthAuthorizeToken");
oAuthConfig.setAccessTokenUrl("https://www.google.com/accounts/OAuthGetAccessToken");
oAuthConfig.setConsumerKey("anonymous");
oAuthConfig.setConsumerSecret("anonymous");
return {oAuthServiceName:name, oAuthUseToken:"always"};
}
Try this out! (at least it worked for me)
var newFolder = DriveApp.createFolder(folderName).addEditor(ownerEmail).setOwner(ownerEmail).addEditor(group.getEmail()).removeEditor(Session.getActiveUser().getEmail());
The above creates a folder and adds a new editor, sets the new editor to be the owner, adds another group to the editors and finally removes the user who has just created the folder from the editors.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With