Ajax calls to TFS 15 Rest Api stopped working after upgrade - tfs

In TFS 2015 Update 3 everything was working without issues. I used to consume all apis using the npm package request without any problems.
Using jquery the following call also would always complete correctly:
//this used to work in 2015 Update 3
var request = {
url: "https://my_server/tfs/DefaultCollection/_apis/projects?api-version=2.0",
type:'GET',
contentType: "application/json",
accepts: "application/json",
dataType: 'json',
data: JSON.stringify(data),
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", "Basic " + btoa("my_username:my_password"));
}
};
$.ajax(request);
After upgrading to TFS 15 RC2 the above mechanism is not working anymore. The server always returns a 401 - Unauthorized error.
Testing the same call via curl, everything worked out well:
//this works well
curl -u my_username:my_password https://my_server/tfs/DefaultCollectiopis/projects?api-version=2.0
But again failed when I tried to send the credentials in the header, something like this:
//this will fail
curl https://my_server/tfs/DefaultCollection/_apis/projects?api-version=2.0 \
-H "Accept: application/json" \
-H "Authorization: Basic eNjPllEmF1emEuYmFuNppOUlOnVuZGVmaW5lZA=="
Same 401 - Unauthorized error.
I tried to set up my Personal Access token, since it is included in TFS 15 RC2, and do a test as indicated here
$( document ).ready(function() {
$.ajax({
url: 'https://my_server/defaultcollection/_apis/projects?api-version=2.0',
dataType: 'json',
headers: {
'Authorization': 'Basic ' + btoa("" + ":" + myPatToken)
}
}).done(function( results ) {
console.log( results.value[0].id + " " + results.value[0].name );
});
});
and it also fails. However, after replacing myPatToken for my actual password and passing my username as well, then the request completed successfully:
//everything works correctly with the headers like this
headers: {
'Authorization': 'Basic ' + btoa("my_username:my_password")
}
In the nutshell, something is going wrong when I setup the header like this (using jquery):
//this fails
beforeSend: function (xhr) {
xhr.setRequestHeader("Authorization", "Basic " + btoa("my_username:my_password"));
}
And looks like the package npm request, which is the one I'm using, also probably uses the beforeSend property or similar and it's failing.
//this used to work with 2015 Update 3, not anymore after upgrading to 15 RC2
var options = {
url: 'https://my_server/defaultcollection/_apis/projects?api-version=2.0',
method:'GET',
headers: {
'Authorization': "Basic " + btoa("my_username:my_password")
},
json: data
};
request(options, (error, response, body) => {
if (!error && response.statusCode == 200) {
console.log(response);
} else {
console.log(error);
}
});
It makes me think it is probably something in the IIS configuration but Basic Authentication is properly configured. Is there a way to get this working using the package request?
Something changed in the IIS configuration after the upgrade?

The problems got solved after restarting the server, so I guess my case was an isolated situation, not related with TFS it self.
Now sending the request using the request package seems to work well.
However, it is strange that testing it in the browser using jquery still fails. I noticed that
var username = "my_username",
password = "my_password";
btoa(my_username + ":" + my_password); //generates wrong encoded string
generates a different encoded string then simply
btoa("my_username:my_password") //generates right encoded string
The right one is a few characters shorter, this is an example:
eXVuaWQuYmZGV12lpmaW5lZA== //wrong
eXVuaWQuYmZGVsbEAxMw== //correct
No idea why, though.

Related

401 Unauthorized - Chrome App Oauth to invoke Google Cloud Functions

I'm following this: https://developer.chrome.com/apps/tut_oauth
But it doesn't work. When I invoke Cloud Function, I get 401 error. The Authorization: Bearer "access-token" is added in the request header. Although another question here[1] states that ID_TOKEN should be used. Which I tried via curl but have the same 401 error.
chrome.identity.getAuthToken({interactive: true}, function(token) {
var dat = {
"user_email":email_id,
"user_id":user_id
};
$.ajax({
type: "POST",
data:dat,
dataType: 'json',
url:str,
contentType: "application/json",
error: function (xhr, status, error) {
console.log(xhr)
}, success: function (data, status, xhr) {
console.log('Success!' +data + status);
},
headers:{
'x-goog-project-id': 'xxxxxxxxxxxxx',
'Authorization': 'Bearer ' + token,
'Content-Type':'application/json',
'Accept': 'application/json'
}
});
});
[1] Why doesn't granting 'allAuthenticatedUsers' member the 'Cloud Functions Invoker' role work for google cloud functions?
The tutorial that you mentioned used "access-token" to accesses a user's Google contacts using the Google People API and the Chrome Identity API.
If you want to access a Google Cloud Function which does not Allow unauthenticated invocations you have to use an ID_TOKEN.
For testing you can create a service account with --role="roles/cloudfunctions.invoker", then create a key.json file and export the GOOGLE_APPLICATION_CREDENTIALS env variable link
Finaly you can use:
curl "https://us-central1-your-project.cloudfunctions.net/yourfunction"
# Error 403 (Forbidden)
curl "https://us-central1-your-project.cloudfunctions.net/yourfunction" -H "Authorization: bearer $(gcloud auth print-identity-token)"
#Success
I gave up on this as there is no direct solution to invoke Cloud function using oauth in Chrome Apps. The alternative solution that worked is to authenticate via API key. That is using Cloud Function with Cloud Endpoints.
I followed the logic here: https://medium.com/#akash.mahale/triggering-google-cloud-functions-with-cloud-endpoints-and-api-key-857e94a8a3aa
But just need to take note that rotation of API keys should be done regularly and automatically..

Render FileContentResult using javascript

I have an Web API written in Core 2 that returns a FileContentResult.
You need to do a GET with an Auth Token in the header for it to work.
If you try it with postman, the file renders fine and it also renders well in an MVC View.
Now we have an external Salesforce system trying to consume the API but due to the limitations of the APEX language they have to use Javascript to inject the token into the GET method.
Example code:
$(document).ready(function() {
$.ajax({
type: 'GET',
url: 'https://file-store.com/document/{! docId}',
headers: {
'Authorization': 'Bearer {! oauthToken}',
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}).done(function (data) {
console.log(data);
});
});
This seems to work as the "data" that is returns contains a file - or at least an array of squiggles that look like the file serialized.
However, there seems to be no way to get the web view to render this.
I tried using embed
var object = '<embed scr="' + data + '" />';
or using an iframe
$('#iFrame').html(data);
or
$('#iFrame').html(object);
and lots of other things but so far had no success.
I do understand that in MVC this is simple, but is it at all feasible using javascript?
We do successfully receive the file, and we do have the data in memory, I just need way to render it on the browser.
Any suggestion is very welcome

Authorization Token is not being received by Django server from ios - React native

When I do a request using Fetch (in ios) from a react native app with a Django backend, the header Authorization Token is not being received, but the others headers are.
I try using nc -l 8090 just to check out if the app was correctly sending the header and it was there. Also, this just happens in the ios version, the android one works just fine.
At checking the Django backend, the Authorization Token is not being received ( I printed what i got in the authentication.py file )
I put the fetch code here:
let response = fetch('http://xxx.xxx.x.xxx:8000/' + 'users', {
method: 'GET',
headers: {
'content-type': 'application/json',
'x-app-key': xxxxxxxxxx,
'Authorization': 'Token xxxxxxxxxxxxxxxxxxxx'
}
}).then((response) => {...}
The error message that im getting in the response is "403 django standar not valid authentication".
I'm not using OAuth2. Any other information that could provide, please let me know and thank you for any help.
Something weird that I just noticed is that when I use the nc cmd (lc -l 8000), at the port 8000, it has the same behavior. The authorization token is not being received.
I solved my problem added a slash at the end of the URL.
let response = fetch('http://xxx.xxx.x.xxx:8000/' + 'users/', {
method: 'GET',
headers: {
'content-type': 'application/json',
'x-app-key': xxxxxxxxxx,
'Authorization': 'Token xxxxxxxxxxxxxxxxxxxx'
}
}).then((response) => {...}
I had a variation of this issue with a backend using the laravel framework. I finally resolved it by using the following in the .htaccess file of the public folder.
# Handle Authorization Header
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^ - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
Combined with one other important factor in my case, losing the trailing slash from the url in the fetch.
Hope this helps, either way. Good luck.

JIRA Worklog API not working

I am trying to log work in JIRA using the Web API :-
My data is:
var post = {};
post.commment = "Test";
post.timeSpent = "6h";
My Ajax call is:
$.ajax({
url: lv_url,
type : 'POST',
data : post,
headers: {
Accept : "application/json; charset=utf-8",
},
contentType: "application/json; charset=utf-8",
dataType : 'json',
xhrFields: {
withCredentials: true
},
async: false,
success : function(data) {
}
});
https://jiraserver.co/rest/api/2/issue/SOCOMPT-1575/worklog
"GET" call is working fine but when i try to POST i get the error:-
1) OPTIONS https://jiraserver.co/rest/api/2/issue/SOCOMPT-1575/worklog 500 (Internal Server Error)
2) XMLHttpRequest cannot load https://jiraserver.co/rest/api/2/issue/SOCOMPT-1575/worklog. Invalid HTTP status code 500
These are the 2 errors is get.
Please Help Guys i really need to get this working.
Thanks in advance,
Vishesh.
I was also strugging on this one as I kept getting HTTP 500 when trying to post to the worklog endpoint.
if you are able check the jira server logs (under logs/catalina.out)
jira seems to be very picky with the iso8601 date format
Try setting also the "started" timestamp in your payload as I believe this is required (for the API like the web UI) even if the documentation is not really clear on that.
post.started = '2015-02-25T14:01:30.000-0500';

Why am I suddenly getting an error about no Access-Control-Allow-Origin header?

Yesterday, I was happily making API calls to SurveyMonkey from my local development machine (http://localhost:nnnn)
This morning however (after changing exactly nothing), I'm suddenly getting the following error:
XMLHttpRequest cannot load https://api.surveymonkey.net/v2/surveys/get_survey_list?api_key=xxxxxxxxxx. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:8500' is therefore not allowed access. The response had HTTP status code 596.
The code I'm using which generates this error is the following:
$.ajax({
url: 'https://api.surveymonkey.net/v2/surveys/get_survey_list?api_key=xxxxxxxxxx',
type: 'post',
contentType: 'application/json',
cache: false,
dataType: 'json',
data: JSON.stringify({
survey_id: 'nnnnnnnn',
respondent_ids: respondents //respondents is an array defined elsewhere
}),
headers:{
Authorization: 'bearer ' + local.SurveyMonkey.AccessToken,
'Content-Type': 'application/json'
},
success: function(survey, textStatus, jqXHR){
$('#SMResults').empty().append('<br />'+textStatus);
$p.fnLog(survey.data);
$p.fnLoadView('surveyView.cfm','SMResults',survey);
},
error: function(jqXHR, textStatus){
$('#SMResults').empty().append('Oh nos!! Something went wrong!');
$p.fnLog(jqXHR);
$p.fnLog('----------------------');
$p.fnLog(textStatus);
},
complete: function(jqXHR, textStatus){
$('#SMResults').append("<br /><br />We're done.");
}
});
Again, this code was working brilliantly last night. My attempts to turn this into a JSONP call failed. :(
Any idea what's going on? Why could I happily make these calls yesterday, but not today?
Thanks for reading.
UPDATE: It turns out upon further inspection of the response headers I'm getting:
X-Mashery-Error-Code: ERR_596_SERVICE_NOT_FOUND
Which is why there's not the appropriate Access-Control header in the response. Any idea what's up with Mashery? or Where I should be looking?
UPDATE 2: I'm feeling much more confident that this is a SurveyMonkey/Mashery problem. I just now visited the SurveyMonkey API Console page and it informed me that the console is experiencing a problem and that they're working to fix it.
I'm guessing that this is just a symptom of a larger problem.

Resources