diff --git a/src/main/java/com/safeqr/app/constants/APIConstants.java b/src/main/java/com/safeqr/app/constants/APIConstants.java index 9f0b861..5502826 100644 --- a/src/main/java/com/safeqr/app/constants/APIConstants.java +++ b/src/main/java/com/safeqr/app/constants/APIConstants.java @@ -24,9 +24,12 @@ public class APIConstants { public static final String API_URL_USER_SET_BOOKMARK = "/user/setBookmark"; public static final String API_URL_USER_DELETE_BOOKMARK = "/user/deleteBookmark"; public static final String API_URL_USER_DELETE_ALL_BOOKMARK = "/user/deleteAllBookmark"; + + public static final String API_URL_GMAIL_GET_EMAILS = "/gmail/getEmails"; public static final String API_URL_GMAIL_GET_SCANNED_EMAILS = "/gmail/getScannedEmails"; + public static final String API_URL_GMAIL_DELETE_MESSAGE = "/gmail/deleteMessage"; + public static final String API_URL_GMAIL_DELETE_ALL_MESSAGES = "/gmail/deleteAllMessages"; - - + public static final String API_URL_TIPS_GET = "/tips/getTips"; } diff --git a/src/main/java/com/safeqr/app/constants/CommonConstants.java b/src/main/java/com/safeqr/app/constants/CommonConstants.java index 7fa623e..7f9c176 100644 --- a/src/main/java/com/safeqr/app/constants/CommonConstants.java +++ b/src/main/java/com/safeqr/app/constants/CommonConstants.java @@ -22,4 +22,11 @@ public class CommonConstants { public static final String CLASSIFY_WARNING = "WARNING"; public static final String CLASSIFY_UNSAFE = "UNSAFE"; public static final String CLASSIFY_UNKNOWN = "UNKNOWN"; + + public static final String CAT_BENIGN = "benign"; + public static final String CAT_DEFACEMENT = "defacement"; + public static final String CAT_MALWARE = "malware"; + public static final String CAT_PHISHING = "phishing"; + + public static final Integer GMAIL_ACTIVE = 1; } diff --git a/src/main/java/com/safeqr/app/gmail/controller/GmailController.java b/src/main/java/com/safeqr/app/gmail/controller/GmailController.java index 06dbc67..3065e3a 100644 --- a/src/main/java/com/safeqr/app/gmail/controller/GmailController.java +++ b/src/main/java/com/safeqr/app/gmail/controller/GmailController.java @@ -1,8 +1,8 @@ package com.safeqr.app.gmail.controller; -import com.google.api.services.gmail.model.*; +import com.safeqr.app.gmail.dto.MessageRequestDto; import com.safeqr.app.gmail.dto.ScannedGmailResponseDto; -import org.apache.commons.codec.binary.Base64; +import com.safeqr.app.gmail.dto.BaseResponse; import org.json.JSONObject; import com.google.api.client.auth.oauth2.AuthorizationCodeRequestUrl; import com.google.api.client.auth.oauth2.Credential; @@ -26,11 +26,11 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import org.springframework.web.servlet.view.RedirectView; import static com.safeqr.app.constants.APIConstants.*; -import java.io.IOException; -import java.lang.Thread; +import static com.safeqr.app.constants.CommonConstants.HEADER_USER_ID; + + import java.util.*; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.CompletionException; @RestController @@ -129,5 +129,17 @@ public class GmailController { return new ResponseEntity<>("Scan Gmail Request is being processed", HttpStatus.ACCEPTED); } + + @PutMapping(value = API_URL_GMAIL_DELETE_MESSAGE, produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity deleteMessage(@RequestHeader(name = HEADER_USER_ID) String userId, @RequestBody MessageRequestDto messageRequestDto) { + logger.info("User Id Invoking PUT Delete Single Email endpoint: {}", userId); + return ResponseEntity.ok(gmailService.deleteMessage(userId, messageRequestDto.getMessageId())); + } + + @PutMapping(value = API_URL_GMAIL_DELETE_ALL_MESSAGES, produces = MediaType.APPLICATION_JSON_VALUE) + public ResponseEntity deleteAllMessages(@RequestHeader(name = HEADER_USER_ID) String userId) { + logger.info("User Id Invoking PUT Delete All Emails endpoint: {}", userId); + return ResponseEntity.ok(gmailService.deleteAllMessages(userId)); + } } diff --git a/src/main/java/com/safeqr/app/gmail/dto/BaseResponse.java b/src/main/java/com/safeqr/app/gmail/dto/BaseResponse.java new file mode 100644 index 0000000..ae25bfb --- /dev/null +++ b/src/main/java/com/safeqr/app/gmail/dto/BaseResponse.java @@ -0,0 +1,12 @@ +package com.safeqr.app.gmail.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; + +@Data +@Builder +@AllArgsConstructor +public class BaseResponse { + private String message; +} diff --git a/src/main/java/com/safeqr/app/gmail/dto/MessageRequestDto.java b/src/main/java/com/safeqr/app/gmail/dto/MessageRequestDto.java new file mode 100644 index 0000000..e000e29 --- /dev/null +++ b/src/main/java/com/safeqr/app/gmail/dto/MessageRequestDto.java @@ -0,0 +1,10 @@ +package com.safeqr.app.gmail.dto; + +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@NoArgsConstructor +public class MessageRequestDto { + private String messageId; +} diff --git a/src/main/java/com/safeqr/app/gmail/entity/GmailEmailEntity.java b/src/main/java/com/safeqr/app/gmail/entity/GmailEmailEntity.java index 9ec084a..4db8ca1 100644 --- a/src/main/java/com/safeqr/app/gmail/entity/GmailEmailEntity.java +++ b/src/main/java/com/safeqr/app/gmail/entity/GmailEmailEntity.java @@ -44,6 +44,9 @@ public class GmailEmailEntity { @Column(name = "date_created") private OffsetDateTime dateCreated; + @Column(name = "active") + private Integer active = 1; + @PrePersist public void prePersist() { dateCreated = OffsetDateTime.now(); diff --git a/src/main/java/com/safeqr/app/gmail/repository/GmailEmailRespository.java b/src/main/java/com/safeqr/app/gmail/repository/GmailEmailRespository.java index a8850f8..e1fbc7f 100644 --- a/src/main/java/com/safeqr/app/gmail/repository/GmailEmailRespository.java +++ b/src/main/java/com/safeqr/app/gmail/repository/GmailEmailRespository.java @@ -3,10 +3,26 @@ package com.safeqr.app.gmail.repository; import com.safeqr.app.gmail.entity.GmailEmailEntity; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Modifying; +import org.springframework.data.jpa.repository.Query; +import org.springframework.transaction.annotation.Transactional; import java.util.List; import java.util.UUID; public interface GmailEmailRespository extends JpaRepository { - List findByUserId(String userId); + // Method to find by userId and active status + List findByUserIdAndActive(String userId, Integer active); + + // Method to update active status to 0 for a specific userId + @Modifying + @Transactional + @Query("UPDATE GmailEmailEntity e SET e.active = 0 WHERE e.userId = :userId") + int deactivateEmailsByUserId(String userId); + + // Method to update active status to 0 for a specific userId and messageId + @Modifying + @Transactional + @Query("UPDATE GmailEmailEntity e SET e.active = 0 WHERE e.userId = :userId AND e.messageId = :messageId") + int deactivateEmailByUserIdAndMessageId(String userId, String messageId); } diff --git a/src/main/java/com/safeqr/app/gmail/service/GmailService.java b/src/main/java/com/safeqr/app/gmail/service/GmailService.java index 3653f74..1008b12 100644 --- a/src/main/java/com/safeqr/app/gmail/service/GmailService.java +++ b/src/main/java/com/safeqr/app/gmail/service/GmailService.java @@ -18,7 +18,9 @@ import com.google.zxing.*; import com.google.zxing.client.j2se.BufferedImageLuminanceSource; import com.google.zxing.common.HybridBinarizer; import com.google.zxing.multi.qrcode.QRCodeMultiReader; -import com.google.zxing.qrcode.encoder.QRCode; + +import com.safeqr.app.exceptions.ResourceNotFoundExceptions; +import com.safeqr.app.gmail.dto.BaseResponse; import com.safeqr.app.gmail.dto.ScannedGmailResponseDto; import com.safeqr.app.gmail.entity.GmailCidEntity; import com.safeqr.app.gmail.entity.GmailEmailEntity; @@ -43,6 +45,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.scheduling.annotation.Async; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import javax.imageio.ImageIO; import java.awt.image.BufferedImage; @@ -64,6 +67,7 @@ import java.util.stream.Stream; import static com.google.api.client.googleapis.auth.oauth2.GoogleOAuthConstants.TOKEN_SERVER_URL; import static com.safeqr.app.constants.APIConstants.APPLICATION_NAME; +import static com.safeqr.app.constants.CommonConstants.GMAIL_ACTIVE; @Service public class GmailService { @@ -263,7 +267,7 @@ public class GmailService { // Fetching Scanned Gmail from database public ScannedGmailResponseDto fetchScannedGmail(String userId){ // Fetching all emails from gmail_email table - List userEmailsList = gmailEmailRespository.findByUserId(userId); + List userEmailsList = gmailEmailRespository.findByUserIdAndActive(userId, GMAIL_ACTIVE); List emailMessageList = new ArrayList<>(); if (userEmailsList != null && !userEmailsList.isEmpty()) { @@ -549,4 +553,21 @@ public class GmailService { String lowerUrl = url.toLowerCase(); return lowerUrl.endsWith(".jpg") || lowerUrl.endsWith(".jpeg") || lowerUrl.endsWith(".png") || lowerUrl.endsWith(".gif") || lowerUrl.endsWith(".bmp"); } + @Transactional + public BaseResponse deleteMessage(String userId, String messageId) { + int updatedCount = gmailEmailRespository.deactivateEmailByUserIdAndMessageId(userId, messageId); + // throw exception if email message not found + if (updatedCount < 1) + throw new ResourceNotFoundExceptions("Email message not found"); + + return BaseResponse.builder().message("Email deleted successfully").build(); + } + + @Transactional + public BaseResponse deleteAllMessages(String userId) { + int updatedCount = gmailEmailRespository.deactivateEmailsByUserId(userId); + return (updatedCount < 1) ? + BaseResponse.builder().message("No Email found").build() : + BaseResponse.builder().message("All Emails deleted successfully").build(); + } } diff --git a/src/main/java/com/safeqr/app/qrcode/entity/ScanHistoryEntity.java b/src/main/java/com/safeqr/app/qrcode/entity/ScanHistoryEntity.java index 0ba129f..862c4e9 100644 --- a/src/main/java/com/safeqr/app/qrcode/entity/ScanHistoryEntity.java +++ b/src/main/java/com/safeqr/app/qrcode/entity/ScanHistoryEntity.java @@ -52,4 +52,9 @@ public class ScanHistoryEntity { dateCreated = now; dateUpdated = now; } + @PreUpdate + public void preUpdate() { + dateUpdated = OffsetDateTime.now(); + } + } \ No newline at end of file diff --git a/src/main/java/com/safeqr/app/qrcode/service/QRCodeTypeService.java b/src/main/java/com/safeqr/app/qrcode/service/QRCodeTypeService.java index daf0ad0..32e5153 100644 --- a/src/main/java/com/safeqr/app/qrcode/service/QRCodeTypeService.java +++ b/src/main/java/com/safeqr/app/qrcode/service/QRCodeTypeService.java @@ -111,7 +111,7 @@ public class QRCodeTypeService { // Create the QR Code Instance based on the QR Code Type & insert into the respective table QRCodeModel qrCodeModel = qrCodeFactoryProvider.createQRCodeInstance(scannedQR); qrCodeModel.setDetails(); - // Get classifications based on verificationsv + // Get classifications based on verifications scannedQR.setResult(qrCodeModel.retrieveClassification()); // update result category in qrcode table qrCodeRepository.save(scannedQR); diff --git a/src/main/java/com/safeqr/app/qrcode/service/URLVerificationService.java b/src/main/java/com/safeqr/app/qrcode/service/URLVerificationService.java index 1a43bec..c225799 100644 --- a/src/main/java/com/safeqr/app/qrcode/service/URLVerificationService.java +++ b/src/main/java/com/safeqr/app/qrcode/service/URLVerificationService.java @@ -428,6 +428,19 @@ public class URLVerificationService { // Get Classification using ML Model public String getClassification(URLModel urlModel){ - return predictionService.predict(urlModel); + // Call ML model + String category = predictionService.predict(urlModel); + + //update in category in url table + + + // return classification results + if (category.equals(CAT_BENIGN)) { + if (!urlModel.getDetails().getTrackingDescriptions().isEmpty()) { + return CLASSIFY_WARNING; + } + return CLASSIFY_SAFE; + } + return CLASSIFY_UNSAFE; } } \ No newline at end of file diff --git a/src/main/java/com/safeqr/app/qrcodetips/controller/QRCodeTipsController.java b/src/main/java/com/safeqr/app/qrcodetips/controller/QRCodeTipsController.java new file mode 100644 index 0000000..127e54a --- /dev/null +++ b/src/main/java/com/safeqr/app/qrcodetips/controller/QRCodeTipsController.java @@ -0,0 +1,30 @@ +package com.safeqr.app.qrcodetips.controller; + +import com.safeqr.app.qrcodetips.entity.QrCodeTipEntity; +import com.safeqr.app.qrcodetips.service.QrCodeTipsService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + + +import static com.safeqr.app.constants.APIConstants.*; + +@RestController +@RequestMapping(API_VERSION) +public class QRCodeTipsController { + private static final Logger logger = LoggerFactory.getLogger(QRCodeTipsController.class); + QrCodeTipsService qrCodeTipsService; + + @Autowired + public QRCodeTipsController (QrCodeTipsService qrCodeTipsService) { this.qrCodeTipsService = qrCodeTipsService;} + + @GetMapping(value = API_URL_TIPS_GET) + public ResponseEntity getRandomTips() { + logger.info("Invoking GET QR Code tips endpoint"); + return ResponseEntity.ok(qrCodeTipsService.getTips()); + } +} diff --git a/src/main/java/com/safeqr/app/qrcodetips/entity/QrCodeTipEntity.java b/src/main/java/com/safeqr/app/qrcodetips/entity/QrCodeTipEntity.java new file mode 100644 index 0000000..5d77e5b --- /dev/null +++ b/src/main/java/com/safeqr/app/qrcodetips/entity/QrCodeTipEntity.java @@ -0,0 +1,24 @@ +package com.safeqr.app.qrcodetips.entity; +import com.fasterxml.jackson.annotation.JsonIgnore; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Entity +@Table(name = "qr_code_tips", schema = "safeqr") +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class QrCodeTipEntity { + + @Id + @JsonIgnore + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String tips; +} + diff --git a/src/main/java/com/safeqr/app/qrcodetips/repository/QrCodeTipRepository.java b/src/main/java/com/safeqr/app/qrcodetips/repository/QrCodeTipRepository.java new file mode 100644 index 0000000..e99b6eb --- /dev/null +++ b/src/main/java/com/safeqr/app/qrcodetips/repository/QrCodeTipRepository.java @@ -0,0 +1,13 @@ +package com.safeqr.app.qrcodetips.repository; + +import com.safeqr.app.qrcodetips.entity.QrCodeTipEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.stereotype.Repository; + +@Repository +public interface QrCodeTipRepository extends JpaRepository { + + @Query(value = "SELECT * FROM safeqr.qr_code_tips ORDER BY RANDOM() LIMIT 1", nativeQuery = true) + QrCodeTipEntity findRandomTip(); +} diff --git a/src/main/java/com/safeqr/app/qrcodetips/service/QrCodeTipsService.java b/src/main/java/com/safeqr/app/qrcodetips/service/QrCodeTipsService.java new file mode 100644 index 0000000..74f4659 --- /dev/null +++ b/src/main/java/com/safeqr/app/qrcodetips/service/QrCodeTipsService.java @@ -0,0 +1,14 @@ +package com.safeqr.app.qrcodetips.service; + +import com.safeqr.app.qrcodetips.entity.QrCodeTipEntity; +import com.safeqr.app.qrcodetips.repository.QrCodeTipRepository; +import org.springframework.stereotype.Service; + +@Service +public class QrCodeTipsService { + QrCodeTipRepository qrCodeTipRepository; + public QrCodeTipsService (QrCodeTipRepository qrCodeTipRepository) { this.qrCodeTipRepository = qrCodeTipRepository; } + public QrCodeTipEntity getTips() { + return qrCodeTipRepository.findRandomTip(); + } +}