Google Drive API service account - file sharing within domain - google-api

I am trying to manage file sharing permission within certain domain using a service account.
Here is the process:
Authorize thru a service account
Create a folder using service account
Upload all the files under the folder
Insert the permission on the folder with
user_permission = {
'value': issuer_email, (ex. user#company.com)
'type': 'user',
'role': 'writer'
}
drive_service.permissions().insert(fileId=f_id, body=user_permission, fields="id").execute()
domain_permission = {
'type': 'domain',
'role': 'writer',
'domain': 'company.com'
}
drive_service.permissions().insert(fileId=f_id, body=domain_permission, fields="id").execute()
For the first 3 steps it goes well. But I am not getting the error for the step (4):
<HttpError 400 when requesting https://www.googleapis.com/drive/v2/files/1RqQUiSKP05ELbPX18YpcoqTGTG_RD2j4/permissions?fields=id&alt=json returned "Permission value field required">
I tried resolving this error by adding different fields but no luck. Also its generating the file and folder I wanted, but the folders and files can be share outside the company domain. (with the share button enable there and I can access it from other domain.)
So how can I limit the file sharing within the domain? Like in the Google Drive UI prompt for sharing, if I choose any email address which is not qualified, it should not be able to share.
Thanks!!! If I am not even on the right track, please kindly give me some pointer for how to do this.
UPDATES
To be more specific, I would want to achieve this:
With the second input field, though I can share files with ppl outside the domain, but ppl would need to ask for permission to access it.
For not its not asking for permission.

Looks like you have some extra code with your value that is probably causing your issue. Try checking the documented example
file_id = '1sTWaJ_j7PkjzaBWtNc3IzovK5hQf21FbOw9yLeeLPNQ'
def callback(request_id, response, exception):
if exception:
# Handle error
print exception
else:
print "Permission Id: %s" % response.get('id')
batch = drive_service.new_batch_http_request(callback=callback)
user_permission = {
'type': 'user',
'role': 'writer',
'value': 'user#example.com'
}
batch.add(drive_service.permissions().insert(
fileId=file_id,
body=user_permission,
fields='id',
))
domain_permission = {
'type': 'domain',
'role': 'reader',
'value': 'example.com'
}
batch.add(drive_service.permissions().insert(
fileId=file_id,
body=domain_permission,
fields='id',
))
batch.execute()
Code ripped from the documentation for Drive v2 manage sharing

If you use a service account to upload and share files, you should make sure that "sendNotificationEmails" is set to False to avoid "You cannot share this item because it has been flagged as inappropriate." The reason is that the api is trying to avid spamming with emails users that potentially has nothing to do with your shared-file.

Related

Delete a contract using using delete_account method from class ContractPromiseBatch near-sdk-core

TLDR:
What is the correct way to do a cross-contract call from parent account sub.myacc.testnet to delete a sub-account one.sub.myacc.testnet using delete_account on ContractPromiseBatch from near-sdk-core without getting permission error
Full Explanation:
From the command line I make sure I am logged in:
near login account myacc.testnet
I created the following subaccount to where I deploy the factory contract:
near create-account sub.myacc.testnet --masterAccount myacc.testnet
I then deploy my factory contract using:
near deploy
Using near-sdk-core, this factory contract has a function that creates, deploys a contract and adds a full_access_key using ContractPromiseBatch
Like this:
ContractPromiseBatch
.create("one.sub.myacc.testnet")
.create_account()
.transfer(u128.from(100))
.add_full_access_key(base58.decode(context.senderPublicKey))
.deploy_contract(code)
I then make sure all accounts have the right keys with near keys <accountId>
near keys sub.myacc.testnet
[
{
access_key: { nonce: 84008729000009, permission: 'FullAccess' },
public_key: 'ed25519:gu5xxxxxxxxxxxx'
}
]
near keys one.sub.myacc.testnet
[
{
access_key: { nonce: 84009033000000, permission: 'FullAccess' },
public_key: 'ed25519:gu5xxxxxxxxxxxx'
}
]
Both keys match.
I then add the key to our main account to make sure all accounts have same access:
near add-key myacc.testnet gu5xxxxxx
If I attempt to delete the contract one.sub.myacc.testnet with the following command:
near delete one.sub.myacc.testnet <beneficiary>
I get the following error:
Unable to find [ testnet ] credentials for [ one.sub.myacc.testnet ]...
If I check ~/.near-credentials/testnet
I see that I do indeed have myacc.testnet.json file with the key we added but I don't see either sub.myacc.testnet.json or one.sub.myacc.testnet.json
So I manually added:
one.sub.myacc.testnet.json and copy the key
This will work:
Deleting account. Account id: one.sub.myacc.testnet
Error:
Now, I have a function in the factory contract where I try to use delete_account method and sign it with either sub.myacc.testnet, one.sub.myacc.testnet, or myacc.testent
ContractPromiseBatch.create(one.sub.myacc.testent)
.delete_account(one.sub.myacc.testent)
I get the following error:
Error: Actor sub.myacc.testent doesn't have permission to account one.sub.myacc.testnet to complete the action
From the docs:
Subaccounts work exactly like standalone accounts, meaning that after creation, the parent account no longer has any special control or access to the subaccount.
I would think that the parent account could control the subaccount if it has the full access key? If so, I am missing a step or a way to call ContractPromiseBatch with the correct full_access_key but can't find an example of how this should be done.
Thanks in advance,
Error: Actor sub.myacc.testent doesn't have permission to account one.sub.myacc.testnet to complete the action
Hey, I hope this is just bad redaction, but if that's not the case, maybe your problem is testent instead of testnet.
Accounts have no power over their sub-accounts. In practice, they work as completely different and independent accounts, the only benefit of sub-accounts is that they allow you to better organize your accounts.
With that being said, the sub account is the only one that can delete itself. However, you could add a method to your subaccount that only the parent account can call that makes the subaccount delete itself (reference).

Zapier CLI Trigger - How to use defined sample data when no results returned during setup

I am trying to prototype a trigger using the Zapier CLI and I am running to an issue with the 'Pull In Samples' section when setting up the trigger in the UI.
This tries to pull in a live sample of data to use, however the documentation states that if no results are returned it will use the sample data that is configured for the trigger.
In most cases there will be no live data and so ideally would actually prefer the sample data to be used in the first instance, however my trigger does not seem to ever use the sample and I have not been able to find a concrete example of a 'no results' response.
The API I am using returns XML so I am manipulating the result into JSON which works fine if there is data.
If there are no results so far I have tried returning '[]', but that just hangs and if I check the zapier http logs it's looping http requests until I cancel the sample check.
Returning '[{}]' returns an error that I need an 'id' field.
The definition I am using is:
module.exports = {
key: 'getsmsinbound',
noun: 'GetSMSInbound',
display: {
label: 'Get Inbound SMS',
description: 'Check for inbound SMS'
},
operation: {
inputFields: [
{ key: 'number', required: true, type: 'string', helpText: 'Enter the inbound number' },
{ key: 'keyword', required: false, type: 'string', helpText: 'Optional if you have configured a keyword and you wish to check for specific keyword messages.' },
],
perform: getsmsinbound,
sample: {
id: 1,
originator: '+447980123456',
destination: '+447781484146',
keyword: '',
date: '2009-07-08',
time: '10:38:55',
body: 'hello world',
network: 'Orange'
}
}
};
I'm hoping it's something obvious as on scouring the web and Zapier documentation I've not had any luck!
Sample data must be provided from your app and the sample payload is not used for this poll specifically. From the docs:
Sample results will NOT be used for a user's Zap testing step. That
step requires data to be received by an event or returned from a
polling URL. If a user chooses to "Skip Test", then the sample result,
if provided, will be used.
Personally, I have never seen "Skip Test" show up. A while back I asked support about this:
That's a great question! It's definitely one of those "chicken and
egg" situations when using REST Hooks - if there isn't a sample
available, then everything just stalls.
When the Zap editor tries to obtain a "sample result", there are three
places where it's going to look:
The Polling endpoint (in Step #3 of your trigger's setup) is invoked for the current user. If that returns "nothing", then the Zap
editor will try the next step.
The "most recent record/data" in the Zap's history. Since this is a brand new Zap, there won't be anything present.
The Sample result (in Step #4 of your trigger's setup). The Zap editor will tell the user that there's "nothing to show", and will
give the user the option to "skip test and continue", which will use
the sample JSON that you've provided here.
In reality, it will just continue to retry the request over and over and never provide the user with a "skip test and continue" option. I just emailed again asking if anything has changed since then, but it looks like existing sample data is a requirement.
Perhaps create a record in your API by default and hide it from normal use and just send back that one?
Or send back dummy data even though Zapier says not to. Not sure, but I don't know how people can set up a zap when no data has been created yet (and Zapier says not many of their apps have this issue, but nearly every trigger I've created and ever use case for other applications would hint to me otherwise).

Entity not Found Error in Google Classroom when creating assignment with STUDENT_COPY material

I'm programmatically submitting a Google Classroom assignment, and I'm seeing different behavior when attach a Material using the STUDENT_COPY shareMode than when I use the VIEW shareMode.
The following code seems to be working fine:
var resource = {
title: name,
description: explanation,
workType: 'ASSIGNMENT',
state: 'PUBLISHED'
};
resource.materials = [];
resource.materials.push({
driveFile: {
driveFile: {
id: 'fileId'
},
shareMode: 'VIEW'
}
});
var params = {auth: creds, courseId: courseId, resource: resource};
classroom.courses.courseWork.create(params, function (err, courseWorkResponse) {
/* handle response */
}
With that code, the assignment gets created and I can see it in Google Classroom. However, if I set the shareMode to STUDENT_COPY instead of VIEW, I get the following error:
{ Error: Requested entity was not found.
at Request._callback (/Users/.../node_modules/googleapis/node_modules/google-auth-library/lib/transporters.js:85:15)
at Request.self.callback (/Users/.../node_modules/googleapis/node_modules/request/request.js:188:22)
at emitTwo (events.js:106:13)
at Request.emit (events.js:191:7)
at Request.<anonymous> (/Users.../node_modules/googleapis/node_modules/request/request.js:1171:10)
at emitOne (events.js:96:13)
at Request.emit (events.js:188:7)
at IncomingMessage.<anonymous> (/Users/.../node_modules/googleapis/node_modules/request/request.js:1091:12)
at IncomingMessage.g (events.js:292:16)
at emitNone (events.js:91:20)
code: 404,
errors:
[ { message: 'Requested entity was not found.',
domain: 'global',
reason: 'notFound' } ] }
The assignment is not being created in Google Classrom. However, I am seeing a [Template] copy of the Google Doc I specified in the driveFile.id being placed into my Google Drive.
I've tried this with several different documents, some of which were basically "Hello World"-level google docs, so I doubt the issue is related to the document.
Other than that, I'm not sure what could be going on. I assume there must be some sort of permissions issue somewhere, but does anybody else have a clue what might be going on?
EDIT: Further information
It seems to be an issue with "publishing" the assignment. If I set the resource.state to DRAFT, I'm able to successfully execute the coursework.create API call. I get back an instance of a CourseWork object as expected.
The problem is I need to ultimately PUBLISH the assignment. And when I try to execute the classroom.courses.courseWork.patch() api call to simply change the state from DRAFT to PUBLISHED, I end up getting the same Requested entity was not found error.
However I am able to go into Google Classroom itself, view my drafts, and click on the ASSIGN button in the application. If I do that, everything finally works! That UI flow is no good for me, though. But it does indicate that there's nothing inherently wrong, as far as I can tell, with the assignment. I just seem to be missing some (undocumented?) step that's necessary in my case.
This happens because entity does not exist yet because the students haven't accessed the assignmend yet in the classroom. So make sure they do and try again.
Reference:
Drive files that correspond to materials with a share mode of
STUDENT_COPY may not exist yet if the student has not accessed the
assignment in Classroom.

Adding members to security group: SetInfo returns error 80070005

Background
I working on (modifying) a vbscript intended to create an AD shadow group formed by all users of several OU's.
The script logs into a remote AD, using alternate credentials.Note: The user I log in as, have full AD read access, but only inherited write access to the OU containing the group I'm adding members to.
Problematic code
The script is easily able to log in, scan for users on the OU's, open the shadow group and list it's current members, perform compares and locate the users to add and remove....but...
the actual adding (and removing) of members to the named security group fails, Error: 80070005 Srce: Active Directory Desc: Access is denied., when I apply .SetInfo.
I'm using this code to read and write:
aMembers = oGroup.GetEx("member") ' This gets populated as it should.
oGroup.PutEx ADS_PROPERTY_APPEND, "member", Array("CN=Doe\, John [LOCATION/COUNTRY],OU=foo,OU=bar,OU=Country,DC=domain,DC=org")
oGroup.SetInfo ' This fails
Just in case this is related to how I log into the AD, here's the code:
' Open an ADO connection using full credentials
Set oConnection = CreateObject("ADODB.Connection")
oConnection.Provider = "ADsDSOObject"
oConnection.Properties("User ID") = sLDAP_USER ' "domain\user"
oConnection.Properties("Password") = sLDAP_PASS ' "pass!word"
oConnection.Properties("Encrypt Password") = True
oConnection.Properties("ADSI Flag") = ADS_SECURE_AUTHENTICATION Or ADS_SERVER_BIND
oConnection.Open "Active Directory Provider"
Verifying my login users rights
I've seen lots of similar posts with this sort of error, and have only seen answers stating that this is a permission problem - however never seen a description of what permission was missing/wrong. The Access is denied error really made me doubt that the login I used had the right permissions, so I attempted to add members to the group by using JXplore. It works, but only if I enable the option to ignore schema checking (Based on online advice, when using JXplore with AD instead of pure LDAP).
Edit: Without ignoring the schema checking, the following properties are also requested to be populated: instanceType, nTSecurityDescriptor and objectCatagory, but I notice they are blank on existing users.
Questions
Did I fall into an obvious pitfall?
Do I also somehow need to ignore the schema in my script? If so, how to do that?

How to update address of a facebook page through API

I am trying to update address/location of a facebook business page through API using koala ruby gem, so far no working solution.
page_access_token = "gw4t3434"
page_api = Koala::Facebook::API.new(page_access_token)
page_api.graph_call('me', {:location => {:street => "my street"}}, 'post') #error. Koala::Facebook::APIError: OAuthException: (#100) Parameters do not match any fields that can be updated
page_api.graph_call('me', {:location => {:address => "my street"}}, 'post') #error. Koala::Facebook::APIError: OAuthException: (#100) Parameters do not match any fields that can be updated
page_api.graph_call('me', {:address => "my street"}}, 'post')# not raise error but not working
page_api.graph_call('me', {:street => "my street"}}, 'post')# not raise error but not working
I can not find clear explanation either in facebook api reference regarding updating address in a page. I may missing something...
You can't write to the location object, only read. See "Updating Page Attributes" in the API. Also, there is no permission to request for writing to a location object.
An alternative is that you write to the Page's about section - this is allowed. Perhaps you can place an address reference here to meet the requirement of making address changes visible to the end user.

Resources