How to write query in springboot? - java

I am making a project where when a user login he will get a mail otp.I have successfully made the login page and also I am sending otp to the user mail address. Now I also want to validate the otp for that I have already created a otp column in database. But I can't figure out how to store the generated otp in the table.
Here is my code.
EmailSenderService class :
public class EmailSenderService {
#Autowired
private JavaMailSender mailSender;
public void sendMail(String toEmail,
String subject,
String body) {
SimpleMailMessage message=new SimpleMailMessage();
message.setFrom("growthgreek#gamil.com");
message.setTo(toEmail);
message.setText(body);
message.setSubject(subject);
mailSender.send(message);
System.out.println("message sent .....");
}
}
OtpEmailController Class:
#Controller
public class OtpEmailController {
#Autowired
private EmailSenderService emailService;
Random random = new Random(1000);
#PostMapping("/send-otp")
public String sendOtp(#RequestParam("email") String email) {
int otp = random.nextInt(999999);
String subject = "OTP from session-handling-proj By Harshit";
String toEmail = email;
String body = "<h1> OTP = " + otp + "</h1>";
this.emailService.sendMail(toEmail, subject, body);
return ("success");
}
Repository Class :
#Repository
#Transactional
public interface SessionHandlingRepository extends JpaRepository<SessionHandling, Integer>{
#Query(value="Select * from session_handling where email= :email",nativeQuery =true)
public SessionHandling findByEmailId(#Param("email")String email);
#Query(value="Select * from session_handling where email= :email AND password= :password",nativeQuery =true)
public SessionHandling findByEmailIdAndPassword(#Param("email")String email, #Param("password")String password);
}
Entity Class :
#Entity
public class SessionHandling {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String name;
private String email;
private String password;
private String cpassword;
private static final long OTP_VALID_DURATION = 5 * 60 * 1000; // 5 minutes
#Column(name = "one_time_password")
private String oneTimePassword;
#Column(name = "otp_requested_time")
private Date otpRequestedTime;
Where and how to write the query for saving the otp in database?

You can do it with your repository, first inject the repository in your service :
#Autowired
private SessionHandlingRepository sessionHandlingRepository;
you can then create an instance of your entity at the desired location (add getter and setter to the entity first):
SessionHandling sessionHandling = new SessionHandling();
sessionHandling.setName("theName");
// call Other setters ...
you can use the following repository method to save the entity in the database :
sessionHandlingRepository.save(sessionHandling);

Related

Update User Detail api returns DataIntegrityViolationException

I'm creating an update API that updates the profile of the super admin, I mapped the member table to a DTO, on the member table password is set to not null and I did not include the password field on the dto because there's a provision for that be, when I tested the API on postman it returned on the console
DataIntegrityViolationException
SQL Error: 1048, SQLState: 23000
Column 'password' cannot be null
Here is my code
Dto
#Getter
#Setter
public class UpdateProfileDto {
#NotNull(message = "{member.firstName.notNull}")
#JsonProperty("first_name")
private String firstName;
#NotNull(message = "{member.lastName.notNull}")
#JsonProperty("last_name")
private String lastName;
#JsonProperty("nationality")
private Long nationality;
#JsonProperty("country_of_residence")
private Long countryOfResidence;
#JsonProperty("date_of_birth")
#DateTimeFormat(iso = DateTimeFormat.ISO.DATE)
#JsonFormat(pattern = "dd-MM-yyyy")
#Past(message = "{customer.dateOfBirth.past}")
private Date dateOfBirth;
#JsonProperty("current_job_title")
private String currentJobTitle;
#NotNull(message = "{member.emailAddress.notNull}")
#JsonProperty("email_address")
private String emailAddress;
#JsonProperty("username")
private String username;
#NotNull(message = "{member.phoneNumber.notNull}")
#PhoneNumber
#JsonProperty("phone_number")
private String phoneNumber;
#Size(max = 300, message = "{member.city.size}")
#JsonProperty("city")
private String city;
#Size(max = 300, message = "{member.state.size}")
#JsonProperty("state")
private String state;
}
ServiceImpl
#Override
#Transactional
public Member updateProfile(UpdateProfileDto body) {
Member superAdmin = repository.getOne(id);
if (superAdmin == null) {
throw new MemberNotFoundException(id);
}
Optional<Role> existingRole = roleJpaRepository.findByCode(RoleType.SUPER_ADMINISTRATOR.getValue());
if (existingRole.isEmpty()) {
throw new RoleNotFoundException(RoleType.SUPER_ADMINISTRATOR.getValue());
}
Member existing;
existing = mapper.map(body, Member.class);
existing.setPassword(superAdmin.getPassword());
existing.getRoles().add(existingRole.get());
existing.setNationality(countryRepository.getOne(body.getNationality()));
existing.setCountryOfResidence(countryRepository.getOne(body.getCountryOfResidence()));
return adminJpaRepository.save(existing);
}
Controller
#RestController
#RequestMapping(
value = "super-admin",
produces = { MediaType.APPLICATION_JSON_VALUE }
)
public class SuperAdminController {
private final SuperAdminService service;
public SuperAdminController(SuperAdminService service) {
this.service = service;
}
#PutMapping("/update")
public Member updateProfile(#Valid #RequestBody UpdateProfileDto body){
Member superAdmin = service.updateProfile(body);
return superAdmin;
}
}
The password bug has been fixed(changes reflected in serviceImpl), but when I run the code it returned Duplicate entry 'ijava#gmail.com-111803918380' for key 'member.email_address_phone_number_uq' email, and the phone number is set as a unique constraint in the member table, how can I bypass this?
You have few options, depending on your exact use case.
Extract existing password, using unique property in UpdateProfileDto, email looks like it can do the job.
Pseudocode:
Member existing = repository.findByEmail;
Member superAdmin = mapper.map(body, Member.class);
superAdmin.setPassword(existing.getPassword());
Set a dummy value for password, to be updated later on.
superAdmin.setPassword("dummy-password");
Make the column nullable in database.

Add custom constructor to swagger generated model

I'm trying to add a custom constructor to a model generated by swagger, I was wondering if its possible for the model generation to be like below
example swagger model
#Schema(description = "Base Profile")
#javax.annotation.Generated(value = "io.swagger.codegen.v3.generators.java.JavaClientCodegen", date = "2020-10-08T18:15:35.865361-04:00[America/Vancouver]")
public class Account {
#SerializedName("id")
private Integer id = null;
#SerializedName("username")
private String username = null;
#SerializedName("lastModified")
private LocalDate lastModified = null;
#SerializedName("email")
private String email = null;
//getter setter
}
I need a constructor that does not contain the username and email
public Account(String username, String email)
Thanks

How to save token in database

I have a class User with:
int id;
String username;
String password;
String token;
Date tokenExpires;
And i have a method like this:
private EntityManager em;
private User authenticate(String username, String password) throws Exception {
// Authenticate against a database, LDAP, file or whatever
// Throw an Exception if the credentials are invalid
Query query = em.createQuery("Select u from User u WHERE u.username = :name and u.password = :password");
query.setParameter("name", username);
query.setParameter("password", password);
return (User) query.getSingleResult();
}
and a method to generate a token:
private String issueToken(String username) {
Random random = new SecureRandom();
String token = new BigInteger(130, random).toString(32);
return token;
}
how to save this token to db, everytime user log in? so when user log in should generate a token, if user log in again it should generate a new token
When a user logs in, simply fetch the user from the database, then set the mentioned fields, the token and its' expiration date:
public User updateUser(String username, String password) {
User user = getUserBy(username, password);
String token = issueToken();
// token expires in 30 mins;
Date tokenExpires = new Date(System.currentTimeMillis() + 1800000);
user.setToken(token);
user.setTokenExpires(tokenExpires);
entityManager.getTransaction().begin();
entityManager.merge(user);
entityManager.getTransaction().commit();
}
Considering you are using Hibernate, then, the User model has to be annotated as well:
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String username;
private String password;
private String token;
#Temporal(TemporalType.TIMESTAMP)
private Date tokenExpires;
// getters and setters, make sure they are present
}
if you use spring, try this guide, for example: https://javadeveloperzone.com/spring-boot/spring-boot-oauth2-jdbc-token-store-example/

Spring-data-mongodb not persist multiple objects on list

I am using Spring-data-mongodb and i can persist an object on a list, but when i try to add another, it doesn't work, the application doesn't throw an exception.
this is my Json:
[
{
idUser: "4a9f10d9-e19f-42af-ba00-891a567cc41f",
login: "peter",
password: "mypassword",
email: "peter#eeee.com",
patients:
[
{
idPatient: "d31e8052-36d3-4285-9f97-454f3437812d",
name: "ada",
birthday: 1363474800000,
idUser: "4a9f10d9-e19f-42af-ba00-891a567cc41f",
region:
{
idRegion: "d8acfa45-486e-49e0-b4e6-edde6743cf30",
name: "Madrid"
},
personalCalendars: null
},
null
]
}
]
As you can see, my first Patient element is correctly, and the second was insert as null.
I leave my code:
User.java
#Document(collection = "users")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private String id;
#Indexed
private UUID idUser;
#Indexed(unique = true)
private String login;
private String password;
#Indexed(unique = true)
private String email;
#DBRef
private List<Patient> patients;
#PersistenceConstructor
public User(UUID idUser, String login, String password, String email, List<Patient> patients){
this.idUser = idUser;
this.login = login;
this.password = password;
this.email = email;
this.patients = patients;
}
Patient.java
#Document(collection = "patients")
public class Patient implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private String id;
#Indexed
private UUID idPatient;
private String name;
private Date birthday;
private UUID idUser;
private Region region;
#Transient
private List<PersonalCalendar> personalCalendars;
#PersistenceConstructor
public Patient(UUID idPatient, String name, Date birthday,UUID idUser, Region region){
this.idPatient = idPatient;
this.name = name;
this.birthday = birthday;
this.idUser = idUser;
this.region = region;
}
and the DAO whereI do the insert.
#Override
public Patient createPatient(User user, Patient patient) {
this.mongoOps.save(patient , "patients");
this.mongoOps.save(user , "users");
return this.getPatientById(patient.getIdPatient());
}
The console returns this, but no persists the patient:
15:16:16.718 [tomcat-http--6] DEBUG o.s.data.mongodb.core.MongoTemplate - Saving DBObject containing fields: [_class, _id, idPatient, name, birthday, idUser, region]
15:16:16.723 [tomcat-http--6] DEBUG o.s.data.mongodb.core.MongoDbUtils - Getting Mongo Database name=[application]
15:16:16.747 [tomcat-http--6] DEBUG org.mongodb.driver.protocol.insert - Inserting 1 documents into namespace application.patients on connection [connectionId{localValue:2, serverValue:119}] to server 127.0.0.1:27017
15:16:16.761 [tomcat-http--6] DEBUG org.mongodb.driver.protocol.insert - Insert completed
I need help.
Thanks a lot
First, if you use Spring Data with MongoDB, use it properly:
#Repository
public interface UserRepository extends MongoRepository<User, String> {
}
Now just inject UserRepository via #Autowired annotation:
#Autowired
private UserRepository userRepository;
User user = new User();
Patient patient = new Patient();
user.addPatient(patient);
// Just call save from userRepository to save your User with Patient.
// save method will return instance of saved user (together with instance of
// patient)
User user = userRepository.save(user);
Note that save method can also be used for updating of existing User. If User is new (not having generated id) it will be inserted. If user exists (has generated id) it will be just updated.
Presuming that User class has a addPatient method that looks like this:
public void addPatient(Patient patient) {
this.patients.add(patient);
}
Also, make sure that your list is initialized: List<Patient> patients = new ArrayList<>();

java ee bean validation

I'm trying to implement user authorization on java ee 7. For validation entered data I use Bean validation annotations.
#NotNull(message = "Please enter email address")
#Column(name = "email")
private String email;
#NotNull(message = "Please enter password")
#Size(min = 6, max = 255)
#Column(name = "password")
private String password;
Also I have #PrePersist method which hash entered password
#PrePersist
public void updatePassword(String password) {
//some code
}
Here is a method where I register user:
#EJB
private UserService userService;
public void register() {
if (userService.getByEmail(email) == null) {
try {
userService.register(email, password);
//log in if users is created
authController.setEmail(email);
authController.setPassword(password);
authController.login();
} catch (Exception e) {
setErrorMessage("Validation error");
}
} else {
setErrorMessage("Please choose another email address");
}
}
UserService
#Stateless
public class UserService {
#EJB
private UserDAO userDAO;
public void register(String email, String password){
User user = new User();
user.setEmail(email);
user.setPassword(password);
userDAO.create(user);
}
}
The problem is if password is null. At first called updatePassword method but not #NotNull annotation over the password field and thus i get NullPointerException. How to make that at first checks validation and then later other methods. Thanks in advance!
It seems that bean validation is not triggered soon enough.
One way to solve this would be to inject ValidatorFactory into UserService and then validate user object after it is created. Something like this:
#Stateless
public class UserService {
#EJB
private UserDAO userDAO;
#Inject
private ValidatorFactory validatorFactory;
public void register(String email, String password){
User user = new User();
user.setEmail(email);
user.setPassword(password);
Set<ConstraintViolation<User>> constraintViolations = validatorFactory.getValidator().validate(user);
if(constraintViolations.size() > 0){
// handle error
}else{
userDAO.create(user);
}
}
}
this answer could be helpful for clarification

Categories