Signing oAuth with apache HttpRequest for a multipart request - oauth

enter code hereI need to send a multipart request to a rest api signed with oAuth
in my pom I'm using
<dependency>
<groupId>oauth.signpost</groupId>
<artifactId>signpost-commonshttp4</artifactId>
<version>1.2.1.1</version>
</dependency>
and I'm using this code to add a multipart form
consumer = new DefaultOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
consumer = new DefaultOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
consumer.setTokenWithSecret("XXXX", "YYYY");
System.out.println("Fetching request token from "
+ REQUEST_TOKEN_ENDPOINT);
PostMethod filePost = new PostMethod("http://..../");
Part[] parts = {
new FilePart("metadata", temp, "application/xml", "UTF8"),
new FilePart("attachment", imageFile, "image/jpeg", null),
};
filePost.setRequestEntity(new MultipartRequestEntity(parts, filePost.getParams()));
HttpClient client = new HttpClient();
int status = client.executeMethod(filePost);
the problem is that to do the consumer.sign(request), to sign the request with oAuth, I need to have an HttpRequest...
so my question is, what can I do to send a multipart POST request with something similar like this using an HttpRequest from apache.
Thanks

Well I reply myself since I solved my problem. I paste here how to do it, hope it may be useful for some body
HttpPost uploadBackgroundPost = new HttpPost ("http://.../");
consumer.sign(uploadBackgroundPost);
MultipartEntity entity = new MultipartEntity (HttpMultipartMode.STRICT);
FileBody tempBody = new FileBody(temp, "application/xml");
FileBody imageBody = new FileBody(imageFile, "image/jpeg");
entity.addPart("metadata", tempBody);
entity.addPart("attachment", imageBody);
uploadBackgroundPost.setEntity(entity);
DefaultHttpClient httpClient = new DefaultHttpClient();
System.out.println(httpClient.execute(uploadBackgroundPost, new BasicResponseHandler()));

Related

Is there any way to bulk delete all permissions of a file using the IGraphServiceClient?

As part of a user action, we are using the MS Graph Java SDK to first list all permissions of a file, then iterating over the list of permissions to delete each one individually. This seems to have some performance issues. We were wondering if there is any way to batch the calls using the IGraphServiceClient.
Relevant APIs used:
https://learn.microsoft.com/en-us/graph/api/driveitem-list-permissions?view=graph-rest-1.0&tabs=http
https://learn.microsoft.com/en-us/graph/api/permission-delete?view=graph-rest-1.0&tabs=http
You can make batch requests.
1. Create MSBatch Request Steps (examples below)
Request requestGetMe = new Request.Builder().url("https://graph.microsoft.com/v1.0/me/").build();
List<String> arrayOfDependsOnIdsGetMe = null;
MSBatchRequestStep stepGetMe = new MSBatchRequestStep("1", requestGetMe, arrayOfDependsOnIdsGetMe);
Request requestGetMePlannerTasks = new Request.Builder().url("https://graph.microsoft.com/v1.0/me/planner/tasks").build();
List<String> arrayOfDependsOnIdsGetMePlannerTasks = Arrays.asList("1");
MSBatchRequestStep stepMePlannerTasks = new MSBatchRequestStep("2", requestGetMePlannerTasks, arrayOfDependsOnIdsGetMePlannerTasks);
String body = "{" +
"\"displayName\": \"My Notebook\"" +
"}";
RequestBody postBody = RequestBody.create(MediaType.parse("application/json"), body);
Request requestCreateNotebook = new Request
.Builder()
.addHeader("Content-Type", "application/json")
.url("https://graph.microsoft.com/v1.0/me/onenote/notebooks")
.post(postBody)
.build();
MSBatchRequestStep stepCreateNotebook = new MSBatchRequestStep("3", requestCreateNotebook, Arrays.asList("2"));
2. Create MSBatch Request Content and get content
List<MSBatchRequestStep> steps = Arrays.asList(stepGetMe, stepMePlannerTasks, stepCreateNotebook);
MSBatchRequestContent requestContent = new MSBatchRequestContent(steps);
String content = requestContent.getBatchRequestContent();
3. Make call to $batch endpoint
OkHttpClient client = HttpClients.createDefault(auth);
Request batchRequest = new Request
.Builder()
.url("https://graph.microsoft.com/v1.0/$batch")
.post(RequestBody.create(MediaType.parse("application/json"), content))
.build();
Response batchResponse = client.newCall(batchRequest).execute();
4. Create MSBatch Response Content
MSBatchResponseContent responseContent = new MSBatchResponseContent(batchResponse);
Response responseGetMe = responseContent.getResponseById("1");
// Use the response of each request

How to convert Office files to PDF using Microsoft Graph

I'm looking for a way to convert Office files to PDF.
I found out that Microsoft Graph could be used.
I'm trying to download converted PDF using Microsoft Graph from OneDrive.
I'd like to convert .docx to .pdf.
However, when I sent the following request, I did not receive a response even if I waited.
GET https://graph.microsoft.com/v1.0/users/{id}/drive/root:/test.docx:/content?format=pdf
Also, the error code is not returned.
If syntax is wrong, an error code will be returned as expected.
It will not return only when it is correct.
In addition, I can download the file if I do not convert.
GET https://graph.microsoft.com/v1.0/users/{id}/drive/root:/test.docx:/content
Is my method wrong or else I need conditions?
If possible, please give me sample code that you can actually do.
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", authResult.AccessToken);
client.BaseAddress = new Uri(graphUrl);
var result = await client.GetAsync("/v1.0/users/xxxxxxxxxxxxxxxxxxxxxxxxx/drive/root:/test.docx:/content?format=pdf");
:
I would like to elaborate a bit Marc's answer by providing a few examples for HttpClient.
Since by default for HttpClient HttpClientHandler.AllowAutoRedirect property is set to True there is no need to explicitly follow HTTP redirection headers and the content could be downloaded like this:
using (HttpClient client = new HttpClient())
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
client.BaseAddress = new Uri("https://graph.microsoft.com");
var response = await client.GetAsync($"/v1.0/drives/{driveId}/root:/{filePath}:/content?format=pdf");
//save content into file
using (var file = System.IO.File.Create(fileName))
{
var stream = await response.Content.ReadAsStreamAsync();
await stream.CopyToAsync(file);
}
}
In case if follow HTTP redirection is disabled, to download the converted file, your app must follow the Location header in the response as demonstrated below:
var handler = new HttpClientHandler()
{
AllowAutoRedirect = false
};
using (HttpClient client = new HttpClient(handler))
{
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
client.BaseAddress = new Uri("https://graph.microsoft.com");
var response = await client.GetAsync($"/v1.0/drives/{driveId}/root:/{filePath}:/content?format=pdf");
if(response.StatusCode == HttpStatusCode.Redirect)
{
response = await client.GetAsync(response.Headers.Location); //get the actual content
}
//save content into file
using (var file = System.IO.File.Create(fileName))
{
var stream = await response.Content.ReadAsStreamAsync();
await stream.CopyToAsync(file);
}
}
The API doesn't return the converted content directly, it returns a link to the converted file. From the documentation:
Returns a 302 Found response redirecting to a pre-authenticated download URL for the converted file.
To download the converted file, your app must follow the Location header in the response.
Pre-authenticated URLs are only valid for a short period of time (a few minutes) and do not require an Authorization header to access.
You need to capture the 302 and make a 2nd call to the URI in the Location header in order to download the converted file.

Forms Authentication Cookie Missing in HttpWebResponse

I am sending a post request from an ASP.NET MVC 2.0 Controller to another site on the same domain using HttpWebRequest. I am sending username and password to logon to the site. That site uses forms authentication. So it sets authentication cookie. But when I get response in HttpWebResponse object, I find cookie neither in cookie container nor inside header (no Cookie or Set-Cookie header found). Let me add some code snippet here used in the MVC controller:
HttpWebRequest httpRequest = (HttpWebRequest) WebRequest.Create(url);
httpRequest.Method = "POST";
httpRequest.ContentType = "application/x-www-form-urlencoded";
httpRequest.ContentLength = postData.Length;
if (httpRequest.CookieContainer == null)
{
//httpRequest.CookieContainer = new CookieContainer();
}
httpRequest.Headers.Add(HttpRequestHeader.Cookie, "a=b");
var streamWriter = new StreamWriter(httpRequest.GetRequestStream());
streamWriter.Write(postData);
streamWriter.Close();
HttpWebResponse httpResponse = (HttpWebResponse) httpRequest.GetResponse();
string postBody = "";
using (StreamReader reader = new StreamReader(httpResponse.GetResponseStream()))
{
postBody = reader.ReadToEnd();
}
return this.Content(postBody);
Please note that I am not using cookie container and cookie header at the same time in HttpWebRequest.
I don't understand what I am missing here to get authentication cookie in web response.
Try to use
request.CookieContainer.Add(new Cookie("a", "b"));
instead of adding cookie as a header.

JIRA rest api to fetch the activity stream

I am trying to get activity stream of my jira instance using the below api and it is not working , can anybody point me in the right direction ?
You should check this page out: https://developer.atlassian.com/docs/atlassian-platform-common-components/activity-streams/consuming-an-activity-streams-feed
The Atom feed of the activity stream works well only if you also log in in your feed reader.
Here is an example of consuming the activity stream through the Jira API using Basic Authentication. This is in C#, but the basic pattern can be applied anywhere:
string myJiraUsername = "username";
string myJiraPassword = "password"; //or API token
string authenticationHeaderValue = Convert.ToBase64String(System.Text.ASCIIEncoding.ASCII.GetBytes(myJiraUsername + ":" + myJiraPassword));
System.Net.Http.HttpClient client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authenticationHeaderValue);
Task<HttpResponseMessage> task = client.GetAsync("https://mycompany.atlassian.net/activity");
task.Wait();
HttpResponseMessage response = task.Result;
string resultOfApiCall = "";
if (response.IsSuccessStatusCode)
{
resultOfApiCall = response.Content.ReadAsStringAsync().Result;
Console.WriteLine("This was returned by your API request:\n" + resultOfApiCall);
}

HttpClient POST request to https

I'm working on a WinRT app that does login to a webpage and get some data. The problem is that I'm getting a "HttpRequestException: An error occurred while sending the request" message. Here is the code:
Uri url = new Uri("https://miyoigo-b.yoigo.com/selfcare/login");
HttpContent msg = new StringContent("account[cli]=" + number + "&password=" + pass);
HttpClientHandler handler = new HttpClientHandler();
handler.UseDefaultCredentials = true;
handler.UseCookies = true;
handler.CookieContainer = new CookieContainer();
HttpClient req = new HttpClient(handler);
req.DefaultRequestHeaders.Add("Host", "miyoigo-b.yoigo.com");
req.DefaultRequestHeaders.ExpectContinue = false;
HttpResponseMessage response = await req.PostAsync(url, msg);
string responseBody = await response.Content.ReadAsStringAsync();
I've been trying a lot of thing I found over the internet, even disabling my firewall, but nothing worked. I'm porting this from a Windows Phone app and it did work with this:
Uri url = new Uri("https://miyoigo-b.yoigo.com/selfcare/login");
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(url);
req.Method = "POST";
req.Headers["Host"] = "miyoigo-b.yoigo.com";
req.CookieContainer = new CookieContainer();
req.BeginGetRequestStream(new AsyncCallback(WriteCallback), req);
And afterwards, in the Callback I created a Stream and wrote the credentials.
Any idea?? I know that the problem is only with this webpage, maybe I'm forgetting to send something or the format of the POST content is not correct...
Thanks
Finally the problema was that Win8 Metro Apps only accepts SSL3.1 and this webpage was using SSL3.0. The solution was using the new version of the webpage.
Thank you all

Resources