Boxapi: Move/copy admin files to service account - box-api

I have been using box since from a year. I manually upload files to Box. A few days back I integrated my nodejs code to Box (api's). I have created an app and set up Client Credentials Grant Authentication, which is a service account by default and I am able to upload files and folders. But I already have hundreds of files in my admin account. And instead of creating all those files again under my new service account, I want to move all those content to the service account. I read the docs about de-provision, but I am not sure if that is what I am looking for. Any suggestions on how can I do this?. Thanks in advance.

Finally, I found the solution. There are two ways(maybe more, but I found these two) to achieve this.
Transfer Owned Folders
const sourceUserID = 'exaplesourceId';
const destinationUserID = 'exampleuserId';
client.enterprise.transferUserContent(sourceUserID, destinationUserID)
.then((movedFolder) => {
resolve(movedFolder);
}).catch((error) => {
reject(error);
});
For reference: https://developer.box.com/guides/users/deprovision/transfer-folders/
The other way is to give access to the service account user to collaborate on existing content. We can do this via the API too.
Reference: https://developer.box.com/guides/users/deprovision/transfer-folders/

Related

Creating the users in the google domain (python)

I am creating an application in which I am getting a Client_secret.json file, and in my application I'm trying to load that json file and get the credentials from it using the following code:
credentials=get_credentials(filename)
http = credentials.authorize(httplib2.Http())
service = discovery.build('admin', 'directory_v1', http=http)
userinfo = {'primaryEmail': primaryEmail,
'name': { 'givenName':user },
'password': password
}
service.users().insert(body = userinfo).execute()
It gives the following error:
httpError 403 when requesting https
//www.googleapis.com/admin/directory/v1/users?alt=json returned
insufficient permission
I'm not sure what I'm doing wrong or am I missing something? I was wondering if the problem is in the json file which I'm creating?
Any help would be appreciated.
Thanks,
Aman
Well, you can start by checking a few things:
If you're using a service account, be sure to enable the "wide domain delegation option" to allow a service account to access user data on behalf of your users and perform operations.
Check if the scope https //www.googleapis.com/admin/directory/v1/users is authorized for your client ID on your google admin console > Security > Advanced settings > Authentication > Manage API client access.
Check if the user that you're using to insert the new user have enough privileges a.k.a super admin privileges.
Check if the Admin SDK API is active on your project.
Keep in mind that just downloading the client_json and activating a API isn't enough to allow these types of operations. For certain APIs like Admin SDK, the user you're gonna use to consume those services need to have specific privileges.
Here's a few helpful links
https://developers.google.com/identity/protocols/OAuth2ServiceAccount#delegatingauthority
https://support.google.com/a/answer/162106?hl=en
I would first check to make sure that you have the correct Admin privileges on the account that you are trying to use OAuth credentials on. I would try logging into the account and going to this reference page in the Directory API for Users:insert
https://developers.google.com/admin-sdk/directory/v1/reference/users/insert
On the right hand side you should go to the Try this API section and see if that account has permissions to create new users.
Also another thing I noticed as well, is that you're not setting the required field familyName inside of the name field. familyName is a required property.

Onedrive API vs LiveSDK

I am developing for WP8.1 and probably will port on other platforms.
I want to integrate a OneDrive functionality, however, I can't understand what is the difference between LiveSDK (from NuGet packages) and OneDrive API.
It seems that Microsoft does not communicate at all regarding that, I really don't understand why. As far as I understood, the LiveSDK is the old one and will be replaced by OneDrive API, but the LiveSDK seems so much simpler to use that I can't understand their logic... On top of that both have been updated recently (in April for the LiveSDK).
So my question is
As long as my app has not been published yet, should I move to
OneDrive API, or keep on the LiveSDK?
Does anyone has already
tried both?
What are the limitations and benefits of both?
Based on a future-proof sight, I will go for the OneDrive API, but my main concern is:
Is is possible to login as easily on OneDrive API than with the Live SDK? (Working temporary solution below)
For now, I have been able to login with the LiveSDK using a single button and three lines of code, no user input required at all, where the AuthenticateAndContinue method used by the OneDrive API opens a Webcontrol and requires to enter manually the login and password.
At the end I have used the LiveSDK Authentication and use the access token provided with the OneDrive API. It is not a clean approach from my point of view, but I couldn't manage to get the AuthenticateAndContinue method to work (I get a 404 error answer after the login).
If anybody has a better solution, I am opened to suggestions :)
[Solution extracted from question to get out of "unanswered" stack]
In summary, my current method is the following:
Authenticate using LiveSDK API
Use the session cookie and the OneDrive API from there
The simplified code is the following:
The method below allows to log in silently, only the first time requires a manual validation from the user allowing the program to use its Live account.
It does not require any password from the user
var authClient = new LiveAuthClient();
var authResult = await authClient.LoginAsync(new string[] {
"wl.signin", "onedrive.readwrite", "onedrive.appfolder"});
if (authResult.Session == null)
throw new InvalidOperationException("You need to sign in and give consent to the app.");
var Connection = new ODConnection("https://api.onedrive.com/v1.0",
new MicrosoftAccountAuthenticationInfo() { TokenType = "Bearer",
AccessToken = odArgs.Session.AccessToken });
It is not as clean as I would like (using 2 different SDK), but it works :)

Google Drive scope drive.file not sufficient for copying app owned files to app user's Google Drive

Participating Components:
(all in the same project)
Android App
Web App
Service Account
The users have authorized the app on their Android devices with Cross Client Identity:
oauth2:server:client_id:[web_app_id].apps.googleusercontent.com scopes ...
Flow:
Several users request the creation of the same file through the Android app ( a file for every user is not desired, see "Known workaround" )
A service account then creates that file ( service account is owner )
Service account shares that file (by link and explicit with users)
User authorized drive service / or service account that impersonates a user tries to copy that file to the user's Google Drive ( User has to be the owner of that copy in the end)
Error:
This fails with scope drive.file ( and also drive.readonly ):
Error Message:
The authenticated user has not granted the app [project_id] write access to the file [file_id]
(btw: why write access is needed with copy()? giving users write access to the file does not change this error)
Known workaround:
It works with full drive scope
( but: my app does not need to see files it has not created - so i want to avoid it)
Same result can also be achieved by re-inserting the file instead of copying it
(this overhead is important for my app though, cause same file might be requested by multiple users)
An explicit interaction with a file from a UI Picker or so will propably not work as the file will have to be created after requesting it. also i can't think of a way how to do that without decreasing usability of the Android app.
Expected result:
www.googleapis.com/auth/drive.file: Per-file access to files created or opened by the app
It seems to me this should be enough.
As the file is created/owned/shared by my app's service account.
and copied by my app on behalf of the user.
www.googleapis.com/auth/drive.readonly Allows read-only access to file metadata and file content
At least this one should work as it should give read access to all files which should be enough to copy a "shared with user" file created by an "authorized by user" app.
Question:
the Web Application and the Service Account are in the same project.
Can the Web Application act like a Service Account on behalf of a user? if so - i don't know how. Would that make a difference anyway?
This seems like a Bug to me in this special use case, as the same result can be achieved with a workaround. At least scope drive.readonly should allow my app to copy app owned files to the user's drive.
Making a copy through the plain Service Account and then changing the owner of that copy to the User would be another workaround, but that fails too.
I must be missing something simple.
Please guide me.
Thank you.
I had the same problem and resolved it using the drive.metadata in combination with the drive.file scopes. Related question

Transfer ownership for ALL files in user's google drive - using google-api-java-client and the Drive SDK

We have a google corporate account and need to transfer ALL of a user's google drive files to another account in certain instances. We want to do what is described at the following link for "all files" but programatically via the latest Drive API http://support.google.com/a/bin/answer.py?hl=en&answer=1247799
We are currently using the following API version(s) below, coupled with domain wide authority delegation as described at https://developers.google.com/drive/delegation and are able to see a user's files, iterate over them etc.
google-api-services-drive 1.14.2-beta
google-api-client 1.14.1-beta
My question is this: it appears that the only way to change permissions is by fileId by fileId etc. Instead of having to traverse and iterate over an entire set of user's files, if we just want to transfer ALL of a user's files to another particular user: is there a way in the API to do this (ownership transfer for ALL files) rather than individual requests file/by file?
Also when transferring ownershisp, must the transferee be in the same #domain or can it be another #domain we manage? I read somewhere that you can only transfer to owners in the same domain. Does this still hold true? For instance we manage #myCompany.com and have our corporate account registered under that, however that shell account has several sub-domains within it. We would like to transfer files from users in the sub-domains to a central user in the #myCompany domain.
You need to change permissions file by file, there is no updateAll type of functionality at the moment.
You cant transfer the ownership to another domain's user. Ownership can only be transferred to another user in the same domain as the current owner.
This answer doesn't directly answer your question, but it could be helpful for both you and future visitors.
As of now, you can mass transfer files to new users with Google's new Admin console. It doesn't let you filter for specific folders, but it does allow you to transfer all of one user's Drive files to a second user.
I know you were trying to create something which uses the API to iterate through folders and files, and you probably have a very specific use-case in mind. However, in the case where you have employees leaving, or you need to transfer everything, using the following method is fast and simple.
Open the Google Admin console
Go to Google Apps > Drive
Click on "Transfer ownership"
Fill out both user fields and submit
This process will even email both users once the process is completed.
You can do this with a single call to the Data Transfer API
Exactly what is needed but only with API!
Open the Google Admin console
Go to Google Apps > Drive
Click on "Transfer ownership"
Fill out both user fields and submit
This process will even email both users once the process is completed.
If this is not possible via API calls, then there is no point deleting a user using API.

about service accounts and unregistered users

I have a web app in php mysql, I want to use one google drive account for my app.
Can I use my app's accounts instead of google users for privilages.
I read in SDK I can use service account to login without promting user, but I don't know how to share or give permissions files for custom users.
In api reference I found this:
"The user is not necessarily yet a Google user (e.g. if a file or folder is shared with an email address that does not yet have an associated Google account). Example: 1111459233037698895607".
How a custom user in my app should get a token for own privilages.
I am not exactly sure what you want to achieve here, but if you want to use your own permission system, you can't. You can, however, apply read/write/owner permissions to files to mirror your own permissions.
If I have totally got the wrong idea, please explain.