I have a Mobile Service with Model classes and DTO classes. I mapped these using Fluent API and got it to work to perform CRUD operations, but I have a problem with the JSON responses returned in some instances.
Take for example a User entity with user name and password. To register a user I have my PostUserDTO method like this:
// POST tables/UserDTO
public async Task<IHttpActionResult> PostUserDTO(UserDTO item)
{
string hashString = PasswordHash.CreateHash(item.Password);
item.Password = hashString;
UserDTO current = await InsertAsync(item);
current.Password = "";
return CreatedAtRoute("Tables", new { id = current.Id }, current);
}
On the method I read the password property sent from the client and then proceed to hash it with a salt, replace the value in the object sent and save it to the database, then I proceed to empty the password so the hashed result isn't returned.
In this case the best practice would be to omit the password property from the response, this also should happen when retrieving all of the users in the table, I only want to return specific information, some information generated by my server should stay out from the response.
How can I select or alter the information from the responses? Do I have to create other DTOs for every kind of response I desire?
Related
Im creating a REST API with express/TypeORM in Typescript.
My application stores users in mysql database, and users can create boards in the application.
When a user create a board i have to send the userId from the client to the backend to identify which user created this table.
1: I created a DTO:
POST:
v1/boards
import { Board } from "../entity/Board";
class BoardDTO {
public board!: Board;
public userId!: string;
};
export default BoardDTO;
to get the userId from the request.body.
OR
I can send the userId in the request url as a parameter like this:
POST:
v1/:userId/boards
The question is which one is the better pattern in real life???
get userId from body or from the request.param????
I have a .net core web api. Db is PostreSQL. I have a simple POST request that create an entity with two fields:
public class ClientDto{
public string Name {get;set;}
public int ClientId{get;set;}
}
ClientId - FK foreign key to table Clients.
Some client (Postman for exapmle) execute request, but in data model send ClientId that not exists in db.
I have global exeption handler and there I handle db exception, but exception object don't include separated information.
I would like to show to user beautiful message something like "Client with id = 1 not exists".
What the best practis to handle db exceptions?
May be before save object in db I need check if client with id = 1 exists in db? But it is an additional query.
May be before save object in db I need check if client with id = 1 exists in db? But it is an additional query.
I'd do this.
If your client doesn't give you good information in its exception then your probably better to do the additional query. If you're querying on an indexed field (which i'd expect given you are using a foreign key) then it will be a very quick query.
Exception throwing and catching is fairly expensive anyway and i'd probably be happy enough with the extra call.
Right now I am using accesscontrol to manage the ACL and it is working great. It looks something like this:
const methods = {
async update(parent, { data }, ctx, info) {
const acUpdate = ac.can('role').updateOwn('model')
if (! acUpdate.granted) throw new ACError()
const filtered = acUpdate.filter({ ...data })
return await ctx.db.mutation.updateOrganization({
data: filtered,
where: { id }
}, info)
}
}
However, on a Query method from GraphQL I don't know how to filter the requests to the DB. For example, on a nested query it may look like this:
{
model {
id
name
user {
id
name
pictures {
id
name
}
}
}
}
So on the resolver it would check if they have access to Model, then it would send the request to the Prisma server without filtering the GQL schema. In this scenario let's say that the user has access to read model but not user. Ideally I'd like to do a permission.filter(...) on the actual request schema (info?) before sending it to Prisma. Have any of you solved this? Of course its possible to filter the request after it has resolved, but that level of computation is not necessary and can cause issues if abused.
I found out this is the topic I was addressing in one of my issue responses because I thought it was asked there. I recognize now that I must have confused it with this one being open in one of the tabs in the back.
https://github.com/maticzav/graphql-shield/issues/113#issuecomment-423766569
I think that the second part of my response concerns you the most. I hope you find it helpful! 🙂
I was having the exact same problem and i am now solving it by using prisma client for making the requests to prisma. Prisma client only queries one level deep each time so you get full control of the resolvers also in nested queries.
See https://stackoverflow.com/a/53703140/1391050
I am inheriting the builtin User model in my own Customer model. The Customer model is having extra parameters like first-name, last-name etc. To create an User and Customer I am using the following code:
// create a Customer
User.create({
email: email,
password: userPassword,
cellnumber: cellDetails.cellnumber
},
function (error, userDet) {
I get an id in response to this call: 59c4c5845dc8de4730645963. But when I am trying to get the account by id i.e. accounts/{id} and pass it the above id, it gives the following error:
the "Unknown \"customer\" id \"59c4c5845dc8de4730645963\"."
So this means that id of the User model and Customer model are somehow not same. How do I resolve this ? Also, in the mongo db database all the properties are getting visible under the User model and not under the Customer model. What am I doing wrong here ? Could anyone let me know.
Thanks
I believe you should create like this: Account.create({ email, password, ... }) , using the Account model rather than User model.
You should use the model you created document with, Account in this case. The thing is, each model works only with it's own MongoDB collection and they are isolated from each other.
Let /users/{id} be a resource url in RESTful service.
Basic authentication is enabled and only authenticated users are allowed to access the url.
Example Scenario:
User_1 & User_2 are authenticated users with userId 1 & 2.
Since both are authenticated, both of them are having access to,
/users/1
/users/2
But the expectation is User_1 should have access to /users/1 and not to /users/2 or other userId.
Question:
How to do resource level authorization in RESTful services?
Note: I am implementing RESTful using Jax-RS (with Apache CXF implementation), helpful if you could explain with Jax-RS.
-Barath
Edit:
As Donal mentioned, I am not looking for role based authorization rather resource level authorization.
To give an example, lets say /users/{id}/photos/{photoId} be another resource url. User_1 should be given access to the photos belong to him only. If photoId of 2 belonging to user_2, then we should give http_404 error code for user_1 when a request /users/1/photos/2 is requested.[Since User_1 is also authenticated user he can invoke /users/2/photos/2, so we must identify the user id based on authentication parameters than via resource url]
Only solution I can think of is, include the unique id which determines the authorization in each query like,
Instead of SELECT * FROM PHOTO_TBL WHERE PHOTO_ID=2;
use SELECT * FROM PHOTO_TBL, USER_TBL WHERE PHOTO_ID=2 AND USER_ID=1 AND USER_ID=PHOTO_ID;
with this resources are delivering data that belongs to specific user. [There should be a mechanism to prevent the modification of the unique id in client side which is used to decide on authorization(userId in this case), since all requests are STATELESS request]
Caveat: Each and every query should be intelligent enough to understand the security concerns and include extra join. This is a bad design to tie up security logic to every business function.
I am yet to look into Spring security and how it can be used in this use case.
I would recommend not having the user id in the url (as if it's being 'limited' by a Basic Auth header then you may as well just have it 'specified' by the Basic auth header). This will reduce the risk of introducing a Direct Object Reference Vulnerability - https://www.owasp.org/index.php/Top_10_2010-A4-Insecure_Direct_Object_References)
In this case you could have one of the following urls:
/users/CURRENT
/me
As photos is a sub resource then you could just create the photos with a "sequence number" within the user. In a sql database this would mean having a "compound key" across both user and photo columns.
/users/CURRENT/photo/{user_photo_seq}
/me/photo/{user_photo_seq}
Your SQL would then look something like:
SELECT * FROM PHOTO_TBL WHERE USER_ID=<BasicAuthUsername> AND PHOTO_ID=<path param value>;
A good explanation of "Basic Auth Headers":
http://en.wikipedia.org/wiki/Basic_access_authentication
JAX-RS specifies sub-resource where instead of handling request in a method, processing is delegated to other object - sub-resource.
Using sub-resources it's enought to take care of the root resource and nested ones will be secured as well.
In the example you can see UserResource and all it's sub-resources available only to authorized user.
#Path("/user/{userId}")
public class UserResource {
private final String userId;
public UserResource(#PathParam("userId") String userId, #Context SecurityContext securityContext) {
this.userId = userId;
boolean authorized = /* authorization code */;
if (!authorized) { throw new WebApplicationException(Status.UNAUTHORIZED); }
}
#Path("photo")
public PhotoResource getPhotoResource() {
return new PhotoResource(userId);
}
}
public class PhotoResource {
private final String userId;
public PhotoResource(String userId) {
this.userId = userId;
}
#GET
public Response listAll() { /* ... */ }
#GET
#Path("{photoId}")
public Response present() { /* ... */ }
}