Zuora payment-methods/credit-cards api returning 90000011 from java Client but returning success response from postman - zuora

I am in the middle of integration zuora apis with my application. These are the below 3 three apis I am using through following steps -
Step 1 Requesting for auth token
Service api (Test)- https://rest.apisandbox.zuora.com/oauth/token
Request Headers - Content-Type:application/x-www-form-urlencoded
Authorization:Basic YWYzNTg5ZWMtNTFmMC00YTc2LWFlZjEtYjk0YzZmYWE0Y2ViOlJDdGV5OGlTWFFUc00xQytTPTFYWD1POE9tRWM1c0FBWVBaaE5vV24=
Request Body - grant_type:client_credentials
Response Body - {
"access_token": "41947f41d664437a98a9da38a293c89d",
"token_type": "bearer",
"expires_in": 3598,
"scope": "entity.a083d63b-b3f5-8626-f793-65cec903f9ca platform.write service.events.read service.events.write service.genesis.read service.genesis.write service.notifications.read service.notifications.write service.usage.delete service.usage.update service.usage.write tenant.41231 user.2c92c094738e5b090173902066c201ba",
"jti": "41947f41d664437a98a9da38a293c89d"
}
Use access_token or jti value from auth token response and pass it on to the headers parameters as Authorization: Bearer
Step 2 : - Request for hmac-signatures for making payment
Service api (Test) - https://rest.apisandbox.zuora.com/v1/hmac-signatures
Request Headers - Content-Type:application/json
Authorization:Bearer 41947f41d664437a98a9da38a293c89d
Request Body - {
"accountKey": "A00000485",
"method": "POST",
"uri": "https://rest.apisandbox.zuora.com/v1/payment-methods/credit-cards"
}
Response Body - {
"signature": "MDgzN2ZkYjAzOTQ5NmQ5NDQyZjc5YTU3NjUwMDgxOGIxNTY3YWM2Mw==",
"token": "C41mzDTudB2uc0Jc6vwrhQGvwq3JTxsF",
"success": true
}
The signature needs to be added in Make Payment header asSignature:MDgzN2ZkYjAzOTQ5NmQ5NDQyZjc5YTU3NjUwMDgxOGIxNTY3YWM2Mw==
The token needs to be added in Make Payment header as Token:C41mzDTudB2uc0Jc6vwrhQGvwq3JTxsF
Step 3:- Make payment request –
Service Api - https://apisandbox-api.zuora.com/rest/v1/payment-methods/credit-cards
Headers Parameters –
Host:apisandbox-api.zuora.com
Signature:MDgzN2ZkYjAzOTQ5NmQ5NDQyZjc5YTU3NjUwMDgxOGIxNTY3YWM2Mw==
Token:C41mzDTudB2uc0Jc6vwrhQGvwq3JTxsF
Content-Type:application/json
Origin:www.test.gov.uk
Cache-Control:no-cache
Request Parameters – {
"defaultPaymentMethod": true,
"cardHolderInfo":
{"addressLine1": "77 Fallon Glen",
"addressLine2": "",
"zipCode": "94020",
"state": "California",
"phone": "4155551234",
"country": "USA",
"cardHolderName": "Bill Thiebault",
"city": "Fremont",
"email": "bill#testaddress.com"},
"expirationMonth": "10",
"accountKey": "A00000485",
"creditCardType": "Visa",
"expirationYear": "2021",
"creditCardNumber": "4012888888881121",
"securityCode": "123"
}
Response Body – {
"success": true,
"**paymentMethodId": "2c92c0fb73ad855c0173b8c3316b36a1"**
}
When I use the same steps using postman I am able to get a success response. And the Payment Method id is also getting generated. Using java client the first two services are being executed. But the issue appears when I hit the request for Payment-Method / credit cards,
It always returns -
{
"success" : false,
"processId" : "84AD9CF25EC6623A",
"reasons" : [ {
"code" : 90000011,
"message" : "this resource is protected, please sign in first"
} ]
}
Please suggest me if I missed anything here.

I missed to set the header value. Here I am posting the method that I used -
It consists Oauth token generation -> generation hmac signature -> making request for payment-method / credit card. It worked for me.
public void testSpringZuorPaymentCreditCardDifferent() {
HTTPHelper httpHelper = null;
String urlOAuthToken = "https://rest.apisandbox.zuora.com/oauth/token";
String resp = null;
try {
String userNameAndPassword ="c59b646b-53c6-45fb-b9c3-d3ea0978033d" + ":" +"6VLNxA=Fbaorb7yqXO3YRaiS2a+WUfLtwOiVugLqQ";
String authorizationHeaderValue = "Basic " + new String(Base64.encode(userNameAndPassword.getBytes()));
httpHelper = new HTTPHelper(new URL(urlOAuthToken));
Map<String, String> hdmp = new HashMap<String, String>();
hdmp.put("Authorization", authorizationHeaderValue);
hdmp.put("Content-Type", "application/x-www-form-urlencoded");
httpHelper.setHeaders(hdmp);
String req = "grant_type=client_credentials";
System.out.println("REQUEST: " + req);
resp = httpHelper.post(req, 60000, 60000);
System.out.println("OAuth token response : " + resp);
}catch(Exception e) {
e.printStackTrace();
}
String[] arrOfStr = resp.split("\\W+");
System.out.println("Bearer token---------" + arrOfStr[2]);
String urlHmacSignatureUrl = "https://rest.apisandbox.zuora.com/v1/hmac-signatures";
try {
httpHelper = new HTTPHelper(new URL(urlHmacSignatureUrl));
Map<String, String> hdmp = new HashMap<String, String>();
hdmp.put("Authorization", "Bearer " + new String(Base64.encode(arrOfStr[2].getBytes())));
hdmp.put("Content-Type", "application/json");
hdmp.put("cache-control", "no-cache");
httpHelper.setHeaders(hdmp);
String req = "{\n \"accountKey\": \"A00000194\", \n \"method\": \"POST\", \n \"uri\": \"https://rest.apisandbox.zuora.com/v1/payment-methods/credit-cards\"\n}";
System.out.println("REQUEST: " + req);
resp = httpHelper.post(req, 60000, 60000);
System.out.println("Hmac Signature response : " + resp);
}catch(Exception e) {
e.printStackTrace();
}
arrOfStr = resp.split("\\W+");
System.out.println("signature : - "+arrOfStr[2]);
System.out.println("token : - "+arrOfStr[4]);
String serverURI = "https://apisandbox-api.zuora.com/rest/v1/payment-methods/credit-cards";
try {
java.util.Map<String, String> headers = new java.util.HashMap<String, String>();
httpHelper = new HTTPHelper(new URL(serverURI));
headers.put("Content-Type", "application/json");
// headers.put("Signature", arrOfStr[2]+"==");
headers.put("Signature", new String(Base64.encode("YjM4MDY5MDliZmVkYmZiOGFkNmQ1YzFhYzFmNzMyOGI3NjExM2JlNQ==".getBytes())));
headers.put("Token", new String(Base64.encode(arrOfStr[4].getBytes())));
httpHelper.setHeaders(headers);
String req = "{\r\n" +
" \"defaultPaymentMethod\":true,\r\n" +
" \"cardHolderInfo\":{\r\n" +
" \"addressLine1\":\"77 Fallon Glen\",\r\n" +
" \"addressLine2\":\"\",\r\n" +
" \"zipCode\":\"94020\",\r\n" +
" \"state\":\"California\",\r\n" +
" \"phone\":\"4155551234\",\r\n" +
" \"country\":\"USA\",\r\n" +
" \"cardHolderName\":\"Bill Thiebault\",\r\n" +
" \"city\":\"Fremont\",\r\n" +
" \"email\":\"bill#testaddress.com\"\r\n" +
" },\r\n" +
" \"expirationMonth\":\"10\",\r\n" +
" \"accountKey\":\"A00000485\",\r\n" +
" \"creditCardType\":\"Visa\",\r\n" +
" \"expirationYear\":\"2021\",\r\n" +
" \"creditCardNumber\":\"4012888888881121\",\r\n" +
" \"securityCode\":\"123\"\r\n" +
"}";
System.out.println("Req: " + req);
resp = httpHelper.post(req, 60000, 60000);
System.out.println("Payment Method - Credit Cards: " + resp);
}catch(Exception e) {
e.printStackTrace();
}
}

Related

POST users import v2 internal server error

I am working on a fully automatic pipeline for my company where we automatically set up projects, add users and upload files with the different APIs on BIM360. On the stage of adding a user I get a 500 internal server error:
{"code":2000,"message":"no implicit conversion of String into Integer"}
We are using a two-legged authentication approach and as such the header looks like this:
Authorization: Bearer <token> (It has account:write rights)
x-user-id: ************ (uid of my admin account)
Content-Type: application/json
The request content is this:
#"{
""email"": """ + ***#********.** + #""",
""services"": {
""document_management"": {
""access_level"": """ + admin+ #"""
},
""project_administration"": {
""access_level"": """ + admin+ #"""
}
},
""industry_roles"": []}";
I just can't quite seem to figure out what I am doing wrong. Hope someone can help me.
EDIT: Full code for this request
public async static Task<HttpStatusCode> AddUserToProjectEmail(string projectId, string accountId, string accessToken, string userToAddEmail, string userPrivilege, string adminUserId)
{
using (HttpClient httpClient = new HttpClient())
{
using (HttpRequestMessage request = new HttpRequestMessage())
{
//Documentation for what to put in the Http POST: https://forge.autodesk.com/en/docs/bim360/v1/reference/http/projects-project_id-users-import-POST/
request.Method = new HttpMethod("POST");
request.RequestUri = new Uri("https://developer.api.autodesk.com/hq/v2/regions/eu/accounts/" + accountId + "/projects/" + projectId + "/users/import");
//Make the request payload
string jsonPayload = AddPayloadToUserAddEmail(userToAddEmail, userPrivilege);
request.Content = new StringContent(jsonPayload);
request.Content.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
request.Headers.Add("x-user-id", adminUserId);
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
//Send request
var response = await httpClient.SendAsync(request);
return response.StatusCode;
}
}
}
And the request payload method:
private static string AddPayloadToUserAddEmail(string userToAddEmail, string userPrivilege)
{
string payload = #"{
""email"": """ + userToAddEmail + #""",
""services"": {
""project_administration"": {
""access_level"": """ + userPrivilege + #"""
},
""document_management"": {
""access_level"": """ + userPrivilege + #"""
}
},
""industry_roles"": []
}";
return payload;
}
I have checked all the IDs through the URL on BIM360, however it's not possible to check the Uid of my account I think.
EDIT 2: I should note that I was getting a different error before I added the x-user-id header, where it just said forbidden which makes sense. This lead me to think it had something to do with the x-user-id header, but I can't figure it out.
Don't be like me and forget to wrap the payload into an array as stated on the docs that it has to be. Using this as payload worked
#"[{
""email"": """ + userToAddEmail + #""",
""services"": {
""project_administration"": {
""access_level"": """ + userPrivilege + #"""
},
""document_management"": {
""access_level"": """ + userPrivilege + #"""
}
},
""industry_roles"": []
}]";

Extract some value without key from a json object

I am using java to extract a list of node ids from an elastic search running tasks response.
The response looks like this
{
"nodes": {
"ZKUuxQZpRCCcJ0njBM1P0A": {
"name": "ZKUuxQZ",
"transport_address": "127.0.0.1:9300",
"host": "127.0.0.1",
"ip": "127.0.0.1:9300",
"roles": [
"master",
"data",
"ingest"
],
"tasks": {
"ZKUuxQZpRCCcJ0njBM1P0A:118": {
"node": "ZKUuxQZpRCCcJ0njBM1P0A",
"id": 118,
"type": "transport",
"action": "indices:data/write/delete/byquery",
"start_time_in_millis": 1527808643421,
"running_time_in_nanos": 154234724059,
"cancellable": true,
"headers": {}
}
}
}
}
}
In this example, I want to exact ZKUuxQZpRCCcJ0njBM1P0A:118. Can someone give me an example how to extract this information?
Option 1, java json parser. I wanted to write a response class and parse the json string, but ZKUuxQZpRCCcJ0njBM1P0A:118 is not in the key:value format. I am not sure how to extract it.
Option 2, using regex. The node id part may also have - or _. Can someone provide a neat java regex solution? So far my regex is [a-zA-Z0-9\-\_]+\:[0-9]+, I am not sure if this is safe enough.
Thanks.
One way you can do this is by using org.json library and create JSONObject and using keys() you can get all the keys and use this to achieve your task
Add the following dependency in your pom.xml
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20180130</version>
</dependency>
Then you can do something like below:
String jsonString = "{\n" +
" \"nodes\": {\n" +
" \"ZKUuxQZpRCCcJ0njBM1P0A\": {\n" +
" \"name\": \"ZKUuxQZ\",\n" +
" \"transport_address\": \"127.0.0.1:9300\",\n" +
" \"host\": \"127.0.0.1\",\n" +
" \"ip\": \"127.0.0.1:9300\",\n" +
" \"roles\": [\n" +
" \"master\",\n" +
" \"data\",\n" +
" \"ingest\"\n" +
" ],\n" +
" \"tasks\": {\n" +
" \"ZKUuxQZpRCCcJ0njBM1P0A:118\": {\n" +
" \"node\": \"ZKUuxQZpRCCcJ0njBM1P0A\",\n" +
" \"id\": 118,\n" +
" \"type\": \"transport\",\n" +
" \"action\": \"indices:data/write/delete/byquery\",\n" +
" \"start_time_in_millis\": 1527808643421,\n" +
" \"running_time_in_nanos\": 154234724059,\n" +
" \"cancellable\": true,\n" +
" \"headers\": {}\n" +
" }\n" +
" }\n" +
" }\n" +
" }\n" +
"}";
JSONObject jsonObject = new JSONObject(jsonString);
Set<String> topLevelKeys = jsonObject.keySet();
for (String key : topLevelKeys) {
Object value = jsonObject.get(key);
if (value instanceof JSONObject) {
JSONObject valueObject = jsonObject.getJSONObject(key);
System.out.println(valueObject.toString());
}
}
Extend this as per your requirement.
So regex is too hacky and I figured it out using gson. I wish ElasticSearch can offer us some standard library to extract all kinds of responses. Here is my solution using gson.
import com.google.gson.*;
import org.json.JSONObject;
public class test {
public static void main(String[] args) throws Exception {
String jsonString = "json_format elasticsearch reponse for listing running tasks"
JsonParser parser = new JsonParser();
JsonObject jsonObject = parser.parse(content).getAsJsonObject();
jsonObject.getAsJsonObject("nodes").entrySet().forEach(
s -> {
s.getValue().getAsJsonObject().getAsJsonObject("tasks").entrySet().forEach( s2 -> {
System.out.println(s2.getKey());
});
});
}
It prints all the running task ids like the following. It's technically nodeId:taskId, but ES has a very vague description in their task API docs(It says you can use TASK_ID to check a status of a task, well that TASK_ID is nodeId:taskId).
Mw-3i39gTHGxu5c8z9viQQ:503209021
DZ29LMsWR0aW9guWZTYe2Q:482931604
6CAbDZSWR8SfwZgnRT0qNg:494351185
Use the following regex:
[a-zA-Z0-9-_]*[0-9]+[a-zA-Z]+:[0-9]*
You can find the test result here:
https://regexr.com/3qdug

Unable to parse the id from moviedb api

Hi I'm trying to parse out the id's from an array. I have a logging method which shows a toast:
StringBuilder data= new StringBuilder();
JSONArray arrayMovies= response.getJSONArray(KEY_MOVIES);
for (int i = 0; i < arrayMovies.length(); i++) {
JSONObject currentMovie = arrayMovies.getJSONObject(i);
String id = currentMovie.getString(KEY_ID);
data.append(id+"\n");
}
L.t(getActivity(), data.toString());
.....
But It's not parsing it out. Just getting a list of the movies.
Here is the json file:
{
"page": 1,
"results": [
{
"adult": false,
"backdrop_path": "/tbhdm8UJAb4ViCTsulYFL3lxMCd.jpg",
"genre_ids": [
53,
28,
12
],
"id": 76341,
"original_language": "en",
"original_title": "Mad Max: Fury Road",
"overview": "An apocalyptic story set in the furthest reaches of our planet, in a stark desert landscape where humanity is broken, and most everyone is crazed fighting for the necessities of life. Within this world exist two rebels on the run who just might be"
}
]
}
Not sure, but maybe because id value has no quote, and therefore, can not be parsed as a String with getString() method
I think your code is OK, just need check the response and keys again, I have tested with hard-code the response as the String and 2 keys as the following:
String jsonString = "{\n" +
" \"page\": 1,\n" +
" \"results\": [\n" +
" {\n" +
" \"adult\": false,\n" +
" \"backdrop_path\": \"/tbhdm8UJAb4ViCTsulYFL3lxMCd.jpg\",\n" +
" \"genre_ids\": [\n" +
" 53,\n" +
" 28,\n" +
" 12\n" +
" ],\n" +
" \"id\": 76341,\n" +
" \"original_language\": \"en\",\n" +
" \"original_title\": \"Mad Max: Fury Road\",\n" +
" \"overview\": \"An apocalyptic story set in the furthest reaches of our planet, in a stark desert landscape where humanity is broken, and most everyone is crazed fighting for the necessities of life. Within this world exist two rebels on the run who just might be\"\n" +
" }\n" +
" ]\n" +
"}";
StringBuilder data= new StringBuilder();
try {
JSONObject jsonObject = new JSONObject(jsonString);
JSONArray arrayMovies= jsonObject.getJSONArray("results");
for (int i = 0; i < arrayMovies.length(); i++) {
JSONObject currentMovie = arrayMovies.getJSONObject(i);
String id = currentMovie.getString("id");
data.append(id+"\n");
}
Log.i("BNK", data.toString());
} catch (JSONException e) {
e.printStackTrace();
}
And here is the screenshot (please pay attention to logcat):

How to read from openTSDB with a JSON POST?

I am running my openTSDB on a virtual maschine and want to read data with a JSON POST request from a client.
Baseurl is the URL to my VM.
Whenever i send this request, i get an error "Unable to pass the given JSON" in my openTSDB. So what's wrong with my request?
Thanks in advance.
EDIT: The Json-Request is supposed to represent this GET Request (which works):
baseurl+"/api/query?start=1356994800000&m=sum:Leistung";
String url = baseurl;
URL obj = new URL(url + "/api/query");
HttpURLConnection con = (HttpURLConnection) obj.openConnection();
//add reuqest header
con.setRequestMethod("POST");
con.setRequestProperty("Content-type", "application/json; charset=utf-8");
con.setRequestProperty("Accept", "application/json; charset=utf-8");
con.setRequestProperty("User-Agent", USER_AGENT);
con.setRequestProperty("Accept-Language", "en-US,en;q=0.5");
con.setDoOutput(true);
DataOutputStream wr = new DataOutputStream(con.getOutputStream());
wr.writeChars("{\n" +
" \"start\": 1356994800000,\n" +
" \"queries\": [\n" +
" {\n" +
" \"aggregator\": \"sum\",\n" +
" \"metric\": \"Leistung\"\n" +
" }\n" +
" ]\n" +
"}");
wr.flush();
wr.close();
int responseCode = con.getResponseCode();
System.out.println("\nSending 'POST' request to URL : " + url);
System.out.println("Response Code : " + responseCode);
BufferedReader in = new BufferedReader(
new InputStreamReader(con.getInputStream()));
String inputLine;
StringBuffer response = new StringBuffer();
while ((inputLine = in.readLine()) != null) {
response.append(inputLine);
}
con.disconnect();
in.close();
System.out.println(response.toString());

Transfer ownership of file uploaded using Google drive API

The Google Drive API is not able to transfer ownership of a file which was uploaded from the API itself.
as per the API documentation, PUT needs to be used for transferring ownership.
when I use it with the parameters required it returns existing permission back.
doesn't update it with new owner.
if i use POST & the required parameters it throws 'The remote server returned an error: (400) Bad Request.'
I was able to change the ownership for the files that were NOT uploaded via API. the same which I use for the files which are uploaded from API. the owner doesn't change.
Is it a bug or I am doing something wrong?
-EDIT-
if anyone wants details of file uploaded using API & file created via gdocs I can.
-EDIT2-
public bool UploadReportToGoogleDrive(Model model, byte[] ReportPDF_ByteArray, string ddlAddFilesFolder = "root", bool doNotify = true)
{
bool isErrorOccured = false;
try
{
SingletonLogger.Instance.Info("UploadReportToGoogleDrive - start");
FileList fileList = new FileList();
Google.Apis.Drive.v2.Data.File uploadedFile = new Google.Apis.Drive.v2.Data.File();
Permission writerPermission = new Permission();
string accessToken = GetAccessToken();
#region FIND REPORT FOLDER
string url = "https://www.googleapis.com/drive/v2/files?"
+ "access_token=" + accessToken
+ "&q=" + HttpUtility.UrlEncode("title='My Reports' and trashed=false and mimeType in 'application/vnd.google-apps.folder'")
;
// Create POST data and convert it to a byte array.
List<string> _postData = new List<string>();
string postData = string.Join("", _postData.ToArray());
try
{
WebRequest request = WebRequest.Create(url);
string responseString = GDriveHelper.GetResponse(request);
fileList = JsonConvert.DeserializeObject<FileList>(responseString);
SingletonLogger.Instance.Info("UploadReportToGoogleDrive - folder search success");
}
catch (Exception ex)
{
SingletonLogger.Instance.Error("UploadReportToGoogleDrive\\FIND REPORT FOLDER", ex);
isErrorOccured = true;
}
#endregion FIND REPORT FOLDER
if (fileList.Items.Count == 0)
{
#region CREATE REPORT FOLDER
url = "https://www.googleapis.com/drive/v2/files?" + "access_token=" + accessToken;
// Create POST data and convert it to a byte array.
_postData = new List<string>();
_postData.Add("{");
_postData.Add("\"title\": \"" + "My Reports" + "\",");
_postData.Add("\"description\": \"Uploaded with Google Drive API\",");
_postData.Add("\"parents\": [{\"id\":\"" + "root" + "\"}],");
_postData.Add("\"mimeType\": \"" + "application/vnd.google-apps.folder" + "\"");
_postData.Add("}");
postData = string.Join("", _postData.ToArray());
try
{
WebRequest request = WebRequest.Create(url);
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/json";
// Set the ContentLength property of the WebRequest.
request.ContentLength = postData.Length;//byteArray.Length;
// Set the Method property of the request to POST.
request.Method = "POST";
// Get the request stream.
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
string responseString = GDriveHelper.GetResponse(request);
Google.Apis.Drive.v2.Data.File ReportFolder = JsonConvert.DeserializeObject<Google.Apis.Drive.v2.Data.File>(responseString);
;
ddlAddFilesFolder = ReportFolder.Id;
SingletonLogger.Instance.Info("UploadReportToGoogleDrive - folder creation success");
}
catch (Exception ex)
{
SingletonLogger.Instance.Error("UploadReportToGoogleDrive\\CREATE REPORT FOLDER", ex);
isErrorOccured = true;
}
#endregion CREATE REPORT FOLDER
}
else
{
ddlAddFilesFolder = fileList.Items.FirstOrDefault().Id;
}
if (!isErrorOccured)
{
#region UPLOAD NEW FILE - STACKOVER FLOW
//Createing the MetaData to send
_postData = new List<string>();
_postData.Add("{");
_postData.Add("\"title\": \"" + "Report_" + model.id + "\",");
_postData.Add("\"description\": \"" + " report of person - " + (model.borrowerDetails.firstName + " " + model.borrowerDetails.lastName) + "\",");
_postData.Add("\"parents\": [{\"id\":\"" + ddlAddFilesFolder + "\"}],");
_postData.Add("\"extension\": \"" + "pdf" + "\",");
_postData.Add("\"appDataContents\": \"" + true + "\",");
_postData.Add("\"mimeType\": \"" + GDriveHelper.GetMimeType("Report.pdf").ToString() + "\"");
_postData.Add("}");
postData = string.Join(" ", _postData.ToArray());
byte[] MetaDataByteArray = Encoding.UTF8.GetBytes(postData);
//// creating the Data For the file
//MemoryStream target = new MemoryStream();
//myFile.InputStream.Position = 0;
//myFile.InputStream.CopyTo(target);
//byte[] FileByteArray = target.ToArray();
string boundry = "foo_bar_baz";
url = "https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart" + "&access_token=" + accessToken;
WebRequest request = WebRequest.Create(url);
request.Method = "POST";
request.ContentType = "multipart/related; boundary=\"" + boundry + "\"";
// Wrighting Meta Data
string headerJson = string.Format("--{0}\r\nContent-Type: {1}\r\n\r\n",
boundry,
"application/json; charset=UTF-8");
string headerFile = string.Format("\r\n--{0}\r\nContent-Type: {1}\r\n\r\n",
boundry,
GDriveHelper.GetMimeType("Report.pdf").ToString());
string footer = "\r\n--" + boundry + "--\r\n";
int headerLenght = headerJson.Length + headerFile.Length + footer.Length;
request.ContentLength = MetaDataByteArray.Length + ReportPDF_ByteArray.Length + headerLenght;
Stream dataStream = request.GetRequestStream();
dataStream.Write(Encoding.UTF8.GetBytes(headerJson), 0, Encoding.UTF8.GetByteCount(headerJson)); // write the MetaData ContentType
dataStream.Write(MetaDataByteArray, 0, MetaDataByteArray.Length); // write the MetaData
dataStream.Write(Encoding.UTF8.GetBytes(headerFile), 0, Encoding.UTF8.GetByteCount(headerFile)); // write the File ContentType
dataStream.Write(ReportPDF_ByteArray, 0, ReportPDF_ByteArray.Length); // write the file
// Add the end of the request. Start with a newline
dataStream.Write(Encoding.UTF8.GetBytes(footer), 0, Encoding.UTF8.GetByteCount(footer));
dataStream.Close();
try
{
WebResponse response = request.GetResponse();
// Get the stream containing content returned by the server.
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);
uploadedFile = JsonConvert.DeserializeObject<Google.Apis.Drive.v2.Data.File>(responseFromServer);
// Clean up the streams.
reader.Close();
dataStream.Close();
response.Close();
SingletonLogger.Instance.Info("UploadReportToGoogleDrive - upload to folder success");
}
catch (Exception ex)
{
SingletonLogger.Instance.Error("UploadReportToGoogleDrive\\CREATE REPORT FOLDER", ex);
isErrorOccured = true;
//return "Exception uploading file: uploading file." + ex.Message;
}
#endregion UPLOAD NEW FILE - STACKOVER FLOW
}
if (!isErrorOccured)
{
#region MAKE ADMIN ACCOUNT OWNER OF UPLOADED FILE - COMMENTED
url = "https://www.googleapis.com/drive/v2/files/" + uploadedFile.Id
+ "/permissions/"
+ uploadedFile.Owners[0].PermissionId
+ "?access_token=" + accessToken
+ "&sendNotificationEmails=" + (doNotify ? "true" : "false")
;
WebRequest request = WebRequest.Create(url);
string role = "owner", type = "user", value = "aniketpatil87#gmail.com";
// Create POST data and convert it to a byte array.
postData = "{"
+ "\"role\":\"" + role + "\""
+ ",\"type\": \"" + type + "\""
+ ",\"value\": \"" + value + "\""
+ ",\"permissionId\":\"" + uploadedFile.Owners[0].PermissionId + "\""
+ ",\"transferOwnership\": \"" + "true" + "\""
+ "}";
byte[] byteArray = Encoding.UTF8.GetBytes(postData);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/json";
// Set the ContentLength property of the WebRequest.
request.ContentLength = postData.Length;//byteArray.Length;
// Set the Method property of the request to POST.
request.Method = "POST";
// Get the request stream.
Stream dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
//TRY CATCH - IF TOKEN IS INVALID
try
{
string responseString = GDriveHelper.GetResponse(request);
SingletonLogger.Instance.Info("UploadReportToGoogleDrive - make admin account owner success");
}
catch (Exception ex)
{
SingletonLogger.Instance.Error("UploadReportToGoogleDrive\\MAKE ADMIN ACCOUNT OWNER OF UPLOADED FILE", ex);
isErrorOccured = true;
}
#endregion MAKE ADMIN ACCOUNT OWNER OF UPLOADED FILE
if (model.Officer != default(int))
{
#region ALLOW OFFICER TO ACCESS UPLOADED FILE
OldModels.MWUsers officer = usersBL.GetAll(model.Officer).FirstOrDefault();
url = "https://www.googleapis.com/drive/v2/files/" + uploadedFile.Id
+ "/permissions/"
//+ uploadedFile.Owners[0].PermissionId
+ "?access_token=" + accessToken
+ "&sendNotificationEmails=" + (doNotify ? "true" : "false")
;
request = WebRequest.Create(url);
role = "writer";
type = "user";
value = Officer.EMail;
// Create POST data and convert it to a byte array.
postData = "{"
+ "\"role\":\"" + role + "\""
+ ",\"type\": \"" + type + "\""
+ ",\"value\": \"" + value + "\""
//+ ",\"permissionId\":\"" + uploadedFile.Owners[0].PermissionId + "\""
//+ ",\"transferOwnership\": \"" + "true" + "\""
+ "}";
byteArray = Encoding.UTF8.GetBytes(postData);
// Set the ContentType property of the WebRequest.
request.ContentType = "application/json";
// Set the ContentLength property of the WebRequest.
request.ContentLength = postData.Length;//byteArray.Length;
// Set the Method property of the request to POST.
request.Method = "POST";
// Get the request stream.
dataStream = request.GetRequestStream();
// Write the data to the request stream.
dataStream.Write(byteArray, 0, byteArray.Length);
// Close the Stream object.
dataStream.Close();
//TRY CATCH - IF TOKEN IS INVALID
try
{
string responseString = GDriveHelper.GetResponse(request);
SingletonLogger.Instance.Info("UploadReportToGoogleDrive - make officer writer success");
}
catch (Exception ex)
{
SingletonLogger.Instance.Error("UploadReportToGoogleDrive\\ALLOW OFFICER TO ACCESS UPLOADED FILE", ex);
isErrorOccured = true;
}
#endregion ALLOW OFFICER TO ACCESS UPLOADED FILE
}
}
if (isErrorOccured)
{
SingletonLogger.Instance.Info("UploadReportToGoogleDrive - report upload to gdrive failed");
}
else
{
//LogHelper.CreateLogEntry(UserContext.CurrentUser.UserID, "Uploaded " + myFileList.Count + " file(s) on Google Drive.", this.HttpContext.Request);
SingletonLogger.Instance.Info("UploadReportToGoogleDrive - report upload to gdrive success");
}
}
catch (Exception ex)
{
SingletonLogger.Instance.Info("UploadReportToGoogleDrive - Outer exception", ex);
isErrorOccured = true;
}
return isErrorOccured;
}
Not sure if you've looked at the PATCH command for permissions. The PATCH command with the proper parameters lets you transfer ownership.
Link to Google Drive API documentation
It looks like you are specifying transferOwnership in the post body, when it must be specified as a URL parameter, as per the documentation.