Skip to content

Commit

Permalink
Merge pull request #279 from IoTeaTime/develop
Browse files Browse the repository at this point in the history
release: 서버 배포
  • Loading branch information
OziinG authored Dec 12, 2024
2 parents b75d51f + 23e87cc commit 873fcf6
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 3 deletions.
6 changes: 6 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ dependencies {
testImplementation 'org.springframework.boot:spring-boot-starter-test'
testImplementation 'org.springframework.batch:spring-batch-test'
implementation 'org.springframework.boot:spring-boot-starter-quartz'

// Gmail
implementation 'com.google.api-client:google-api-client:2.0.0'
implementation 'com.google.oauth-client:google-oauth-client-jetty:1.34.1'
implementation 'com.google.apis:google-api-services-gmail:v1-rev20220404-2.0.0'
implementation 'javax.mail:mail:1.4.7'
}

spotless {
Expand Down
2 changes: 1 addition & 1 deletion scripts/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ services:
- '8080:8080'
env_file: .env
volumes:
- "./client_secret.json:/client_secret.json"
- "./client_secret_442820160906-mpbltfh7036rl8jtlal40so1tfotkf24.apps.googleusercontent.com.json:/client_secret_442820160906-mpbltfh7036rl8jtlal40so1tfotkf24.apps.googleusercontent.com.json"
- "./monghanyang-21fad-54f38c79a642.json:/monghanyang-21fad-54f38c79a642.json"
- "./logs:/logs"
labels:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import org.ioteatime.meonghanyangserver.auth.dto.request.LoginRequest;
import org.ioteatime.meonghanyangserver.auth.mapper.AuthEntityMapper;
import org.ioteatime.meonghanyangserver.auth.mapper.AuthResponseMapper;
import org.ioteatime.meonghanyangserver.clients.google.GoogleMailClient;
import org.ioteatime.meonghanyangserver.clients.ses.SesClient;
import org.ioteatime.meonghanyangserver.common.exception.BadRequestException;
import org.ioteatime.meonghanyangserver.common.exception.NotFoundException;
Expand All @@ -36,6 +37,7 @@
public class AuthService {
private final JwtUtils jwtUtils;
private final SesClient sesClient;
private final GoogleMailClient googleMailClient;
private final MemberRepository memberRepository;
private final GroupMemberRepository deviceRepository;
private final EmailCodeRepository emailCodeRepository;
Expand Down Expand Up @@ -103,7 +105,8 @@ public void send(String email) {
<p>%s</p>
"""
.formatted(code);
sesClient.sendEmail(email, mailSubject, mailContent);
googleMailClient.sendMail(email, mailSubject, mailContent);
// sesClient.sendEmail(email, mailSubject, mailContent);
}

private static String getCode() {
Expand Down Expand Up @@ -157,6 +160,7 @@ public void issuePassword(IssuePasswordRequest issuePasswordRequest) {
<p>%s</p>
"""
.formatted(password);
sesClient.sendEmail(issuePasswordRequest.email(), mailSubject, mailContent);
googleMailClient.sendMail(issuePasswordRequest.email(), mailSubject, mailContent);
// sesClient.sendEmail(issuePasswordRequest.email(), mailSubject, mailContent);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package org.ioteatime.meonghanyangserver.clients.google;

import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.googleapis.json.GoogleJsonError;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.gmail.Gmail;
import com.google.api.services.gmail.GmailScopes;
import com.google.api.services.gmail.model.Message;
import java.io.*;
import java.nio.file.Paths;
import java.security.GeneralSecurityException;
import java.util.Properties;
import java.util.Set;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import org.apache.commons.codec.binary.Base64;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service
public class GoogleMailClient {
@Value("${google.service-account}")
private String gcpServiceAccount;

@Value("${google.official-gmail}")
private String fromEmailAddress;

private Credential getCredentials(
final NetHttpTransport HTTP_TRANSPORT, GsonFactory jsonFactory) {
try {
// Load client secrets.
InputStream in = new FileInputStream(gcpServiceAccount);
GoogleClientSecrets clientSecrets =
GoogleClientSecrets.load(jsonFactory, new InputStreamReader(in));

// Build flow and trigger user authorization request.
GoogleAuthorizationCodeFlow flow =
new GoogleAuthorizationCodeFlow.Builder(
HTTP_TRANSPORT,
jsonFactory,
clientSecrets,
Set.of(GmailScopes.GMAIL_SEND))
.setDataStoreFactory(
new FileDataStoreFactory(Paths.get("tokens").toFile()))
.setAccessType("offline")
.build();
LocalServerReceiver receiver = new LocalServerReceiver.Builder().setPort(8888).build();
return new AuthorizationCodeInstalledApp(flow, receiver).authorize("user");
} catch (IOException e) {
throw new RuntimeException("Google Credential 획득 중 I/O 오류가 발생하였습니다.");
}
}

public void sendMail(String toEmailAddress, String subject, String message) {
try {
NetHttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
GsonFactory jsonFactory = GsonFactory.getDefaultInstance();
Gmail service =
new Gmail.Builder(
httpTransport,
jsonFactory,
getCredentials(httpTransport, jsonFactory))
.setApplicationName("Test Mailer")
.build();

// Encode as MIME message
Properties props = new Properties();
Session session = Session.getDefaultInstance(props, null);
MimeMessage email = new MimeMessage(session);
email.setFrom(new InternetAddress(fromEmailAddress));
email.addRecipient(
javax.mail.Message.RecipientType.TO, new InternetAddress(toEmailAddress));
email.setSubject(subject);
email.setContent(message, "text/html;charset=utf-8");

// Encode and wrap the MIME message into a gmail message
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
email.writeTo(buffer);
byte[] rawMessageBytes = buffer.toByteArray();
String encodedEmail = Base64.encodeBase64URLSafeString(rawMessageBytes);
Message msg = new Message();
msg.setRaw(encodedEmail);

// Create send message
msg = service.users().messages().send("me", msg).execute();
System.out.println("Message id: " + msg.getId());
System.out.println(msg.toPrettyString());

} catch (GoogleJsonResponseException e) {
GoogleJsonError error = e.getDetails();
if (error.getCode() == 403) {
System.err.println("Unable to send message: " + e.getDetails());
} else {
throw new RuntimeException(
"Gmail Send Mail에서 GoogleJsonResponseException이 발생하였습니다.");
}
} catch (AddressException e) {
throw new RuntimeException("Gmail Send Mail에서 AddressException이 발생하였습니다.");
} catch (MessagingException e) {
throw new RuntimeException("Gmail Send Mail에서 MessagingException이 발생하였습니다.");
} catch (IOException e) {
throw new RuntimeException("Gmail Send Mail에서 IOException이 발생하였습니다.");
} catch (GeneralSecurityException e) {
throw new RuntimeException("Gmail Client GeneralSecurityException이 발생하였습니다.");
}
}
}
1 change: 1 addition & 0 deletions src/main/resources/application-key.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ token:
cctv-secret: ${JWT_CCTV_SECRET}

google:
service-account: ${GCP_SERVICE_ACCOUNT}
official-gmail: ${OFFICIAL_GMAIL}
application-credentials: ${GOOGLE_APPLICATION_CREDENTIALS}

Expand Down

0 comments on commit 873fcf6

Please sign in to comment.