diff --git a/pom.xml b/pom.xml index 6c201fbbafb516b807d23f59e206af7abff3abe3..e869025f45e7d271adfcb6739fe91d1a8011af52 100644 --- a/pom.xml +++ b/pom.xml @@ -232,6 +232,16 @@ <artifactId>json-utils</artifactId> <version>0.0.24</version> </dependency> + <!-- Spring Boot Starter Data Redis --> + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-data-redis</artifactId> + </dependency> + + <dependency> + <groupId>org.springframework.boot</groupId> + <artifactId>spring-boot-starter-mail</artifactId> + </dependency> </dependencies> <build> <plugins> diff --git a/src/main/java/org/upsmf/grievance/controller/OtpController.java b/src/main/java/org/upsmf/grievance/controller/OtpController.java new file mode 100644 index 0000000000000000000000000000000000000000..9b504b5fa39310ef8b2e0b3bd6932f0f231db6f8 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/controller/OtpController.java @@ -0,0 +1,35 @@ +package org.upsmf.grievance.controller; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.upsmf.grievance.model.OtpRequest; +import org.upsmf.grievance.model.OtpValidationRequest; +import org.upsmf.grievance.model.Ticket; +import org.upsmf.grievance.service.OtpService; +import org.upsmf.grievance.service.TicketService; + +@RestController +@RequestMapping("/otp") +public class OtpController { + + @Autowired + private OtpService otpService; + + @PostMapping("/generate-otp") + public void generateOtp(@RequestBody OtpRequest otpRequest) { + otpService.generateAndSendOtp(otpRequest); + } + + @PostMapping("/validate-otp") + public ResponseEntity<String> validateOtp(@RequestBody OtpValidationRequest otpValidationRequest) { + boolean isValid = otpService.validateOtp(otpValidationRequest.getEmail(), otpValidationRequest.getOtp()); + if (isValid) { + return ResponseEntity.ok("OTP validation successful."); + } else { + return ResponseEntity.badRequest().body("Invalid OTP."); + } + } + + +} diff --git a/src/main/java/org/upsmf/grievance/dao/TicketDao.java b/src/main/java/org/upsmf/grievance/dao/TicketDao.java index dfed0c3168f5ffc5739211621d6a835ea81e713a..289e58da94b88f948640a6fef76c82d940c7322c 100644 --- a/src/main/java/org/upsmf/grievance/dao/TicketDao.java +++ b/src/main/java/org/upsmf/grievance/dao/TicketDao.java @@ -81,4 +81,6 @@ public interface TicketDao { boolean sendRepliesToReviews(Updates updates); + Ticket addTicketwithOtp(Ticket ticket,String Otp); + } diff --git a/src/main/java/org/upsmf/grievance/dao/impl/TicketDaoImpl.java b/src/main/java/org/upsmf/grievance/dao/impl/TicketDaoImpl.java index 6e841c48be70c2e92d70fbf1b9baa49e26c6eff0..08bf76462ec6ae2171063c5bc7fc2ea4f2d39ede 100644 --- a/src/main/java/org/upsmf/grievance/dao/impl/TicketDaoImpl.java +++ b/src/main/java/org/upsmf/grievance/dao/impl/TicketDaoImpl.java @@ -53,6 +53,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; @@ -63,6 +64,7 @@ import org.springframework.jdbc.core.BatchPreparedStatementSetter; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.PreparedStatementCreator; import org.springframework.jdbc.support.KeyHolder; +import org.springframework.mail.javamail.JavaMailSender; import org.springframework.stereotype.Repository; import org.springframework.web.client.RestTemplate; import org.springframework.web.multipart.MultipartFile; @@ -98,6 +100,7 @@ import org.upsmf.grievance.model.mapper.SqlDataMapper; import org.upsmf.grievance.model.mapper.SqlDataMapper.HelpdeskRowRecordMapper; import org.upsmf.grievance.model.mapper.SqlDataMapper.TicketWorkFlowMapperV2; import org.upsmf.grievance.service.HelpdeskService; +import org.upsmf.grievance.service.OtpService; import org.upsmf.grievance.service.UserService; import org.upsmf.grievance.util.Constants; import org.upsmf.grievance.util.DateUtil; @@ -174,6 +177,9 @@ public class TicketDaoImpl implements TicketDao { @Autowired private TicketsRequestInterceptor ticketsRequestInterceptor; + @Autowired + private OtpService otpService; + public TicketDaoImpl(@Value("${image.source.attachment.aws}") Boolean attachmentSource, JdbcTemplate jdbcTemplate, HelpdeskDao helpdeskDao, HelpdeskService helpdeskService, SuperAdminDao superAdminDao) { this.attachmentSource = attachmentSource; @@ -287,7 +293,129 @@ public class TicketDaoImpl implements TicketDao { ticket.setOperation("save"); ticket.setStatus(value); if (ticket.getSourceId().equals(3L)) { - sendTicketEmail(ticket,ticket.getRequesterEmail()); + sendTicketEmailVal(ticket,ticket.getRequesterEmail()); + ticketsRequestInterceptor.addData(ticket); + } + if (!value1) { + return null; + } + } catch (Exception e) { + LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); + return null; + } + addTicketActivityLog(ticket.getId(), "New ticket has been created", ticket.getRequestedBy()); + return ticket; + } + + @Override + public Ticket addTicketwithOtp(Ticket ticket, String Otp){ + if (ProjectUtil.isObjectNull(intializeAddTicket(ticket))) { + return null; + } + KeyHolder keyHolder = KeyFactory.getkeyHolder(); + try { + if (ProjectUtil.isObjectNull(getApps(ticket))) { + return null; + } + if(!otpService.validateOtp(ticket.getRequesterEmail(),Otp)){ + return null; + } + + Long orgId = jdbcTemplate.queryForObject(Apps.GET_ORG_ID_FROM_APP_ID, new Object[] { ticket.getAppId() }, + Long.class); + ticket.setOrgId(orgId); + if (ticket.getHelpdeskId() == null) { + Long helpdeskId = jdbcTemplate.queryForObject(Apps.GET_HELPDESK_ID_FROM_APP_ID, + new Object[] { ticket.getAppId() }, Long.class); + ticket.setHelpdeskId(helpdeskId); + } + if (sourceId(ticket)) { + ticket.setSourceId(3L); + } + if (ticket.getHelpdeskId() != null) { + Helpdesk helpdesk = jdbcTemplate.query(Sql.UserQueries.GET_HELPDESK_CHANNELS, + new Object[] { ticket.getHelpdeskId() }, MasterDataManager.rowMapHelpdesk).get(0); + boolean val = val(ticket, helpdesk); + if (val) { + return null; + } + } + if (ticket.getRequestedBy() == null) { + setUsername(ticket); + } + jdbcTemplate.update(new PreparedStatementCreator() { + @Override + public PreparedStatement createPreparedStatement(Connection connection) throws SQLException { + String[] returnValColumn = new String[] { "id" }; + PreparedStatement statement = connection.prepareStatement(Sql.Ticket.ADD_TICKET, returnValColumn); + ticket.setCreatedTime(new Timestamp(new Date().getTime())); + ticket.setUpdatedTime(new Timestamp(new Date().getTime())); + ticket.setCreatedTimeTS(new Date().getTime()); + ticket.setUpdatedTimeTS(new Date().getTime()); + statement.setTimestamp(1, ticket.getCreatedTime()); + if (!StringUtils.isBlank(String.valueOf(ticket.getRate()))) { + statement.setLong(2, ticket.getRate()); + } else { + statement.setLong(2, 0L); + } + if (!StringUtils.isBlank(String.valueOf(ticket.getMaxRating()))) { + statement.setLong(3, ticket.getMaxRating()); + } else { + statement.setLong(3, 0L); + } + if (!StringUtils.isBlank(ticket.getPriority())) { + statement.setString(4, ticket.getPriority()); + } else { + statement.setString(4, "p3"); + } + if (ticket.getRequestedBy() != null) { + statement.setLong(5, ticket.getRequestedBy()); + } + if (ticket.getDescription() != null) { + statement.setString(6, ticket.getDescription()); + } else if (ticket.getFeedback() != null) { + ticket.setDescription(ticket.getFeedback()); + statement.setString(6, ticket.getFeedback()); + } else { + statement.setString(6, ""); + } + if (ticket.getType() != null) { + statement.setLong(7, ticket.getType()); + } else { + Long id = jdbcTemplate.queryForObject(Sql.Ticket.GET_DEFAULT_TICKET_TYPE, + new Object[] { ticket.getHelpdeskId() }, Long.class); + ticket.setType(id); + if (id > 0) { + statement.setLong(7, id); + } + } + statement.setTimestamp(8, ticket.getUpdatedTime()); + statement.setBoolean(9, false); + return statement; + } + }, keyHolder); + ticket.setId(keyHolder.getKey().longValue()); + if (ticket.getReviewId() != null) { + jdbcTemplate.update(Sql.Ticket.UPDATE_TICKET_REVIEW_ID, + new Object[] { ticket.getReviewId(), ticket.getId() }); + boolean v = value(ticket); + if (v) { + jdbcTemplate.update(Sql.Ticket.ADD_UPDATES, + new Object[] { ticket.getDeveloperComment(), ticket.getRequestedBy(), ticket.getId(), + convertFromTimestampToUTC(ticket.getDeveloperTimestamp()) }); + } + } + ticket.setSourceId(ticket.getSourceId()); + mapTicketToHelpdesk(ticket); + addCc(ticket); + TicketTypeDto ticketTypeDto = new TicketTypeDto(ticket); + String value = addDefaultWorkflowForTicketType(ticketTypeDto); + Boolean value1 = addChecklistForTicketType(ticketTypeDto); + ticket.setActive(true); + ticket.setOperation("save"); + ticket.setStatus(value); + if (ticket.getSourceId().equals(3L)) { + sendTicketEmailVal(ticket,ticket.getRequesterEmail()); ticketsRequestInterceptor.addData(ticket); } if (!value1) { @@ -411,7 +539,7 @@ public class TicketDaoImpl implements TicketDao { return RandomStringUtils.random(length, randomText); } - /*private void sendTicketEmail(Ticket ticket) { + private void sendTicketEmail(Ticket ticket) { try { User user = superAdminDao.userDetailsByUserId(ticket.getRequestedBy()); user.setOrgId(MasterDataManager.getUserOrgMap().get(ticket.getRequestedBy())); @@ -427,10 +555,10 @@ public class TicketDaoImpl implements TicketDao { } catch (ResourceNotFoundException e) { LOGGER.error(String.format(ENCOUNTERED_AN_EXCEPTION_S, e.getMessage())); } - }*/ + } - private void sendTicketEmail(Ticket ticket, String recipientEmail) { + private void sendTicketEmailVal(Ticket ticket, String recipientEmail) { try { DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/YYYY"); User user = superAdminDao.userDetailsByUserId(ticket.getRequestedBy()); diff --git a/src/main/java/org/upsmf/grievance/model/GrievanceRaise.java b/src/main/java/org/upsmf/grievance/model/GrievanceRaise.java index 1fd712815efd188404c8e8980723b3d8663f39cf..45f9680d88be297d49154e193b46cd1a74b947e2 100644 --- a/src/main/java/org/upsmf/grievance/model/GrievanceRaise.java +++ b/src/main/java/org/upsmf/grievance/model/GrievanceRaise.java @@ -29,5 +29,7 @@ public class GrievanceRaise { private List<String> filePath; + private String otp; + } diff --git a/src/main/java/org/upsmf/grievance/model/OtpRequest.java b/src/main/java/org/upsmf/grievance/model/OtpRequest.java new file mode 100644 index 0000000000000000000000000000000000000000..c570af4db0b0bad5efc9a30db57443c4d4d7980a --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/OtpRequest.java @@ -0,0 +1,17 @@ +package org.upsmf.grievance.model; + +import lombok.*; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +public class OtpRequest { + + private String email; + private String phoneNumber; + + private String name; + +} diff --git a/src/main/java/org/upsmf/grievance/model/OtpValidationRequest.java b/src/main/java/org/upsmf/grievance/model/OtpValidationRequest.java new file mode 100644 index 0000000000000000000000000000000000000000..92093c2b3896c21bfa13bd01f93197753e966255 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/model/OtpValidationRequest.java @@ -0,0 +1,15 @@ +package org.upsmf.grievance.model; + + +import lombok.*; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString(includeFieldNames = true) +public class OtpValidationRequest { + + private String email; + private String otp; +} diff --git a/src/main/java/org/upsmf/grievance/service/OtpService.java b/src/main/java/org/upsmf/grievance/service/OtpService.java new file mode 100644 index 0000000000000000000000000000000000000000..af2d950d03a637d012381775c7a9225cf2d21d8a --- /dev/null +++ b/src/main/java/org/upsmf/grievance/service/OtpService.java @@ -0,0 +1,12 @@ +package org.upsmf.grievance.service; + +import org.springframework.stereotype.Service; +import org.upsmf.grievance.model.OtpRequest; +import org.upsmf.grievance.model.Ticket; + +@Service +public interface OtpService { + + String generateAndSendOtp(OtpRequest otpRequest); + boolean validateOtp(String email, String otp); +} diff --git a/src/main/java/org/upsmf/grievance/service/OtpServiceImpl.java b/src/main/java/org/upsmf/grievance/service/OtpServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..e23935fd7e226aa02623984565df464db2cd7df4 --- /dev/null +++ b/src/main/java/org/upsmf/grievance/service/OtpServiceImpl.java @@ -0,0 +1,108 @@ +package org.upsmf.grievance.service; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.mail.SimpleMailMessage; +import org.springframework.mail.javamail.JavaMailSender; +import org.springframework.stereotype.Service; +import org.upsmf.grievance.model.OtpRequest; +import org.upsmf.grievance.model.RedisTicketData; + + +import java.util.concurrent.TimeUnit; + +@Service(value = "OtpService") +public class OtpServiceImpl implements OtpService{ + + @Autowired + private StringRedisTemplate redisTemplate; + + @Autowired + private JavaMailSender mailSender; + + @Value("${otp.expiration.minutes}") + private int otpExpirationMinutes; + + + + @Autowired + public OtpServiceImpl(StringRedisTemplate redisTemplate, JavaMailSender mailSender) { + this.redisTemplate = redisTemplate; + this.mailSender = mailSender; + } + + @Override + public String generateAndSendOtp(OtpRequest otpRequest) { + String email = otpRequest.getEmail(); + String otp = generateOtp(); + RedisTicketData redisTicketData = new RedisTicketData(); + redisTicketData.setEmail(email); + redisTicketData.setPhonenumber(otpRequest.getPhoneNumber()); + redisTicketData.setOtp(otp); + + String redisKey = "otp:" + email; + redisTemplate.opsForValue().set(redisKey, toJson(redisTicketData), otpExpirationMinutes, TimeUnit.MINUTES); + + sendOtpEmail(email, otp); + return otp; + } + + @Override + public boolean validateOtp(String email, String enteredOtp) { + String redisKey = "otp:" + email; + String redisData = redisTemplate.opsForValue().get(redisKey); + if (redisData != null) { + RedisTicketData ticketData = fromJson(redisData, RedisTicketData.class); + if (ticketData.getOtp().equals(enteredOtp)) { + // Remove the data from Redis after successful validation + redisTemplate.delete(redisKey); + return true; + } + } + return false; + } + + private String toJson(Object obj) { + try { + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.writeValueAsString(obj); + } catch (JsonProcessingException e) { + // Handle the exception + return null; + } + } + + private <T> T fromJson(String json, Class<T> valueType) { + try { + ObjectMapper objectMapper = new ObjectMapper(); + return objectMapper.readValue(json, valueType); + } catch (JsonProcessingException e) { + // Handle the exception + return null; + } + } + + + private String generateOtp() { + int otpLength = 6; + StringBuilder otp = new StringBuilder(); + + for (int i = 0; i < otpLength; i++) { + int digit = (int) (Math.random() * 10); + otp.append(digit); + } + + return otp.toString(); + } + + private void sendOtpEmail(String email, String otp) { + SimpleMailMessage message = new SimpleMailMessage(); + message.setTo(email); + message.setSubject("Your OTP for Ticket Creation"); + message.setText("Your OTP is: " + otp); + mailSender.send(message); + } +} diff --git a/src/main/java/org/upsmf/grievance/service/TicketService.java b/src/main/java/org/upsmf/grievance/service/TicketService.java index 4cf25d731ca97d80a91d4d63d8d1a59fd3234326..34ad309d3ddf48a7c7f9eeb9ed46842fbd5ebd1b 100644 --- a/src/main/java/org/upsmf/grievance/service/TicketService.java +++ b/src/main/java/org/upsmf/grievance/service/TicketService.java @@ -79,4 +79,6 @@ public interface TicketService { TicketCount getNoOfTickets(Long userId); boolean pinTicket(Ticket ticket); + + Ticket addTicketWithOtp(Ticket ticket, String otp); } diff --git a/src/main/java/org/upsmf/grievance/service/impl/GrievanceRaiseServiceImpl.java b/src/main/java/org/upsmf/grievance/service/impl/GrievanceRaiseServiceImpl.java index e12515f82ec013dd40036d48154c6988b9e76187..34e4ab365aa032c7bf2c140f4e34eee4bfb4608a 100644 --- a/src/main/java/org/upsmf/grievance/service/impl/GrievanceRaiseServiceImpl.java +++ b/src/main/java/org/upsmf/grievance/service/impl/GrievanceRaiseServiceImpl.java @@ -48,7 +48,7 @@ public class GrievanceRaiseServiceImpl implements GrievanceRaiseService { ticket.setRequesterEmail(grievance.getEmailId()); ticket.setRequesterPhoneNumber(grievance.getPhone()); LOGGER.info("added all values to ticket" + ticket); - ticket=ticketService.addTicket(ticket); + ticket=ticketService.addTicketWithOtp(ticket,grievance.getOtp()); // checking response GrievanceTicket grievanceTicket = null; diff --git a/src/main/java/org/upsmf/grievance/service/impl/TicketServiceImpl.java b/src/main/java/org/upsmf/grievance/service/impl/TicketServiceImpl.java index 3925cd5233a1a42c85de0095f1310e4adecea3fd..009558eed9513de1e94affb27bda367f588983ad 100644 --- a/src/main/java/org/upsmf/grievance/service/impl/TicketServiceImpl.java +++ b/src/main/java/org/upsmf/grievance/service/impl/TicketServiceImpl.java @@ -234,6 +234,11 @@ public class TicketServiceImpl implements TicketService { return ticketDao.pinTicket(ticket); } + @Override + public Ticket addTicketWithOtp(Ticket ticket, String otp) { + return ticketDao.addTicketwithOtp(ticket,otp); + } + @Override public TicketCount getNoOfTickets(Long userId) { return ticketDao.getNoOfTickets(userId); diff --git a/src/main/resources/application.properties b/src/main/resources/application.properties index 22fd476aa8011d8553c83eba6ac2972a805d275d..f3aff8c23b97d9e7685c9cb38f0a01da7ed19b30 100644 --- a/src/main/resources/application.properties +++ b/src/main/resources/application.properties @@ -13,7 +13,7 @@ spring.jpa.hibernate.ddl-auto=none spring.datasource.initialization-mode=always spring.jpa.properties.hibernate.jdbc.lob.non_contextual_creation=true -urls.whitelist=/,/user/login,/user/logout,/signup,/token/validate,/upload,/user/forgotPassword,/superadmin/getAuthTypes,/tickets/getTemplateVersion,/user/updateEkstepUser,/superadmin/addOrganization,/helpdesk/getPerformanceWithoutAccessControl,/grievance/grievanceRaise +urls.whitelist=/,/user/login,/user/logout,/signup,/token/validate,/upload,/user/forgotPassword,/superadmin/getAuthTypes,/tickets/getTemplateVersion,/user/updateEkstepUser,/superadmin/addOrganization,/helpdesk/getPerformanceWithoutAccessControl,/grievance/grievanceRaise,/otp/generate-otp,/otp/validate-otp services.esindexer.host=es.rain.idc.tarento.com services.esindexer.host.name=http://es.rain.idc.tarento.com/ @@ -37,4 +37,17 @@ default_app_name=test app 9 default_app_id=1 default_app_key=26f3847b-74f5-418d-9621-c331b1907131 +spring.redis.host= +spring.redis.port= + +# OTP expiration time in minutes +otp.expiration.minutes=5 + +spring.mail.host= +spring.mail.port= +spring.mail.username= +spring.mail.password= +spring.mail.properties.mail.smtp.auth=true +spring.mail.properties.mail.smtp.starttls.enable=true +