Breeze js - How to validate complex business rules on save? - entity-framework

I'm getting familiar with Breeze because I think that it can help me a lot dealing with data. Hovewer my biggest concern is data validation on server side. I read the documentation and I know that you should use your own ContextProvider and apply custom validation inside. I also read this SO post where someone was asking similar question.
But I think I got the case that cannot be handled in BeforeSaveEntity function. If it can, please tell me how:
Let's say that user is trying to update an article (his own article). This article has some ID.
How could I check if user is updating his article and not someone elses (he could change article ID in the browser, and this ID could be someone elses article ID). So entity would be still valid, but business rule does not allow to change other users articles by everyone.
I want to use EntityFramework and ASP.NET Web Api by the way.
If only i could get to something like "current user" and ID of article inside BeforeSaveEntity function...

You are rightly concerned to validate client save requests thoroughly and right also to distrust-in-principle anything the client sends.
Two issues here: who is the user and does s/he really own this article.
Who is the user?
Breeze stays out of the authentication business which we believe should be addressed by means that are (largely) external to the application code you write on server and client.
I would not roll my own security layer. That's asking for trouble. You might start your research with this article by Mike Wasson on Web API security.
Once you know who the user is, you must get application-specific facts about him or her such as the userId and what the user is allowed to do. I don't know where you get those facts as that is something specific to your application.
Whose article is this?
Let's suppose the current userId is 12345 and the update request specifies an article with articleId == 42 and userId == 12345. Clearly this article belongs to the current user. Is that good enough? Should we go ahead and save the changed article?
The answer depends upon how you assess the consequences of a rogue client updating another person's article. I'm not worried about updating a Todo (maybe I should?). I wouldn't trust this request if it concerned a bank withdraw.
I recommend spinning up a separate DbContext and querying the database for articleId 42.
Do not query the database with the DbContext from the Breeze ContextProvider inside the BeforeSave. That DbContext holds the modified article from the client. You want a separate DbContext to hold the actual entity per the database as it stands right now. These are separate entity objects in separate states. You can't have two different articles with the same id in the same DbContext.
If the queried article has userId 12345, you know the client made a valid request and you proceed. If the queried article's userId property is other than 12345, you reject the request.
You might treat this failed request as a potential attack and log it where you log security attacks. Maybe you'll monitor this user and the IP address and who knows what. I'm out of my depth here.
I'd probably reject the request with a mysterious 500. A real client wouldn't have made such a request and I don't want to tell a potential attacker the reason I rejected it.

Related

REST endpoint for complex actions

I have a REST API which serves data from the database to the frontend React app and to Android app.
The API have multiple common endpoints for each model:
- GET /model/<id> to retrieve a single object
- POST /model to create
- PATCH /model/<id> to update a single model
- GET /model to list objects
- DELETE /model/<id> to delete an object
Currently I'm developing an Android app and I find such scheme to make me do many extra requests to the API. For example, each Order object has a user_creator entry. So, if I want to delete all the orders created by specified user I need to
1) List all users GET /user
2) Select the one I need
3) List all orders he created GET /order?user=user_id
4) Select the order I want to delete
5) Delete the order DELETE /order/<id>
I'm wondering whether this will be okay to add several endpoints like GET /order/delete?user=user_id. By doing this I can get rid of action 4 and 5. And all the filtering will be done at the backend. However it seems to me as a bad architecture solution because all the APIs I've used before don't have such methods and all the filtering, sorting and other "beautifying" stuff is usually at the API user side, not the backend.
In your answer please offer a solution that is the best in your opinion for this problem and explain your point of view at least in brief, so I can learn from it
Taking your problem is in isolation:
You have an Order collection and a User collection
User 1..* Orders
You want to delete all orders for a given user ID
I would use the following URI:
// delete all orders for a given user
POST /users/:id/orders/delete
Naturally, this shows the relationship between Users & Orders and is self-explanatory that you are only dealing with orders associated with a particular user. Also, given the operation will result in side-effects on the server then you should POST rather than GET (reading a resource should never change the server). The same logic could be used to create an endpoint for pulling only user orders e.g.
// get all orders for a given user
GET /users/:id/orders
The application domain of HTTP is the transfer of documents over a network. Your "REST API" is a facade that acts like a document store, and performs useful work as a side effect of transferring documents. See Jim Webber (2011).
So the basic idioms are that we post a document, or we send a bunch of edits to an existing document, and the server interprets those changes and does something useful.
So a simple protocol, based on the existing remote authoring semantics, might look like
GET /orders?user=user_id
Make local edits to the representation of that list provided by the server
PUT /orders?user=user_id
The semantics of how to do that are something that needs to be understood by both ends of the exchange. Maybe you remove unwanted items from the list? Maybe there is a status entry for each record in the list, and you change the status from active to expired.
On the web, instead of remote authoring semantics we tend to instead use form submissions. You get a blank form from somewhere, you fill it out yourself, you post it to the indicated inbox, and the person responsible for processing that inbox does the work.
So we load a blank form into our browser, and we make our changes to it, and then we post it to the resource listed in the form.
GET /the-blank-form?user=user_id
Make changes in the form...
POST ????
What should the target-uri be? The web browser doesn't care; it is just going to submit the form to whatever target is specified by the representation it received. One answer might be to send it right back where we got it:
POST /the-blank-form?user=user_id
And that works fine (as long as you manage the metadata correctly). Another possibility is to instead send the changes to the resource you expect to reflect those changes:
POST /orders?user=user_id
and it turns out that works fine too. HTTP has interesting cache invalidation semantics built into the specification, so we can make sure the client's stale copy or the orders collection resource is invalidated by using that same resource as the target of the POST call.
Currently my API satisfies the table from the bottom of the REST, so, any extra endpoint will break it. Will it be fatal or not, that's the question.
No, it will be fine -- just add/extend a POST handler on the appropriate resource to handle the new semantics.
Longer answer: the table in wikipedia is a good representation of common practices; but common practices aren't quite on the mark. Part of the problem is that REST includes a uniform interface. Among other things, that means that all resources understand the same message semantics. The notion of "collection resources" vs "member resources" doesn't exist in REST -- the semantics are the same for both.
Another way of saying this is that a general-purpose component never knows if the resource it is talking to is a collection or a member. All unsafe methods (POST/PUT/PATCH/DELETE/etc) imply invalidation of the representations of the target-uri.
Now POST, as it happens, means "do something that hasn't been standardized" -- see Fielding 2009. It's the method that has the fewest semantic constraints.
The POST method requests that the target resource process the representation enclosed in the request according to the resource's own specific semantics. -- RFC 7231
It's perfectly fine for a POST handler to branch based on the contents of the request payload; if you see X, create something, if you see Y delete something else. It's analogous to having two different web forms, with different semantics, that submit to the same target resource.

Creating user record / profile for first time sign in

I use an authentication service Auth0 to allow users to log into my application. The application is a Q&A platform much like stackoverflow. I store a user profile on my server with information such as: 'about me', votes, preferences, etc.
When new user signs in i need to do 1 of 2 things:
For an existing user - retrieve the user profile from my api server
For a new user - create a new profile on the database
After the user signs in, Auth0(the authentication service) will send me some details(unique id, name and email) about the user but it does not indicate whether this is a new user(a sign up) or a existing user(a sign in).
This is not a complex problem but it would be good to understand best practice. I can think of 2 less than ideal ways to deal with this:
**Solution 1 - GET request **
Send a get request to api server passing the unique id
If a record is found return it
Else create new profile on db and return the new profile
This seems incorrect because the GET request should not be writing to the server.
**Solution 2 - One GET and a conditional POST request **
Send a get request to api server passing the unique id
The server checks the db and returns the profile or an error message
If the api server returns an error message send a post request to create a new profile
Else redirect to the home page
This seems inefficient because we need 2 requests to achieve a simple result.
Can anyone shed some light on what's best practice?
There's an extra option. You can use a rule in Auth0 to send a POST to the /users/create endpoint in your API server when it's the first time the user is logging in, assuming both the user database in Auth0 and in your app are up-to-date.
It would look something like this:
[...]
var loginCount = context.stats.loginsCount;
if (loginCount == 1) {
// send POST to your API and create the user
// most likely you'll want to await for response before moving on with the login flow
}
[...]
If, on the other hand, you're referring to proper API design and how to implement a find-or-create endpoint that's RESTful, maybe this answer is useful.
There seems to be a bit of disagreement on the best approach and some interesting subtleties as discussed in this post: REST Lazy Reference Create GET or POST?
Please read the entire post but I lean towards #Cormac Mulhall and #Blake Mitchell answers:
The client wants the current state of the resource from the server. It is not aware this might mean creating a resource and it does not care one jolt that this is the first time anyone has attempted to get this resource before, nor that the server has to create the resource on its end.
The following quote from The RESTful cookbook provided by #Blake Mitchell makes a subtle distinction which also supports Mulhall's view:
What are idempotent and/or safe methods?
Safe methods are HTTP methods that do not modify resources. For instance, using GET or HEAD on a resource URL, should NEVER change the resource. However, this is not completely true. It means: it won't change the resource representation. It is still possible, that safe methods do change things on a server or resource, but this should not reflect in a different representation.
Finally this key distinction is made in Section 9.1.1 of the HTTP specification:
Naturally, it is not possible to ensure that the server does not
generate side-effects as a result of performing a GET request; in
fact, some dynamic resources consider that a feature. The important
distinction here is that the user did not request the side-effects,
so therefore cannot be held accountable for them.
Going back to the initial question, the above seems to support Solution 1 which is to create the profile on the server if it does not already exist.

REST API Design: When should we use association in Uri for the resources?

We have simple e-commerce website where we have several products. Currently, each product has "Place order" button.
When user clicks on this button, we show user a form to fill Name, Mobile number and address. We don't support any monetary transaction. Once user fills this form, the order is saved to database. The order table has OrderId, ProductId, UserName, UserMobile.
We are designing API to save the user order. Should we have association b/w product and order while designing this?
For example URI to save the user order should be like:
POST /api/products/1/lead/ - The request body has user information i.e. name,mobile,address. OR
POST /api/lead/ - The request body has "PRODUCT ID" and user information i.e. name,mobile,address.
I am confused whether productId should be in request URI or in the request body? How do we make such decision?
Given that
you're first navigating to a product, before actually placing the order
the product id has nothing in common with the UserInformation model that you're posting
I'd go with the first option: POST /api/products/1/lead/
I would always go with a more shallow route for representing resources, just for the sake of simplicity. No, a nested route isn't complicated or anything, but I've seen nesting go really far. So I would keep it as shallow as possible unless...
1) You plan on having more than one thing that can have a lead. For example, you can have a lead on a product:
api/products/1/lead
or a lead on a managed service that you all provide or something (I'm reaching right now):
api/managed_services/2/lead
You could pass that info in the body always, but I imagine it would become a little cumbersome to base what resource to create based on what properties were defined in the json.
2) You plan on breaking out that route and having it go to a different service eventually. Maybe this app will have to scale substantially and a ton of users will be hitting this route moreso than any other endpoint in the system. It's a lot easier to redirect all requests to a different microservice based on the url starting with api/products than it would be redirect based on the request body.
But honestly, I don't think it matters too much. As long as it's easy for your clients to consume.

Updating something in REST

Philosophically, I had questions about some examples on how to tackle the following REST scenarios:
1) A user who is signed in wants to 'favorite' someone's blog posting. The user id is a guid and the blog posting is a guid. Should this be a PUT because user/blog exist, or POST because there is no entry in the 'favorites' table?
2) A security row in the DB consists of 10+ properties, but I'd only want to update one part of the entity (# of failed login attempts for a user). What should the call be? Pass the entire data transfer object in JSON? Or just add a new api route for the specific action to update? I.e. a PUT with just one parameter (the # of login attempts) and pass the id of the user.
3) Similar to #2, a user class (consisting of 25+ properties) but I'd only like the user to update a specific part of the class, not the whole thing. Philosophically do I need to pass the entire user object over? Or is it OK to just update one thing. It seems I could get crazy and make lots of specific calls for specific properties, but the reality is I will probably only update 2-3 specific parts of the user (as well as obviously updating the whole thing in other cases). What's the approach here for updating specific parts of an entity in the DB?
Thanks so much
Use a POST if you don't have an ID/UUID yet.
The resource is the security record. Do a PUT on that ID, and pass a block of the properties to be changed.
Ditto (2). You should get whatever parameters will help you identify that record in the DB. If it's unsavory to send these in the POST request and you're doing AJAX, just stash them in the session.
With REST, everything is about updating discrete resources ("nouns"). It's up to you how you want to assign these, but a simple interface that uses verbs ("PUT", "GET", "DELETE", etc..) sensibly, returns relevant HTTP codes, and is easy for others to implement is the best way to go.
So, just ask yourself, "What nouns do I want to give CRUD to, and am I going to exhaust people who wish to consume my API?"

Restful Api: User id in each repository method?

I am new to both .Net & RESTful services.
Here is the object hierarchy I have in the database: Users->Folders->Notes.
The API: GET /api/note/{noteid}
would get mapped to the repository call
NoteRepository::GetNote(userId, noteId)
Notice that I am passing on the userId to make sure that the note belongs to the logged in user for security purpose.
Is this the right approach? Meaning, every repository call would have the first parameter as the userId to check if the object being accessed belongs to the user.
Is there any better approach?
You don't need the User Id since the
GET /api/note/{noteid}
is indeed unique.
A valid scenario for adding the id would be:
GET /api/{userId}/notes
And then if you want a specific note you can:
GET /api/{userId}/notes/{noteId}
I would implement security at the entry level. whether the user has rights to perform a method on that specific resource. A role model approach would be fine.
Regards.
I would also introduce the user id in the API, because of Stateless and Cacheable constraints described in the Wikipedia REST article.
However, if I check Google Tasks REST API, they don't include the user id, same thing for Twitter API, so it seems a trend not to include the user id. If someone can shed some light I would be grateful.
UPDATE: Thinking more about it, if the noteid is unique across all users, there is no need to include the user id, so a GET /api/note/{noteid} is fine.
However, the logical parent in a restful interface would be GET /api/note/ to get a list of all notes, and here I've the objection, since the list would differ according to the user requesting it, making it non cacheable.
As for your dot net part I think that passing the userid among dot net methods is perfectly fine.