Google data API for .Net allows Sharing outside organization in Google apps account - google-docs-api

I am using Google Data API for .Net(version 1.9) in my application.
I have created a Google apps account and i have set the "Users cannot share documents outside this organization" setting under Google Docs.
When i try to share a file outside of the domain(organization) from Google docs web, i get a error saying the file cannot be shared outside of my domain.
But when i try the same thing from the API, it succeeds. I get a 200 success from the API. When i try to access the file from the share link it says 'You need permission to access this resource'. My question is shouldn't the API return with a error? how can i handle this case?
Here is the code that I am using:
DocumentsRequest request = null;
/* request initialization */
string csBatchReqBody = "<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:gAcl="http://schemas.google.com/acl/2007" xmlns:batch="http://schemas.google.com/gdata/batch"><category scheme="http://schemas.google.com/g/2005#kind" term="http://schemas.google.com/acl/2007#accessRule"/><entry><id>https://docs.google.com/feeds/default/private/full/document:1DsELtiNwq-ogOrp8cAONdMpGR4gBF79PjijTae-vVNg/acl/user:myusername#mydomain.com</id><batch:operation type="query"/></entry><entry><batch:id>1</batch:id><batch:operation type="insert"/><gAcl:role value="reader"/><gAcl:scope type="user" value="myusername#gmail.com"/></entry>"
string Url = "https://docs.google.com/feeds/default/private/full/document:1DsELtiNwq-ogOrp8cAONdMpGR4gBF79PjijTae-vVNg/acl/batch";
byte[] byteArray = Encoding.ASCII.GetBytes(csBatchReqBody);
MemoryStream inputStream = new MemoryStream(byteArray);
AtomEntry reply = request.Service.Insert(new Uri(Url), inputStream, "application/atom+xml", "");
MemoryStream stream = new MemoryStream();
reply.SaveToXml(stream);

The API actually returns a 400 if you try to share a file outside the domain and the admins have set the "Users cannot share documents outside this organization" flag.
Your code sends a batch request (even if for a single element), you'd have to check the batch response to notice the error.
Instead, use the following code to share a document to a single user, it assumes that entry is the DocumentEntry you want to share:
AclEntry acl = new AclEntry();
acl.Scope = new AclScope("username#gmail.com", "user");
acl.Role = new AclRole("reader");
acl = service.Insert(new Uri(entry.AccessControlList), acl);

Related

Upload fail for DrievItems in Drive of SitePages List

Upload fail for all the DrivesItems in Drive associated with SitePage list in a sharepoint site.
Graph API request:
UploadSession uploadSession = GraphCLient.Sites[{SiteId}].Drives[{DriveId of SitePages List }]. Items[{DriveFolderID}].ItemWithPath(driveItem.Item.Name).CreateUploadSession().Request().PostAsync().Result;
The uploadSession will be created sucessfully but chunkuploadprovider gives error.
Error response: Code: accessDenied Message: The caller does not have
permission to perform the action. Inner error
Code Snippet:
private void UploadItem(OneDriveJsonStructure driveItem)
{
try
{
MemoryStream memStream = (MemoryStream)driveItem.Content;
byte[] buffer = memStream.ToArray();
DriveItem item = null;
using (System.IO.MemoryStream ms = new System.IO.MemoryStream(buffer))
{
UploadSession uploadSession = this._SharepointOperations._GraphCLient.Sites[this._SiteId].Drives[this._DriveId].Items[this._DriveFolderId].ItemWithPath(driveItem.Item.Name).CreateUploadSession().Request().PostAsync().Result;
var provider = new ChunkedUploadProvider(uploadSession, this._SharepointOperations._GraphCLient, memStream);
var chunkRequests = provider.GetUploadChunkRequests();
var readBuffer = new byte[buffer.Length];
var trackedExceptions = new List<Exception>();
DriveItem itemResult = null;
foreach (var request in chunkRequests)
{
// Send chunk request
var result = provider.GetChunkRequestResponseAsync(request, readBuffer, trackedExceptions).Result;
if (result.UploadSucceeded)
{
itemResult = result.ItemResponse;
item = result.ItemResponse;
}
}
if (itemResult == null)
{
UploadChunkResult result = null;
// Retry the upload ...
foreach (var request in chunkRequests)
{
// Send chunk request
result = provider.GetChunkRequestResponseAsync(request, readBuffer, trackedExceptions).Result;
}
item = result.ItemResponse;
}
}
item.Permissions = driveItem.Item.Permissions;
GivePermission(item);
Permission Provide to Client App from Azure AD:
Graph Permission:
Sharepoint Permissions:
Even after all these permissions it gives this error message:
"The caller does not have permission to perform the action".
Which permissions are needed to perform this action?
Upload for driveItems of other drive execute sucessfully.
Now that uploading for driveItems of other drive execute successfully, your code should be OK.
So the key to the issue lies in the user's SharePoint permissions.
Please check if the user account can upload files into the target folder in your SharePoint site.
If the user doesn't have the permission to do that, you need to use an admin account to grant edit permission to the user.
Detailed steps:
Next to the folder name, click the Ellipsis…
On the file popup window, click Share.
On the Share dialog box, click Shared with, and then click
Advanced.
Click Stop Inheriting Permissions.
Add the user into an SharePoint Group which has Edit or Contribute
permission. (If you don't want to modify the default SharePoint
Group, just create a new one)
A quick method: Share this folder (with edit permission) with the user.
Next to the folder name, click the Ellipsis…. On the file popup window, click Share. On the Share dialog box, follow the screenshot.
UPDATE:
Note that we can't upload any documents into Site Pages document library. Using API is also not supported.

How to fetch the list of Tags in TFS 2015 Update 3

Is there a way to fetch the list of tags created for a team project, basically we need information such as creation date, created by user etc.
Can we fetch these information using TFS RestApi? If so it would be helpful if code snippets are provided.
There isn't the information of created by user, you can check it in dbo.tbl_TagDefinition table of collection database.
To fetch the list of Tags, you can refer to Giulio’s answer, for example:
[collection URL]/_apis/tagging/scopes/[Team Project ID]/tags?api-version=1.0
To get Team Project ID, you can call this REST API:
[Collection URL]/_apis/projects?api-version=1.0
Simple code for C#:
String MyURI = "[collection URL]/_apis/tagging/scopes/f593de42-d419-4e07-afc7-1f334077c212/tags?api-version=1.0";
WebRequest WReq = WebRequest.Create(MyURI);
WReq.Credentials =
new NetworkCredential("[user name]", "[password]", "[domain"");
WebResponse response = WReq.GetResponse();
Console.WriteLine(((HttpWebResponse)response).StatusDescription);
// Get the stream containing content returned by the server.
Stream dataStream = response.GetResponseStream();
// Open the stream using a StreamReader for easy access.
StreamReader reader = new StreamReader(dataStream);
// Read the content.
string responseFromServer = reader.ReadToEnd();
// Display the content.
Console.WriteLine(responseFromServer);
There is a REST API to manage Tags, but there is not auditing information as per your request.
If you want to learn how to call a REST API there is plenty of sources, starting from the Get started page.

Download revit file from a360 forge bucket

How can I download a file from an Autodesk A360 bucket that I created? The file is a Revit project file and I used 2-legged OAuth for authorization.
You need to use 3 legged authentication to access files from A360, because you need the approval of the user whose account you are accessing - the user is the 3rd leg.
If you are trying to access files from your own application's private bucket on OSS then you do not need a user's approval because the bucket belongs to your app and not a user.
As a side note, in case of trying to access BIM 360 files (in case that's what you are talking about) using the Data Management API, then for the time being you need to use 2 legged authentication but your app needs to be manually approved by us.
2-legged vs 3-legged authentication is covered by Augusto's webcast:
Introduction to oAuth and Data Management API
I don't get a bucket key after attempting to create a bucket in when i change v1 to v2...
see below
public static string GetBucket(string accessToken, string bucketKey, string policy)
{
// (1) Build request
var client = new RestClient();
client.BaseUrl = new System.Uri(baseApiUrl);
// Set resource/end point
var request = new RestRequest();
request.Resource = "oss/v1/buckets";
request.Method = Method.GET;
// Add headers
request.AddHeader("Authorization", "Bearer " + accessToken);
request.AddHeader("Content-Type", "application/json"); // MH: skipping this works.
// Add JSON body. in simplest form.
request.AddJsonBody(new { bucketKey = bucketKey, policy = policy });
// (2) Execute request and get response
IRestResponse response = client.Execute(request);
//TaskDialog.Show("create bucket", response.StatusDescription);
// Save response. This is to see the response for our learning.
m_lastResponse = response;
TaskDialog.Show("response", m_lastResponse.ToString());
// Get the key = bucket name
string key = "";
if (response.StatusCode == HttpStatusCode.OK)
{
JsonDeserializer deserial = new JsonDeserializer();
OssBucketsResponse bucketsResponse = deserial.Deserialize<OssBucketsResponse>(response);
key = bucketsResponse.key;
}
return key; // the bucket name
}

Can I POST data to a Google Web App without having to authenticate?

I'm trying to POST data to a Google Web App to automatically enter some tedious data. Whenever I try I get a response back asking me to log in, the Web App is deployed to be accessible by anyone.
Can I POST data to the form without authentication? If not, what type of authentication is required?
Edit: Quick code sample I threw together:
WebClient client = new WebClient();
var keyValue = new NameValueCollection();
keyValue.Add("agentName", "John Doe");
keyValue.Add("dayOff", "Sunday");
keyValue.Add("startTime", "8:00 AM");
Uri uri = new Uri("mywebapp url");
byte[] response = client.UploadValues(uri, "POST", keyValue);
string result = Encoding.UTF8.GetString(response);
In order to allow anyone to execute your script, even if they are not signed in to a Google account, you need to use the following settings in the "Deploy as web app" dialog:
Project version: if in doubt, select "New" to ensure that you are deploying the latest copy of the script's code.
Execute the app as: select "Me". This ensures that the "even anonymous" option will be available.
Who has access to the app: select "Anyone, even anonymous". (Note that if you select "Anyone", only users that are signed-in to a Google account will be able to execute your script.)
Once you have selected these options, click the "Update" button and copy the script URL. It should look like https://script.google.com/a/macros/<APPS DOMAIN>/s/<SCRIPT KEY>/exec. At this point an unauthenticated GET or POST to the script's URL should be successful.
Be aware that the script's execution will count against your daily Apps Script quota.

uploading a file from iOS mobile application to SharePoint

I'm working on a SharePoint mobile solution where I'm using the web services exposed in server/_vti_bin/sitedata.asmx, server/_vti_bin/Lists.asmx and server/_vti_bin/copy.asmx.
I'm able to successfully fetch the list of sites, document libraries and files using the services defined in server/_vti_bin/sitedata.asmx.
Now I'm actually trying to upload an image file from Photo Albums available in iOS to SharePoint. For this, I tried using CopyIntoItems web service, where in I'm getting the following error response.
<CopyResult ErrorCode="DestinationInvalid" ErrorMessage="The Copy web service method must be called on the same domain that contains the destination url." DestinationUrl="http://xxxxserveripxxxxxx/Shared Documents/image1.png"/>
But came to know that this service is used only if the file to be uploaded is also from the same source(i.e., from sharepoint).
Is there any other way to upload a file available in iPhone to SharePoint.
Also tired addAttachment service defiend in server/_vti_bin/Lists.asmx but I'm unable to identify the input parameters which requires list name and list Item ID.
I'm trying to upload a file to Shared Documents, so I've List Name value which is the one in curly braces of Shared Documents but now what should be the List Item Id value?
These are the details I've with regard to "Shared Documents" document library.
{
AllowAnonymousAccess = false;
AnonymousViewListItems = false;
BaseTemplate = DocumentLibrary;
BaseType = DocumentLibrary;
DefaultViewUrl = "/Shared Documents/Forms/AllItems.aspx";
Description = "Share a document with the team by adding it to this document library.";
InheritedSecurity = true;
InternalName = "{425F837A-F110-4876-98DE-C92902446935}";
LastModified = "2013-07-26 20:09:58Z";
ReadSecurity = 1;
Title = "Shared Documents";
},
So, I'm using the using InternalName value for listName tag.
What should be the value of listItemID?
Am I going in the right way or is there any other approach to upload a local file from mobile to SharePoint?
Thanks
Sudheer
Are you actually calling a URL or are you using the IP (you x'ed it out and said server IP)? If you don't have Alternate Access Mappings defined for the IP, uploads will fail but the GET requests will generally work ok.

Resources