How to pass through `ember-cli-mirage` request to a specific API and Host - ember.js

I am trying to use passthrough feature of ember-cli-mirage to allow my app to request to different API and Host.
export default function() {
//window.server = this;
//this.namespace = 'api';
this.passthrough('locales/en/translation.json');
this.get('/api/customers');
this.passthrough();
this.host='https://abcd.site.com';//need something like this, but not working
this.namespace = 'api/Service.svc';
};
I want to point the requests to outside of the environment where current ember server is running.
But the requests which are passing through fixed URL's like /api/authenticate.
It is throwing exceptions as follows.
POST http://localhost:4200/api/authenticate 404 (Not Found)
I want configure the requests to something like this below
https://abcd.site.com/api/Service.svc/authenticate
Is there any option available in ember-cli-mirage/ pretender? Please help.

Passthrough is correct. Just give the full url as parameter, like:
this.passthrough('https://abcd.site.com/api/Service.svc/authenticate');
Take a look at the twitter example here: http://www.ember-cli-mirage.com/docs/v0.2.x/route-handlers/

Related

ckan.toolkit.redirect_to does not redirect

I'm currently developing an ckan extension, where i need to redirect to a url on a different domain.
In my plugin i defined a custom action function:
#side_effect_free
def download_json(context, data_dict):
toolkit.redirect_to('http://my.json-builder.com?id=1234')
But when i call this endpoint i just get following response:
response screenshot
So i assume that the action function is called, but the redirect_to call does not redirect to the url i defined.
Thanks for your help!
Florian
It's a bit hard to figure out what you're trying to accomplish but here's a few things I hope will help.
Short Answer:
No, you can't redirect from an API endpoint in CKAN. The endpoint response in CKAN is built up and expects certain things from your action. Your action should return some kind of result. In your case it's returning nothing but trying to redirect. A logic action function with IActions is not the same as a Blueprint or pylons controller action.
See Making an API request docs, specifically the breakdown of an API response in CKAN. Also, you can review the pylons implementation that builds up the API response or the flask blueprints implementation.
More Info to help with your approach:
You say you are trying to call an endpoint that redirects a user to a different domain url. Based on this consider the following:
The first thing I thought you wanted was to have a url that someone goes to through the web interface of your site and are redirected to another site. In this case your example code of toolkit.redirect_to('http://my.json-builder.com?id=1234') makes sense and works for a custom controller action using/implemented with IRoutes or if you're using flask then IBlueprint. A User would go to a URL on your site such as http://localhost.com/download_json and be redirected to the new URL/site in their browser.
If you are intending this to be an API call for other users this starts to feel a little bit odd. If a user is using your API, they would expect to get results from your site in JSON CKAN's API is designed to return JSON. Someone consuming your API endpoint would not expect to be redirected to another site e.g. if I called http://localhost.com/api/3/action/download_json I would expect to get a JSON object like
{
help: "http://localhost/api/3/action/help_show?name=download_json",
success: true,
result: {
...
}
}
They would look for success to make sure the call worked and then they would use the result to keep moving forward with their desired processes. If you do want someone via an API to get redirect info I'd likely return the redirect url as the result e.g. result: {'redirect_url': 'http://my.json-builder.com?id=1234'} and document this well in your extension's API docs (e.g. why you're returning this endpoint, what you expect someone to do with it, etc).
If this is an API call for your own extension I'm guessing what you are trying to do is use my.json-builder.com to build a json of something (a dataset maybe?) and return that json as the result at your endpoint or maybe even consume the result to make something else? If that's the case, then in your function you could make the call to my.json-builder.com, process the results and return the results to the user. In this case, you're not actually wanting to redirect a user to a new site but instead make a call to the new site to get some results. If you actually want the results for your extension you don't need an additional endpoint. You could make the call from your extension, consume the results and return the desired object you're trying to create.
Hope this helps and sorry if I've miss-understood completely.

Restangular fails with promise and cross-origin requests

I am reading about Restangular and everywhere is mentioned that Restangular promises and Angular works smart and the template is updating in situations like this:
As Angular supports setting promises to scope variables as soon as we
get the information from the server, it will be shown in our template
$scope.something = Restagular.one('something').get();
I am trying to do the same thing but the Restangular is in a service because I want to keep my controllers clean. When I make a request to my REST API the Angular template is not updating and I receive this error:
XMLHttpRequest cannot load http://localhost:3000/api/template/1. The request was redirected to 'http://localhost:3000/api/template/1/', which is disallowed for cross-origin requests that require preflight.
Here is my code:
in the service...
myAppServices.service('TemplateService', ['$http', '$cookies', '$cookieStore', Restangular',
function($http, $cookies, $cookieStore, Restangular) {
Restangular.setBaseUrl(constants.serverAddress);
var getTemplate = function(templateId) {
// Check the input
if (!isValidId(templateId))
return;
return Restangular.one('api/template', templateId).get();
};
// Public getters
this.getTemplate = getTemplate;
}]);
in the controller..
$scope.currentCard = TemplateService.getTemplate(1);
So where is the problem in this case - on the client or on the server. For my API I am using django-rest-framework but I don't have problems when I am getting list with all templates (without a specific id).
I know that I can try to return a promise from the service and from its .then() to set my scope variable but in the official repo of Restangular is mentioned this and I want to use it because the code remains clean.
The issue that you are having is because Django will automatically redirect urls without a slash to urls with a slash. This isn't framework specific, as I recently discovered it is an issue for ExtJS as well.
Because you are requesting the url api/templates/1 without the trailing slash and the API is being served at api/templates/1/, Django is automatically redirecting requests from one location to the other. Normally this issue an issue, you just see the redirect happening in the console and nobody cares, but CORS requires you to have permission for the url you requested, which means it can't redirect.
You can fix this two different ways: on the client side or on the server side.
If you want to fix this on the client side, and keep the server requiring slashes, you need to tell restangular to add a slash to the end. Restangular allows you to do this by setting
RestangularProvider.setRequestSuffix('/');
In your code, which will tell restangular to always add the trailing slash.
If you want to fix this on the server side, you are going to need to stop requiring slashes in your API. This has the unpleasant side effect of not allowing any requests with a slash, and may break existing applications which are working as expected. Django REST Framework allows you to do this on the router level by setting trailing_slash=False when initializing the router.
router = SimpleRouter(trailing_slash=False)
This will tell Django REST Framework to register all of the urls without a trailing slash.

EmberJs as a PhoneGap with external API

please can you advise on the following:
I have a web application written in emberjs with Rails as back-end. And now I'm going to port this application with phonegap to iOS, and the thing that I'm struggling is how to set my API endpoint that will be working in iPhone?
As I understand EmberJs when used on the web via browser, uses your current location to issue API requests, but this approach doesn't working when using the application as iOS app.
I'm really looking for some elegant solution to simply replace the host name or something?
Thanks for help!
UPDATE:
This one works for changing the API URL
DS.RESTAdapter.reopen({
url: 'http://somedomain.com'
});
But now, there is access-controll issue:
Origin http://somedomain.com is not allowed by Access-Control-Allow-Origin.
Since you haven't posted any code on how your adapter is configured, this is the right way to set a custom url for your adapter:
DS.RESTAdapter.reopen({
url: 'https://somedomain.com/api'
});
Then if you have a model e.g. App.User, the requests for the list of App.User would now go to https://somedomain.com/api/user/ and for a specific user id to https://somedomain.com/api/user/123 respectively.
Update
When testing from the browser you have to start the browser (assuming chrome) with the flag --disable-web-security to make cross origin work. But in real live you have to configure your server to set the response HTTP HEADERS using:
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, ...
So in the case of rails you could do something like this to configure your controllers serverside to accept cross origin requests and set the headers accordingly:
...
after_filter :cors_set_access_control_headers
def cors_set_access_control_headers
headers['Access-Control-Allow-Origin'] = '*'
headers['Access-Control-Allow-Methods'] = 'POST, GET, PUT' # etc. etc.
headers['Access-Control-Max-Age'] = "1728000"
end
...
For more extensive examples on how to configure CORS for rails you could search for "CORS for JSON and Rails" for example.
Hope it helps

Testing WebAPI actions that have authorization filters

I’ve got a Web API that I’ve added [Authorize] attributes to, which means that the unit tests I had previously now fail due to them being unauthorised. Here’s a sample of a basic test along with an initialiser method:
[TestInitialize]
public void CreateServer() {
var config = new HttpConfiguration();
WebApiConfig.Configure(config); // Create the routes
var server = new HttpServer(config);
this.client = new HttpClient(server);
}
[TestMethod]
public void MyThings_GET_Returns_All_MyThings() {
var response = this.client.GetAsync("http://localhost/api/1.0/mythings").Result;
var mythings = response.Content.ReadAsAsync<IEnumerable<MyThing>>().Result;
Assert.AreEqual(HttpStatusCode.OK, response.StatusCode);
Assert.AreEqual(4, mythings.Count());
}
What I’m wondering is if there’s any way that I can either make my test log in so that it passes the authorization filter, or if there’s any way that I can pass as ASPXAUTH cookie along with the HttpClient request? Or another way of passing authorization that I haven’t thought of?
Nothing I’ve tried seems to work and I’m struggling to find any helpful info anywhere.
Thanks in advance.
What does your Authorize attribute do when it performs the authorization check? There are quite a few options that come to mind:
Have the authorize filter support multiple means of getting the "authorization token" that it requires (e.g. through an HTTP header or a querystring parameter, etc)
Right after your test initialization, clear out the filter from the configuration (so that it is not called at all). If you choose to go this route then you may wish to pop in a new filter that sets any authorization values that might be used further along the pipeline
If you are using dependency injection, move the "authorization check" into some sort of IAuthorize location that can be updated in your configuration
I would also recommend using RestSharp for making queries to your endpoints as it does a very good job of specifying headers, parameters, etc.
I decided that the way I was going about the problem was fundamentally wrong. Using cookie-based authorisation with Web API is just not a good idea, so I’ve decided to get rid of the authorize attributes and perform API-Key-based authentication instead. This makes it easier to test as I can just pass the correct API key in the request, but also means that I’m not relying on cookies for authorisation.

How do I capture (in Fiddler) the HTTP requests issued by Nancy.Testing.Browser

I have the following NancyFX unit test.
var browser = new Browser(new UnitTestBootstrapper());
var response = browser.Post("/login", with =>
{
with.FormValue("UserName", userName);
with.FormValue("Password", password);
});
response.ShouldHaveRedirectedTo("/home");
You can see that I use an instance of Nancy.Testing.Browser to POST some form values. I would like to capture this Http request in Fiddler but I am not sure how to set-up the Browser (a proxy perhaps?)
Thanks
You can't because they never hit the network; that's the whole point of the browser class - to give you end to end testing without the performance hit/configuration issues of having to use hosting/http/networking/browser rendering.
If you want to go via the networking stack then use something like Selenium, or spin up a self host and poke it with EasyHttp or manually with HttpClient.