Get file list from owncloud - c#

I want to get file list from owncloud on my ASP site. I was succeed using
curl -X PROPFIND -u user:password "http://yourserver.com/owncloud/remote.php/webdav/" from linux but I can't get the same result using default http request with propfind type in order to use it then in c# https://user:password#host/owncloud/remote.php/webdav. I get 400 code as a result on my request. Also I tried webdavclient from nuget but received method not allowed exception.
IClient c = new Client(new NetworkCredential { UserName = "user", Password = "password" });
var client = new WebDAVClient.Client(new NetworkCredential());
c.Server = "xxx.com/owncloud/remote.php/webdav/";
var isfolderCreated = c.CreateDir("/", "lalala").Result;
Could anybody say to me how to send http request to owncloud to get the file list? I tried webdav protocol that is used by clients but maybe I should try anything else?

I found the issue that prevented me. I just didn't use basic authorization correctly in http request. Since I add correct credentials I could send the http request and get the response. And here is the code I use in c#:
var request = (HttpWebRequest)WebRequest.Create("xxx.com/owncloud/remote.php/webdav/");
request.Credentials = new NetworkCredential("user", "password");
request.PreAuthenticate = true;
request.Method = #"PROPFIND";
request.Headers.Add(#"Translate", "F");
var httpGetResponse = (HttpWebResponse)request.GetResponse();
using (var responseStream = httpGetResponse.GetResponseStream())
{
long responseLength = httpGetResponse.ContentLength;
using (var streamReader = new StreamReader(responseStream, Encoding.UTF8))
{
var files = XElement.Parse(streamReader.ReadToEnd());
streamReader.Close();
}
responseStream.Close();
}

Related

C#: HttpWebRequest POST data not working

I am developing a C# wpf application that has a functionality of logging into my website and download the file. This said website has an Authorize attribute on its action. I need 2 cookies for me to able to download the file, first cookie is for me to log in, second cookie(which is provided after successful log in) is for me to download the file. So i came up with the flow of keeping my cookies after my httpwebrequest/httpwebresponse. I am looking at my posting flow as maybe it is the problem. Here is my code.
void externalloginanddownload()
{
string pageSource = string.Empty;
CookieContainer cookies = new CookieContainer();
HttpWebRequest getrequest = (HttpWebRequest)WebRequest.Create("login uri");
getrequest.CookieContainer = cookies;
getrequest.Method = "GET";
getrequest.AllowAutoRedirect = false;
HttpWebResponse getresponse = (HttpWebResponse)getrequest.GetResponse();
using (StreamReader sr = new StreamReader(getresponse.GetResponseStream()))
{
pageSource = sr.ReadToEnd();
}
var values = new NameValueCollection
{
{"Username", "username"},
{"Password", "password"},
{ "Remember me?","False"},
};
var parameters = new StringBuilder();
foreach (string key in values.Keys)
{
parameters.AppendFormat("{0}={1}&",
HttpUtility.UrlEncode(key),
HttpUtility.UrlEncode(values[key]));
}
parameters.Length -= 1;
HttpWebRequest postrequest = (HttpWebRequest)WebRequest.Create("login uri");
postrequest.CookieContainer = cookies;
postrequest.Method = "POST";
using (var writer = new StreamWriter(postrequest.GetRequestStream()))
{
writer.Write(parameters.ToString());
}
using (WebResponse response = postrequest.GetResponse()) // the error 500 occurs here
{
using (var streamReader = new StreamReader(response.GetResponseStream()))
{
string html = streamReader.ReadToEnd();
}
}
}
When you get the WebResponse, the cookies returned will be in the response, not in the request (oddly enough, even though you need to CookieContainer on the request).
You will need to add the cookies from the response object to your CookieContainer, so it gets sent on the next request.
One simple way:
for(var cookie in getresponse.Cookies)
cookies.Add(cookie)
Since the cookies in response is already a cookies container, you can do this (might help to check for null in case all cookies were already there)
if (response.Cookies != null) cookies.Add(response.Cookies)
You may also have trouble with your POST as you need to set ContentType and length:
myWebRequest.ContentLength = parameters.Length;
myWebRequest.AllowWriteStreamBuffering = true;
If you have any multibyte characters to think about, you may have to address that as well by setting the encoding to UTF-8 on the request and the stringbuilder, and converting string to bytes and using that length.
Another tip: some web server code chokes if there is no user agent. Try:
myWebRequest.UserAgent = "Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)";
And just in case you have any multibyte characters, it is better to do this:
var databytes = System.Text.Encoding.UTF8.GetBytes(parameters.ToString());
myWebRequest.ContentLength = databytes.Length;
myWebRequest.ContentType = "application/x-www-form-urlencoded; charset=utf-8";
using (var stream = myWebRequest.GetRequestStream())
{
stream.Write(databytes, 0, databytes.Length);
}
In C# Application (Server side Web API) Enable the C++ Exception and Common Language Run time Exceptions using (Ctrl+Alt+E) what is the Server side Exception it's throw.
First you check data is binding Properly. After you can see what it is Exact Exception. the Internal Server Error Mostly throw the data is not correct format and not properly managed Exception.

OneLogin Create Session Login Token API returns status 400 with message: Bad Request

I am developing a C# application which needs to use the onelogin API to retrieve a session token. I am able to authenticate and and create a token with the following code:
WebRequest Authrequest = WebRequest.Create("https://api.us.onelogin.com/auth/oauth2/token");
Authrequest.Method = "POST";
Authrequest.ContentType = "application/json";
Authrequest.Headers.Add("cache-control", "no-cache");
Authrequest.Headers.Add("Authorization: client_id:XXXXXXX7bbf2c50200d8175206f664dc28ffd3ec66eef0bfedb68c3366420dc, client_secret:XXXXXXXXXX6ba2802187feb23f6450c6812b8e6639361d24aa83f12010f ");
using (var streamWriter = new StreamWriter(Authrequest.GetRequestStream()))
{
string Authjson = new JavaScriptSerializer().Serialize(new
{
grant_type = "client_credentials"
});
streamWriter.Write(Authjson);
}
WebResponse AuthReponse;
AuthReponse = Authrequest.GetResponse();
Stream receiveStream = AuthReponse.GetResponseStream ();
// Pipes the stream to a higher level stream reader with the required encoding format.
StreamReader readStream = new StreamReader (receiveStream);
JObject incdata = JObject.Parse(readStream.ReadToEnd());
string sToken = incdata["data"][0]["access_token"].Value<string>();
AuthReponse.Close();
However, when running the Create Session Login Token with the following code, it only returns a 400 error, and the message has no detail. Just Bad Request:
//Get the session token for the specified user, using the token recieved from previous web request
WebRequest request = WebRequest.Create("https://api.us.onelogin.com/api/1/login/auth");
request.Method = "POST";
request.ContentType = "application/json";
request.Headers.Add("authorization", "bearer:" + sToken);
using (var streamWriter2 = new StreamWriter(request.GetRequestStream()))
{
string json = JsonConvert.SerializeObject(new
{
username_or_email = sUsername,
password = sPassword,
subdomain = "comp-alt-dev"
});
streamWriter2.Write(json);
}
WebResponse response;
response = request.GetResponse();
string streamText = "";
var responseStream = response.GetResponseStream();
using (responseStream)
{
var streamReader = new StreamReader(responseStream);
using (streamReader)
{
streamText = streamReader.ReadToEnd();
streamReader.Close();
//
}
responseStream.Close();
}
Any ideas?
-Thank you
Also for anyone who may be getting this error. in C# the email is case sensitive. I tried User.email.com. In onelogin it was saved as user#email.com. changing the c# to lower case fixed it.
Can you let us know what payload you're sending across the wire to the .../1/login/auth endpoint as well as the response (either as others have suggested as packet snoop, or just as a debug output from the code)
400 means either bad json or the endpoint requires MFA, so this will narrow it down.
~thanks!
Just joining the troubleshooting effort =) -- I can replicate a 400 Bad Request status code with a "bad request" message when the request body contains a username_or_email and/or subdomain value that does not exist, or if the request body is empty.
Can you post what goes over the wire to the OneLogin endpoint...
OK Thanks. So it appears your subdomain does not exist. If you give me an email in the account I can find the correct subdomain value for you.

Insert photo ERROR: The remote server returned an error: (403) Forbidden

I need your help!.
Im trying to insert a new photo into a Picasa Album using Oauth 2.0 and a simple HttpRequest process. The result is that I cant insert a new photo into my Picasa web album after following the instructions listed on: https://developers.google.com/picasa-web/docs/2.0/developers_guide_protocol#Auth
I also have to say that I tried using the .Net library that they provide with the same results.
The implementation that I'm using now is the following:
public static string PostImage(
string streamImageConvertedToString)
{
string url = string.Format("https://picasaweb.google.com/data/feed/api/user/{0}/albumid/{1}", "username#gmail.com", "idAlbum");
HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.ContentType = "image/jpeg";
request.ContentLength = Encoding.UTF8.GetByteCount(data);
request.Method = "POST";
request.Headers.Add("GData-Version", "2");
request.Headers.Add("Slug", "cute_baby_kitten.jpg");
request.Headers.Add("Authorization", "Bearer " + GetToken());
if (data != null)
{
using (StreamWriter writer = new StreamWriter(request.GetRequestStream()))
{
writer.Write(data);
}
}
HttpWebResponse response = request.GetResponse() as HttpWebResponse;
string result = string.Empty;
using (StreamReader reader = new StreamReader(response.GetResponseStream()))
{
result = reader.ReadToEnd();
}
return result;
}
private static string GetToken() {
const string ServiceAccountEmail = "someid#developer.gserviceaccount.com";
var servicio = new PicasaService(null);
var certificate = new X509Certificate2(HttpContext.Current.Server.MapPath("/key2.p12"), "notasecret", X509KeyStorageFlags.Exportable);
var serviceAccountCredentialInitializer =
new ServiceAccountCredential.Initializer(ServiceAccountEmail)
{
Scopes = new[] { "https://picasaweb.google.com/data/" }
}.FromCertificate(certificate);
var credential = new ServiceAccountCredential(serviceAccountCredentialInitializer);
if (!credential.RequestAccessTokenAsync(System.Threading.CancellationToken.None).Result)
throw new InvalidOperationException("Access token request failed.");
return credential.Token.AccessToken;
}
Any help is welcome!!
(403) Forbidden
Means that you are trying to use a method insert which requires authorization to do.
you are connecting to service account someid#developer.gserviceaccount.com which should give you access to someid#developer.gserviceaccount.com pictures then.
you appear to be trying to access username#gmail.com unless you have given someid#developer.gserviceaccount.com access to insert pictures on behalf of username#gmail.com (Which I am not even sure is possible) you are not going to have permission to do this.
Remember a service account is a sudo user it has its own drive account, calendar account ... it does not have access to a random users data unless that user has given them access like they would any other user.
Note: Google .net client library does not support gdata APIs. Picasa is a gdata library I like how are trying to merge the two I am have to test this.
You're best (imho) approach would be to forget libraries and forget service accounts. Get a refresh token for the google user account you're trying to insert to, and use the raw HTTP REST API to invoke Picasa.

Calling Eventbrite API from .Net results in 401

I am trying to retrieve an order from the Eventbrite API. I have a valid OAuth token and order number. I have verified this by using postman which successfully returns the correct JSON.
However when I make the call using the following c# code, I get a 401 Unauthorised:
var client = new HttpClient();
var req = new HttpRequestMessage(HttpMethod.Get, "https://www.eventbriteapi.com/v3/orders/{orderNo}");
req.Headers.Add("Authorization", "Bearer {authToken}");
var response = await client.SendAsync(req);
I've tried replacing the header with:
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("{authToken}");
I have also tried:
HttpWebRequest request = (HttpWebRequest)WebRequest.Create("https://www.eventbriteapi.com/v3/orders/{orderNo}");
request.Headers.Add("Authorization", "Bearer {authToken}");
request.Accept = "application/json";
using(WebResponse response = request.GetResponse())
{
using(Stream dataStream = response.GetResponseStream())
{
using(StreamReader reader = new StreamReader(dataStream))
{
string responseFromServer = reader.ReadToEnd();
}
}
}
All of these get a 401 response.
I know the authtoken and the eventid are correct, so there must be something wrong with my code.
Am I doing something wrong with the authroisation token?
Have you tried ?token={authToken} option on the EventBrite API?
This would at least confirm if it's a problem with the way the header is being sent across.
http://developer.eventbrite.com/docs/auth/
You omitted the trailing '/' in the URL, which caused a subsequent redirect from "eventbriteapi.com/v3/orders/{orderNo}" to "eventbriteapi.com/v3/orders/{orderNo}/". The authorization header was dropped in the redirect.

Can't access Web of Trust (WoT) API w/ JSON.Net

I'm new to JSON & am using VS 2013/C#. Here's the code for the request & response. Pretty straightforward, no?
Request request = new Request();
//request.hosts = ListOfURLs();
request.hosts = "www.cnn.com/www.cisco.com/www.microsoft.com/";
request.callback = "process";
request.key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
string output = JsonConvert.SerializeObject(request);
//string test = "hosts=www.cnn.com/www.cisco.com/www.microsoft.com/&callback=process&key=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";
try
{
var httpWebRequest = (HttpWebRequest) WebRequest.Create("http://api.mywot.com/0.4/public_link_json2?);
httpWebRequest.ContentType = "application/json";
httpWebRequest.Method = "POST";
using (var streamWriter = new StreamWriter(httpWebRequest.GetRequestStream()))
{
string json = output;
streamWriter.Write(json);
}
var httpResponse = (HttpWebResponse) httpWebRequest.GetResponse();
using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
var responseText = streamReader.ReadToEnd();
}
}
catch (WebException e)
{
MessageBox.Show(e.ToString());
}
//response = true.
//no response = false
return true;
}
When I run this, I get a 405 error indicating method not allowed.
It seems to me that there are at least two possible problems here: (1) The WoT API (www.mywot.com/wiki/API) requires a GET request w/ a body, & httpWebRequest doesn't allow a GET in the httpWebRequest.Method; or (2) the serialized string isn't serialized properly.
NOTE: In the following I've had to remove the leading "http://" since I don't have enough rep to post more than 2 links.
It should look like:
api.mywot.com/0.4/public_link_json2?hosts=www.cnn.com/www.cisco.com/www.microsoft.com/&callback=process&key=xxxxxxxxxxxxxx
but instead looks like:
api.mywot.com/0.4/public_link_json2?{"hosts":"www.cnn.com/www.cisco.com/www.microsoft.com/","callback":"process","key":"xxxxxxxxxxxxxxxxxxx"}.
If I browse to:api.mywot.com/0.4/public_link_json2?hosts=www.cnn.com/www.cisco.com/www.microsoft.com/&callback=process&key=xxxxxxxxxxxxxx; I get the expected response.
If I browse to: api.mywot.com/0.4/public_link_json2?{"hosts":"www.cnn.com/www.cisco.com/www.microsoft.com/","callback":"process","key":"xxxxxxxxxxxxxxxxxxx"}; I get a 403 denied error.
If I hardcode the request & send as a GET like below:
var httpWebRequest = (HttpWebRequest) WebRequest.Create("api.mywot.com/0.4/public_link_json2? + "test"); it also works as expected.
I'd appreciate any help w/ this & hope I've made the problem clear. Thx.
Looks to me like the problem is that you are sending JSON in the URL. According to the API doc that you referenced, the API is expecting regular URL encoded parameters (not JSON), and it will return JSON to you in the body of the response:
Requests
The API consists of a number of interfaces, all of which are called using normal HTTP GET requests to api.mywot.com and return a response in XML or JSON format if successful. HTTP status codes are used for returning error information and parameters are passed using standard URL conventions. The request format is as follows:
http://api.mywot.com/version/interface?param1=value1&param2=value2
You should not be serializing your request; you should be deserializing the response. All of your tests above bear this out.

Categories

Resources