Apigility InputFilter injection - laminas-api-tools

Given I am posting to an endpoint as so:
POST http://foo.com/user/:user_id/articles
{
"content": "some text"
}
when I configure the Validator within the config I am struggling to find how to inject the :user_id from the route along with the "content" from the body. So my Validator is stuck trying to validate if "content" is ok without the :user_id.
What is the proper Apigility way to inject IDs (or even ideally objects) from route parameters into the Validator(s) along with the normal body $data payload?
Many thanks

As far as i know, apigility has no way to validate the route parameters.
Personally i validate them in de resource or the controller.
That way i can do some more complex validation, like does this id exist?
If you want an object as a route parameter, you van try serializing the object and putting that in your parameter.
But i would advice against this. Would you even trust an external party to provide you with whole objects?
If you need some user info you could look into JWT or similar techniques.
JWT is a authorisation token that also contains any data (it's json based).
Now, any body params can be validated.
In the apigility ui, you can go to fields, and add the fields you want to validate there (or it should be all of them for simplicity).
Then you can assign filters and validators here. Even custom ones you have configured in your zf2 application.

Related

Custom Header with token in PASOE Business Class Entity with Web Service?

I have a PASOE Business Class Entity setup as a Web Service. I'm trying to determine how to create a custom header that will allow me to pass in a hashed token. Is this something that I need to upgrade to 11.7.4 for DOH(OpenEdge.Web.DataObject.DataObjectHandler)? Or is this something that I simply add into a method that's defined in the class? Apologies, for the lack of code to illustrate my situation, but I'm not sure where to begin.
If you're using a Business Entity with the web transport then you're using the DOH, and the below applies. If you're using the rest transport then you are not using the DOH, and are more limited in your choices.
There is doc available on the DOH at https://documentation.progress.com/output/oe117sp/index.html#page/gssp4/openedge-data-object-handler.html - it's for 11.7.4 but largely applies to all versions (that is, from 11.6.3+). This describes the JSON mapping file, which you'll need to create an override to the default, generated one.
If you want to use the header's value for all operations, then you may want to use one of the DOH's events. There's an example of event handlers at https://github.com/PeterJudge-PSC/http_samples/blob/master/web_handler/data_object_handler/DOHEventHandler.cls ; you will need to start that handler in a session startup procedure using new DOHEventHandler() (the way that code is written is that it makes itself a singleton).
You can now add handling code for the Invoking event which fires before the business logic is run.
If you want to pass the header value into the business logic you will need to
Copy the generated mapping file <service>.gen to a <service.map> , in the same folder. "gen" files are generated and will be overwritten by the tooling
In the .map file, add a new arg entry. This must be in the same order as the parameters to the BE's method.
The JSON should look something like the below. this will read the value of the header and pass it as an input parameter into the method.
{ "ablName": "<parameter_name>",
"ablType": "CHARACTER",
"ioMode": "INPUT",
"msgElem": {"type": "HEADER", "name": "<http-header-name>"}
}

Symfony2: Why weren't query string parameters included in the routing component?

I am porting a legacy application to Symfony2 and I am struggling because routing doesn't include query string parameters. Some quick examples: Suppose you have a search page for books where you can filter results based on criteria:
http://www.bookstore.com/books?author=Stephen+King&maxPrice=20
The nice thing about query string parameters in a case like this is you can have any number of filters, use the ones you want for any given request, and not crowd the URL with filters you're not using.
Let's say we rewrote the routing for the above query using the Symfony2 routing component. It might look like this:
http://www.mybookstore.com/book/any_title/stephen%20king/any_release_date/max_price_20/any_min_price/any_format/any_category
Even not taking into account how arbitrarily long an unclean that URL is I still don't think it is as intuitive because each 'segment' of that route is not a key value pair but instead just a value (e.g. author=Stephen+King > /stephen%20king/).
You can of course access query string parameters in the controller by passing the Request object into the action method (e.g. indexAction(Request $request) {) but then validating them and passing them into other parts of the application becomes a hassle (i.e. where I find myself now). What if you are using the Knp Menu Bundle to build your sidebar and you want parts to be marked as .current based on query string parameters? There is no functionality for that, just functionality to integrate with Symfony2 routes.
And how to validate that your query string parameters are acceptable? I am currently looking at validating them like a form to then pass them into the database to generate a query. Maybe this is the way the Symfony2 team envisioned handling them? If so I'd just really like to know why. It feels like I'm fighting the application.
I ended up actually asking Fabien this question at Symfony Live San Francisco 2012. There was another talk at the same conference in regards to this question and I will share with you the slides here:
http://www.slideshare.net/Wombert/phpjp-urls-rest#btnNext
Basically in the slides you can see that the author agrees with me in that query string parameters should be used for filtering. What they should not be used for is determining a content source. So a route should point to a product (or whatever) and query string parameters should then be used in your controller to apply whatever logic you require to filter that content source (as per Fabien).
I ended up creating an entity in my application that I bind all my query string parameters to and then manipulate, much the same way forms are handled. In fact when you think about it it's basically the same thing.
Like in Symfony1, query strings are independent from the route parameters.
If you have a path defined as #Route("/page/{id}", name="single_page"), you can create a path in your view like this:
{{ path('single_page', { id: 3, foo: "bar" }) }}
The resulting URL will be /page/3?foo=bar.

Authorize request in ASP.NET Web API based on specific user

I followed this tutorial http://www.tugberkugurlu.com/archive/api-key-authorization-through-query-string-in-asp-net-web-api-authorizationfilterattribute
to create custom Authorization filter.
I have CarController with my custom Authorize Attribute:
[ApiKeyAuth("apiKey", typeof(ApiKeyAuthorizer))]
I send two parameters in the url .. host/Car/4?username=xxx&pass=xxx
It works basically fine, however I want to allow only car owners to see information about their cars.
E.g. user ABC can see only host/Car/5 and user DEF can see host/Car/6 and host/Car/10
how can I solve this scenario?
How can I access the id of the car used in query (host/Car/ID) in my ApiKeyAuthorizer.
Greetings
If you look at his code, https://github.com/tugberkugurlu/ASPNETWebAPISamples/tree/master/TugberkUg.Web.Http/src/samples and https://github.com/tugberkugurlu/ASPNETWebAPISamples/tree/master/TugberkUg.Web.Http/src/TugberkUg.Web.Http, I think you'll find that he's pulling the data directly from the query string. It should simply be a matter of extending that method to pull in the id parameter. You might also want to look at the RequestContentKeyValueModel on the HttpActionContext parameter passed into the OnAuthorization method. The documentation is sketchy and I haven't played with it yet, but that seems like a likely candidate to me. However, the route data is available indirectly through the HttpRequestMessage via an extension method, specifically:
message.GetRouteData();

Why have a separate call to get Json?

I need to get some Json to the client side from the server and it's somewhat troublesome as almost all tutorials assume an Ajax call to a separate action to get the Json.
This led me to think that there must be some reason why it is done this way. In Asp.Net MVC we can pass a Model along with the view to get the information but we can't seem to easily pass a Json object. Instead you are supposed to make a separate call to get this information.
What if the Json info is known when the page is generated, why not generate it at the same time?
I'm sorry if I wasn't clear enough. While it's nice to hear of ways to get Json to the client, the question is actually whether there is a specific reason the Ajax call method is much more popular, like security or anything like that.
Can you put something like this into your view? (rough pseudo code, assuming using a Razor view)
< script >
var myJSON = { Field: #model.Field, Field2: #model.Field2 };
< /script >
Because you do not need both at the same time... on the first call will be to get html (the view of the data - represented by a view model), and any ajax calls will be to get the possibly updated data (json serialized view model).
No reason why you can't. You could use the javacript serializer to create a JSON string that drop on the page. You could also create an action that return the json string that you called from a script tag.
What you want if you're using KnockOut, would be the Mapping plugin that turns an ordinary JS object, like that generated above, into an observable ready for KnockOut to use. See here from info. http://knockoutjs.com/documentation/plugins-mapping.html
You can use content-negotiation by setting accept header. This is considered a best practice (and according to some RESTful).
This needs to be supported and implemented at server as well. ASP NET MVC does not make it easy to support content-negotiation and you have to implement it yourself by if-else or using ActionFilter and implementing action selector.

Custom SOAP response of ASMX service

I'm trying to implement a custom SOAP response of the legacy web service.
At the moment it has the following format:
<ServiceResponse>
<ServiceResult>some return value</ServiceResult>
</ServiceResponse>
I need to add string value like this:
<ServiceResponse>NEW VALUE
<ServiceResult>some return value</ServiceResult>
</ServiceResponse>
I'm not sure if it is a good idea at all? Is this SOAP xml valid? If yes, how it can be accomplished?
Any suggestion or idea would be appreciated
That xml isn't valid, in a node you can't have both text and a child node like you have there.
If you're writing your webservice in .NET I would advise you construct a Serializable class that represents the data structure that you want to return, when you create your webservice it will automatically get converted into a valid soap data structure. You will also be able to see the definition of your response when you browse the WSDL at Service.asmx?wsdl.
If you'd like some more info on SOAP checkout the specification at w3.org
Edit: Removed false claim as pointed out by marc_s

Resources