Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/docker-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ jobs:
SPRING_DATASOURCE_USERNAME: ${{ secrets.SPRING_DATASOURCE_USERNAME }}
SPRING_DATASOURCE_PASSWORD: ${{ secrets.SPRING_DATASOURCE_PASSWORD }}
SPRING_PROFILES_ACTIVE: ${{ secrets.SPRING_PROFILES_ACTIVE }}
EMAIL_USERNAME: ${{ secrets.EMAIL_USERNAME }}
EMAIL_PASSWORD: ${{ secrets.EMAIL_PASSWORD }}

steps:
- name: Checkout code
Expand Down Expand Up @@ -108,3 +110,6 @@ jobs:
ghcr.io/${{ env.IMAGE_REPO }}:${{ github.run_number }}
cache-from: type=gha
cache-to: type=gha,mode=max
build-args: |
EMAIL_USERNAME=${{ secrets.EMAIL_USERNAME }}
EMAIL_PASSWORD=${{ secrets.EMAIL_PASSWORD }}
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,4 @@ FROM amazoncorretto:21
WORKDIR /app
COPY --from=build /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java","-Dspring.profiles.active=prod", "-jar", "app.jar"]
ENTRYPOINT ["java", "-jar", "app.jar"]
1,337 changes: 0 additions & 1,337 deletions logs/app.log

Large diffs are not rendered by default.

15 changes: 14 additions & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@
<artifactId>PKWMTT-backend</artifactId>
<version>0.1.0-ALPHA</version>
<name>PKWMTT-backend</name>
<description>PKWM App (Server) – timetable, exam calendar and ECTS calculator for students of Mechanical Engineering @ Cracow University of Technology </description>
<description>PKWM App (Server) – timetable, exam calendar and ECTS calculator for students of Mechanical Engineering
@ Cracow University of Technology
</description>
<url>https://github.com/PKTTTeam/PKWMTT-backend</url>
<licenses>
<license>
Expand Down Expand Up @@ -147,6 +149,17 @@
<artifactId>wiremock-spring-boot</artifactId>
<version>3.10.0</version>
</dependency>
<!--EMAIL-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!--.ENV-->
<dependency>
<groupId>io.github.cdimascio</groupId>
<artifactId>dotenv-java</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.pkwmtt.exceptions;

public class MailServiceNotAvailableException
extends RuntimeException {
public MailServiceNotAvailableException () {
super("Mail service is not available right now.");
}

}
46 changes: 46 additions & 0 deletions src/main/java/org/pkwmtt/mail/EmailService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package org.pkwmtt.mail;

import jakarta.annotation.PostConstruct;
import jakarta.mail.MessagingException;
import jakarta.mail.internet.MimeMessage;
import lombok.RequiredArgsConstructor;
import org.pkwmtt.exceptions.MailServiceNotAvailableException;
import org.pkwmtt.mail.config.MailConfig;
import org.pkwmtt.mail.dto.MailDTO;
import org.springframework.core.env.Environment;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;

@RequiredArgsConstructor
@Service
public class EmailService {
private final Environment environment;

private final JavaMailSender mailSender;

private String hostEmail;

@PostConstruct
private void assignProperties () {
hostEmail = environment.getProperty("spring.mail.username");
}

public void send (MailDTO mail) throws MessagingException, MailServiceNotAvailableException {
if (!MailConfig.isEnabled()) {
throw new MailServiceNotAvailableException();
}


MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true, "UTF-8");

helper.setFrom(hostEmail);
helper.setTo(mail.getRecipient());
helper.setText(mail.getDescription(), true);
helper.setSubject(mail.getTitle());

mailSender.send(message);

}
}
35 changes: 35 additions & 0 deletions src/main/java/org/pkwmtt/mail/EmailTempController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package org.pkwmtt.mail;

import jakarta.mail.MessagingException;
import lombok.RequiredArgsConstructor;
import org.pkwmtt.exceptions.MailServiceNotAvailableException;
import org.pkwmtt.exceptions.dto.ErrorResponseDTO;
import org.pkwmtt.mail.dto.MailDTO;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequiredArgsConstructor
@RequestMapping("/mail")
public class EmailTempController {

private final EmailService service;

@PostMapping
public void sendMail (@RequestParam(name = "r") String recipientEmailAddress)
throws MessagingException, MailServiceNotAvailableException {
service.send(new MailDTO()
.setRecipient(recipientEmailAddress)
.setDescription("TEST")
.setTitle("TEST"));
}

@ExceptionHandler(MailServiceNotAvailableException.class)
public ResponseEntity<ErrorResponseDTO> handle (Exception e) {
return new ResponseEntity<>(
new ErrorResponseDTO(e.getMessage()),
HttpStatus.SERVICE_UNAVAILABLE
);
}
}
57 changes: 57 additions & 0 deletions src/main/java/org/pkwmtt/mail/config/MailConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
package org.pkwmtt.mail.config;

import jakarta.annotation.PostConstruct;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl;

import java.util.Properties;

@Configuration
@RequiredArgsConstructor
public class MailConfig {

@Getter
private static boolean enabled = true;

private final Environment environment;

private String username;
private String password;

@PostConstruct
private void assignAndValidateProperties () {
username = environment.getProperty("spring.mail.username");
password = environment.getProperty("spring.mail.password");

if (username == null || password == null || username.isEmpty() || password.isEmpty()) {
enabled = false;
}
}

@Bean
public JavaMailSender javaMailSender () {
JavaMailSenderImpl mailSender = new JavaMailSenderImpl();

if (!enabled) {
return mailSender;
}

mailSender.setHost("smtp.gmail.com");
mailSender.setPort(587);
mailSender.setUsername(username);
mailSender.setPassword(password);

Properties props = mailSender.getJavaMailProperties();
props.put("mail.transport.protocol", "smtp");
props.put("mail.smtp.auth", "true");
props.put("mail.smtp.starttls.enable", "true");

return mailSender;
}

}
14 changes: 14 additions & 0 deletions src/main/java/org/pkwmtt/mail/dto/MailDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.pkwmtt.mail.dto;

import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.Accessors;

@Data
@Accessors(chain = true)
@NoArgsConstructor
public class MailDTO {
private String recipient;
private String title;
private String description;
}
26 changes: 26 additions & 0 deletions src/main/java/org/pkwmtt/status/DatabaseStatusChecker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package org.pkwmtt.status;


import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.sql.DataSource;
import java.sql.SQLException;

@Slf4j
@Service
public class DatabaseStatusChecker {
@Getter
private static boolean enabled = false;

@Autowired
DatabaseStatusChecker (DataSource dataSource) {
try {
enabled = dataSource.getConnection().isValid(2);
} catch (SQLException e) {
log.error("Couldn't check database connection. Service will be unavailable");
}
}
}
47 changes: 47 additions & 0 deletions src/main/java/org/pkwmtt/status/SystemStatusCheckerService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package org.pkwmtt.status;

import jakarta.annotation.PostConstruct;
import org.pkwmtt.mail.config.MailConfig;
import org.pkwmtt.timetable.TimetableCacheService;
import org.pkwmtt.timetable.TimetableService;
import org.springframework.stereotype.Service;


@Service
public class SystemStatusCheckerService {

private String mailingStatus;
private String databaseStatus;
private String cacheStatus;
private String timetableStatus;

SystemStatusCheckerService () {
checkStatuses();
}

@PostConstruct
private void checkStatuses () {
mailingStatus = assignStatus(MailConfig.isEnabled());
databaseStatus = assignStatus(DatabaseStatusChecker.isEnabled());
timetableStatus = assignStatus(TimetableService.isEnabled());
cacheStatus = assignStatus(TimetableCacheService.isCacheAvailable());
}

public String getStatus () {
return String.format(
"""
Server: ✅;
Services:
Mail: %s
Database: %s,
Timetable: %s,
Cache: %s
""", mailingStatus, databaseStatus, timetableStatus, cacheStatus
);
}


private String assignStatus (boolean condition) {
return condition ? "✅" : "❌";
}
}
20 changes: 20 additions & 0 deletions src/main/java/org/pkwmtt/status/SystemStatusController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.pkwmtt.status;

import lombok.RequiredArgsConstructor;
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;

@RestController
@RequestMapping("/pkwmtt/system/status")
@RequiredArgsConstructor
public class SystemStatusController {
private final SystemStatusCheckerService service;

@GetMapping
public ResponseEntity<String> getSystemStatus () {
return ResponseEntity.ok(service.getStatus());
}

}
Loading