Update object properties - java

I'm using Struts 2, my problem is that I don't want to update all my object properties because I got some sensitive data.
Here is my code example
public class person {
private name;
private email;
private password;
}
In my form for example I display the name and email for update ,so when I update my person properties after submission ,the password property of the person gets the value null,but when I put the property password in the <s:hidden> tag in the form the update works fine.
How to make Struts 2 remember the value of the password without using the hidden tag in the form ?

If you need to store informations that
must be persistent across the requests;
must not be shown in the page;
then you have to use the Session, by implementing SessionAware:
That said, I'm not sure you should store the user password, nor associate passwords to users;
You should make a login page in your web application, handling the password in that Action only, validating it against the database (or whatever), and storing some authentication id in the Session, not the password itself (you won't validate the user again, unless the session expires, then the user will be redirected to login page... no need to keep the password in memory).
That said too, the best practices for user authentication discourage to validate entered passwords against stored passwords on database;
you should use some one-way hashing algorithm (adding a salt to prevent Rainbow Tables attacks) to hash a password, and checking it against the hashed password on the database. This way, not even the database administrator could know the passwords of the users, and in case of a forgotten password, it will be resetted, not retrieved.
In Java one of the best implementations out there is jBCrypt, based on BCrypt.
Hope that helps...
EDIT
As a way to conceptually separate the objects you handle in your Web Application, you can use two different beans: a "Full Bean" for reading, with all the properties, and a "Subset Bean" for writing, containing only the properties that could change.
For example, ID and Password should not change... you could read from Database the "Full", and write to the JSP and then to database the "Subset" (except that in user registration, where you will write the full)...
To make it more understandable, the Full Bean is the Dao Object mapping exactly the database fields, while the Subset Bean is a Presentation Object, that you will create by copying only the desired attributes from the Dao Object... they're both DTOs, but with two different levels of semantic.
Otherwise just put in session your bean, it is one row of code, and you will be ok.

You can check "null"(or a unique value) value at server-side (If it is null, it means : There is no change.) .
or you can use this class for update request
Public class person
{
protected name;
protected email;
}
Public class personNew: person // inherit from person
{
private password;
}
I dont use "Struts 2", but in my Web-app(APS.NET C#). I go on this way

Related

How to implement atomic "save if not exists" logic by using Spring data JPA crud methods?

I have users registration controller in my Spring Boot project with spring-boot-starter-data-jpa and spring-boot-starter-web dependencies, which implements the following logic, where usersRepository is an instance of standard CrudRepository:
#PostMapping
public String processRegistrationForm(#Valid #ModelAttribute("registrationForm") UserForm form,
Errors errors, Model model) {
if (!errors.hasErrors()) {
UserEntity user = usersRepository.findByUsername(form.getUsername());
if (user != null) {
errors.rejectValue("username", "registration.username.not.unique");
} else {
usersRepository.save(form.toUserEntity(passwordEncoder));
model.addAttribute("isRegistrationComplete", true);
}
}
return "registration";
}
The method first checks whether the user with the given username exists, and if not - saves it into the database. The problem here is that this check-then-act behavior may result in DataIntegrityViolationException (with the underlying unique username constraint violation) if someone intervenes in between findByUsername() and save() calls and manages to save the user with the same username into the database. How can I avoid this? And would making the whole method #Transactional solve this problem?
It seems you want to create an entity but not overwrite it, and in an atomic operation you cannot test for existence first.
You could, however put a unique key on your resource and then simply go for the create option. If that entity (with that specific key) already exists you should receive an exception telling you about duplicate data. Now you can still decide whether you want to error out or simply update the existing entry.
Edit: Reading the other comments: your unique key is probably the user name, and you want to error out saying that the chosen user name is already in use.
Edit2: So you mention that my suggestion is what you had implemented but you were not happy. I think you did not suffer from performance but did not like the code (parsing - see my comment) or the user behaviour.
A user just fills in a form to register and while being delayed by a captcha or some bad password pattern all of a sudden that user name is taken by someone else. Not a nice situation.
You will only resolve it by acting as soon as a user tries to register with a name. Upon the first such check (and when you return the status that the user is still available) create the entity with an attribute that this is just a placeholder. While the user still fills in the registration form other users already can see the name is taken.
For all cases where a registration is not finished and thus names are blocked for nothing, have a garbage collector job that removes all placeholders after some time. So if a placeholder has not completed to a full user account within one hour, just remove that entry from the DB and another user is free to reuse the name.

Partial fields update REST API

There is this MongoBean: SuperBean
class SuperBean extends MongoBaseBean{
private String id;
private String title;
private String parent;
//And getters, setters
}
Need is to write an update API, which is capable of performing partial attributes update. Common approach seen across the web as well as heard from my peers is to check the fields in the request for Null and update if not null. But what if the update request is for the value to be updated to Null??
After few discussions, we came up with three approaches:
Set default value for the field in the bean. Hence instead of non-null parent field, if it does not have $ in the request, this will be considered for update.
class SuperBean extends MongoBaseBean{
private String id;
private String title;
private String parent = "$";
//And getters, setters
}
Let the update API Implementation accept a Map. The actual bean is fetched and all the fields that are present in the request map will be updated.
#Post
public SuperBean updatePartial(Map<String,Object> dataObject) {}
Let the update API accept DTO, that contains 2 maps. One to contain old values, other for new values. This could be advantageous in scenarios, where the update has to happen only if the database contains the values as sent in oldDataObj. But this increases the payload size.
class SuperBeanUpdateDTO {
private Map<String, Object> oldDataObj;
private Map<String, Object> newDataObject;
//getters, setters
}
#Post
public SuperBean updatePartial(SuperBeanUpdateDTO updateDTO) {}
What factors should be considered to chose one of these approaches? Is there another better way to approach this problem?
In my projects, we usually choose the way that similar with your second way. but not exactly the same.
for example, in your client side, you have a page or a view to modify your profile info, includes name, birthday, gender, although you just modify the name value, when you click save button, it still will send the data to server includes birthday and gender with name field, but just keep its value as old. and the server API will directly update these three values in database, won't check whether its value changed or not.
if you have another page or view to modify other parts of the profile, likes password, it need add a new method in client and a new API in server. the API URL likes PATCH /reset_password, and the sent data should include old_password and new_password field.
PS:
1. we use PUT or PATCH to update a resource, not POST, POST is used to create a new resource.
2. when you update a resource, in the above example, the API likes PATCH /profiles/:id (other's profile) or PATCH /profile (yourself profile), so the sent data doesn't need id field anymore, it includes in your API URL.

Mapping single bean class to multiple tables in hibernate

I have developed a spring rest service which will accepts a json input and freeze the details in to database and return the status as json output. everything is working fine.
now i need to update the service with the new requirement, i will get address details of the user and i need to update the address table as well. My question is
1) How to change the input request currently my controller is as follows
#Requestmappping(value="/register", metod=RequestMethod.POST)
public #ResponseBody ResponseEntity userRegis(#RequestBody UserBean userdetails){
}
2) How to change the UserBean format. Currently it is mapping to one single table. Now i need to update the bean with address fields. and i need to map the address fields to new table.
please help on this.
What you are referring to in composition in OOP. So, basically user has address or addresses.
class User {
....
private Address addres;
//private List<Address> addres; use something like this if user has multiple addesses
}
class Address {
}
And offcourse you would not want to map same bean to multiple tables or something like that. The above relation is simple parent child relation. Read here

Administrator being able to delete any user from the database

I have a simple small application which involves an admin having the ability to update and delete information or individual user's from a database. Basically, so far the administrator can view all the current registered user's in a table format on a page. I need to know how I can delete or update the user information based on the user in each row, so assuming based on their actual userID. So far I have been able to extract all the user's from the database and put them into a table, and using JSTL fill in the necessary table values(username, email, etc..).
I do not know, the proper process for doing this, and do not know how to code up the controller to handle this specific task. So far my controller is like this:
#RequestMapping("/deleteUser")
public String deleteUser(#RequestParam(value = "id", required= false) Integer id) {
usersService.delete(id);
return "users";
}
where the request mapping comes from a button in the table, and "return users;" just returns back to the same jsp page which displays all the users. This is a little buggy, and I would like to know what would be the proper and best way to implementing this functionality.
Check the users Authority with the Principal.
#RequestMapping("/deleteUser")
public String deleteUser(#RequestParam(value = "id", required= false, Principal princiapl) Integer id) {
// Check if user has admin authority using principal.getAuthorities();
}
You could also use the #Secured("ROLE_ADMIN") annotation and lock down the method to the admin role.

Expressing Audit functionality with JPA annotations

I'm in the middle of fumbling around with JPA. I've so far successfully created an entity representing the user data and a stateless bean for the access to the user data.
The data the users can work on is like this (SQLFiddle link):
CREATE TABLE data
(
email character varying(128) NOT NULL,
data character varying(128) NOT NULL,
lastchange timestamp NOT NULL,
CONSTRAINT email_data PRIMARY KEY (email,data)
);
The idea is to save the unaltered, current version for all users with an empty email key. Then, when a user alters the data and creates an auditable version, the email field is filled with the users email. This way, each user can alter their copy of the data. The merging is a problem for a later date and not part of my question.
Now, I have the entities already in place. I created a stateless bean to load/save/find the data records by using the EntityManager. The logic to load the user specific version first, then load the unaltered version if the user has no user specific version still eludes me.
Consider this part of the bean:
#Stateless
public class DataBean {
#PersistenceContext(unitName = "authPU")
private EntityManager em;
public List<DataEntry> findAll() {
TypedQuery<DataEntry> query = em.createQuery("SELECT d FROM data d", DataEntry.class);
List<DataEntry> list = query.getResultList();
return query.getResultList();
}
...
}
How do I inject the user information into this class? I need to get the data for the current user first, then get the data for all users if there's no user-specific data available.
You could use standard EJB authentication. Then you can call SessionContext.getCallerPrincipal() in your session bean to get a user ID. Use this user ID to query the database.
In this case you have to add another column to your table (containing the user ID), if the authentication user ID does not equal the email address.
Far simpler (but less elegant) is to add the email address to the arguments of your EJB service method: Just make it part of the public API.

Categories

Resources