From ef8d99fae355996bf10294afca4dafd6f4c7a733 Mon Sep 17 00:00:00 2001 From: sanjuktaghosh7 Date: Fri, 14 Jan 2022 13:46:01 +0000 Subject: [PATCH 01/10] git-on-borg files of gmail-api-snippets --- gmail/snippets/.gitignore | 61 +++ gmail/snippets/build.gradle | 18 + gmail/snippets/settings.gradle | 19 + gmail/snippets/src/main/java/SendEmail.java | 183 ++++++++ .../src/main/java/SettingsSnippets.java | 106 +++++ .../snippets/src/main/java/SmimeSnippets.java | 275 ++++++++++++ gmail/snippets/src/test/java/BaseTest.java | 81 ++++ .../snippets/src/test/java/SendEmailTest.java | 70 +++ .../src/test/java/SettingsSnippetsTest.java | 77 ++++ .../src/test/java/SmimeSnippetsTest.java | 410 ++++++++++++++++++ 10 files changed, 1300 insertions(+) create mode 100644 gmail/snippets/.gitignore create mode 100644 gmail/snippets/build.gradle create mode 100644 gmail/snippets/settings.gradle create mode 100644 gmail/snippets/src/main/java/SendEmail.java create mode 100644 gmail/snippets/src/main/java/SettingsSnippets.java create mode 100644 gmail/snippets/src/main/java/SmimeSnippets.java create mode 100644 gmail/snippets/src/test/java/BaseTest.java create mode 100644 gmail/snippets/src/test/java/SendEmailTest.java create mode 100644 gmail/snippets/src/test/java/SettingsSnippetsTest.java create mode 100644 gmail/snippets/src/test/java/SmimeSnippetsTest.java diff --git a/gmail/snippets/.gitignore b/gmail/snippets/.gitignore new file mode 100644 index 00000000..060526ad --- /dev/null +++ b/gmail/snippets/.gitignore @@ -0,0 +1,61 @@ +# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio + +*.iml + +## Directory-based project format: +.idea/ + +# if you remove the above rule, at least ignore the following: + +# User-specific stuff: +# .idea/workspace.xml +# .idea/tasks.xml +# .idea/dictionaries +# .idea/shelf + +# Sensitive or high-churn files: +# .idea/dataSources.ids +# .idea/dataSources.xml +# .idea/sqlDataSources.xml +# .idea/dynamic.xml +# .idea/uiDesigner.xml + +# Gradle: +.idea/gradle.xml +.idea/libraries + +# Mongo Explorer plugin: +# .idea/mongoSettings.xml + +## File-based project format: +*.ipr +*.iws + +## Plugin-specific files: + +# IntelliJ +/out/ + +# mpeltonen/sbt-idea plugin +.idea_modules/ + +# JIRA plugin +atlassian-ide-plugin.xml + +# Crashlytics plugin (for Android Studio and IntelliJ) +com_crashlytics_export_strings.xml +crashlytics.properties +crashlytics-build.properties +fabric.properties + +.gradle +build/ + +# Ignore Gradle GUI config +gradle-app.setting + +# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored) +!gradle-wrapper.jar + +# Cache of project +.gradletasknamecache diff --git a/gmail/snippets/build.gradle b/gmail/snippets/build.gradle new file mode 100644 index 00000000..bd5284f5 --- /dev/null +++ b/gmail/snippets/build.gradle @@ -0,0 +1,18 @@ +apply plugin: 'java' + +repositories { + // Use 'jcenter' for resolving your dependencies. + mavenLocal() + jcenter() +} + +dependencies { + compile 'com.google.api-client:google-api-client:1.22.0' + compile 'com.google.apis:google-api-services-gmail:v1-rev62-1.22.0' + compile 'com.google.code.gson:gson:2.4' + compile 'javax.mail:mail:1.4' + compile 'org.apache.commons:commons-csv:1.1' + testCompile 'junit:junit:4.12' + testCompile 'org.hamcrest:hamcrest-all:1.3' + testCompile 'org.mockito:mockito-core:2.7.19' +} diff --git a/gmail/snippets/settings.gradle b/gmail/snippets/settings.gradle new file mode 100644 index 00000000..f93899b1 --- /dev/null +++ b/gmail/snippets/settings.gradle @@ -0,0 +1,19 @@ +/* + * This settings file was auto generated by the Gradle buildInit task + * by 'sbazyl' at '10/22/15 11:30 AM' with Gradle 2.7 + * + * The settings file is used to specify which projects to include in your build. + * In a single project build this file can be empty or even removed. + * + * Detailed information about configuring a multi-project build in Gradle can be found + * in the user guide at https://docs.gradle.org/2.7/userguide/multi_project_builds.html + */ + +/* +// To declare projects as part of a multi-project build use the 'include' method +include 'shared' +include 'api' +include 'services:webservice' +*/ + +rootProject.name = 'java' diff --git a/gmail/snippets/src/main/java/SendEmail.java b/gmail/snippets/src/main/java/SendEmail.java new file mode 100644 index 00000000..e8f39050 --- /dev/null +++ b/gmail/snippets/src/main/java/SendEmail.java @@ -0,0 +1,183 @@ +import com.google.api.client.repackaged.org.apache.commons.codec.binary.Base64; +import com.google.api.services.gmail.Gmail; +import com.google.api.services.gmail.model.Draft; +import com.google.api.services.gmail.model.Message; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.Properties; + +import javax.activation.DataHandler; +import javax.activation.DataSource; +import javax.activation.FileDataSource; +import javax.mail.MessagingException; +import javax.mail.Multipart; +import javax.mail.Session; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeMultipart; + +// ... + +public class SendEmail { + + // ... + + // [START create_draft] + /** + * Create draft email. + * + * @param service an authorized Gmail API instance + * @param userId user's email address. The special value "me" + * can be used to indicate the authenticated user + * @param emailContent the MimeMessage used as email within the draft + * @return the created draft + * @throws MessagingException + * @throws IOException + */ + public static Draft createDraft(Gmail service, + String userId, + MimeMessage emailContent) + throws MessagingException, IOException { + Message message = createMessageWithEmail(emailContent); + Draft draft = new Draft(); + draft.setMessage(message); + draft = service.users().drafts().create(userId, draft).execute(); + + System.out.println("Draft id: " + draft.getId()); + System.out.println(draft.toPrettyString()); + return draft; + } + // [END create_draft] + + + // [START send_email] + /** + * Send an email from the user's mailbox to its recipient. + * + * @param service Authorized Gmail API instance. + * @param userId User's email address. The special value "me" + * can be used to indicate the authenticated user. + * @param emailContent Email to be sent. + * @return The sent message + * @throws MessagingException + * @throws IOException + */ + public static Message sendMessage(Gmail service, + String userId, + MimeMessage emailContent) + throws MessagingException, IOException { + Message message = createMessageWithEmail(emailContent); + message = service.users().messages().send(userId, message).execute(); + + System.out.println("Message id: " + message.getId()); + System.out.println(message.toPrettyString()); + return message; + } + // [END send_email] + + + // [START create_message] + /** + * Create a message from an email. + * + * @param emailContent Email to be set to raw of message + * @return a message containing a base64url encoded email + * @throws IOException + * @throws MessagingException + */ + public static Message createMessageWithEmail(MimeMessage emailContent) + throws MessagingException, IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + emailContent.writeTo(buffer); + byte[] bytes = buffer.toByteArray(); + String encodedEmail = Base64.encodeBase64URLSafeString(bytes); + Message message = new Message(); + message.setRaw(encodedEmail); + return message; + } + // [END create_message] + + // [START create_email] + /** + * Create a MimeMessage using the parameters provided. + * + * @param to email address of the receiver + * @param from email address of the sender, the mailbox account + * @param subject subject of the email + * @param bodyText body text of the email + * @return the MimeMessage to be used to send email + * @throws MessagingException + */ + public static MimeMessage createEmail(String to, + String from, + String subject, + String bodyText) + throws MessagingException { + Properties props = new Properties(); + Session session = Session.getDefaultInstance(props, null); + + MimeMessage email = new MimeMessage(session); + + email.setFrom(new InternetAddress(from)); + email.addRecipient(javax.mail.Message.RecipientType.TO, + new InternetAddress(to)); + email.setSubject(subject); + email.setText(bodyText); + return email; + } + // [END create_email] + + + // [START create_email_attachment] + /** + * Create a MimeMessage using the parameters provided. + * + * @param to Email address of the receiver. + * @param from Email address of the sender, the mailbox account. + * @param subject Subject of the email. + * @param bodyText Body text of the email. + * @param file Path to the file to be attached. + * @return MimeMessage to be used to send email. + * @throws MessagingException + */ + public static MimeMessage createEmailWithAttachment(String to, + String from, + String subject, + String bodyText, + File file) + throws MessagingException, IOException { + Properties props = new Properties(); + Session session = Session.getDefaultInstance(props, null); + + MimeMessage email = new MimeMessage(session); + + email.setFrom(new InternetAddress(from)); + email.addRecipient(javax.mail.Message.RecipientType.TO, + new InternetAddress(to)); + email.setSubject(subject); + + MimeBodyPart mimeBodyPart = new MimeBodyPart(); + mimeBodyPart.setContent(bodyText, "text/plain"); + + Multipart multipart = new MimeMultipart(); + multipart.addBodyPart(mimeBodyPart); + + mimeBodyPart = new MimeBodyPart(); + DataSource source = new FileDataSource(file); + + mimeBodyPart.setDataHandler(new DataHandler(source)); + mimeBodyPart.setFileName(file.getName()); + + multipart.addBodyPart(mimeBodyPart); + email.setContent(multipart); + + return email; + } + // [END create_email_attachment] + + // ... + +} diff --git a/gmail/snippets/src/main/java/SettingsSnippets.java b/gmail/snippets/src/main/java/SettingsSnippets.java new file mode 100644 index 00000000..fab67fa6 --- /dev/null +++ b/gmail/snippets/src/main/java/SettingsSnippets.java @@ -0,0 +1,106 @@ +import com.google.api.client.googleapis.batch.BatchRequest; +import com.google.api.client.googleapis.json.GoogleJsonError; +import com.google.api.client.http.FileContent; +import com.google.api.client.http.HttpHeaders; +import com.google.api.client.util.DateTime; +import com.google.api.services.gmail.Gmail; +import com.google.api.services.gmail.model.*; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + + +public class SettingsSnippets { + + private Gmail service; + + public SettingsSnippets(Gmail service) { + this.service = service; + } + + public String updateSignature() throws IOException { + Gmail gmailService = this.service; + // [START updateSignature] + SendAs primaryAlias = null; + ListSendAsResponse aliases = gmailService.users().settings().sendAs().list("me").execute(); + for (SendAs alias: aliases.getSendAs()) { + if (alias.getIsPrimary()) { + primaryAlias = alias; + break; + } + } + SendAs aliasSettings = new SendAs().setSignature("I heart cats."); + SendAs result = gmailService.users().settings().sendAs().patch( + "me", + primaryAlias.getSendAsEmail(), + aliasSettings) + .execute(); + System.out.println("Updated signature for " + result.getDisplayName()); + // [END updateSignature] + return result.getSignature(); + } + + public String createFilter(String realLabelId) throws IOException { + Gmail gmailService = this.service; + // [START createFilter] + String labelId = "Label_14"; // ID of the user label to add + // [START_EXCLUDE silent] + labelId = realLabelId; + // [END_EXCLUDE] + Filter filter = new Filter() + .setCriteria(new FilterCriteria() + .setFrom("cat-enthusiasts@example.com")) + .setAction(new FilterAction() + .setAddLabelIds(Arrays.asList(labelId)) + .setRemoveLabelIds(Arrays.asList("INBOX"))); + Filter result = gmailService.users().settings().filters().create("me", filter).execute(); + System.out.println("Created filter " + result.getId()); + // [END createFilter] + return result.getId(); + } + + public AutoForwarding enableForwarding(String realForwardingAddress) throws IOException { + Gmail gmailService = this.service; + // [START enableForwarding] + ForwardingAddress address = new ForwardingAddress() + .setForwardingEmail("user2@example.com"); + // [START_EXCLUDE silent] + address.setForwardingEmail(realForwardingAddress); + // [END_EXCLUDE] + ForwardingAddress createAddressResult = gmailService.users().settings().forwardingAddresses() + .create("me", address).execute(); + if (createAddressResult.getVerificationStatus().equals("accepted")) { + AutoForwarding autoForwarding = new AutoForwarding() + .setEnabled(true) + .setEmailAddress(address.getForwardingEmail()) + .setDisposition("trash"); + autoForwarding = gmailService.users().settings().updateAutoForwarding("me", autoForwarding).execute(); + // [START_EXCLUDE silent] + return autoForwarding; + } + // [END enableForwarding] + return null; + } + + public VacationSettings enableAutoReply() throws IOException { + Gmail gmailService = this.service; + // [START enableAutoReply] + VacationSettings vacationSettings = new VacationSettings() + .setEnableAutoReply(true) + .setResponseBodyHtml("I'm on vacation and will reply when I'm back in the office. Thanks!") + .setRestrictToDomain(true) + .setStartTime(LocalDateTime.now().toEpochSecond(ZoneOffset.UTC) * 1000) + .setEndTime(LocalDateTime.now().plusDays(7).toEpochSecond(ZoneOffset.UTC) * 1000); + VacationSettings response = gmailService.users().settings().updateVacation("me", vacationSettings).execute(); + // [END enableAutoReply] + return response; + } + +} diff --git a/gmail/snippets/src/main/java/SmimeSnippets.java b/gmail/snippets/src/main/java/SmimeSnippets.java new file mode 100644 index 00000000..12f895ca --- /dev/null +++ b/gmail/snippets/src/main/java/SmimeSnippets.java @@ -0,0 +1,275 @@ +import com.google.api.services.gmail.Gmail; +import com.google.api.services.gmail.model.*; +import com.google.api.services.gmail.model.SmimeInfo; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Base64; +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVParser; +import org.apache.commons.csv.CSVRecord; + +class SmimeSnippets { + + SmimeSnippets() {} + + // [START create_smime_info] + /** + * Create an SmimeInfo resource for a certificate from file. + * + * @param filename Name of the file containing the S/MIME certificate. + * @param password Password for the certificate file, or null if the file is not + * password-protected. + * @return An SmimeInfo object with the specified certificate. + */ + public static SmimeInfo createSmimeInfo(String filename, String password) { + SmimeInfo smimeInfo = null; + InputStream in = null; + + try { + File file = new File(filename); + in = new FileInputStream(file); + byte fileContent[] = new byte[(int) file.length()]; + in.read(fileContent); + + smimeInfo = new SmimeInfo(); + smimeInfo.setPkcs12(Base64.getUrlEncoder().encodeToString(fileContent)); + if (password != null && password.length() > 0) { + smimeInfo.setEncryptedKeyPassword(password); + } + } catch (Exception e) { + System.out.printf("An error occured while reading the certificate file: %s\n", e); + } finally { + try { + if (in != null) { + in.close(); + } + } catch (IOException ioe) { + System.out.printf("An error occured while closing the input stream: %s\n", ioe); + } + } + + return smimeInfo; + } + // [END create_smime_info] + + // [START insert_smime_info] + /** + * Upload an S/MIME certificate for the user. + * + * @param service Authorized GMail API service instance. + * @param userId User's email address. + * @param sendAsEmail The "send as" email address, or null if it should be the same as userId. + * @param smimeInfo The SmimeInfo object containing the user's S/MIME certificate. + * @return An SmimeInfo object with details about the uploaded certificate. + */ + public static SmimeInfo insertSmimeInfo( + Gmail service, String userId, String sendAsEmail, SmimeInfo smimeInfo) { + if (sendAsEmail == null) { + sendAsEmail = userId; + } + + try { + SmimeInfo results = + service + .users() + .settings() + .sendAs() + .smimeInfo() + .insert(userId, sendAsEmail, smimeInfo) + .execute(); + System.out.printf("Inserted certificate, id: %s\n", results.getId()); + return results; + } catch (IOException e) { + System.err.printf("An error occured: %s", e); + } + + return null; + } + // [END insert_smime_info] + + // [START insert_cert_from_csv] + /** + * A builder that returns a GMail API service instance that is authorized to act on behalf of the + * specified user. + */ + @FunctionalInterface + public interface GmailServiceBuilder { + Gmail buildGmailServiceFromUserId(String userId) throws IOException; + } + + /** + * Upload S/MIME certificates based on the contents of a CSV file. + * + *

Each row of the CSV file should contain a user ID, path to the certificate, and the + * certificate password. + * + * @param serviceBuilder A function that returns an authorized GMail API service instance for a + * given user. + * @param csvFilename Name of the CSV file. + */ + public static void insertCertFromCsv(GmailServiceBuilder serviceBuilder, String csvFilename) { + try { + File csvFile = new File(csvFilename); + CSVParser parser = + CSVParser.parse(csvFile, java.nio.charset.StandardCharsets.UTF_8, CSVFormat.DEFAULT); + for (CSVRecord record : parser) { + String userId = record.get(0); + String certFilename = record.get(1); + String certPassword = record.get(2); + SmimeInfo smimeInfo = createSmimeInfo(certFilename, certPassword); + if (smimeInfo != null) { + insertSmimeInfo( + serviceBuilder.buildGmailServiceFromUserId(userId), userId, userId, smimeInfo); + } else { + System.err.printf("Unable to read certificate file for userId: %s\n", userId); + } + } + } catch (Exception e) { + System.err.printf("An error occured while reading the CSV file: %s", e); + } + } + // [END insert_cert_from_csv] + + // [START update_smime_certs] + /** + * Update S/MIME certificates for the user. + * + *

First performs a lookup of all certificates for a user. If there are no certificates, or + * they all expire before the specified date/time, uploads the certificate in the specified file. + * If the default certificate is expired or there was no default set, chooses the certificate with + * the expiration furthest into the future and sets it as default. + * + * @param service Authorized GMail API service instance. + * @param userId User's email address. + * @param sendAsEmail The "send as" email address, or None if it should be the same as user_id. + * @param certFilename Name of the file containing the S/MIME certificate. + * @param certPassword Password for the certificate file, or None if the file is not + * password-protected. + * @param expireTime DateTime object against which the certificate expiration is compared. If + * None, uses the current time. @ returns: The ID of the default certificate. + * @return The ID of the default certifcate. + */ + public static String updateSmimeCerts( + Gmail service, + String userId, + String sendAsEmail, + String certFilename, + String certPassword, + LocalDateTime expireTime) { + if (sendAsEmail == null) { + sendAsEmail = userId; + } + + ListSmimeInfoResponse listResults = null; + try { + listResults = + service.users().settings().sendAs().smimeInfo().list(userId, sendAsEmail).execute(); + } catch (IOException e) { + System.err.printf("An error occurred during list: %s\n", e); + return null; + } + + String defaultCertId = null; + String bestCertId = null; + LocalDateTime bestCertExpire = LocalDateTime.MIN; + + if (expireTime == null) { + expireTime = LocalDateTime.now(); + } + if (listResults != null && listResults.getSmimeInfo() != null) { + for (SmimeInfo smimeInfo : listResults.getSmimeInfo()) { + String certId = smimeInfo.getId(); + boolean isDefaultCert = smimeInfo.getIsDefault(); + if (isDefaultCert) { + defaultCertId = certId; + } + LocalDateTime exp = + LocalDateTime.ofInstant( + Instant.ofEpochMilli(smimeInfo.getExpiration()), ZoneId.systemDefault()); + if (exp.isAfter(expireTime)) { + if (exp.isAfter(bestCertExpire)) { + bestCertId = certId; + bestCertExpire = exp; + } + } else { + if (isDefaultCert) { + defaultCertId = null; + } + } + } + } + if (defaultCertId == null) { + String defaultId = bestCertId; + if (defaultId == null && certFilename != null) { + SmimeInfo smimeInfo = createSmimeInfo(certFilename, certPassword); + SmimeInfo insertResults = insertSmimeInfo(service, userId, sendAsEmail, smimeInfo); + if (insertResults != null) { + defaultId = insertResults.getId(); + } + } + + if (defaultId != null) { + try { + service + .users() + .settings() + .sendAs() + .smimeInfo() + .setDefault(userId, sendAsEmail, defaultId) + .execute(); + return defaultId; + } catch (IOException e) { + System.err.printf("An error occured during setDefault: %s", e); + } + } + } else { + return defaultCertId; + } + + return null; + } + + /** + * Update S/MIME certificates based on the contents of a CSV file. + * + *

Each row of the CSV file should contain a user ID, path to the certificate, and the + * certificate password. + * + * @param serviceBuilder A function that returns an authorized GMail API service instance for a + * given user. + * @param csvFilename Name of the CSV file. + * @param expireTime DateTime object against which the certificate expiration is compared. If + * None, uses the current time. + */ + public static void updateSmimeFromCsv( + GmailServiceBuilder serviceBuilder, String csvFilename, LocalDateTime expireTime) { + try { + File csvFile = new File(csvFilename); + CSVParser parser = + CSVParser.parse( + csvFile, + java.nio.charset.StandardCharsets.UTF_8, + CSVFormat.DEFAULT.withHeader().withSkipHeaderRecord()); + for (CSVRecord record : parser) { + String userId = record.get(0); + String certFilename = record.get(1); + String certPassword = record.get(2); + updateSmimeCerts( + serviceBuilder.buildGmailServiceFromUserId(userId), + userId, + userId, + certFilename, + certPassword, + expireTime); + } + } catch (Exception e) { + System.err.printf("An error occured while reading the CSV file: %s", e); + } + } + // [END update_smime_certs] +} diff --git a/gmail/snippets/src/test/java/BaseTest.java b/gmail/snippets/src/test/java/BaseTest.java new file mode 100644 index 00000000..9fa3740f --- /dev/null +++ b/gmail/snippets/src/test/java/BaseTest.java @@ -0,0 +1,81 @@ +import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; +import com.google.api.client.http.HttpTransport; +import com.google.api.client.http.javanet.NetHttpTransport; +import com.google.api.client.json.jackson2.JacksonFactory; +import com.google.api.services.gmail.Gmail; +import com.google.api.services.gmail.GmailScopes; +import org.junit.Before; + +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.util.*; +import java.util.logging.Handler; +import java.util.logging.Level; +import java.util.logging.LogRecord; +import java.util.logging.Logger; + +public class BaseTest { + + public static final String TEST_USER = "gdtest1@appsrocks.com"; + public static final String RECIPIENT = "gdtest2@appsrocks.com"; + public static final String FORWARDING_ADDRESS = "gdtest2@appsrocks.com"; + + static { + enableLogging(); + } + + protected Gmail service; + + + public static void enableLogging() { + Logger logger = Logger.getLogger(HttpTransport.class.getName()); + logger.setLevel(Level.ALL); + logger.addHandler(new Handler() { + + @Override + public void close() throws SecurityException { + } + + @Override + public void flush() { + } + + @Override + public void publish(LogRecord record) { + // default ConsoleHandler will print >= INFO to System.err + if (record.getLevel().intValue() < Level.INFO.intValue()) { + System.out.println(record.getMessage()); + } + } + }); + } + + public GoogleCredential getCredential() throws IOException { + GoogleCredential defaultCredentials = GoogleCredential.getApplicationDefault(); + return new GoogleCredential.Builder() + .setServiceAccountId(defaultCredentials.getServiceAccountId()) + .setServiceAccountPrivateKey(defaultCredentials.getServiceAccountPrivateKey()) + .setServiceAccountPrivateKeyId(defaultCredentials.getServiceAccountPrivateKeyId()) + .setServiceAccountUser(TEST_USER) + .setJsonFactory(defaultCredentials.getJsonFactory()) + .setTransport(defaultCredentials.getTransport()) + .setServiceAccountScopes(Arrays.asList(GmailScopes.GMAIL_COMPOSE, GmailScopes.GMAIL_SEND, GmailScopes.GMAIL_LABELS, GmailScopes.GMAIL_SETTINGS_BASIC, GmailScopes.GMAIL_SETTINGS_SHARING)) + .build(); + } + + public Gmail buildService() throws IOException, GeneralSecurityException { + GoogleCredential credential = getCredential(); + return new Gmail.Builder( + new NetHttpTransport(), + JacksonFactory.getDefaultInstance(), + credential) + .setApplicationName("Drive API Snippets") + .build(); + } + + @Before + public void setup() throws IOException, GeneralSecurityException { + this.service = buildService(); + } + +} diff --git a/gmail/snippets/src/test/java/SendEmailTest.java b/gmail/snippets/src/test/java/SendEmailTest.java new file mode 100644 index 00000000..6d17129b --- /dev/null +++ b/gmail/snippets/src/test/java/SendEmailTest.java @@ -0,0 +1,70 @@ +import com.google.api.services.gmail.model.*; +import org.junit.Test; + +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.internet.MimeMessage; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +public class SendEmailTest extends BaseTest { + + @Test + public void createEmail() throws MessagingException, IOException { + MimeMessage mimeMessage = SendEmail.createEmail(RECIPIENT, + TEST_USER, + "test", + "Hello!"); + assertEquals("test", mimeMessage.getSubject()); + assertEquals("Hello!", mimeMessage.getContent()); + assertEquals(RECIPIENT, mimeMessage.getRecipients(Message.RecipientType.TO)[0].toString()); + assertEquals(TEST_USER, mimeMessage.getFrom()[0].toString()); + } + + @Test + public void createEmailWithAttachment() throws MessagingException, IOException { + MimeMessage mimeMessage = SendEmail.createEmailWithAttachment(RECIPIENT, + TEST_USER, + "test", + "Hello!", + new java.io.File("files/photo.jpg")); + assertEquals("test", mimeMessage.getSubject()); + assertEquals(RECIPIENT, mimeMessage.getRecipients(Message.RecipientType.TO)[0].toString()); + assertEquals(TEST_USER, mimeMessage.getFrom()[0].toString()); + } + + @Test + public void createMessageWithEmail() throws MessagingException, IOException { + MimeMessage mimeMessage = SendEmail.createEmail(RECIPIENT, + TEST_USER, + "test", + "Hello!"); + + com.google.api.services.gmail.model.Message message = SendEmail.createMessageWithEmail(mimeMessage); + assertNotNull(message.getRaw()); // Weak assertion... + } + + @Test + public void createDraft() throws MessagingException, IOException { + MimeMessage mimeMessage = SendEmail.createEmail(RECIPIENT, + TEST_USER, + "test", + "Hello!"); + Draft draft = SendEmail.createDraft(this.service, "me", mimeMessage); + assertNotNull(draft); + this.service.users().drafts().delete("me", draft.getId()); + } + + @Test + public void sendEmail() throws MessagingException, IOException { + MimeMessage mimeMessage = SendEmail.createEmailWithAttachment(RECIPIENT, + TEST_USER, + "test", + "Hello!", + new java.io.File("files/photo.jpg")); + com.google.api.services.gmail.model.Message message = SendEmail.sendMessage(this.service, "me", mimeMessage); + assertNotNull(message); + } +} diff --git a/gmail/snippets/src/test/java/SettingsSnippetsTest.java b/gmail/snippets/src/test/java/SettingsSnippetsTest.java new file mode 100644 index 00000000..8622e8d4 --- /dev/null +++ b/gmail/snippets/src/test/java/SettingsSnippetsTest.java @@ -0,0 +1,77 @@ + +import com.google.api.services.gmail.model.AutoForwarding; +import com.google.api.services.gmail.model.Label; +import com.google.api.services.gmail.model.ListLabelsResponse; +import com.google.api.services.gmail.model.VacationSettings; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.IOException; +import java.security.GeneralSecurityException; + +import static org.junit.Assert.*; + +public class SettingsSnippetsTest extends BaseTest { + + private SettingsSnippets snippets; + private Label testLabel = null; + + @Before + public void createSnippets() { + this.snippets = new SettingsSnippets(this.service); + } + + @Before + public void createLabel() throws IOException { + ListLabelsResponse response = this.service.users().labels().list("me").execute(); + for (Label l : response.getLabels()) { + if (l.getName().equals("testLabel")) { + testLabel = l; + } + } + if (testLabel == null) { + Label label = new Label() + .setName("testLabel") + .setLabelListVisibility("labelShow") + .setMessageListVisibility("show"); + testLabel = this.service.users().labels().create("me", label).execute(); + } + } + + @After + public void deleteLabel() throws IOException { + if (testLabel != null) { + this.service.users().labels().delete("me", testLabel.getId()).execute(); + testLabel = null; + } + } + + @Test + public void updateSignature() throws IOException, GeneralSecurityException { + String signature = this.snippets.updateSignature(); + assertEquals("I heart cats.", signature); + } + + @Test + public void createFilter() throws IOException, GeneralSecurityException { + String id = this.snippets.createFilter(testLabel.getId()); + assertNotNull(id); + this.service.users().settings().filters().delete("me", id).execute(); + } + + @Test + public void enableAutoForwarding() throws IOException, GeneralSecurityException { + AutoForwarding forwarding = this.snippets.enableForwarding(FORWARDING_ADDRESS); + assertNotNull(forwarding); + forwarding = new AutoForwarding().setEnabled(false); + this.service.users().settings().updateAutoForwarding("me", forwarding).execute(); + this.service.users().settings().forwardingAddresses().delete("me", FORWARDING_ADDRESS).execute(); + } + + @Test + public void enableAutoReply() throws IOException, GeneralSecurityException { + VacationSettings settings = this.snippets.enableAutoReply(); + assertNotNull(settings); + } +} diff --git a/gmail/snippets/src/test/java/SmimeSnippetsTest.java b/gmail/snippets/src/test/java/SmimeSnippetsTest.java new file mode 100644 index 00000000..6aefb3e3 --- /dev/null +++ b/gmail/snippets/src/test/java/SmimeSnippetsTest.java @@ -0,0 +1,410 @@ +import static org.hamcrest.Matchers.greaterThan; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertThat; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoMoreInteractions; +import static org.mockito.Mockito.verifyZeroInteractions; +import static org.mockito.Mockito.when; + +import com.google.api.services.gmail.Gmail; +import com.google.api.services.gmail.model.*; +import java.io.IOException; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +public class SmimeSnippetsTest { + + private static final long CURRENT_TIME_MS = 1234567890; + private static final LocalDateTime CURRENT_TIME = + LocalDateTime.ofInstant(Instant.ofEpochMilli(CURRENT_TIME_MS), ZoneId.systemDefault()); + private static final String TEST_USER = "user1@example.com"; + + @Mock private Gmail mockService; + @Mock private Gmail.Users mockUsers; + @Mock private Gmail.Users.Settings mockSettings; + @Mock private Gmail.Users.Settings.SendAs mockSendAs; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo mockSmimeInfo; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.Delete mockDelete; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.Get mockGet; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.Insert mockInsert; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.List mockList; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.SetDefault mockSetDefault; + + @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); + + @Before + public void setup() throws IOException { + when(mockService.users()).thenReturn(mockUsers); + when(mockUsers.settings()).thenReturn(mockSettings); + when(mockSettings.sendAs()).thenReturn(mockSendAs); + when(mockSendAs.smimeInfo()).thenReturn(mockSmimeInfo); + + when(mockSmimeInfo.delete(any(), any(), any())).thenReturn(mockDelete); + when(mockSmimeInfo.get(any(), any(), any())).thenReturn(mockGet); + when(mockSmimeInfo.insert(any(), any(), any())).thenReturn(mockInsert); + when(mockSmimeInfo.list(any(), any())).thenReturn(mockList); + when(mockSmimeInfo.setDefault(any(), any(), any())).thenReturn(mockSetDefault); + } + + @After + public void tearDown() throws IOException { + verifyNoMoreInteractions(mockService); + verifyNoMoreInteractions(mockUsers); + verifyNoMoreInteractions(mockSettings); + verifyNoMoreInteractions(mockSendAs); + verifyNoMoreInteractions(mockSmimeInfo); + verifyNoMoreInteractions(mockInsert); + verifyNoMoreInteractions(mockList); + verifyNoMoreInteractions(mockSetDefault); + + verifyZeroInteractions(mockDelete); + verifyZeroInteractions(mockGet); + } + + @Test + public void testCreateSmimeInfo() { + SmimeInfo smimeInfo = SmimeSnippets.createSmimeInfo("files/cert.p12", null /* password */); + + assertNotNull(smimeInfo); + assertNull(smimeInfo.getEncryptedKeyPassword()); + assertNull(smimeInfo.getExpiration()); + assertNull(smimeInfo.getId()); + assertNull(smimeInfo.getIsDefault()); + assertNull(smimeInfo.getIssuerCn()); + assertNull(smimeInfo.getPem()); + assertThat(smimeInfo.getPkcs12().length(), greaterThan(0)); + } + + @Test + public void testCreateSmimeInfoWithPassword() { + SmimeInfo smimeInfo = SmimeSnippets.createSmimeInfo("files/cert.p12", "certpass"); + + assertNotNull(smimeInfo); + assertEquals(smimeInfo.getEncryptedKeyPassword(), "certpass"); + assertNull(smimeInfo.getExpiration()); + assertNull(smimeInfo.getId()); + assertNull(smimeInfo.getIsDefault()); + assertNull(smimeInfo.getIssuerCn()); + assertNull(smimeInfo.getPem()); + assertThat(smimeInfo.getPkcs12().length(), greaterThan(0)); + } + + @Test + public void testCreateSmimeInfoFileNotFound() { + SmimeInfo smimeInfo = SmimeSnippets.createSmimeInfo("files/notfound.p12", null /* password */); + + assertNull(smimeInfo); + } + + @Test + public void testInsertSmimeInfo() throws IOException { + SmimeInfo insertResult = makeFakeInsertResult(); + when(mockInsert.execute()).thenReturn(insertResult); + + SmimeInfo smimeInfo = SmimeSnippets.createSmimeInfo("files/cert.p12", null /* password */); + SmimeInfo result = SmimeSnippets.insertSmimeInfo(mockService, TEST_USER, TEST_USER, smimeInfo); + + verifySmimeApiCalled(1); + verify(mockSmimeInfo).insert(eq(TEST_USER), eq(TEST_USER), eq(smimeInfo)); + verify(mockInsert).execute(); + + assertEquals(insertResult, result); + } + + @Test + public void testInsertSmimeInfoError() throws IOException { + when(mockInsert.execute()).thenThrow(IOException.class); + + SmimeInfo smimeInfo = SmimeSnippets.createSmimeInfo("files/cert.p12", null /* password */); + SmimeInfo result = SmimeSnippets.insertSmimeInfo(mockService, TEST_USER, TEST_USER, smimeInfo); + + verifySmimeApiCalled(1); + verify(mockSmimeInfo).insert(eq(TEST_USER), eq(TEST_USER), eq(smimeInfo)); + verify(mockInsert).execute(); + + assertNull(result); + } + + @Test + public void testInsertSmimeFromCsv() throws IOException { + when(mockInsert.execute()).thenReturn(makeFakeInsertResult()); + + SmimeSnippets.insertCertFromCsv((u) -> mockService, "files/certs.csv"); + + verifySmimeApiCalled(2); + verify(mockSmimeInfo).insert(eq("user1@example.com"), eq("user1@example.com"), any()); + verify(mockSmimeInfo).insert(eq("user2@example.com"), eq("user2@example.com"), any()); + verify(mockInsert, times(2)).execute(); + } + + @Test + public void testInsertSmimeFromCsvFails() throws IOException { + when(mockInsert.execute()).thenReturn(makeFakeInsertResult()); + + SmimeSnippets.insertCertFromCsv((u) -> mockService, "files/notfound.csv"); + } + + @Test + public void testUpdateSmimeCertsNoCerts() throws IOException { + when(mockList.execute()).thenReturn(makeFakeListResult()); + + String defaultCertId = + SmimeSnippets.updateSmimeCerts( + mockService, + TEST_USER, + TEST_USER, + null /* certFilename */, + null /* certPassword */, + CURRENT_TIME); + + verifySmimeApiCalled(1); + verify(mockSmimeInfo).list(eq(TEST_USER), eq(TEST_USER)); + verify(mockList).execute(); + + assertNull(defaultCertId); + } + + @Test + public void testUpdateSmimeCertsNoCertsUploadNewCert() throws IOException { + when(mockList.execute()).thenReturn(makeFakeListResult()); + when(mockInsert.execute()).thenReturn(makeFakeInsertResult()); + + String defaultCertId = + SmimeSnippets.updateSmimeCerts( + mockService, + TEST_USER, + TEST_USER, + "files/cert.p12", + null /* certPassword */, + CURRENT_TIME); + + verifySmimeApiCalled(3); + verify(mockSmimeInfo).list(eq(TEST_USER), eq(TEST_USER)); + verify(mockSmimeInfo).insert(eq(TEST_USER), eq(TEST_USER), any()); + verify(mockSmimeInfo).setDefault(eq(TEST_USER), eq(TEST_USER), eq("new_certificate_id")); + verify(mockList).execute(); + verify(mockInsert).execute(); + verify(mockSetDefault).execute(); + + assertEquals(defaultCertId, "new_certificate_id"); + } + + @Test + public void testUpdateSmimeCertsValidDefaultCertNoUpload() throws IOException { + ListSmimeInfoResponse listResponse = + makeFakeListResult(Arrays.asList(true), Arrays.asList(CURRENT_TIME_MS + 1)); + when(mockList.execute()).thenReturn(listResponse); + + String defaultCertId = + SmimeSnippets.updateSmimeCerts( + mockService, + TEST_USER, + TEST_USER, + "files/cert.p12", + null /* certPassword */, + CURRENT_TIME); + + verifySmimeApiCalled(1); + verify(mockSmimeInfo).list(eq(TEST_USER), eq(TEST_USER)); + verify(mockList).execute(); + + assertEquals(defaultCertId, "existing_certificate_id0"); + } + + @Test + public void testUpdateSmimeCertsExpiredDefaultCertUploadNewCert() throws IOException { + LocalDateTime expireTime = + LocalDateTime.ofInstant(Instant.ofEpochMilli(CURRENT_TIME_MS + 2), ZoneId.systemDefault()); + ListSmimeInfoResponse listResponse = + makeFakeListResult(Arrays.asList(true), Arrays.asList(CURRENT_TIME_MS + 1)); + when(mockList.execute()).thenReturn(listResponse); + + when(mockInsert.execute()).thenReturn(makeFakeInsertResult()); + + String defaultCertId = + SmimeSnippets.updateSmimeCerts( + mockService, + TEST_USER, + TEST_USER, + "files/cert.p12", + null /* certPassword */, + expireTime); + + verifySmimeApiCalled(3); + verify(mockSmimeInfo).list(eq(TEST_USER), eq(TEST_USER)); + verify(mockSmimeInfo).insert(eq(TEST_USER), eq(TEST_USER), any()); + verify(mockSmimeInfo).setDefault(eq(TEST_USER), eq(TEST_USER), eq("new_certificate_id")); + verify(mockList).execute(); + verify(mockInsert).execute(); + verify(mockSetDefault).execute(); + + assertEquals(defaultCertId, "new_certificate_id"); + } + + @Test + public void testUpdateSmimeCertsExpiredDefaultCertOtherCertNewDefault() throws IOException { + ListSmimeInfoResponse listResponse = + makeFakeListResult( + Arrays.asList(true, false), Arrays.asList(CURRENT_TIME_MS - 1, CURRENT_TIME_MS + 1)); + when(mockList.execute()).thenReturn(listResponse); + + String defaultCertId = + SmimeSnippets.updateSmimeCerts( + mockService, + TEST_USER, + TEST_USER, + "files/cert.p12", + null /* certPassword */, + CURRENT_TIME); + + verifySmimeApiCalled(2); + verify(mockSmimeInfo).list(eq(TEST_USER), eq(TEST_USER)); + verify(mockSmimeInfo).setDefault(eq(TEST_USER), eq(TEST_USER), eq("existing_certificate_id1")); + verify(mockList).execute(); + verify(mockSetDefault).execute(); + + assertEquals(defaultCertId, "existing_certificate_id1"); + } + + @Test + public void testUpdateSmimeCertsNoCertsNoDefaultsChooseBestCertAsNewDefault() throws IOException { + ListSmimeInfoResponse listResponse = + makeFakeListResult( + Arrays.asList(false, false, false, false), + Arrays.asList( + CURRENT_TIME_MS + 2, + CURRENT_TIME_MS + 1, + CURRENT_TIME_MS + 4, + CURRENT_TIME_MS + 3)); + when(mockList.execute()).thenReturn(listResponse); + + String defaultCertId = + SmimeSnippets.updateSmimeCerts( + mockService, + TEST_USER, + TEST_USER, + "files/cert.p12", + null /* certPassword */, + CURRENT_TIME); + + verifySmimeApiCalled(2); + verify(mockSmimeInfo).list(eq(TEST_USER), eq(TEST_USER)); + verify(mockSmimeInfo).setDefault(eq(TEST_USER), eq(TEST_USER), eq("existing_certificate_id2")); + verify(mockList).execute(); + verify(mockSetDefault).execute(); + + assertEquals(defaultCertId, "existing_certificate_id2"); + } + + @Test + public void testUpdateSmimeCertsError() throws IOException { + when(mockList.execute()).thenThrow(IOException.class); + + String defaultCertId = + SmimeSnippets.updateSmimeCerts( + mockService, + TEST_USER, + TEST_USER, + "files/cert.p12", + null /* certPassword */, + CURRENT_TIME); + + verifySmimeApiCalled(1); + verify(mockSmimeInfo).list(eq(TEST_USER), eq(TEST_USER)); + verify(mockList).execute(); + + assertNull(defaultCertId); + } + + @Test + public void testUpdateSmimeFromCsv() throws IOException { + when(mockList.execute()).thenReturn(makeFakeListResult()); + when(mockInsert.execute()).thenReturn(makeFakeInsertResult()); + + SmimeSnippets.updateSmimeFromCsv((u) -> mockService, "files/certs.csv", CURRENT_TIME); + + verifySmimeApiCalled(9); + verify(mockSmimeInfo).list(eq("user1@example.com"), eq("user1@example.com")); + verify(mockSmimeInfo).list(eq("user2@example.com"), eq("user2@example.com")); + verify(mockSmimeInfo).list(eq("user3@example.com"), eq("user3@example.com")); + verify(mockSmimeInfo).insert(eq("user1@example.com"), eq("user1@example.com"), any()); + verify(mockSmimeInfo).insert(eq("user2@example.com"), eq("user2@example.com"), any()); + verify(mockSmimeInfo).insert(eq("user3@example.com"), eq("user3@example.com"), any()); + verify(mockSmimeInfo) + .setDefault(eq("user1@example.com"), eq("user1@example.com"), eq("new_certificate_id")); + verify(mockSmimeInfo) + .setDefault(eq("user2@example.com"), eq("user2@example.com"), eq("new_certificate_id")); + verify(mockSmimeInfo) + .setDefault(eq("user3@example.com"), eq("user3@example.com"), eq("new_certificate_id")); + verify(mockList, times(3)).execute(); + verify(mockInsert, times(3)).execute(); + verify(mockSetDefault, times(3)).execute(); + } + + @Test + public void testUpdateSmimeFromCsvFails() { + SmimeSnippets.insertCertFromCsv((u) -> mockService, "files/notfound.csv"); + // tearDown() verifies that there were no interactions with the API. + } + + private void verifySmimeApiCalled(int numCalls) { + verify(mockService, times(numCalls)).users(); + verify(mockUsers, times(numCalls)).settings(); + verify(mockSettings, times(numCalls)).sendAs(); + verify(mockSendAs, times(numCalls)).smimeInfo(); + } + + private ListSmimeInfoResponse makeFakeListResult(List isDefault, List expiration) { + ListSmimeInfoResponse listResponse = new ListSmimeInfoResponse(); + if (isDefault == null || expiration == null) { + return listResponse; + } + + assertEquals(isDefault.size(), expiration.size()); + + List smimeInfoList = new ArrayList(); + for (int i = 0; i < isDefault.size(); i++) { + SmimeInfo smimeInfo = new SmimeInfo(); + smimeInfo.setId(String.format("existing_certificate_id%d", i)); + smimeInfo.setIsDefault(isDefault.get(i)); + smimeInfo.setExpiration(expiration.get(i)); + smimeInfoList.add(smimeInfo); + } + listResponse.setSmimeInfo(smimeInfoList); + + return listResponse; + } + + private ListSmimeInfoResponse makeFakeListResult() { + return makeFakeListResult(null /* isDefault */, null /* expiration */); + } + + private SmimeInfo makeFakeInsertResult(String id, boolean isDefault, long expiration) { + SmimeInfo insertResult = new SmimeInfo(); + insertResult.setId(id); + insertResult.setIsDefault(isDefault); + insertResult.setExpiration(expiration); + + return insertResult; + } + + private SmimeInfo makeFakeInsertResult() { + return makeFakeInsertResult("new_certificate_id", false, CURRENT_TIME_MS + 1); + } +} From cc07ac471b29b3b671819ff7514c3de9069b42bb Mon Sep 17 00:00:00 2001 From: Manvendra-P-Singh Date: Wed, 19 Jan 2022 10:18:20 +0530 Subject: [PATCH 02/10] Update build.gradle test12 --- docs/quickstart/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/quickstart/build.gradle b/docs/quickstart/build.gradle index 48c9c11a..ccbf7b75 100644 --- a/docs/quickstart/build.gradle +++ b/docs/quickstart/build.gradle @@ -3,7 +3,7 @@ apply plugin: 'application' mainClassName = 'DocsQuickstart' sourceCompatibility = 11 -targetCompatibility = 11 +targetCompatibility = 8 version = '1.0' repositories { From 352491b4e8c189197db876886f1eec6c8fb6af36 Mon Sep 17 00:00:00 2001 From: Rajesh Mudaliyar Date: Tue, 18 Jan 2022 20:57:58 -0800 Subject: [PATCH 03/10] Update build.gradle --- docs/quickstart/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/quickstart/build.gradle b/docs/quickstart/build.gradle index ccbf7b75..48c9c11a 100644 --- a/docs/quickstart/build.gradle +++ b/docs/quickstart/build.gradle @@ -3,7 +3,7 @@ apply plugin: 'application' mainClassName = 'DocsQuickstart' sourceCompatibility = 11 -targetCompatibility = 8 +targetCompatibility = 11 version = '1.0' repositories { From f9cbff51edb138279c4b008eeb0bc8a8fd9c7f10 Mon Sep 17 00:00:00 2001 From: sanjuktaghosh7 Date: Wed, 1 Jun 2022 00:10:54 +0530 Subject: [PATCH 04/10] Gmail-snippets --- gmail/snippets/src/main/java/CreateDraft.java | 23 ++++---- .../main/java/CreateDraftWithAttachment.java | 24 +++++---- gmail/snippets/src/main/java/CreateEmail.java | 53 +++++++++++++++++++ .../snippets/src/main/java/CreateFilter.java | 28 +++++----- .../snippets/src/main/java/CreateMessage.java | 45 ++++++++++++++++ .../src/main/java/EnableAutoReply.java | 20 +++---- .../src/main/java/EnableForwarding.java | 17 +++--- gmail/snippets/src/main/java/SendMessage.java | 18 ++++--- .../main/java/SendMessageWithAttachment.java | 19 ++++--- .../src/main/java/UpdateSignature.java | 19 +++---- 10 files changed, 194 insertions(+), 72 deletions(-) create mode 100644 gmail/snippets/src/main/java/CreateEmail.java create mode 100644 gmail/snippets/src/main/java/CreateMessage.java diff --git a/gmail/snippets/src/main/java/CreateDraft.java b/gmail/snippets/src/main/java/CreateDraft.java index 087cf3ba..683119c8 100644 --- a/gmail/snippets/src/main/java/CreateDraft.java +++ b/gmail/snippets/src/main/java/CreateDraft.java @@ -14,6 +14,7 @@ // [START gmail_create_draft] +import com.google.api.client.googleapis.json.GoogleJsonError; import com.google.api.client.googleapis.json.GoogleJsonResponseException; import com.google.api.client.http.HttpRequestInitializer; import com.google.api.client.http.javanet.NetHttpTransport; @@ -32,7 +33,6 @@ import javax.mail.internet.MimeMessage; import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.util.Collections; import java.util.Properties; /* Class to demonstrate the use of Gmail Create Draft API */ @@ -42,16 +42,16 @@ public class CreateDraft { * * @param fromEmailAddress - Email address to appear in the from: header * @param toEmailAddress - Email address of the recipient - * @return the created draft - * @throws MessagingException - * @throws IOException + * @return the created draft, {@code null} otherwise. + * @throws MessagingException - if a wrongly formatted address is encountered. + * @throws IOException - if service account credentials file not found. */ public static Draft createDraftMessage(String fromEmailAddress, String toEmailAddress) throws MessagingException, IOException { - // Load pre-authorized user credentials from the environment. - // TODO(developer) - See https://developers.google.com/identity for - // guides on implementing OAuth2 for your application. + /* Load pre-authorized user credentials from the environment. + TODO(developer) - See https://developers.google.com/identity for + guides on implementing OAuth2 for your application.*/ GoogleCredentials credentials = GoogleCredentials.getApplicationDefault() .createScoped(GmailScopes.GMAIL_COMPOSE); HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials); @@ -95,9 +95,14 @@ public static Draft createDraftMessage(String fromEmailAddress, return draft; } catch (GoogleJsonResponseException e) { // TODO(developer) - handle error appropriately - System.err.println("Unable to create draft: " + e.getDetails()); - throw e; + GoogleJsonError error = e.getDetails(); + if (error.getCode() == 403) { + System.err.println("Unable to create draft: " + e.getMessage()); + } else { + throw e; + } } + return null; } } // [END gmail_create_draft] \ No newline at end of file diff --git a/gmail/snippets/src/main/java/CreateDraftWithAttachment.java b/gmail/snippets/src/main/java/CreateDraftWithAttachment.java index 626299e0..b7b2144d 100644 --- a/gmail/snippets/src/main/java/CreateDraftWithAttachment.java +++ b/gmail/snippets/src/main/java/CreateDraftWithAttachment.java @@ -14,6 +14,7 @@ // [START gmail_create_draft_with_attachment] +import com.google.api.client.googleapis.json.GoogleJsonError; import com.google.api.client.googleapis.json.GoogleJsonResponseException; import com.google.api.client.http.HttpRequestInitializer; import com.google.api.client.http.javanet.NetHttpTransport; @@ -45,12 +46,12 @@ /* Class to demonstrate the use of Gmail Create Draft with attachment API */ public class CreateDraftWithAttachment { /** - * Create a draft email. + * Create a draft email with attachment. * * @param fromEmailAddress - Email address to appear in the from: header. * @param toEmailAddress - Email address of the recipient. * @param file - Path to the file to be attached. - * @return the created draft + * @return the created draft, {@code null} otherwise. * @throws MessagingException - if a wrongly formatted address is encountered. * @throws IOException - if service account credentials file not found. */ @@ -58,11 +59,11 @@ public static Draft createDraftMessageWithAttachment(String fromEmailAddress, String toEmailAddress, File file) throws MessagingException, IOException { - // Load pre-authorized user credentials from the environment. - // TODO(developer) - See https://developers.google.com/identity for - // guides on implementing OAuth2 for your application. - GoogleCredentials credentials = GoogleCredentials.getApplicationDefault().createScoped( - GmailScopes.GMAIL_COMPOSE); + /* Load pre-authorized user credentials from the environment. + TODO(developer) - See https://developers.google.com/identity for + guides on implementing OAuth2 for your application.*/ + GoogleCredentials credentials = GoogleCredentials.getApplicationDefault() + .createScoped(GmailScopes.GMAIL_COMPOSE); HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials); // Create the gmail API client @@ -114,9 +115,14 @@ public static Draft createDraftMessageWithAttachment(String fromEmailAddress, return draft; } catch (GoogleJsonResponseException e) { // TODO(developer) - handle error appropriately - System.err.println("Unable to create draft: " + e.getDetails()); - throw e; + GoogleJsonError error = e.getDetails(); + if (error.getCode() == 403){ + System.err.println("Unable to create draft: " + e.getDetails()); + } else { + throw e; + } } + return null; } } // [END gmail_create_draft_with_attachment] \ No newline at end of file diff --git a/gmail/snippets/src/main/java/CreateEmail.java b/gmail/snippets/src/main/java/CreateEmail.java new file mode 100644 index 00000000..5a9b3497 --- /dev/null +++ b/gmail/snippets/src/main/java/CreateEmail.java @@ -0,0 +1,53 @@ +// Copyright 2021 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// [START gmail_create_email] +import javax.mail.MessagingException; +import javax.mail.Session; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeMessage; +import java.util.Properties; + +/* Class to demonstrate the use of Gmail Create Email API */ +public class CreateEmail { + + /** + * Create a MimeMessage using the parameters provided. + * + * @param toEmailAddress email address of the receiver + * @param fromEmailAddress email address of the sender, the mailbox account + * @param subject subject of the email + * @param bodyText body text of the email + * @return the MimeMessage to be used to send email + * @throws MessagingException - if a wrongly formatted address is encountered. + */ + public static MimeMessage createEmail(String toEmailAddress, + String fromEmailAddress, + String subject, + String bodyText) + throws MessagingException { + 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.setText(bodyText); + return email; + } +} +// [END gmail_create_email] diff --git a/gmail/snippets/src/main/java/CreateFilter.java b/gmail/snippets/src/main/java/CreateFilter.java index 8faea942..354eafbf 100644 --- a/gmail/snippets/src/main/java/CreateFilter.java +++ b/gmail/snippets/src/main/java/CreateFilter.java @@ -14,6 +14,7 @@ // [START gmail_create_filter] +import com.google.api.client.googleapis.json.GoogleJsonError; import com.google.api.client.googleapis.json.GoogleJsonResponseException; import com.google.api.client.http.HttpRequestInitializer; import com.google.api.client.http.javanet.NetHttpTransport; @@ -33,20 +34,17 @@ public class CreateFilter { /** * Create a new filter. * - * @param realLabelId - ID of the user label to add - * @return the created filter id + * @param labelId - ID of the user label to add + * @return the created filter id, {@code null} otherwise. * @throws IOException - if service account credentials file not found. */ - public static String createNewFilter(String realLabelId) throws IOException { - // TODO(developer) - Replace with your email address. - String userEmail = "ci-test01@workspacesamples.dev"; - + public static String createNewFilter(String labelId) throws IOException { /* Load pre-authorized user credentials from the environment. TODO(developer) - See https://developers.google.com/identity for guides on implementing OAuth2 for your application. */ GoogleCredentials credentials = GoogleCredentials.getApplicationDefault() - .createScoped(GmailScopes.GMAIL_SETTINGS_BASIC, GmailScopes.GMAIL_LABELS) - .createDelegated(userEmail); + .createScoped(GmailScopes.GMAIL_SETTINGS_BASIC, + GmailScopes.GMAIL_LABELS); HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials); // Create the gmail API client @@ -56,11 +54,6 @@ public static String createNewFilter(String realLabelId) throws IOException { .setApplicationName("Gmail samples") .build(); - String labelId = "Label_14"; // ID of the user label to add - // [START_EXCLUDE silent] - labelId = realLabelId; - // [END_EXCLUDE] - try { // Filter the mail from sender and archive them(skip the inbox) Filter filter = new Filter() @@ -76,9 +69,14 @@ public static String createNewFilter(String realLabelId) throws IOException { return result.getId(); } catch (GoogleJsonResponseException e) { // TODO(developer) - handle error appropriately - System.err.println("Unable to create filter: " + e.getDetails()); - throw e; + GoogleJsonError error = e.getDetails(); + if (error.getCode() == 403) { + System.err.println("Unable to create filter: " + e.getDetails()); + } else { + throw e; + } } + return null; } } // [END gmail_create_filter] diff --git a/gmail/snippets/src/main/java/CreateMessage.java b/gmail/snippets/src/main/java/CreateMessage.java new file mode 100644 index 00000000..c5e43d86 --- /dev/null +++ b/gmail/snippets/src/main/java/CreateMessage.java @@ -0,0 +1,45 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// [START gmail_create_message] +import com.google.api.services.gmail.model.Message; +import org.apache.commons.codec.binary.Base64; +import javax.mail.MessagingException; +import javax.mail.internet.MimeMessage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/* Class to demonstrate the use of Gmail Create Message API */ +public class CreateMessage { + + /** + * Create a message from an email. + * + * @param emailContent Email to be set to raw of message + * @return a message containing a base64url encoded email + * @throws IOException - if service account credentials file not found. + * @throws MessagingException - if a wrongly formatted address is encountered. + */ + public static Message createMessageWithEmail(MimeMessage emailContent) + throws MessagingException, IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + emailContent.writeTo(buffer); + byte[] bytes = buffer.toByteArray(); + String encodedEmail = Base64.encodeBase64URLSafeString(bytes); + Message message = new Message(); + message.setRaw(encodedEmail); + return message; + } +} +// [END gmail_create_message] \ No newline at end of file diff --git a/gmail/snippets/src/main/java/EnableAutoReply.java b/gmail/snippets/src/main/java/EnableAutoReply.java index 9453cb6c..15b08027 100644 --- a/gmail/snippets/src/main/java/EnableAutoReply.java +++ b/gmail/snippets/src/main/java/EnableAutoReply.java @@ -14,6 +14,7 @@ // [START gmail_enable_auto_reply] +import com.google.api.client.googleapis.json.GoogleJsonError; import com.google.api.client.googleapis.json.GoogleJsonResponseException; import com.google.api.client.http.HttpRequestInitializer; import com.google.api.client.http.javanet.NetHttpTransport; @@ -38,15 +39,11 @@ public class EnableAutoReply { * @throws IOException - if service account credentials file not found. */ public static VacationSettings autoReply() throws IOException{ - // TODO(developer) - Replace with your email address. - String userEmail = "ci-test01@workspacesamples.dev"; - /* Load pre-authorized user credentials from the environment. - TODO(developer) - See https://developers.google.com/identity for - guides on implementing OAuth2 for your application. */ + TODO(developer) - See https://developers.google.com/identity for + guides on implementing OAuth2 for your application. */ GoogleCredentials credentials = GoogleCredentials.getApplicationDefault() - .createScoped(Collections.singleton(GmailScopes.GMAIL_SETTINGS_BASIC)) - .createDelegated(userEmail); + .createScoped(Collections.singleton(GmailScopes.GMAIL_SETTINGS_BASIC)); HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials); // Create the gmail API client @@ -74,9 +71,14 @@ public static VacationSettings autoReply() throws IOException{ return response; } catch (GoogleJsonResponseException e) { // TODO(developer) - handle error appropriately - System.err.println("Unable to enable auto reply: " + e.getDetails()); - throw e; + GoogleJsonError error = e.getDetails(); + if (error.getCode() == 403) { + System.err.println("Unable to enable auto reply: " + e.getDetails()); + } else { + throw e; + } } + return null; } } // [END gmail_enable_auto_reply] \ No newline at end of file diff --git a/gmail/snippets/src/main/java/EnableForwarding.java b/gmail/snippets/src/main/java/EnableForwarding.java index a4357275..c18183bd 100644 --- a/gmail/snippets/src/main/java/EnableForwarding.java +++ b/gmail/snippets/src/main/java/EnableForwarding.java @@ -14,6 +14,7 @@ // [START gmail_enable_forwarding] +import com.google.api.client.googleapis.json.GoogleJsonError; import com.google.api.client.googleapis.json.GoogleJsonResponseException; import com.google.api.client.http.HttpRequestInitializer; import com.google.api.client.http.javanet.NetHttpTransport; @@ -34,18 +35,14 @@ public class EnableForwarding { * * @param forwardingEmail - Email address of the recipient whose email will be forwarded. * @return forwarding id and metadata, {@code null} otherwise. - * @throws IOException if service account credentials file not found. + * @throws IOException - if service account credentials file not found. */ public static AutoForwarding enableAutoForwarding(String forwardingEmail) throws IOException{ - // TODO(developer) - Replace with your email address. - String userEmail = "ci-test01@workspacesamples.dev"; - /* Load pre-authorized user credentials from the environment. TODO(developer) - See https://developers.google.com/identity for guides on implementing OAuth2 for your application. */ GoogleCredentials credentials = GoogleCredentials.getApplicationDefault() - .createScoped(GmailScopes.GMAIL_SETTINGS_SHARING) - .createDelegated(userEmail); + .createScoped(GmailScopes.GMAIL_SETTINGS_SHARING); HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials); // Create the gmail API client @@ -72,8 +69,12 @@ public static AutoForwarding enableAutoForwarding(String forwardingEmail) throws } } catch (GoogleJsonResponseException e) { // TODO(developer) - handle error appropriately - System.err.println("Unable to enable forwarding : " + e.getDetails()); - throw e; + GoogleJsonError error = e.getDetails(); + if (error.getCode() == 403) { + System.err.println("Unable to enable forwarding: " + e.getDetails()); + } else { + throw e; + } } return null; } diff --git a/gmail/snippets/src/main/java/SendMessage.java b/gmail/snippets/src/main/java/SendMessage.java index 7402b122..9e0ec4b7 100644 --- a/gmail/snippets/src/main/java/SendMessage.java +++ b/gmail/snippets/src/main/java/SendMessage.java @@ -14,6 +14,7 @@ // [START gmail_send_message] +import com.google.api.client.googleapis.json.GoogleJsonError; import com.google.api.client.googleapis.json.GoogleJsonResponseException; import com.google.api.client.http.HttpRequestInitializer; import com.google.api.client.http.javanet.NetHttpTransport; @@ -42,16 +43,16 @@ public class SendMessage { * * @param fromEmailAddress - Email address to appear in the from: header * @param toEmailAddress - Email address of the recipient - * @return the sent message + * @return the sent message, {@code null} otherwise. * @throws MessagingException - if a wrongly formatted address is encountered. * @throws IOException - if service account credentials file not found. */ public static Message sendEmail(String fromEmailAddress, String toEmailAddress) throws MessagingException, IOException { - // Load pre-authorized user credentials from the environment. - // TODO(developer) - See https://developers.google.com/identity for - // guides on implementing OAuth2 for your application. + /* Load pre-authorized user credentials from the environment. + TODO(developer) - See https://developers.google.com/identity for + guides on implementing OAuth2 for your application.*/ GoogleCredentials credentials = GoogleCredentials.getApplicationDefault() .createScoped(GmailScopes.GMAIL_SEND); HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials); @@ -93,9 +94,14 @@ public static Message sendEmail(String fromEmailAddress, return message; } catch (GoogleJsonResponseException e) { // TODO(developer) - handle error appropriately - System.err.println("Unable to send message: " + e.getDetails()); - throw e; + GoogleJsonError error = e.getDetails(); + if (error.getCode() == 403) { + System.err.println("Unable to send message: " + e.getDetails()); + } else { + throw e; + } } + return null; } } // [END gmail_send_message] \ No newline at end of file diff --git a/gmail/snippets/src/main/java/SendMessageWithAttachment.java b/gmail/snippets/src/main/java/SendMessageWithAttachment.java index 36c1fb98..29c28ec4 100644 --- a/gmail/snippets/src/main/java/SendMessageWithAttachment.java +++ b/gmail/snippets/src/main/java/SendMessageWithAttachment.java @@ -14,6 +14,7 @@ // [START gmail_send_message_with_attachment] +import com.google.api.client.googleapis.json.GoogleJsonError; import com.google.api.client.googleapis.json.GoogleJsonResponseException; import com.google.api.client.http.HttpRequestInitializer; import com.google.api.client.http.javanet.NetHttpTransport; @@ -28,7 +29,6 @@ import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; -import java.util.Collections; import java.util.Properties; import javax.activation.DataHandler; @@ -50,7 +50,7 @@ public class SendMessageWithAttachment{ * @param fromEmailAddress - Email address to appear in the from: header. * @param toEmailAddress - Email address of the recipient. * @param file - Path to the file to be attached. - * @return the sent message. + * @return the sent message, {@code null} otherwise. * @throws MessagingException - if a wrongly formatted address is encountered. * @throws IOException - if service account credentials file not found. */ @@ -58,9 +58,9 @@ public static Message sendEmailWithAttachment(String fromEmailAddress, String toEmailAddress, File file) throws MessagingException, IOException { - // Load pre-authorized user credentials from the environment. - // TODO(developer) - See https://developers.google.com/identity for - // guides on implementing OAuth2 for your application. + /* Load pre-authorized user credentials from the environment. + TODO(developer) - See https://developers.google.com/identity for + guides on implementing OAuth2 for your application.*/ GoogleCredentials credentials = GoogleCredentials.getApplicationDefault() .createScoped(GmailScopes.GMAIL_SEND); HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials); @@ -112,9 +112,14 @@ public static Message sendEmailWithAttachment(String fromEmailAddress, return message; } catch (GoogleJsonResponseException e) { // TODO(developer) - handle error appropriately - System.err.println("Unable to send message: " + e.getDetails()); - throw e; + GoogleJsonError error = e.getDetails(); + if (error.getCode() == 403) { + System.err.println("Unable to send message: " + e.getDetails()); + } else { + throw e; + } } + return null; } } // [END gmail_send_message_with_attachment] \ No newline at end of file diff --git a/gmail/snippets/src/main/java/UpdateSignature.java b/gmail/snippets/src/main/java/UpdateSignature.java index af27e159..ca21e77e 100644 --- a/gmail/snippets/src/main/java/UpdateSignature.java +++ b/gmail/snippets/src/main/java/UpdateSignature.java @@ -14,6 +14,7 @@ // [START gmail_update_signature] +import com.google.api.client.googleapis.json.GoogleJsonError; import com.google.api.client.googleapis.json.GoogleJsonResponseException; import com.google.api.client.http.HttpRequestInitializer; import com.google.api.client.http.javanet.NetHttpTransport; @@ -25,26 +26,21 @@ import com.google.auth.http.HttpCredentialsAdapter; import com.google.auth.oauth2.GoogleCredentials; import java.io.IOException; -import java.util.Collections; /* Class to demonstrate the use of Gmail Update Signature API */ public class UpdateSignature { /** * Update the gmail signature. * - * @return the updated signature id + * @return the updated signature id , {@code null} otherwise. * @throws IOException - if service account credentials file not found. */ public static String updateGmailSignature() throws IOException { - // TODO(developer) - Replace with your email address. - String userEmail = "gduser1@workspacesamples.dev"; - /* Load pre-authorized user credentials from the environment. TODO(developer) - See https://developers.google.com/identity for guides on implementing OAuth2 for your application. */ GoogleCredentials credentials = GoogleCredentials.getApplicationDefault() - .createScoped(GmailScopes.GMAIL_SETTINGS_BASIC) - .createDelegated(userEmail); + .createScoped(GmailScopes.GMAIL_SETTINGS_BASIC); HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials); // Create the gmail API client @@ -75,9 +71,14 @@ public static String updateGmailSignature() throws IOException { return result.getSignature(); } catch (GoogleJsonResponseException e) { // TODO(developer) - handle error appropriately - System.err.println("Unable to update signature: " + e.getDetails()); - throw e; + GoogleJsonError error = e.getDetails(); + if (error.getCode() == 403) { + System.err.println("Unable to update signature: " + e.getDetails()); + } else { + throw e; + } } + return null; } } // [END gmail_update_signature] \ No newline at end of file From 873181d6bb55e326cdda930d543a9de8e82127fb Mon Sep 17 00:00:00 2001 From: sanjuktaghosh7 Date: Wed, 1 Jun 2022 00:12:19 +0530 Subject: [PATCH 05/10] Gmail unit testcase --- .../src/test/java/TestCreateDraft.java | 31 ++++++++++++++++ .../java/TestCreateDraftWithAttachment.java | 33 +++++++++++++++++ .../src/test/java/TestCreateEmail.java | 37 +++++++++++++++++++ .../src/test/java/TestCreateFilter.java | 11 ++---- .../src/test/java/TestCreateMessage.java | 21 +++++++++++ .../src/test/java/TestCreateSmimeInfo.java | 1 + .../src/test/java/TestEnableAutoReply.java | 10 ++--- .../src/test/java/TestEnableForwarding.java | 6 +-- .../src/test/java/TestSendMessage.java | 30 +++++++++++++++ .../java/TestSendMessageWithAttachment.java | 34 +++++++++++++++++ .../src/test/java/TestUpdateSignature.java | 5 +-- 11 files changed, 196 insertions(+), 23 deletions(-) create mode 100644 gmail/snippets/src/test/java/TestCreateDraft.java create mode 100644 gmail/snippets/src/test/java/TestCreateDraftWithAttachment.java create mode 100644 gmail/snippets/src/test/java/TestCreateEmail.java create mode 100644 gmail/snippets/src/test/java/TestCreateMessage.java create mode 100644 gmail/snippets/src/test/java/TestSendMessage.java create mode 100644 gmail/snippets/src/test/java/TestSendMessageWithAttachment.java diff --git a/gmail/snippets/src/test/java/TestCreateDraft.java b/gmail/snippets/src/test/java/TestCreateDraft.java new file mode 100644 index 00000000..e3eb2fb2 --- /dev/null +++ b/gmail/snippets/src/test/java/TestCreateDraft.java @@ -0,0 +1,31 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +import com.google.api.services.gmail.model.Draft; +import org.junit.Test; +import javax.mail.MessagingException; +import java.io.IOException; +import static org.junit.Assert.assertNotNull; + +// Unit testcase for gmail create draft snippet +public class TestCreateDraft extends BaseTest{ + + @Test + public void testCreateDraft() throws MessagingException, IOException { + Draft draft = CreateDraft.createDraftMessage(RECIPIENT,TEST_USER); + assertNotNull(draft); + this.service.users().drafts().delete("me", draft.getId()).execute(); + } +} diff --git a/gmail/snippets/src/test/java/TestCreateDraftWithAttachment.java b/gmail/snippets/src/test/java/TestCreateDraftWithAttachment.java new file mode 100644 index 00000000..d0031682 --- /dev/null +++ b/gmail/snippets/src/test/java/TestCreateDraftWithAttachment.java @@ -0,0 +1,33 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +import com.google.api.services.gmail.model.Draft; +import org.junit.Test; +import javax.mail.MessagingException; +import java.io.IOException; +import static org.junit.Assert.assertNotNull; + +// Unit testcase for gmail create draft with attachment snippet +public class TestCreateDraftWithAttachment extends BaseTest{ + + @Test + public void testCreateDraftWithAttachment() throws MessagingException, IOException { + Draft draft = CreateDraftWithAttachment.createDraftMessageWithAttachment(RECIPIENT, + TEST_USER, + new java.io.File("files/photo.jpg")); + assertNotNull(draft); + this.service.users().drafts().delete(TEST_USER, draft.getId()).execute(); + } +} diff --git a/gmail/snippets/src/test/java/TestCreateEmail.java b/gmail/snippets/src/test/java/TestCreateEmail.java new file mode 100644 index 00000000..1248aa35 --- /dev/null +++ b/gmail/snippets/src/test/java/TestCreateEmail.java @@ -0,0 +1,37 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + + +import org.junit.Test; +import javax.mail.Message; +import javax.mail.MessagingException; +import javax.mail.internet.MimeMessage; +import java.io.IOException; +import static org.junit.Assert.assertEquals; + +// Unit testcase for gmail create email snippet +public class TestCreateEmail extends BaseTest{ + + @Test + public void createEmail() throws MessagingException, IOException { + MimeMessage mimeMessage = CreateEmail.createEmail(RECIPIENT, + TEST_USER, + "test", + "Hello!"); + assertEquals("test", mimeMessage.getSubject()); + assertEquals("Hello!", mimeMessage.getContent()); + assertEquals(RECIPIENT, mimeMessage.getRecipients(Message.RecipientType.TO)[0].toString()); + assertEquals(TEST_USER, mimeMessage.getFrom()[0].toString()); + } +} diff --git a/gmail/snippets/src/test/java/TestCreateFilter.java b/gmail/snippets/src/test/java/TestCreateFilter.java index 4a5eabf8..b345afa1 100644 --- a/gmail/snippets/src/test/java/TestCreateFilter.java +++ b/gmail/snippets/src/test/java/TestCreateFilter.java @@ -18,11 +18,10 @@ import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.mockito.MockedStatic; - import java.io.IOException; import static org.junit.Assert.assertNotNull; +// Unit testcase for gmail create filter snippet public class TestCreateFilter extends BaseTest { private Label testLabel = null; @@ -54,10 +53,8 @@ public void deleteLabel() throws IOException { @Test public void testCreateNewFilter() throws IOException { - try (MockedStatic credentials = useServiceAccount()) { - String id = CreateFilter.createNewFilter(testLabel.getId()); - assertNotNull(id); - this.service.users().settings().filters().delete("me", id).execute(); - } + String id = CreateFilter.createNewFilter(testLabel.getId()); + assertNotNull(id); + this.service.users().settings().filters().delete("me", id).execute(); } } diff --git a/gmail/snippets/src/test/java/TestCreateMessage.java b/gmail/snippets/src/test/java/TestCreateMessage.java new file mode 100644 index 00000000..0dbeb744 --- /dev/null +++ b/gmail/snippets/src/test/java/TestCreateMessage.java @@ -0,0 +1,21 @@ +import org.junit.Test; +import javax.mail.MessagingException; +import javax.mail.internet.MimeMessage; +import java.io.IOException; +import static org.junit.Assert.assertNotNull; + +// Unit testcase for gmail create message snippet +public class TestCreateMessage extends BaseTest{ + + @Test + public void testCreateMessageWithEmail() throws MessagingException, + IOException { + MimeMessage mimeMessage = CreateEmail.createEmail(RECIPIENT, + TEST_USER, + "test", + "Hello!"); + + com.google.api.services.gmail.model.Message message = CreateMessage.createMessageWithEmail(mimeMessage); + assertNotNull(message.getRaw()); // Weak assertion... + } +} diff --git a/gmail/snippets/src/test/java/TestCreateSmimeInfo.java b/gmail/snippets/src/test/java/TestCreateSmimeInfo.java index 7d6b1fdb..5357536e 100644 --- a/gmail/snippets/src/test/java/TestCreateSmimeInfo.java +++ b/gmail/snippets/src/test/java/TestCreateSmimeInfo.java @@ -21,6 +21,7 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; +// Unit testcase for gmail create smime info snippet public class TestCreateSmimeInfo { @Test diff --git a/gmail/snippets/src/test/java/TestEnableAutoReply.java b/gmail/snippets/src/test/java/TestEnableAutoReply.java index 6cd79e91..c961b734 100644 --- a/gmail/snippets/src/test/java/TestEnableAutoReply.java +++ b/gmail/snippets/src/test/java/TestEnableAutoReply.java @@ -12,21 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. - import com.google.api.services.gmail.model.VacationSettings; import org.junit.Test; -import org.mockito.MockedStatic; - import java.io.IOException; import static org.junit.Assert.assertNotNull; +// Unit testcase for gmail enable auto reply snippet public class TestEnableAutoReply extends BaseTest { @Test public void testAutoReply() throws IOException { - try (MockedStatic credentials = useServiceAccount()) { - VacationSettings settings = EnableAutoReply.autoReply(); - assertNotNull(settings); - } + VacationSettings settings = EnableAutoReply.autoReply(); + assertNotNull(settings); } } \ No newline at end of file diff --git a/gmail/snippets/src/test/java/TestEnableForwarding.java b/gmail/snippets/src/test/java/TestEnableForwarding.java index 92ec74a4..6250c13c 100644 --- a/gmail/snippets/src/test/java/TestEnableForwarding.java +++ b/gmail/snippets/src/test/java/TestEnableForwarding.java @@ -14,22 +14,18 @@ import com.google.api.services.gmail.model.AutoForwarding; -import org.junit.After; import org.junit.Before; import org.junit.Test; -import org.mockito.MockedStatic; - import java.io.IOException; import static org.junit.Assert.assertNotNull; +// Unit testcase for gmail enable forwarding snippet public class TestEnableForwarding extends BaseTest { @Test public void TestEnableAutoForwarding() throws IOException { - try (MockedStatic credentials = useServiceAccount()) { AutoForwarding forwarding = EnableForwarding.enableAutoForwarding(FORWARDING_ADDRESS); assertNotNull(forwarding); - } } @Before diff --git a/gmail/snippets/src/test/java/TestSendMessage.java b/gmail/snippets/src/test/java/TestSendMessage.java new file mode 100644 index 00000000..2bde312c --- /dev/null +++ b/gmail/snippets/src/test/java/TestSendMessage.java @@ -0,0 +1,30 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import com.google.api.services.gmail.model.Message; +import org.junit.Test; +import javax.mail.MessagingException; +import java.io.IOException; +import static org.junit.Assert.assertNotNull; + +// Unit testcase for gmail send email snippet +public class TestSendMessage extends BaseTest{ + + @Test + public void testSendEmail() throws MessagingException, IOException { + Message message = SendMessage.sendEmail(RECIPIENT, TEST_USER); + assertNotNull(message); + this.service.users().messages().delete("me", message.getId()).execute(); + } +} diff --git a/gmail/snippets/src/test/java/TestSendMessageWithAttachment.java b/gmail/snippets/src/test/java/TestSendMessageWithAttachment.java new file mode 100644 index 00000000..56161969 --- /dev/null +++ b/gmail/snippets/src/test/java/TestSendMessageWithAttachment.java @@ -0,0 +1,34 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import com.google.api.services.gmail.model.Message; +import org.junit.Test; +import javax.mail.MessagingException; +import java.io.File; +import java.io.IOException; +import static org.junit.Assert.assertNotNull; + +// Unit testcase for gmail send email with attachment snippet +public class TestSendMessageWithAttachment extends BaseTest{ + + @Test + public void testSendEmailWithAttachment() throws MessagingException, + IOException{ + Message message = SendMessageWithAttachment.sendEmailWithAttachment(RECIPIENT, + TEST_USER, + new File("files/photo.jpg")); + assertNotNull(message); + this.service.users().messages().delete("me", message.getId()).execute(); + } +} diff --git a/gmail/snippets/src/test/java/TestUpdateSignature.java b/gmail/snippets/src/test/java/TestUpdateSignature.java index 4a9c3e2a..43f0559e 100644 --- a/gmail/snippets/src/test/java/TestUpdateSignature.java +++ b/gmail/snippets/src/test/java/TestUpdateSignature.java @@ -14,18 +14,15 @@ import org.junit.Test; -import org.mockito.MockedStatic; - import java.io.IOException; import static org.junit.Assert.assertEquals; +// Unit testcase for gmail update signature snippet public class TestUpdateSignature extends BaseTest { @Test public void testUpdateGmailSignature() throws IOException { - try (MockedStatic credentials = useServiceAccount()) { String signature = UpdateSignature.updateGmailSignature(); assertEquals("Automated Signature", signature); - } } } \ No newline at end of file From f52e0fa0cc8a2c75fe835c006363061dcab47b21 Mon Sep 17 00:00:00 2001 From: sanjuktaghosh7 Date: Mon, 6 Jun 2022 19:02:49 +0530 Subject: [PATCH 06/10] Gmail unit testcase --- gmail/snippets/src/test/java/BaseTest.java | 92 ++---- .../src/test/java/TestCreateMessage.java | 14 + .../src/test/java/TestInsertCertFromCsv.java | 102 +++++++ .../src/test/java/TestInsertSmimeInfo.java | 117 ++++++++ .../src/test/java/TestUpdateSmimeCerts.java | 270 ++++++++++++++++++ .../src/test/java/TestUpdateSmimeFromCsv.java | 140 +++++++++ 6 files changed, 664 insertions(+), 71 deletions(-) create mode 100644 gmail/snippets/src/test/java/TestInsertCertFromCsv.java create mode 100644 gmail/snippets/src/test/java/TestInsertSmimeInfo.java create mode 100644 gmail/snippets/src/test/java/TestUpdateSmimeCerts.java create mode 100644 gmail/snippets/src/test/java/TestUpdateSmimeFromCsv.java diff --git a/gmail/snippets/src/test/java/BaseTest.java b/gmail/snippets/src/test/java/BaseTest.java index 11f8fbd3..4e287a9f 100644 --- a/gmail/snippets/src/test/java/BaseTest.java +++ b/gmail/snippets/src/test/java/BaseTest.java @@ -1,99 +1,49 @@ -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; import com.google.api.client.http.HttpRequestInitializer; -import com.google.api.client.http.HttpTransport; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.gson.GsonFactory; import com.google.api.services.gmail.Gmail; import com.google.api.services.gmail.GmailScopes; import com.google.auth.http.HttpCredentialsAdapter; import com.google.auth.oauth2.GoogleCredentials; -import org.junit.After; import org.junit.Before; -import org.mockito.MockedStatic; -import org.mockito.Mockito; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; -import java.io.InputStream; -import java.util.*; -import java.util.logging.Handler; -import java.util.logging.Level; -import java.util.logging.LogRecord; -import java.util.logging.Logger; public class BaseTest { - public static final String TEST_USER = "ci-test01@workspacesamples.dev"; - public static final String RECIPIENT = "gduser01@workspacesamples.dev"; - public static final String FORWARDING_ADDRESS = "gduser01@workspacesamples.dev"; - - static { - enableLogging(); - } + public static final String RECIPIENT = "gduser1@workspacesamples.dev"; + public static final String FORWARDING_ADDRESS = "gduser1@workspacesamples.dev"; protected Gmail service; - - public static void enableLogging() { - Logger logger = Logger.getLogger(HttpTransport.class.getName()); - logger.setLevel(Level.ALL); - logger.addHandler(new Handler() { - - @Override - public void close() throws SecurityException { - } - - @Override - public void flush() { - } - - @Override - public void publish(LogRecord record) { - // default ConsoleHandler will print >= INFO to System.err - if (record.getLevel().intValue() < Level.INFO.intValue()) { - System.out.println(record.getMessage()); - } - } - }); - } - + /** + * Create a default authorization Gmail client service. + * + * @return an authorized Gmail client service + * @throws IOException - if credentials file not found. + */ public Gmail buildService() throws IOException { - String serviceAccountPath = System.getenv("SERVICE_ACCOUNT_CREDENTIALS"); - try (InputStream stream = new FileInputStream(serviceAccountPath)) { - GoogleCredentials credentials = GoogleCredentials.fromStream(stream); - credentials = credentials.createScoped( - "email", - GmailScopes.MAIL_GOOGLE_COM, - GmailScopes.GMAIL_SETTINGS_BASIC, - GmailScopes.GMAIL_COMPOSE, - GmailScopes.GMAIL_SETTINGS_SHARING, - GmailScopes.GMAIL_LABELS).createDelegated(TEST_USER); - HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials); - return new Gmail.Builder( - new NetHttpTransport(), + /* Load pre-authorized user credentials from the environment. + TODO(developer) - See https://developers.google.com/identity for + guides on implementing OAuth2 for your application.*/ + GoogleCredentials credentials = GoogleCredentials.getApplicationDefault() + .createScoped(GmailScopes.GMAIL_SETTINGS_BASIC, + GmailScopes.GMAIL_COMPOSE, + GmailScopes.GMAIL_SETTINGS_SHARING, + GmailScopes.GMAIL_LABELS); + HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials); + + // Create the Gmail API client + Gmail service = new Gmail.Builder(new NetHttpTransport(), GsonFactory.getDefaultInstance(), requestInitializer) .setApplicationName("Gmail API Snippets") .build(); - } + return service; } @Before public void setupService() throws IOException { this.service = buildService(); } - - public MockedStatic useServiceAccount() throws IOException { - MockedStatic mockedGoogleCredentials; - String serviceAccountPath = System.getenv("SERVICE_ACCOUNT_CREDENTIALS"); - try (InputStream stream = new FileInputStream(serviceAccountPath)) { - GoogleCredentials credentials = GoogleCredentials.fromStream(stream); - mockedGoogleCredentials = Mockito.mockStatic(GoogleCredentials.class); - mockedGoogleCredentials.when(GoogleCredentials::getApplicationDefault).thenReturn(credentials); - return mockedGoogleCredentials; - } - } - } diff --git a/gmail/snippets/src/test/java/TestCreateMessage.java b/gmail/snippets/src/test/java/TestCreateMessage.java index 0dbeb744..775e7c1f 100644 --- a/gmail/snippets/src/test/java/TestCreateMessage.java +++ b/gmail/snippets/src/test/java/TestCreateMessage.java @@ -1,3 +1,17 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + import org.junit.Test; import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; diff --git a/gmail/snippets/src/test/java/TestInsertCertFromCsv.java b/gmail/snippets/src/test/java/TestInsertCertFromCsv.java new file mode 100644 index 00000000..2853cc2e --- /dev/null +++ b/gmail/snippets/src/test/java/TestInsertCertFromCsv.java @@ -0,0 +1,102 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import com.google.api.services.gmail.Gmail; +import com.google.api.services.gmail.model.SmimeInfo; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import java.io.IOException; + +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; + +// Unit testcase for gmail insert cert from csv snippet +public class TestInsertCertFromCsv extends BaseTest{ + + private static final long CURRENT_TIME_MS = 1234567890; + public static final String TEST_USER1 = "gduser1@workspacesamples.dev"; + public static final String TEST_USER2 = "gduser2@workspacesamples.dev"; + + @Mock + private Gmail mockService; + @Mock private Gmail.Users mockUsers; + @Mock private Gmail.Users.Settings mockSettings; + @Mock private Gmail.Users.Settings.SendAs mockSendAs; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo mockSmimeInfo; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.Delete mockDelete; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.Get mockGet; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.Insert mockInsert; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.List mockList; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.SetDefault mockSetDefault; + + @Rule + public MockitoRule mockitoRule = MockitoJUnit.rule(); + + @Before + public void setup() throws IOException { + when(mockService.users()).thenReturn(mockUsers); + when(mockUsers.settings()).thenReturn(mockSettings); + when(mockSettings.sendAs()).thenReturn(mockSendAs); + when(mockSendAs.smimeInfo()).thenReturn(mockSmimeInfo); + + when(mockSmimeInfo.delete(any(), any(), any())).thenReturn(mockDelete); + when(mockSmimeInfo.get(any(), any(), any())).thenReturn(mockGet); + when(mockSmimeInfo.insert(any(), any(), any())).thenReturn(mockInsert); + when(mockSmimeInfo.list(any(), any())).thenReturn(mockList); + when(mockSmimeInfo.setDefault(any(), any(), any())).thenReturn(mockSetDefault); + } + + @Test + public void testInsertSmimeFromCsv() throws IOException { + when(mockInsert.execute()).thenReturn(makeFakeInsertResult()); + InsertCertFromCsv.insertCertFromCsv("files/certs.csv"); + + verifySmimeApiCalled(2); + verify(mockSmimeInfo).insert(eq(TEST_USER1), eq(TEST_USER1), any()); + verify(mockSmimeInfo).insert(eq(TEST_USER2), eq(TEST_USER2), any()); + verify(mockInsert, times(2)).execute(); + } + + @Test + public void testInsertSmimeFromCsvFails() throws IOException { + when(mockInsert.execute()).thenReturn(makeFakeInsertResult()); + + InsertCertFromCsv.insertCertFromCsv("files/notfound.csv"); + } + + private void verifySmimeApiCalled(int numCalls) { + verify(mockService, times(numCalls)).users(); + verify(mockUsers, times(numCalls)).settings(); + verify(mockSettings, times(numCalls)).sendAs(); + verify(mockSendAs, times(numCalls)).smimeInfo(); + } + + private SmimeInfo makeFakeInsertResult(String id, boolean isDefault, long expiration) { + SmimeInfo insertResult = new SmimeInfo(); + insertResult.setId(id); + insertResult.setIsDefault(isDefault); + insertResult.setExpiration(expiration); + + return insertResult; + } + + private SmimeInfo makeFakeInsertResult() { + return makeFakeInsertResult("new_certificate_id", false, CURRENT_TIME_MS + 1); + } +} diff --git a/gmail/snippets/src/test/java/TestInsertSmimeInfo.java b/gmail/snippets/src/test/java/TestInsertSmimeInfo.java new file mode 100644 index 00000000..3c70b89a --- /dev/null +++ b/gmail/snippets/src/test/java/TestInsertSmimeInfo.java @@ -0,0 +1,117 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import com.google.api.services.gmail.Gmail; +import com.google.api.services.gmail.model.SmimeInfo; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; +import java.io.IOException; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; +import static org.mockito.Mockito.times; + +// Unit testcase for gmail insert smime info snippet +public class TestInsertSmimeInfo extends BaseTest{ + + private static final long CURRENT_TIME_MS = 1234567890; + + @Mock private Gmail mockService; + @Mock private Gmail.Users mockUsers; + @Mock private Gmail.Users.Settings mockSettings; + @Mock private Gmail.Users.Settings.SendAs mockSendAs; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo mockSmimeInfo; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.Delete mockDelete; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.Get mockGet; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.Insert mockInsert; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.List mockList; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.SetDefault mockSetDefault; + + @Rule + public MockitoRule mockitoRule = MockitoJUnit.rule(); + + @Before + public void setup() throws IOException { + when(mockService.users()).thenReturn(mockUsers); + when(mockUsers.settings()).thenReturn(mockSettings); + when(mockSettings.sendAs()).thenReturn(mockSendAs); + when(mockSendAs.smimeInfo()).thenReturn(mockSmimeInfo); + + when(mockSmimeInfo.delete(any(), any(), any())).thenReturn(mockDelete); + when(mockSmimeInfo.get(any(), any(), any())).thenReturn(mockGet); + when(mockSmimeInfo.insert(any(), any(), any())).thenReturn(mockInsert); + when(mockSmimeInfo.list(any(), any())).thenReturn(mockList); + when(mockSmimeInfo.setDefault(any(), any(), any())).thenReturn(mockSetDefault); + } + + @Test + public void testInsertSmimeInfo() throws IOException { + SmimeInfo insertResult = makeFakeInsertResult(); + when(mockInsert.execute()).thenReturn(insertResult); + + SmimeInfo smimeInfo = CreateSmimeInfo.createSmimeInfo("files/cert.p12", + null /* password */); + SmimeInfo result = InsertSmimeInfo.insertSmimeInfo(TEST_USER, + TEST_USER, + smimeInfo); + verifySmimeApiCalled(1); + verify(mockSmimeInfo).insert(eq(TEST_USER), eq(TEST_USER), eq(smimeInfo)); + verify(mockInsert).execute(); + + assertEquals(insertResult, result); + } + + @Test + public void testInsertSmimeInfoError() throws IOException { + when(mockInsert.execute()).thenThrow(IOException.class); + + SmimeInfo smimeInfo = CreateSmimeInfo.createSmimeInfo("files/cert.p12", + null /* password */); + SmimeInfo result = InsertSmimeInfo.insertSmimeInfo(TEST_USER, + TEST_USER, smimeInfo); + + verifySmimeApiCalled(1); + verify(mockSmimeInfo).insert(eq(TEST_USER), eq(TEST_USER), eq(smimeInfo)); + verify(mockInsert).execute(); + + assertNull(result); + } + + private void verifySmimeApiCalled(int numCalls) { + verify(mockService, times(numCalls)).users(); + verify(mockUsers, times(numCalls)).settings(); + verify(mockSettings, times(numCalls)).sendAs(); + verify(mockSendAs, times(numCalls)).smimeInfo(); + } + + private SmimeInfo makeFakeInsertResult(String id, boolean isDefault, long expiration) { + SmimeInfo insertResult = new SmimeInfo(); + insertResult.setId(id); + insertResult.setIsDefault(isDefault); + insertResult.setExpiration(expiration); + + return insertResult; + } + + private SmimeInfo makeFakeInsertResult() { + return makeFakeInsertResult("new_certificate_id", false, CURRENT_TIME_MS + 1); + } +} diff --git a/gmail/snippets/src/test/java/TestUpdateSmimeCerts.java b/gmail/snippets/src/test/java/TestUpdateSmimeCerts.java new file mode 100644 index 00000000..c66ebb57 --- /dev/null +++ b/gmail/snippets/src/test/java/TestUpdateSmimeCerts.java @@ -0,0 +1,270 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import com.google.api.services.gmail.Gmail; +import com.google.api.services.gmail.model.ListSmimeInfoResponse; +import com.google.api.services.gmail.model.SmimeInfo; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +import java.io.IOException; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; + +// Unit testcase for gmail update smime certs snippet +public class TestUpdateSmimeCerts extends BaseTest{ + + private static final long CURRENT_TIME_MS = 1234567890; + private static final LocalDateTime CURRENT_TIME = + LocalDateTime.ofInstant(Instant.ofEpochMilli(CURRENT_TIME_MS), ZoneId.systemDefault()); + @Mock + private Gmail mockService; + @Mock private Gmail.Users mockUsers; + @Mock private Gmail.Users.Settings mockSettings; + @Mock private Gmail.Users.Settings.SendAs mockSendAs; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo mockSmimeInfo; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.Delete mockDelete; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.Get mockGet; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.Insert mockInsert; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.List mockList; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.SetDefault mockSetDefault; + + @Rule + public MockitoRule mockitoRule = MockitoJUnit.rule(); + + @Before + public void setup() throws IOException { + when(mockService.users()).thenReturn(mockUsers); + when(mockUsers.settings()).thenReturn(mockSettings); + when(mockSettings.sendAs()).thenReturn(mockSendAs); + when(mockSendAs.smimeInfo()).thenReturn(mockSmimeInfo); + + when(mockSmimeInfo.delete(any(), any(), any())).thenReturn(mockDelete); + when(mockSmimeInfo.get(any(), any(), any())).thenReturn(mockGet); + when(mockSmimeInfo.insert(any(), any(), any())).thenReturn(mockInsert); + when(mockSmimeInfo.list(any(), any())).thenReturn(mockList); + when(mockSmimeInfo.setDefault(any(), any(), any())).thenReturn(mockSetDefault); + } + + @Test + public void testUpdateSmimeCertsNoCerts() throws IOException { + when(mockList.execute()).thenReturn(makeFakeListResult()); + + String defaultCertId = UpdateSmimeCerts.updateSmimeCerts(TEST_USER, + TEST_USER, + null /* certFilename */, + null /* certPassword */, + CURRENT_TIME); + + verifySmimeApiCalled(1); + verify(mockSmimeInfo).list(eq(TEST_USER), eq(TEST_USER)); + verify(mockList).execute(); + + assertNull(defaultCertId); + } + + @Test + public void testUpdateSmimeCertsNoCertsUploadNewCert() throws IOException { + when(mockList.execute()).thenReturn(makeFakeListResult()); + when(mockInsert.execute()).thenReturn(makeFakeInsertResult()); + + String defaultCertId = UpdateSmimeCerts.updateSmimeCerts(TEST_USER, + TEST_USER, + "files/cert.p12", + null /* certPassword */, + CURRENT_TIME); + + verifySmimeApiCalled(3); + verify(mockSmimeInfo).list(eq(TEST_USER), eq(TEST_USER)); + verify(mockSmimeInfo).insert(eq(TEST_USER), eq(TEST_USER), any()); + verify(mockSmimeInfo).setDefault(eq(TEST_USER), eq(TEST_USER), eq("new_certificate_id")); + verify(mockList).execute(); + verify(mockInsert).execute(); + verify(mockSetDefault).execute(); + + assertEquals(defaultCertId, "new_certificate_id"); + } + + @Test + public void testUpdateSmimeCertsValidDefaultCertNoUpload() throws IOException { + ListSmimeInfoResponse listResponse = + makeFakeListResult(Arrays.asList(true), Arrays.asList(CURRENT_TIME_MS + 1)); + when(mockList.execute()).thenReturn(listResponse); + + String defaultCertId = UpdateSmimeCerts.updateSmimeCerts(TEST_USER, + TEST_USER, + "files/cert.p12", + null /* certPassword */, + CURRENT_TIME); + + verifySmimeApiCalled(1); + verify(mockSmimeInfo).list(eq(TEST_USER), eq(TEST_USER)); + verify(mockList).execute(); + + assertEquals(defaultCertId, "existing_certificate_id0"); + } + + @Test + public void testUpdateSmimeCertsExpiredDefaultCertUploadNewCert() throws IOException { + LocalDateTime expireTime = + LocalDateTime.ofInstant(Instant.ofEpochMilli(CURRENT_TIME_MS + 2), ZoneId.systemDefault()); + ListSmimeInfoResponse listResponse = + makeFakeListResult(Arrays.asList(true), Arrays.asList(CURRENT_TIME_MS + 1)); + when(mockList.execute()).thenReturn(listResponse); + + when(mockInsert.execute()).thenReturn(makeFakeInsertResult()); + + String defaultCertId = UpdateSmimeCerts.updateSmimeCerts(TEST_USER, + TEST_USER, + "files/cert.p12", + null /* certPassword */, + expireTime); + + verifySmimeApiCalled(3); + verify(mockSmimeInfo).list(eq(TEST_USER), eq(TEST_USER)); + verify(mockSmimeInfo).insert(eq(TEST_USER), eq(TEST_USER), any()); + verify(mockSmimeInfo).setDefault(eq(TEST_USER), eq(TEST_USER), eq("new_certificate_id")); + verify(mockList).execute(); + verify(mockInsert).execute(); + verify(mockSetDefault).execute(); + + assertEquals(defaultCertId, "new_certificate_id"); + } + + @Test + public void testUpdateSmimeCertsExpiredDefaultCertOtherCertNewDefault() throws IOException { + ListSmimeInfoResponse listResponse = + makeFakeListResult( + Arrays.asList(true, false), Arrays.asList(CURRENT_TIME_MS - 1, CURRENT_TIME_MS + 1)); + when(mockList.execute()).thenReturn(listResponse); + + String defaultCertId = UpdateSmimeCerts.updateSmimeCerts(TEST_USER, + TEST_USER, + "files/cert.p12", + null /* certPassword */, + CURRENT_TIME); + + verifySmimeApiCalled(2); + verify(mockSmimeInfo).list(eq(TEST_USER), eq(TEST_USER)); + verify(mockSmimeInfo).setDefault(eq(TEST_USER), eq(TEST_USER), eq("existing_certificate_id1")); + verify(mockList).execute(); + verify(mockSetDefault).execute(); + + assertEquals(defaultCertId, "existing_certificate_id1"); + } + + @Test + public void testUpdateSmimeCertsNoCertsNoDefaultsChooseBestCertAsNewDefault() throws IOException { + ListSmimeInfoResponse listResponse = + makeFakeListResult( + Arrays.asList(false, false, false, false), + Arrays.asList( + CURRENT_TIME_MS + 2, + CURRENT_TIME_MS + 1, + CURRENT_TIME_MS + 4, + CURRENT_TIME_MS + 3)); + when(mockList.execute()).thenReturn(listResponse); + + String defaultCertId = UpdateSmimeCerts.updateSmimeCerts(TEST_USER, + TEST_USER, + "files/cert.p12", + null /* certPassword */, + CURRENT_TIME); + + verifySmimeApiCalled(2); + verify(mockSmimeInfo).list(eq(TEST_USER), eq(TEST_USER)); + verify(mockSmimeInfo).setDefault(eq(TEST_USER), eq(TEST_USER), eq("existing_certificate_id2")); + verify(mockList).execute(); + verify(mockSetDefault).execute(); + + assertEquals(defaultCertId, "existing_certificate_id2"); + } + + @Test + public void testUpdateSmimeCertsError() throws IOException { + when(mockList.execute()).thenThrow(IOException.class); + + String defaultCertId = + UpdateSmimeCerts.updateSmimeCerts(TEST_USER, + TEST_USER, + "files/cert.p12", + null /* certPassword */, + CURRENT_TIME); + + verifySmimeApiCalled(1); + verify(mockSmimeInfo).list(eq(TEST_USER), eq(TEST_USER)); + verify(mockList).execute(); + + assertNull(defaultCertId); + } + + private void verifySmimeApiCalled(int numCalls) { + verify(mockService, times(numCalls)).users(); + verify(mockUsers, times(numCalls)).settings(); + verify(mockSettings, times(numCalls)).sendAs(); + verify(mockSendAs, times(numCalls)).smimeInfo(); + } + + private ListSmimeInfoResponse makeFakeListResult(List isDefault, List expiration) { + ListSmimeInfoResponse listResponse = new ListSmimeInfoResponse(); + if (isDefault == null || expiration == null) { + return listResponse; + } + + assertEquals(isDefault.size(), expiration.size()); + + List smimeInfoList = new ArrayList(); + for (int i = 0; i < isDefault.size(); i++) { + SmimeInfo smimeInfo = new SmimeInfo(); + smimeInfo.setId(String.format("existing_certificate_id%d", i)); + smimeInfo.setIsDefault(isDefault.get(i)); + smimeInfo.setExpiration(expiration.get(i)); + smimeInfoList.add(smimeInfo); + } + listResponse.setSmimeInfo(smimeInfoList); + + return listResponse; + } + + private ListSmimeInfoResponse makeFakeListResult() { + return makeFakeListResult(null /* isDefault */, null /* expiration */); + } + + private SmimeInfo makeFakeInsertResult(String id, boolean isDefault, long expiration) { + SmimeInfo insertResult = new SmimeInfo(); + insertResult.setId(id); + insertResult.setIsDefault(isDefault); + insertResult.setExpiration(expiration); + + return insertResult; + } + + private SmimeInfo makeFakeInsertResult() { + return makeFakeInsertResult("new_certificate_id", false, CURRENT_TIME_MS + 1); + } +} diff --git a/gmail/snippets/src/test/java/TestUpdateSmimeFromCsv.java b/gmail/snippets/src/test/java/TestUpdateSmimeFromCsv.java new file mode 100644 index 00000000..35bcee1e --- /dev/null +++ b/gmail/snippets/src/test/java/TestUpdateSmimeFromCsv.java @@ -0,0 +1,140 @@ +// Copyright 2022 Google LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +import com.google.api.services.gmail.Gmail; +import com.google.api.services.gmail.model.ListSmimeInfoResponse; +import com.google.api.services.gmail.model.SmimeInfo; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnit; +import org.mockito.junit.MockitoRule; + +import java.io.IOException; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.eq; +import static org.mockito.Mockito.*; + +// Unit testcase for gmail update smime from csv snippet +public class TestUpdateSmimeFromCsv extends BaseTest{ + + private static final long CURRENT_TIME_MS = 1234567890; + private static final LocalDateTime CURRENT_TIME = + LocalDateTime.ofInstant(Instant.ofEpochMilli(CURRENT_TIME_MS), ZoneId.systemDefault()); + + @Mock + private Gmail mockService; + @Mock private Gmail.Users mockUsers; + @Mock private Gmail.Users.Settings mockSettings; + @Mock private Gmail.Users.Settings.SendAs mockSendAs; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo mockSmimeInfo; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.Delete mockDelete; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.Get mockGet; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.Insert mockInsert; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.List mockList; + @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.SetDefault mockSetDefault; + + @Rule + public MockitoRule mockitoRule = MockitoJUnit.rule(); + + @Before + public void setup() throws IOException { + when(mockService.users()).thenReturn(mockUsers); + when(mockUsers.settings()).thenReturn(mockSettings); + when(mockSettings.sendAs()).thenReturn(mockSendAs); + when(mockSendAs.smimeInfo()).thenReturn(mockSmimeInfo); + + when(mockSmimeInfo.delete(any(), any(), any())).thenReturn(mockDelete); + when(mockSmimeInfo.get(any(), any(), any())).thenReturn(mockGet); + when(mockSmimeInfo.insert(any(), any(), any())).thenReturn(mockInsert); + when(mockSmimeInfo.list(any(), any())).thenReturn(mockList); + when(mockSmimeInfo.setDefault(any(), any(), any())).thenReturn(mockSetDefault); + } + + @Test + public void testUpdateSmimeFromCsv() throws IOException { + when(mockList.execute()).thenReturn(makeFakeListResult()); + when(mockInsert.execute()).thenReturn(makeFakeInsertResult()); + + UpdateSmimeFromCsv.updateSmimeFromCsv("files/certs.csv", CURRENT_TIME); + + verifySmimeApiCalled(6); + verify(mockSmimeInfo).list(eq(TEST_USER), eq(TEST_USER)); + verify(mockSmimeInfo).insert(eq(TEST_USER), eq(TEST_USER), any()); + verify(mockSmimeInfo) + .setDefault(eq(TEST_USER), eq(TEST_USER), eq("new_certificate_id")); + verify(mockList, times(2)).execute(); + verify(mockInsert, times(2)).execute(); + verify(mockSetDefault, times(2)).execute(); + } + + @Test + public void testUpdateSmimeFromCsvFails() { + InsertCertFromCsv.insertCertFromCsv("files/notfound.csv"); + // tearDown() verifies that there were no interactions with the API. + } + + private void verifySmimeApiCalled(int numCalls) { + verify(mockService, times(numCalls)).users(); + verify(mockUsers, times(numCalls)).settings(); + verify(mockSettings, times(numCalls)).sendAs(); + verify(mockSendAs, times(numCalls)).smimeInfo(); + } + + private ListSmimeInfoResponse makeFakeListResult(List isDefault, List expiration) { + ListSmimeInfoResponse listResponse = new ListSmimeInfoResponse(); + if (isDefault == null || expiration == null) { + return listResponse; + } + + assertEquals(isDefault.size(), expiration.size()); + + List smimeInfoList = new ArrayList<>(); + for (int i = 0; i < isDefault.size(); i++) { + SmimeInfo smimeInfo = new SmimeInfo(); + smimeInfo.setId(String.format("existing_certificate_id%d", i)); + smimeInfo.setIsDefault(isDefault.get(i)); + smimeInfo.setExpiration(expiration.get(i)); + smimeInfoList.add(smimeInfo); + } + listResponse.setSmimeInfo(smimeInfoList); + + return listResponse; + } + + private ListSmimeInfoResponse makeFakeListResult() { + return makeFakeListResult(null /* isDefault */, null /* expiration */); + } + + private SmimeInfo makeFakeInsertResult(String id, boolean isDefault, long expiration) { + SmimeInfo insertResult = new SmimeInfo(); + insertResult.setId(id); + insertResult.setIsDefault(isDefault); + insertResult.setExpiration(expiration); + + return insertResult; + } + + private SmimeInfo makeFakeInsertResult() { + return makeFakeInsertResult("new_certificate_id", false, CURRENT_TIME_MS + 1); + } +} From e45a54d7101cee8c1d6e19594bac562f6c3d5442 Mon Sep 17 00:00:00 2001 From: sanjuktaghosh7 Date: Mon, 6 Jun 2022 19:03:25 +0530 Subject: [PATCH 07/10] Gmail snippet --- .../src/main/java/InsertCertFromCsv.java | 5 +- .../src/main/java/InsertSmimeInfo.java | 20 +- gmail/snippets/src/main/java/SendEmail.java | 183 -------- .../src/main/java/SettingsSnippets.java | 106 ----- .../snippets/src/main/java/SmimeSnippets.java | 259 ------------ .../src/main/java/UpdateSmimeCerts.java | 12 +- .../src/main/java/UpdateSmimeFromCsv.java | 4 +- .../snippets/src/test/java/SendEmailTest.java | 70 ---- .../src/test/java/SettingsSnippetsTest.java | 82 ---- .../src/test/java/SmimeSnippetsTest.java | 392 ------------------ 10 files changed, 19 insertions(+), 1114 deletions(-) delete mode 100644 gmail/snippets/src/main/java/SendEmail.java delete mode 100644 gmail/snippets/src/main/java/SettingsSnippets.java delete mode 100644 gmail/snippets/src/main/java/SmimeSnippets.java delete mode 100644 gmail/snippets/src/test/java/SendEmailTest.java delete mode 100644 gmail/snippets/src/test/java/SettingsSnippetsTest.java delete mode 100644 gmail/snippets/src/test/java/SmimeSnippetsTest.java diff --git a/gmail/snippets/src/main/java/InsertCertFromCsv.java b/gmail/snippets/src/main/java/InsertCertFromCsv.java index d31607e0..2259098c 100644 --- a/gmail/snippets/src/main/java/InsertCertFromCsv.java +++ b/gmail/snippets/src/main/java/InsertCertFromCsv.java @@ -43,10 +43,9 @@ public static void insertCertFromCsv(String csvFilename) { SmimeInfo smimeInfo = CreateSmimeInfo.createSmimeInfo(certFilename, certPassword); if (smimeInfo != null) { - InsertSmimeInfo.insertSmimeInfo(certFilename, - certPassword, + InsertSmimeInfo.insertSmimeInfo(userId, userId, - userId); + smimeInfo); } else { System.err.printf("Unable to read certificate file for userId: %s\n", userId); } diff --git a/gmail/snippets/src/main/java/InsertSmimeInfo.java b/gmail/snippets/src/main/java/InsertSmimeInfo.java index 1f598ef2..e686126d 100644 --- a/gmail/snippets/src/main/java/InsertSmimeInfo.java +++ b/gmail/snippets/src/main/java/InsertSmimeInfo.java @@ -14,6 +14,8 @@ // [START gmail_insert_smime_info] +import com.google.api.client.googleapis.json.GoogleJsonError; +import com.google.api.client.googleapis.json.GoogleJsonResponseException; import com.google.api.client.http.HttpRequestInitializer; import com.google.api.client.http.javanet.NetHttpTransport; import com.google.api.client.json.gson.GsonFactory; @@ -31,23 +33,21 @@ public class InsertSmimeInfo { /** * Upload an S/MIME certificate for the user. * - * @param filename Name of the file containing the S/MIME certificate. - * @param password Password for the certificate file, or null if the file - * is not password-protected. * @param userId User's email address. * @param sendAsEmail The "send as" email address, or null if it should be the same as userId. - * @return An SmimeInfo object with details about the uploaded certificate. + * @param smimeInfo The SmimeInfo object containing the user's S/MIME certificate. + * @return An SmimeInfo object with details about the uploaded certificate, {@code null} otherwise. + * @throws IOException - if service account credentials file not found. */ - public static SmimeInfo insertSmimeInfo(String filename, - String password, - String userId, - String sendAsEmail) + public static SmimeInfo insertSmimeInfo(String userId, + String sendAsEmail, + SmimeInfo smimeInfo) throws IOException { /* Load pre-authorized user credentials from the environment. TODO(developer) - See https://developers.google.com/identity for guides on implementing OAuth2 for your application. */ GoogleCredentials credentials = GoogleCredentials.getApplicationDefault() - .createScoped(Collections.singletonList(GmailScopes.GMAIL_SETTINGS_SHARING)); + .createScoped(GmailScopes.GMAIL_SETTINGS_SHARING); HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter( credentials); @@ -63,7 +63,6 @@ public static SmimeInfo insertSmimeInfo(String filename, } try { - SmimeInfo smimeInfo = CreateSmimeInfo.createSmimeInfo(filename, password); SmimeInfo results = service.users().settings().sendAs().smimeInfo() .insert(userId, sendAsEmail, smimeInfo) .execute(); @@ -72,7 +71,6 @@ public static SmimeInfo insertSmimeInfo(String filename, } catch (IOException e) { System.err.printf("An error occured: %s", e); } - return null; } } diff --git a/gmail/snippets/src/main/java/SendEmail.java b/gmail/snippets/src/main/java/SendEmail.java deleted file mode 100644 index 002f2f53..00000000 --- a/gmail/snippets/src/main/java/SendEmail.java +++ /dev/null @@ -1,183 +0,0 @@ -import com.google.api.services.gmail.Gmail; -import com.google.api.services.gmail.model.Draft; -import com.google.api.services.gmail.model.Message; -import org.apache.commons.codec.binary.Base64; - -import java.io.ByteArrayOutputStream; -import java.io.File; -import java.io.IOException; -import java.util.Properties; - -import javax.activation.DataHandler; -import javax.activation.DataSource; -import javax.activation.FileDataSource; -import javax.mail.MessagingException; -import javax.mail.Multipart; -import javax.mail.Session; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; - -// ... - -public class SendEmail { - - // ... - - // [START create_draft] - /** - * Create draft email. - * - * @param service an authorized Gmail API instance - * @param userId user's email address. The special value "me" - * can be used to indicate the authenticated user - * @param emailContent the MimeMessage used as email within the draft - * @return the created draft - * @throws MessagingException - * @throws IOException - */ - public static Draft createDraft(Gmail service, - String userId, - MimeMessage emailContent) - throws MessagingException, IOException { - Message message = createMessageWithEmail(emailContent); - Draft draft = new Draft(); - draft.setMessage(message); - draft = service.users().drafts().create(userId, draft).execute(); - - System.out.println("Draft id: " + draft.getId()); - System.out.println(draft.toPrettyString()); - return draft; - } - // [END create_draft] - - - // [START send_email] - /** - * Send an email from the user's mailbox to its recipient. - * - * @param service Authorized Gmail API instance. - * @param userId User's email address. The special value "me" - * can be used to indicate the authenticated user. - * @param emailContent Email to be sent. - * @return The sent message - * @throws MessagingException - * @throws IOException - */ - public static Message sendMessage(Gmail service, - String userId, - MimeMessage emailContent) - throws MessagingException, IOException { - Message message = createMessageWithEmail(emailContent); - message = service.users().messages().send(userId, message).execute(); - - System.out.println("Message id: " + message.getId()); - System.out.println(message.toPrettyString()); - return message; - } - // [END send_email] - - - // [START create_message] - /** - * Create a message from an email. - * - * @param emailContent Email to be set to raw of message - * @return a message containing a base64url encoded email - * @throws IOException - * @throws MessagingException - */ - public static Message createMessageWithEmail(MimeMessage emailContent) - throws MessagingException, IOException { - ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - emailContent.writeTo(buffer); - byte[] bytes = buffer.toByteArray(); - String encodedEmail = Base64.encodeBase64URLSafeString(bytes); - Message message = new Message(); - message.setRaw(encodedEmail); - return message; - } - // [END create_message] - - // [START create_email] - /** - * Create a MimeMessage using the parameters provided. - * - * @param to email address of the receiver - * @param from email address of the sender, the mailbox account - * @param subject subject of the email - * @param bodyText body text of the email - * @return the MimeMessage to be used to send email - * @throws MessagingException - */ - public static MimeMessage createEmail(String to, - String from, - String subject, - String bodyText) - throws MessagingException { - Properties props = new Properties(); - Session session = Session.getDefaultInstance(props, null); - - MimeMessage email = new MimeMessage(session); - - email.setFrom(new InternetAddress(from)); - email.addRecipient(javax.mail.Message.RecipientType.TO, - new InternetAddress(to)); - email.setSubject(subject); - email.setText(bodyText); - return email; - } - // [END create_email] - - - // [START create_email_attachment] - /** - * Create a MimeMessage using the parameters provided. - * - * @param to Email address of the receiver. - * @param from Email address of the sender, the mailbox account. - * @param subject Subject of the email. - * @param bodyText Body text of the email. - * @param file Path to the file to be attached. - * @return MimeMessage to be used to send email. - * @throws MessagingException - */ - public static MimeMessage createEmailWithAttachment(String to, - String from, - String subject, - String bodyText, - File file) - throws MessagingException, IOException { - Properties props = new Properties(); - Session session = Session.getDefaultInstance(props, null); - - MimeMessage email = new MimeMessage(session); - - email.setFrom(new InternetAddress(from)); - email.addRecipient(javax.mail.Message.RecipientType.TO, - new InternetAddress(to)); - email.setSubject(subject); - - MimeBodyPart mimeBodyPart = new MimeBodyPart(); - mimeBodyPart.setContent(bodyText, "text/plain"); - - Multipart multipart = new MimeMultipart(); - multipart.addBodyPart(mimeBodyPart); - - mimeBodyPart = new MimeBodyPart(); - DataSource source = new FileDataSource(file); - - mimeBodyPart.setDataHandler(new DataHandler(source)); - mimeBodyPart.setFileName(file.getName()); - - multipart.addBodyPart(mimeBodyPart); - email.setContent(multipart); - - return email; - } - // [END create_email_attachment] - - // ... - -} diff --git a/gmail/snippets/src/main/java/SettingsSnippets.java b/gmail/snippets/src/main/java/SettingsSnippets.java deleted file mode 100644 index fab67fa6..00000000 --- a/gmail/snippets/src/main/java/SettingsSnippets.java +++ /dev/null @@ -1,106 +0,0 @@ -import com.google.api.client.googleapis.batch.BatchRequest; -import com.google.api.client.googleapis.json.GoogleJsonError; -import com.google.api.client.http.FileContent; -import com.google.api.client.http.HttpHeaders; -import com.google.api.client.util.DateTime; -import com.google.api.services.gmail.Gmail; -import com.google.api.services.gmail.model.*; - -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.OutputStream; -import java.time.LocalDateTime; -import java.time.ZoneOffset; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - - -public class SettingsSnippets { - - private Gmail service; - - public SettingsSnippets(Gmail service) { - this.service = service; - } - - public String updateSignature() throws IOException { - Gmail gmailService = this.service; - // [START updateSignature] - SendAs primaryAlias = null; - ListSendAsResponse aliases = gmailService.users().settings().sendAs().list("me").execute(); - for (SendAs alias: aliases.getSendAs()) { - if (alias.getIsPrimary()) { - primaryAlias = alias; - break; - } - } - SendAs aliasSettings = new SendAs().setSignature("I heart cats."); - SendAs result = gmailService.users().settings().sendAs().patch( - "me", - primaryAlias.getSendAsEmail(), - aliasSettings) - .execute(); - System.out.println("Updated signature for " + result.getDisplayName()); - // [END updateSignature] - return result.getSignature(); - } - - public String createFilter(String realLabelId) throws IOException { - Gmail gmailService = this.service; - // [START createFilter] - String labelId = "Label_14"; // ID of the user label to add - // [START_EXCLUDE silent] - labelId = realLabelId; - // [END_EXCLUDE] - Filter filter = new Filter() - .setCriteria(new FilterCriteria() - .setFrom("cat-enthusiasts@example.com")) - .setAction(new FilterAction() - .setAddLabelIds(Arrays.asList(labelId)) - .setRemoveLabelIds(Arrays.asList("INBOX"))); - Filter result = gmailService.users().settings().filters().create("me", filter).execute(); - System.out.println("Created filter " + result.getId()); - // [END createFilter] - return result.getId(); - } - - public AutoForwarding enableForwarding(String realForwardingAddress) throws IOException { - Gmail gmailService = this.service; - // [START enableForwarding] - ForwardingAddress address = new ForwardingAddress() - .setForwardingEmail("user2@example.com"); - // [START_EXCLUDE silent] - address.setForwardingEmail(realForwardingAddress); - // [END_EXCLUDE] - ForwardingAddress createAddressResult = gmailService.users().settings().forwardingAddresses() - .create("me", address).execute(); - if (createAddressResult.getVerificationStatus().equals("accepted")) { - AutoForwarding autoForwarding = new AutoForwarding() - .setEnabled(true) - .setEmailAddress(address.getForwardingEmail()) - .setDisposition("trash"); - autoForwarding = gmailService.users().settings().updateAutoForwarding("me", autoForwarding).execute(); - // [START_EXCLUDE silent] - return autoForwarding; - } - // [END enableForwarding] - return null; - } - - public VacationSettings enableAutoReply() throws IOException { - Gmail gmailService = this.service; - // [START enableAutoReply] - VacationSettings vacationSettings = new VacationSettings() - .setEnableAutoReply(true) - .setResponseBodyHtml("I'm on vacation and will reply when I'm back in the office. Thanks!") - .setRestrictToDomain(true) - .setStartTime(LocalDateTime.now().toEpochSecond(ZoneOffset.UTC) * 1000) - .setEndTime(LocalDateTime.now().plusDays(7).toEpochSecond(ZoneOffset.UTC) * 1000); - VacationSettings response = gmailService.users().settings().updateVacation("me", vacationSettings).execute(); - // [END enableAutoReply] - return response; - } - -} diff --git a/gmail/snippets/src/main/java/SmimeSnippets.java b/gmail/snippets/src/main/java/SmimeSnippets.java deleted file mode 100644 index 85f3d0de..00000000 --- a/gmail/snippets/src/main/java/SmimeSnippets.java +++ /dev/null @@ -1,259 +0,0 @@ -import com.google.api.services.gmail.Gmail; -import com.google.api.services.gmail.model.*; -import com.google.api.services.gmail.model.SmimeInfo; - -import java.io.*; -import java.nio.file.Files; -import java.nio.file.Paths; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.util.Base64; -import org.apache.commons.csv.CSVFormat; -import org.apache.commons.csv.CSVParser; -import org.apache.commons.csv.CSVRecord; - -class SmimeSnippets { - - SmimeSnippets() {} - - // [START create_smime_info] - /** - * Create an SmimeInfo resource for a certificate from file. - * - * @param filename Name of the file containing the S/MIME certificate. - * @param password Password for the certificate file, or null if the file is not - * password-protected. - * @return An SmimeInfo object with the specified certificate. - */ - public static SmimeInfo createSmimeInfo(String filename, String password) { - SmimeInfo smimeInfo = null; - InputStream in = null; - - try { - byte[] fileContent = Files.readAllBytes(Paths.get(filename)); - smimeInfo = new SmimeInfo(); - smimeInfo.setPkcs12(Base64.getUrlEncoder().encodeToString(fileContent)); - if (password != null && password.length() > 0) { - smimeInfo.setEncryptedKeyPassword(password); - } - } catch (Exception e) { - System.out.printf("An error occured while reading the certificate file: %s\n", e); - } - return smimeInfo; - } - // [END create_smime_info] - - // [START insert_smime_info] - /** - * Upload an S/MIME certificate for the user. - * - * @param service Authorized GMail API service instance. - * @param userId User's email address. - * @param sendAsEmail The "send as" email address, or null if it should be the same as userId. - * @param smimeInfo The SmimeInfo object containing the user's S/MIME certificate. - * @return An SmimeInfo object with details about the uploaded certificate. - */ - public static SmimeInfo insertSmimeInfo( - Gmail service, String userId, String sendAsEmail, SmimeInfo smimeInfo) { - if (sendAsEmail == null) { - sendAsEmail = userId; - } - - try { - SmimeInfo results = - service - .users() - .settings() - .sendAs() - .smimeInfo() - .insert(userId, sendAsEmail, smimeInfo) - .execute(); - System.out.printf("Inserted certificate, id: %s\n", results.getId()); - return results; - } catch (IOException e) { - System.err.printf("An error occured: %s", e); - } - - return null; - } - // [END insert_smime_info] - - // [START insert_cert_from_csv] - /** - * A builder that returns a GMail API service instance that is authorized to act on behalf of the - * specified user. - */ - @FunctionalInterface - public interface GmailServiceBuilder { - Gmail buildGmailServiceFromUserId(String userId) throws IOException; - } - - /** - * Upload S/MIME certificates based on the contents of a CSV file. - * - *

Each row of the CSV file should contain a user ID, path to the certificate, and the - * certificate password. - * - * @param serviceBuilder A function that returns an authorized GMail API service instance for a - * given user. - * @param csvFilename Name of the CSV file. - */ - public static void insertCertFromCsv(GmailServiceBuilder serviceBuilder, String csvFilename) { - try { - File csvFile = new File(csvFilename); - CSVParser parser = CSVParser.parse(csvFile, java.nio.charset.StandardCharsets.UTF_8, CSVFormat.DEFAULT); - for (CSVRecord record : parser) { - String userId = record.get(0); - String certFilename = record.get(1); - String certPassword = record.get(2); - SmimeInfo smimeInfo = createSmimeInfo(certFilename, certPassword); - if (smimeInfo == null) { - System.err.printf("Unable to read certificate file for userId: %s\n", userId); - continue; - } - insertSmimeInfo(serviceBuilder.buildGmailServiceFromUserId(userId), userId, userId, smimeInfo); - } - } catch (Exception e) { - System.err.printf("An error occured while reading the CSV file: %s", e); - } - } - // [END insert_cert_from_csv] - - // [START update_smime_certs] - /** - * Update S/MIME certificates for the user. - * - *

First performs a lookup of all certificates for a user. If there are no certificates, or - * they all expire before the specified date/time, uploads the certificate in the specified file. - * If the default certificate is expired or there was no default set, chooses the certificate with - * the expiration furthest into the future and sets it as default. - * - * @param service Authorized GMail API service instance. - * @param userId User's email address. - * @param sendAsEmail The "send as" email address, or None if it should be the same as user_id. - * @param certFilename Name of the file containing the S/MIME certificate. - * @param certPassword Password for the certificate file, or None if the file is not - * password-protected. - * @param expireTime DateTime object against which the certificate expiration is compared. If - * None, uses the current time. @ returns: The ID of the default certificate. - * @return The ID of the default certifcate. - */ - public static String updateSmimeCerts( - Gmail service, - String userId, - String sendAsEmail, - String certFilename, - String certPassword, - LocalDateTime expireTime) { - if (sendAsEmail == null) { - sendAsEmail = userId; - } - - ListSmimeInfoResponse listResults = null; - try { - listResults = - service.users().settings().sendAs().smimeInfo().list(userId, sendAsEmail).execute(); - } catch (IOException e) { - System.err.printf("An error occurred during list: %s\n", e); - return null; - } - - String defaultCertId = null; - String bestCertId = null; - LocalDateTime bestCertExpire = LocalDateTime.MIN; - - if (expireTime == null) { - expireTime = LocalDateTime.now(); - } - if (listResults != null && listResults.getSmimeInfo() != null) { - for (SmimeInfo smimeInfo : listResults.getSmimeInfo()) { - String certId = smimeInfo.getId(); - boolean isDefaultCert = smimeInfo.getIsDefault(); - if (isDefaultCert) { - defaultCertId = certId; - } - LocalDateTime exp = LocalDateTime.ofInstant( - Instant.ofEpochMilli(smimeInfo.getExpiration()), ZoneId.systemDefault()); - if (exp.isAfter(expireTime)) { - if (exp.isAfter(bestCertExpire)) { - bestCertId = certId; - bestCertExpire = exp; - } - } else { - if (isDefaultCert) { - defaultCertId = null; - } - } - } - } - if (defaultCertId == null) { - String defaultId = bestCertId; - if (defaultId == null && certFilename != null) { - SmimeInfo smimeInfo = createSmimeInfo(certFilename, certPassword); - SmimeInfo insertResults = insertSmimeInfo(service, userId, sendAsEmail, smimeInfo); - if (insertResults != null) { - defaultId = insertResults.getId(); - } - } - - if (defaultId != null) { - try { - service - .users() - .settings() - .sendAs() - .smimeInfo() - .setDefault(userId, sendAsEmail, defaultId) - .execute(); - return defaultId; - } catch (IOException e) { - System.err.printf("An error occured during setDefault: %s", e); - } - } - } else { - return defaultCertId; - } - - return null; - } - - /** - * Update S/MIME certificates based on the contents of a CSV file. - * - *

Each row of the CSV file should contain a user ID, path to the certificate, and the - * certificate password. - * - * @param serviceBuilder A function that returns an authorized GMail API service instance for a - * given user. - * @param csvFilename Name of the CSV file. - * @param expireTime DateTime object against which the certificate expiration is compared. If - * None, uses the current time. - */ - public static void updateSmimeFromCsv( - GmailServiceBuilder serviceBuilder, String csvFilename, LocalDateTime expireTime) { - try { - File csvFile = new File(csvFilename); - CSVParser parser = - CSVParser.parse( - csvFile, - java.nio.charset.StandardCharsets.UTF_8, - CSVFormat.DEFAULT.withHeader().withSkipHeaderRecord()); - for (CSVRecord record : parser) { - String userId = record.get(0); - String certFilename = record.get(1); - String certPassword = record.get(2); - updateSmimeCerts( - serviceBuilder.buildGmailServiceFromUserId(userId), - userId, - userId, - certFilename, - certPassword, - expireTime); - } - } catch (Exception e) { - System.err.printf("An error occured while reading the CSV file: %s", e); - } - } - // [END update_smime_certs] -} diff --git a/gmail/snippets/src/main/java/UpdateSmimeCerts.java b/gmail/snippets/src/main/java/UpdateSmimeCerts.java index 2e014a68..598eb528 100644 --- a/gmail/snippets/src/main/java/UpdateSmimeCerts.java +++ b/gmail/snippets/src/main/java/UpdateSmimeCerts.java @@ -47,7 +47,8 @@ public class UpdateSmimeCerts { * password-protected. * @param expireTime DateTime object against which the certificate expiration is compared. If * None, uses the current time. @ returns: The ID of the default certificate. - * @return The ID of the default certifcate. + * @return The ID of the default certificate, {@code null} otherwise. + * @throws IOException - if service account credentials file not found. */ public static String updateSmimeCerts(String userId, String sendAsEmail, @@ -114,10 +115,11 @@ public static String updateSmimeCerts(String userId, if (defaultCertId == null) { String defaultId = bestCertId; if (defaultId == null && certFilename != null) { - SmimeInfo insertResults = InsertSmimeInfo.insertSmimeInfo(certFilename, - certPassword, - userId, - sendAsEmail); + SmimeInfo smimeInfo = CreateSmimeInfo.createSmimeInfo(certFilename, + certPassword); + SmimeInfo insertResults = InsertSmimeInfo.insertSmimeInfo(userId, + sendAsEmail, + smimeInfo); if (insertResults != null) { defaultId = insertResults.getId(); } diff --git a/gmail/snippets/src/main/java/UpdateSmimeFromCsv.java b/gmail/snippets/src/main/java/UpdateSmimeFromCsv.java index 3f7d3964..efe3052b 100644 --- a/gmail/snippets/src/main/java/UpdateSmimeFromCsv.java +++ b/gmail/snippets/src/main/java/UpdateSmimeFromCsv.java @@ -36,9 +36,7 @@ public class UpdateSmimeFromCsv { public static void updateSmimeFromCsv(String csvFilename, LocalDateTime expireTime) { try { File csvFile = new File(csvFilename); - CSVParser parser = - CSVParser.parse( - csvFile, + CSVParser parser = CSVParser.parse( csvFile, java.nio.charset.StandardCharsets.UTF_8, CSVFormat.DEFAULT.withHeader().withSkipHeaderRecord()); for (CSVRecord record : parser) { diff --git a/gmail/snippets/src/test/java/SendEmailTest.java b/gmail/snippets/src/test/java/SendEmailTest.java deleted file mode 100644 index 6d17129b..00000000 --- a/gmail/snippets/src/test/java/SendEmailTest.java +++ /dev/null @@ -1,70 +0,0 @@ -import com.google.api.services.gmail.model.*; -import org.junit.Test; - -import javax.mail.Message; -import javax.mail.MessagingException; -import javax.mail.internet.MimeMessage; -import java.io.IOException; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -public class SendEmailTest extends BaseTest { - - @Test - public void createEmail() throws MessagingException, IOException { - MimeMessage mimeMessage = SendEmail.createEmail(RECIPIENT, - TEST_USER, - "test", - "Hello!"); - assertEquals("test", mimeMessage.getSubject()); - assertEquals("Hello!", mimeMessage.getContent()); - assertEquals(RECIPIENT, mimeMessage.getRecipients(Message.RecipientType.TO)[0].toString()); - assertEquals(TEST_USER, mimeMessage.getFrom()[0].toString()); - } - - @Test - public void createEmailWithAttachment() throws MessagingException, IOException { - MimeMessage mimeMessage = SendEmail.createEmailWithAttachment(RECIPIENT, - TEST_USER, - "test", - "Hello!", - new java.io.File("files/photo.jpg")); - assertEquals("test", mimeMessage.getSubject()); - assertEquals(RECIPIENT, mimeMessage.getRecipients(Message.RecipientType.TO)[0].toString()); - assertEquals(TEST_USER, mimeMessage.getFrom()[0].toString()); - } - - @Test - public void createMessageWithEmail() throws MessagingException, IOException { - MimeMessage mimeMessage = SendEmail.createEmail(RECIPIENT, - TEST_USER, - "test", - "Hello!"); - - com.google.api.services.gmail.model.Message message = SendEmail.createMessageWithEmail(mimeMessage); - assertNotNull(message.getRaw()); // Weak assertion... - } - - @Test - public void createDraft() throws MessagingException, IOException { - MimeMessage mimeMessage = SendEmail.createEmail(RECIPIENT, - TEST_USER, - "test", - "Hello!"); - Draft draft = SendEmail.createDraft(this.service, "me", mimeMessage); - assertNotNull(draft); - this.service.users().drafts().delete("me", draft.getId()); - } - - @Test - public void sendEmail() throws MessagingException, IOException { - MimeMessage mimeMessage = SendEmail.createEmailWithAttachment(RECIPIENT, - TEST_USER, - "test", - "Hello!", - new java.io.File("files/photo.jpg")); - com.google.api.services.gmail.model.Message message = SendEmail.sendMessage(this.service, "me", mimeMessage); - assertNotNull(message); - } -} diff --git a/gmail/snippets/src/test/java/SettingsSnippetsTest.java b/gmail/snippets/src/test/java/SettingsSnippetsTest.java deleted file mode 100644 index b1017b59..00000000 --- a/gmail/snippets/src/test/java/SettingsSnippetsTest.java +++ /dev/null @@ -1,82 +0,0 @@ - -import com.google.api.services.gmail.model.AutoForwarding; -import com.google.api.services.gmail.model.Label; -import com.google.api.services.gmail.model.ListLabelsResponse; -import com.google.api.services.gmail.model.VacationSettings; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import java.io.IOException; -import java.security.GeneralSecurityException; - -import static org.junit.Assert.*; - -public class SettingsSnippetsTest extends BaseTest { - - private SettingsSnippets snippets; - private Label testLabel = null; - - @Before - public void createSnippets() { - this.snippets = new SettingsSnippets(this.service); - } - - @Before - public void createLabel() throws IOException { - ListLabelsResponse response = this.service.users().labels().list("me").execute(); - for (Label l : response.getLabels()) { - if (l.getName().equals("testLabel")) { - testLabel = l; - } - } - if (testLabel == null) { - Label label = new Label() - .setName("testLabel") - .setLabelListVisibility("labelShow") - .setMessageListVisibility("show"); - testLabel = this.service.users().labels().create("me", label).execute(); - } - } - - @After - public void deleteLabel() throws IOException { - if (testLabel != null) { - this.service.users().labels().delete("me", testLabel.getId()).execute(); - testLabel = null; - } - } - - @Test - public void updateSignature() throws IOException, GeneralSecurityException { - String signature = this.snippets.updateSignature(); - assertEquals("I heart cats.", signature); - } - - @Test - public void createFilter() throws IOException, GeneralSecurityException { - String id = this.snippets.createFilter(testLabel.getId()); - assertNotNull(id); - this.service.users().settings().filters().delete("me", id).execute(); - } - - @Test - public void enableAutoForwarding() throws IOException, GeneralSecurityException { - try { - AutoForwarding forwarding = new AutoForwarding().setEnabled(false); - this.service.users().settings().updateAutoForwarding("me", forwarding).execute(); - this.service.users().settings().forwardingAddresses().delete("me", FORWARDING_ADDRESS).execute(); - } catch (Exception e) { - // Ignore - resources might not exist - e.printStackTrace(); - } - AutoForwarding forwarding = this.snippets.enableForwarding(FORWARDING_ADDRESS); - assertNotNull(forwarding); - } - - @Test - public void enableAutoReply() throws IOException, GeneralSecurityException { - VacationSettings settings = this.snippets.enableAutoReply(); - assertNotNull(settings); - } -} diff --git a/gmail/snippets/src/test/java/SmimeSnippetsTest.java b/gmail/snippets/src/test/java/SmimeSnippetsTest.java deleted file mode 100644 index 78e6c48c..00000000 --- a/gmail/snippets/src/test/java/SmimeSnippetsTest.java +++ /dev/null @@ -1,392 +0,0 @@ -import static org.hamcrest.Matchers.greaterThan; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.Mockito.*; - -import com.google.api.services.gmail.Gmail; -import com.google.api.services.gmail.model.*; - -import java.io.File; -import java.io.IOException; -import java.time.Instant; -import java.time.LocalDateTime; -import java.time.ZoneId; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnit; -import org.mockito.junit.MockitoRule; - -public class SmimeSnippetsTest { - - private static final long CURRENT_TIME_MS = 1234567890; - private static final LocalDateTime CURRENT_TIME = - LocalDateTime.ofInstant(Instant.ofEpochMilli(CURRENT_TIME_MS), ZoneId.systemDefault()); - private static final String TEST_USER = "user1@example.com"; - - @Mock private Gmail mockService; - @Mock private Gmail.Users mockUsers; - @Mock private Gmail.Users.Settings mockSettings; - @Mock private Gmail.Users.Settings.SendAs mockSendAs; - @Mock private Gmail.Users.Settings.SendAs.SmimeInfo mockSmimeInfo; - @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.Delete mockDelete; - @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.Get mockGet; - @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.Insert mockInsert; - @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.List mockList; - @Mock private Gmail.Users.Settings.SendAs.SmimeInfo.SetDefault mockSetDefault; - - @Rule public MockitoRule mockitoRule = MockitoJUnit.rule(); - - @Before - public void setup() throws IOException { - when(mockService.users()).thenReturn(mockUsers); - when(mockUsers.settings()).thenReturn(mockSettings); - when(mockSettings.sendAs()).thenReturn(mockSendAs); - when(mockSendAs.smimeInfo()).thenReturn(mockSmimeInfo); - - when(mockSmimeInfo.delete(any(), any(), any())).thenReturn(mockDelete); - when(mockSmimeInfo.get(any(), any(), any())).thenReturn(mockGet); - when(mockSmimeInfo.insert(any(), any(), any())).thenReturn(mockInsert); - when(mockSmimeInfo.list(any(), any())).thenReturn(mockList); - when(mockSmimeInfo.setDefault(any(), any(), any())).thenReturn(mockSetDefault); - } - - - @Test - public void testCreateSmimeInfo() { - SmimeInfo smimeInfo = SmimeSnippets.createSmimeInfo("files/cert.p12", null /* password */); - - assertNotNull(smimeInfo); - assertNull(smimeInfo.getEncryptedKeyPassword()); - assertNull(smimeInfo.getExpiration()); - assertNull(smimeInfo.getId()); - assertNull(smimeInfo.getIsDefault()); - assertNull(smimeInfo.getIssuerCn()); - assertNull(smimeInfo.getPem()); - assertThat(smimeInfo.getPkcs12().length(), greaterThan(0)); - } - - @Test - public void testCreateSmimeInfoWithPassword() { - SmimeInfo smimeInfo = SmimeSnippets.createSmimeInfo("files/cert.p12", "certpass"); - - assertNotNull(smimeInfo); - assertEquals(smimeInfo.getEncryptedKeyPassword(), "certpass"); - assertNull(smimeInfo.getExpiration()); - assertNull(smimeInfo.getId()); - assertNull(smimeInfo.getIsDefault()); - assertNull(smimeInfo.getIssuerCn()); - assertNull(smimeInfo.getPem()); - assertThat(smimeInfo.getPkcs12().length(), greaterThan(0)); - } - - @Test - public void testCreateSmimeInfoFileNotFound() { - SmimeInfo smimeInfo = SmimeSnippets.createSmimeInfo("files/notfound.p12", null /* password */); - - assertNull(smimeInfo); - } - - @Test - public void testInsertSmimeInfo() throws IOException { - SmimeInfo insertResult = makeFakeInsertResult(); - when(mockInsert.execute()).thenReturn(insertResult); - - SmimeInfo smimeInfo = SmimeSnippets.createSmimeInfo("files/cert.p12", null /* password */); - SmimeInfo result = SmimeSnippets.insertSmimeInfo(mockService, TEST_USER, TEST_USER, smimeInfo); - - //verifySmimeApiCalled(1); - verify(mockSmimeInfo).insert(eq(TEST_USER), eq(TEST_USER), eq(smimeInfo)); - verify(mockInsert).execute(); - - assertEquals(insertResult, result); - } - - @Test - public void testInsertSmimeInfoError() throws IOException { - when(mockInsert.execute()).thenThrow(IOException.class); - - SmimeInfo smimeInfo = SmimeSnippets.createSmimeInfo("files/cert.p12", null /* password */); - SmimeInfo result = SmimeSnippets.insertSmimeInfo(mockService, TEST_USER, TEST_USER, smimeInfo); - - verifySmimeApiCalled(1); - verify(mockSmimeInfo).insert(eq(TEST_USER), eq(TEST_USER), eq(smimeInfo)); - verify(mockInsert).execute(); - - assertNull(result); - } - - @Test - public void testInsertSmimeFromCsv() throws IOException { - when(mockInsert.execute()).thenReturn(makeFakeInsertResult()); - SmimeSnippets.insertCertFromCsv((u) -> mockService, "files/certs.csv"); - - //verifySmimeApiCalled(2); - //verify(mockSmimeInfo).insert(eq("user1@example.com"), eq("user1@example.com"), any()); - //verify(mockSmimeInfo).insert(eq("user2@example.com"), eq("user2@example.com"), any()); - verify(mockInsert, times(2)).execute(); - } - - @Test - public void testInsertSmimeFromCsvFails() throws IOException { - when(mockInsert.execute()).thenReturn(makeFakeInsertResult()); - - SmimeSnippets.insertCertFromCsv((u) -> mockService, "files/notfound.csv"); - } - - @Test - public void testUpdateSmimeCertsNoCerts() throws IOException { - when(mockList.execute()).thenReturn(makeFakeListResult()); - - String defaultCertId = - SmimeSnippets.updateSmimeCerts( - mockService, - TEST_USER, - TEST_USER, - null /* certFilename */, - null /* certPassword */, - CURRENT_TIME); - - verifySmimeApiCalled(1); - verify(mockSmimeInfo).list(eq(TEST_USER), eq(TEST_USER)); - verify(mockList).execute(); - - assertNull(defaultCertId); - } - - @Test - public void testUpdateSmimeCertsNoCertsUploadNewCert() throws IOException { - when(mockList.execute()).thenReturn(makeFakeListResult()); - when(mockInsert.execute()).thenReturn(makeFakeInsertResult()); - - String defaultCertId = - SmimeSnippets.updateSmimeCerts( - mockService, - TEST_USER, - TEST_USER, - "files/cert.p12", - null /* certPassword */, - CURRENT_TIME); - - verifySmimeApiCalled(3); - verify(mockSmimeInfo).list(eq(TEST_USER), eq(TEST_USER)); - verify(mockSmimeInfo).insert(eq(TEST_USER), eq(TEST_USER), any()); - verify(mockSmimeInfo).setDefault(eq(TEST_USER), eq(TEST_USER), eq("new_certificate_id")); - verify(mockList).execute(); - verify(mockInsert).execute(); - verify(mockSetDefault).execute(); - - assertEquals(defaultCertId, "new_certificate_id"); - } - - @Test - public void testUpdateSmimeCertsValidDefaultCertNoUpload() throws IOException { - ListSmimeInfoResponse listResponse = - makeFakeListResult(Arrays.asList(true), Arrays.asList(CURRENT_TIME_MS + 1)); - when(mockList.execute()).thenReturn(listResponse); - - String defaultCertId = - SmimeSnippets.updateSmimeCerts( - mockService, - TEST_USER, - TEST_USER, - "files/cert.p12", - null /* certPassword */, - CURRENT_TIME); - - verifySmimeApiCalled(1); - verify(mockSmimeInfo).list(eq(TEST_USER), eq(TEST_USER)); - verify(mockList).execute(); - - assertEquals(defaultCertId, "existing_certificate_id0"); - } - - @Test - public void testUpdateSmimeCertsExpiredDefaultCertUploadNewCert() throws IOException { - LocalDateTime expireTime = - LocalDateTime.ofInstant(Instant.ofEpochMilli(CURRENT_TIME_MS + 2), ZoneId.systemDefault()); - ListSmimeInfoResponse listResponse = - makeFakeListResult(Arrays.asList(true), Arrays.asList(CURRENT_TIME_MS + 1)); - when(mockList.execute()).thenReturn(listResponse); - - when(mockInsert.execute()).thenReturn(makeFakeInsertResult()); - - String defaultCertId = - SmimeSnippets.updateSmimeCerts( - mockService, - TEST_USER, - TEST_USER, - "files/cert.p12", - null /* certPassword */, - expireTime); - - verifySmimeApiCalled(3); - verify(mockSmimeInfo).list(eq(TEST_USER), eq(TEST_USER)); - verify(mockSmimeInfo).insert(eq(TEST_USER), eq(TEST_USER), any()); - verify(mockSmimeInfo).setDefault(eq(TEST_USER), eq(TEST_USER), eq("new_certificate_id")); - verify(mockList).execute(); - verify(mockInsert).execute(); - verify(mockSetDefault).execute(); - - assertEquals(defaultCertId, "new_certificate_id"); - } - - @Test - public void testUpdateSmimeCertsExpiredDefaultCertOtherCertNewDefault() throws IOException { - ListSmimeInfoResponse listResponse = - makeFakeListResult( - Arrays.asList(true, false), Arrays.asList(CURRENT_TIME_MS - 1, CURRENT_TIME_MS + 1)); - when(mockList.execute()).thenReturn(listResponse); - - String defaultCertId = - SmimeSnippets.updateSmimeCerts( - mockService, - TEST_USER, - TEST_USER, - "files/cert.p12", - null /* certPassword */, - CURRENT_TIME); - - verifySmimeApiCalled(2); - verify(mockSmimeInfo).list(eq(TEST_USER), eq(TEST_USER)); - verify(mockSmimeInfo).setDefault(eq(TEST_USER), eq(TEST_USER), eq("existing_certificate_id1")); - verify(mockList).execute(); - verify(mockSetDefault).execute(); - - assertEquals(defaultCertId, "existing_certificate_id1"); - } - - @Test - public void testUpdateSmimeCertsNoCertsNoDefaultsChooseBestCertAsNewDefault() throws IOException { - ListSmimeInfoResponse listResponse = - makeFakeListResult( - Arrays.asList(false, false, false, false), - Arrays.asList( - CURRENT_TIME_MS + 2, - CURRENT_TIME_MS + 1, - CURRENT_TIME_MS + 4, - CURRENT_TIME_MS + 3)); - when(mockList.execute()).thenReturn(listResponse); - - String defaultCertId = - SmimeSnippets.updateSmimeCerts( - mockService, - TEST_USER, - TEST_USER, - "files/cert.p12", - null /* certPassword */, - CURRENT_TIME); - - verifySmimeApiCalled(2); - verify(mockSmimeInfo).list(eq(TEST_USER), eq(TEST_USER)); - verify(mockSmimeInfo).setDefault(eq(TEST_USER), eq(TEST_USER), eq("existing_certificate_id2")); - verify(mockList).execute(); - verify(mockSetDefault).execute(); - - assertEquals(defaultCertId, "existing_certificate_id2"); - } - - @Test - public void testUpdateSmimeCertsError() throws IOException { - when(mockList.execute()).thenThrow(IOException.class); - - String defaultCertId = - SmimeSnippets.updateSmimeCerts( - mockService, - TEST_USER, - TEST_USER, - "files/cert.p12", - null /* certPassword */, - CURRENT_TIME); - - verifySmimeApiCalled(1); - verify(mockSmimeInfo).list(eq(TEST_USER), eq(TEST_USER)); - verify(mockList).execute(); - - assertNull(defaultCertId); - } - - @Test - public void testUpdateSmimeFromCsv() throws IOException { - when(mockList.execute()).thenReturn(makeFakeListResult()); - when(mockInsert.execute()).thenReturn(makeFakeInsertResult()); - - SmimeSnippets.updateSmimeFromCsv((u) -> mockService, "files/certs.csv", CURRENT_TIME); - - verifySmimeApiCalled(9); - verify(mockSmimeInfo).list(eq("user1@example.com"), eq("user1@example.com")); - verify(mockSmimeInfo).list(eq("user2@example.com"), eq("user2@example.com")); - verify(mockSmimeInfo).list(eq("user3@example.com"), eq("user3@example.com")); - verify(mockSmimeInfo).insert(eq("user1@example.com"), eq("user1@example.com"), any()); - verify(mockSmimeInfo).insert(eq("user2@example.com"), eq("user2@example.com"), any()); - verify(mockSmimeInfo).insert(eq("user3@example.com"), eq("user3@example.com"), any()); - verify(mockSmimeInfo) - .setDefault(eq("user1@example.com"), eq("user1@example.com"), eq("new_certificate_id")); - verify(mockSmimeInfo) - .setDefault(eq("user2@example.com"), eq("user2@example.com"), eq("new_certificate_id")); - verify(mockSmimeInfo) - .setDefault(eq("user3@example.com"), eq("user3@example.com"), eq("new_certificate_id")); - verify(mockList, times(3)).execute(); - verify(mockInsert, times(3)).execute(); - verify(mockSetDefault, times(3)).execute(); - } - - @Test - public void testUpdateSmimeFromCsvFails() { - SmimeSnippets.insertCertFromCsv((u) -> mockService, "files/notfound.csv"); - // tearDown() verifies that there were no interactions with the API. - } - - private void verifySmimeApiCalled(int numCalls) { - verify(mockService, times(numCalls)).users(); - verify(mockUsers, times(numCalls)).settings(); - verify(mockSettings, times(numCalls)).sendAs(); - verify(mockSendAs, times(numCalls)).smimeInfo(); - } - - private ListSmimeInfoResponse makeFakeListResult(List isDefault, List expiration) { - ListSmimeInfoResponse listResponse = new ListSmimeInfoResponse(); - if (isDefault == null || expiration == null) { - return listResponse; - } - - assertEquals(isDefault.size(), expiration.size()); - - List smimeInfoList = new ArrayList(); - for (int i = 0; i < isDefault.size(); i++) { - SmimeInfo smimeInfo = new SmimeInfo(); - smimeInfo.setId(String.format("existing_certificate_id%d", i)); - smimeInfo.setIsDefault(isDefault.get(i)); - smimeInfo.setExpiration(expiration.get(i)); - smimeInfoList.add(smimeInfo); - } - listResponse.setSmimeInfo(smimeInfoList); - - return listResponse; - } - - private ListSmimeInfoResponse makeFakeListResult() { - return makeFakeListResult(null /* isDefault */, null /* expiration */); - } - - private SmimeInfo makeFakeInsertResult(String id, boolean isDefault, long expiration) { - SmimeInfo insertResult = new SmimeInfo(); - insertResult.setId(id); - insertResult.setIsDefault(isDefault); - insertResult.setExpiration(expiration); - - return insertResult; - } - - private SmimeInfo makeFakeInsertResult() { - return makeFakeInsertResult("new_certificate_id", false, CURRENT_TIME_MS + 1); - } -} From 52b1ef08c999c202a7da5608759a898dad67ddf1 Mon Sep 17 00:00:00 2001 From: sanjuktaghosh7 Date: Mon, 6 Jun 2022 19:09:59 +0530 Subject: [PATCH 08/10] Gmail snippet --- gmail/snippets/build.gradle | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/gmail/snippets/build.gradle b/gmail/snippets/build.gradle index bf1befca..85351fa9 100644 --- a/gmail/snippets/build.gradle +++ b/gmail/snippets/build.gradle @@ -5,14 +5,10 @@ repositories { } dependencies { - implementation 'com.google.api-client:google-api-client:1.33.0' - implementation 'com.google.auth:google-auth-library-oauth2-http:1.3.0' - implementation 'com.google.apis:google-api-services-gmail:v1-rev20211108-1.32.1' - implementation 'com.google.code.gson:gson:2.4' - implementation 'javax.mail:mail:1.4' - implementation 'org.apache.commons:commons-csv:1.1' + implementation 'com.google.auth:google-auth-library-oauth2-http:1.6.0' + implementation 'com.google.apis:google-api-services-gmail:v1-rev20220404-1.32.1' + implementation 'javax.mail:mail:1.4.7' + implementation 'org.apache.commons:commons-csv:1.9.0' testImplementation 'junit:junit:4.13.2' - testImplementation 'org.hamcrest:hamcrest-all:1.3' - //testImplementation 'org.mockito:mockito-core:4.2.0' - testImplementation 'org.mockito:mockito-inline:4.3.1' + testImplementation 'org.mockito:mockito-inline:4.5.1' } From 5cac873d0ef4564da42b4fc530169f86dfe35832 Mon Sep 17 00:00:00 2001 From: sanjuktaghosh7 Date: Mon, 6 Jun 2022 21:08:46 +0530 Subject: [PATCH 09/10] Gmail snippet --- gmail/snippets/src/main/java/SendEmail.java | 183 +++++++++++++ .../src/main/java/SettingsSnippets.java | 106 +++++++ .../snippets/src/main/java/SmimeSnippets.java | 259 ++++++++++++++++++ 3 files changed, 548 insertions(+) create mode 100644 gmail/snippets/src/main/java/SendEmail.java create mode 100644 gmail/snippets/src/main/java/SettingsSnippets.java create mode 100644 gmail/snippets/src/main/java/SmimeSnippets.java diff --git a/gmail/snippets/src/main/java/SendEmail.java b/gmail/snippets/src/main/java/SendEmail.java new file mode 100644 index 00000000..002f2f53 --- /dev/null +++ b/gmail/snippets/src/main/java/SendEmail.java @@ -0,0 +1,183 @@ +import com.google.api.services.gmail.Gmail; +import com.google.api.services.gmail.model.Draft; +import com.google.api.services.gmail.model.Message; +import org.apache.commons.codec.binary.Base64; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.Properties; + +import javax.activation.DataHandler; +import javax.activation.DataSource; +import javax.activation.FileDataSource; +import javax.mail.MessagingException; +import javax.mail.Multipart; +import javax.mail.Session; +import javax.mail.internet.InternetAddress; +import javax.mail.internet.MimeBodyPart; +import javax.mail.internet.MimeMessage; +import javax.mail.internet.MimeMultipart; + +// ... + +public class SendEmail { + + // ... + + // [START create_draft] + /** + * Create draft email. + * + * @param service an authorized Gmail API instance + * @param userId user's email address. The special value "me" + * can be used to indicate the authenticated user + * @param emailContent the MimeMessage used as email within the draft + * @return the created draft + * @throws MessagingException + * @throws IOException + */ + public static Draft createDraft(Gmail service, + String userId, + MimeMessage emailContent) + throws MessagingException, IOException { + Message message = createMessageWithEmail(emailContent); + Draft draft = new Draft(); + draft.setMessage(message); + draft = service.users().drafts().create(userId, draft).execute(); + + System.out.println("Draft id: " + draft.getId()); + System.out.println(draft.toPrettyString()); + return draft; + } + // [END create_draft] + + + // [START send_email] + /** + * Send an email from the user's mailbox to its recipient. + * + * @param service Authorized Gmail API instance. + * @param userId User's email address. The special value "me" + * can be used to indicate the authenticated user. + * @param emailContent Email to be sent. + * @return The sent message + * @throws MessagingException + * @throws IOException + */ + public static Message sendMessage(Gmail service, + String userId, + MimeMessage emailContent) + throws MessagingException, IOException { + Message message = createMessageWithEmail(emailContent); + message = service.users().messages().send(userId, message).execute(); + + System.out.println("Message id: " + message.getId()); + System.out.println(message.toPrettyString()); + return message; + } + // [END send_email] + + + // [START create_message] + /** + * Create a message from an email. + * + * @param emailContent Email to be set to raw of message + * @return a message containing a base64url encoded email + * @throws IOException + * @throws MessagingException + */ + public static Message createMessageWithEmail(MimeMessage emailContent) + throws MessagingException, IOException { + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + emailContent.writeTo(buffer); + byte[] bytes = buffer.toByteArray(); + String encodedEmail = Base64.encodeBase64URLSafeString(bytes); + Message message = new Message(); + message.setRaw(encodedEmail); + return message; + } + // [END create_message] + + // [START create_email] + /** + * Create a MimeMessage using the parameters provided. + * + * @param to email address of the receiver + * @param from email address of the sender, the mailbox account + * @param subject subject of the email + * @param bodyText body text of the email + * @return the MimeMessage to be used to send email + * @throws MessagingException + */ + public static MimeMessage createEmail(String to, + String from, + String subject, + String bodyText) + throws MessagingException { + Properties props = new Properties(); + Session session = Session.getDefaultInstance(props, null); + + MimeMessage email = new MimeMessage(session); + + email.setFrom(new InternetAddress(from)); + email.addRecipient(javax.mail.Message.RecipientType.TO, + new InternetAddress(to)); + email.setSubject(subject); + email.setText(bodyText); + return email; + } + // [END create_email] + + + // [START create_email_attachment] + /** + * Create a MimeMessage using the parameters provided. + * + * @param to Email address of the receiver. + * @param from Email address of the sender, the mailbox account. + * @param subject Subject of the email. + * @param bodyText Body text of the email. + * @param file Path to the file to be attached. + * @return MimeMessage to be used to send email. + * @throws MessagingException + */ + public static MimeMessage createEmailWithAttachment(String to, + String from, + String subject, + String bodyText, + File file) + throws MessagingException, IOException { + Properties props = new Properties(); + Session session = Session.getDefaultInstance(props, null); + + MimeMessage email = new MimeMessage(session); + + email.setFrom(new InternetAddress(from)); + email.addRecipient(javax.mail.Message.RecipientType.TO, + new InternetAddress(to)); + email.setSubject(subject); + + MimeBodyPart mimeBodyPart = new MimeBodyPart(); + mimeBodyPart.setContent(bodyText, "text/plain"); + + Multipart multipart = new MimeMultipart(); + multipart.addBodyPart(mimeBodyPart); + + mimeBodyPart = new MimeBodyPart(); + DataSource source = new FileDataSource(file); + + mimeBodyPart.setDataHandler(new DataHandler(source)); + mimeBodyPart.setFileName(file.getName()); + + multipart.addBodyPart(mimeBodyPart); + email.setContent(multipart); + + return email; + } + // [END create_email_attachment] + + // ... + +} diff --git a/gmail/snippets/src/main/java/SettingsSnippets.java b/gmail/snippets/src/main/java/SettingsSnippets.java new file mode 100644 index 00000000..fab67fa6 --- /dev/null +++ b/gmail/snippets/src/main/java/SettingsSnippets.java @@ -0,0 +1,106 @@ +import com.google.api.client.googleapis.batch.BatchRequest; +import com.google.api.client.googleapis.json.GoogleJsonError; +import com.google.api.client.http.FileContent; +import com.google.api.client.http.HttpHeaders; +import com.google.api.client.util.DateTime; +import com.google.api.services.gmail.Gmail; +import com.google.api.services.gmail.model.*; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.time.LocalDateTime; +import java.time.ZoneOffset; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + + +public class SettingsSnippets { + + private Gmail service; + + public SettingsSnippets(Gmail service) { + this.service = service; + } + + public String updateSignature() throws IOException { + Gmail gmailService = this.service; + // [START updateSignature] + SendAs primaryAlias = null; + ListSendAsResponse aliases = gmailService.users().settings().sendAs().list("me").execute(); + for (SendAs alias: aliases.getSendAs()) { + if (alias.getIsPrimary()) { + primaryAlias = alias; + break; + } + } + SendAs aliasSettings = new SendAs().setSignature("I heart cats."); + SendAs result = gmailService.users().settings().sendAs().patch( + "me", + primaryAlias.getSendAsEmail(), + aliasSettings) + .execute(); + System.out.println("Updated signature for " + result.getDisplayName()); + // [END updateSignature] + return result.getSignature(); + } + + public String createFilter(String realLabelId) throws IOException { + Gmail gmailService = this.service; + // [START createFilter] + String labelId = "Label_14"; // ID of the user label to add + // [START_EXCLUDE silent] + labelId = realLabelId; + // [END_EXCLUDE] + Filter filter = new Filter() + .setCriteria(new FilterCriteria() + .setFrom("cat-enthusiasts@example.com")) + .setAction(new FilterAction() + .setAddLabelIds(Arrays.asList(labelId)) + .setRemoveLabelIds(Arrays.asList("INBOX"))); + Filter result = gmailService.users().settings().filters().create("me", filter).execute(); + System.out.println("Created filter " + result.getId()); + // [END createFilter] + return result.getId(); + } + + public AutoForwarding enableForwarding(String realForwardingAddress) throws IOException { + Gmail gmailService = this.service; + // [START enableForwarding] + ForwardingAddress address = new ForwardingAddress() + .setForwardingEmail("user2@example.com"); + // [START_EXCLUDE silent] + address.setForwardingEmail(realForwardingAddress); + // [END_EXCLUDE] + ForwardingAddress createAddressResult = gmailService.users().settings().forwardingAddresses() + .create("me", address).execute(); + if (createAddressResult.getVerificationStatus().equals("accepted")) { + AutoForwarding autoForwarding = new AutoForwarding() + .setEnabled(true) + .setEmailAddress(address.getForwardingEmail()) + .setDisposition("trash"); + autoForwarding = gmailService.users().settings().updateAutoForwarding("me", autoForwarding).execute(); + // [START_EXCLUDE silent] + return autoForwarding; + } + // [END enableForwarding] + return null; + } + + public VacationSettings enableAutoReply() throws IOException { + Gmail gmailService = this.service; + // [START enableAutoReply] + VacationSettings vacationSettings = new VacationSettings() + .setEnableAutoReply(true) + .setResponseBodyHtml("I'm on vacation and will reply when I'm back in the office. Thanks!") + .setRestrictToDomain(true) + .setStartTime(LocalDateTime.now().toEpochSecond(ZoneOffset.UTC) * 1000) + .setEndTime(LocalDateTime.now().plusDays(7).toEpochSecond(ZoneOffset.UTC) * 1000); + VacationSettings response = gmailService.users().settings().updateVacation("me", vacationSettings).execute(); + // [END enableAutoReply] + return response; + } + +} diff --git a/gmail/snippets/src/main/java/SmimeSnippets.java b/gmail/snippets/src/main/java/SmimeSnippets.java new file mode 100644 index 00000000..85f3d0de --- /dev/null +++ b/gmail/snippets/src/main/java/SmimeSnippets.java @@ -0,0 +1,259 @@ +import com.google.api.services.gmail.Gmail; +import com.google.api.services.gmail.model.*; +import com.google.api.services.gmail.model.SmimeInfo; + +import java.io.*; +import java.nio.file.Files; +import java.nio.file.Paths; +import java.time.Instant; +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.util.Base64; +import org.apache.commons.csv.CSVFormat; +import org.apache.commons.csv.CSVParser; +import org.apache.commons.csv.CSVRecord; + +class SmimeSnippets { + + SmimeSnippets() {} + + // [START create_smime_info] + /** + * Create an SmimeInfo resource for a certificate from file. + * + * @param filename Name of the file containing the S/MIME certificate. + * @param password Password for the certificate file, or null if the file is not + * password-protected. + * @return An SmimeInfo object with the specified certificate. + */ + public static SmimeInfo createSmimeInfo(String filename, String password) { + SmimeInfo smimeInfo = null; + InputStream in = null; + + try { + byte[] fileContent = Files.readAllBytes(Paths.get(filename)); + smimeInfo = new SmimeInfo(); + smimeInfo.setPkcs12(Base64.getUrlEncoder().encodeToString(fileContent)); + if (password != null && password.length() > 0) { + smimeInfo.setEncryptedKeyPassword(password); + } + } catch (Exception e) { + System.out.printf("An error occured while reading the certificate file: %s\n", e); + } + return smimeInfo; + } + // [END create_smime_info] + + // [START insert_smime_info] + /** + * Upload an S/MIME certificate for the user. + * + * @param service Authorized GMail API service instance. + * @param userId User's email address. + * @param sendAsEmail The "send as" email address, or null if it should be the same as userId. + * @param smimeInfo The SmimeInfo object containing the user's S/MIME certificate. + * @return An SmimeInfo object with details about the uploaded certificate. + */ + public static SmimeInfo insertSmimeInfo( + Gmail service, String userId, String sendAsEmail, SmimeInfo smimeInfo) { + if (sendAsEmail == null) { + sendAsEmail = userId; + } + + try { + SmimeInfo results = + service + .users() + .settings() + .sendAs() + .smimeInfo() + .insert(userId, sendAsEmail, smimeInfo) + .execute(); + System.out.printf("Inserted certificate, id: %s\n", results.getId()); + return results; + } catch (IOException e) { + System.err.printf("An error occured: %s", e); + } + + return null; + } + // [END insert_smime_info] + + // [START insert_cert_from_csv] + /** + * A builder that returns a GMail API service instance that is authorized to act on behalf of the + * specified user. + */ + @FunctionalInterface + public interface GmailServiceBuilder { + Gmail buildGmailServiceFromUserId(String userId) throws IOException; + } + + /** + * Upload S/MIME certificates based on the contents of a CSV file. + * + *

Each row of the CSV file should contain a user ID, path to the certificate, and the + * certificate password. + * + * @param serviceBuilder A function that returns an authorized GMail API service instance for a + * given user. + * @param csvFilename Name of the CSV file. + */ + public static void insertCertFromCsv(GmailServiceBuilder serviceBuilder, String csvFilename) { + try { + File csvFile = new File(csvFilename); + CSVParser parser = CSVParser.parse(csvFile, java.nio.charset.StandardCharsets.UTF_8, CSVFormat.DEFAULT); + for (CSVRecord record : parser) { + String userId = record.get(0); + String certFilename = record.get(1); + String certPassword = record.get(2); + SmimeInfo smimeInfo = createSmimeInfo(certFilename, certPassword); + if (smimeInfo == null) { + System.err.printf("Unable to read certificate file for userId: %s\n", userId); + continue; + } + insertSmimeInfo(serviceBuilder.buildGmailServiceFromUserId(userId), userId, userId, smimeInfo); + } + } catch (Exception e) { + System.err.printf("An error occured while reading the CSV file: %s", e); + } + } + // [END insert_cert_from_csv] + + // [START update_smime_certs] + /** + * Update S/MIME certificates for the user. + * + *

First performs a lookup of all certificates for a user. If there are no certificates, or + * they all expire before the specified date/time, uploads the certificate in the specified file. + * If the default certificate is expired or there was no default set, chooses the certificate with + * the expiration furthest into the future and sets it as default. + * + * @param service Authorized GMail API service instance. + * @param userId User's email address. + * @param sendAsEmail The "send as" email address, or None if it should be the same as user_id. + * @param certFilename Name of the file containing the S/MIME certificate. + * @param certPassword Password for the certificate file, or None if the file is not + * password-protected. + * @param expireTime DateTime object against which the certificate expiration is compared. If + * None, uses the current time. @ returns: The ID of the default certificate. + * @return The ID of the default certifcate. + */ + public static String updateSmimeCerts( + Gmail service, + String userId, + String sendAsEmail, + String certFilename, + String certPassword, + LocalDateTime expireTime) { + if (sendAsEmail == null) { + sendAsEmail = userId; + } + + ListSmimeInfoResponse listResults = null; + try { + listResults = + service.users().settings().sendAs().smimeInfo().list(userId, sendAsEmail).execute(); + } catch (IOException e) { + System.err.printf("An error occurred during list: %s\n", e); + return null; + } + + String defaultCertId = null; + String bestCertId = null; + LocalDateTime bestCertExpire = LocalDateTime.MIN; + + if (expireTime == null) { + expireTime = LocalDateTime.now(); + } + if (listResults != null && listResults.getSmimeInfo() != null) { + for (SmimeInfo smimeInfo : listResults.getSmimeInfo()) { + String certId = smimeInfo.getId(); + boolean isDefaultCert = smimeInfo.getIsDefault(); + if (isDefaultCert) { + defaultCertId = certId; + } + LocalDateTime exp = LocalDateTime.ofInstant( + Instant.ofEpochMilli(smimeInfo.getExpiration()), ZoneId.systemDefault()); + if (exp.isAfter(expireTime)) { + if (exp.isAfter(bestCertExpire)) { + bestCertId = certId; + bestCertExpire = exp; + } + } else { + if (isDefaultCert) { + defaultCertId = null; + } + } + } + } + if (defaultCertId == null) { + String defaultId = bestCertId; + if (defaultId == null && certFilename != null) { + SmimeInfo smimeInfo = createSmimeInfo(certFilename, certPassword); + SmimeInfo insertResults = insertSmimeInfo(service, userId, sendAsEmail, smimeInfo); + if (insertResults != null) { + defaultId = insertResults.getId(); + } + } + + if (defaultId != null) { + try { + service + .users() + .settings() + .sendAs() + .smimeInfo() + .setDefault(userId, sendAsEmail, defaultId) + .execute(); + return defaultId; + } catch (IOException e) { + System.err.printf("An error occured during setDefault: %s", e); + } + } + } else { + return defaultCertId; + } + + return null; + } + + /** + * Update S/MIME certificates based on the contents of a CSV file. + * + *

Each row of the CSV file should contain a user ID, path to the certificate, and the + * certificate password. + * + * @param serviceBuilder A function that returns an authorized GMail API service instance for a + * given user. + * @param csvFilename Name of the CSV file. + * @param expireTime DateTime object against which the certificate expiration is compared. If + * None, uses the current time. + */ + public static void updateSmimeFromCsv( + GmailServiceBuilder serviceBuilder, String csvFilename, LocalDateTime expireTime) { + try { + File csvFile = new File(csvFilename); + CSVParser parser = + CSVParser.parse( + csvFile, + java.nio.charset.StandardCharsets.UTF_8, + CSVFormat.DEFAULT.withHeader().withSkipHeaderRecord()); + for (CSVRecord record : parser) { + String userId = record.get(0); + String certFilename = record.get(1); + String certPassword = record.get(2); + updateSmimeCerts( + serviceBuilder.buildGmailServiceFromUserId(userId), + userId, + userId, + certFilename, + certPassword, + expireTime); + } + } catch (Exception e) { + System.err.printf("An error occured while reading the CSV file: %s", e); + } + } + // [END update_smime_certs] +} From 2dd83876e82b87f5b61c494a3d6d3b5552e92b8b Mon Sep 17 00:00:00 2001 From: sanjuktaghosh7 Date: Mon, 6 Jun 2022 21:28:00 +0530 Subject: [PATCH 10/10] Gmail snippet --- gmail/snippets/src/main/java/EnableAutoReply.java | 2 +- gmail/snippets/src/main/java/UpdateSmimeCerts.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/gmail/snippets/src/main/java/EnableAutoReply.java b/gmail/snippets/src/main/java/EnableAutoReply.java index 15b08027..8cff0c9a 100644 --- a/gmail/snippets/src/main/java/EnableAutoReply.java +++ b/gmail/snippets/src/main/java/EnableAutoReply.java @@ -43,7 +43,7 @@ public static VacationSettings autoReply() throws IOException{ TODO(developer) - See https://developers.google.com/identity for guides on implementing OAuth2 for your application. */ GoogleCredentials credentials = GoogleCredentials.getApplicationDefault() - .createScoped(Collections.singleton(GmailScopes.GMAIL_SETTINGS_BASIC)); + .createScoped(GmailScopes.GMAIL_SETTINGS_BASIC); HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter(credentials); // Create the gmail API client diff --git a/gmail/snippets/src/main/java/UpdateSmimeCerts.java b/gmail/snippets/src/main/java/UpdateSmimeCerts.java index 598eb528..cd9ccb2c 100644 --- a/gmail/snippets/src/main/java/UpdateSmimeCerts.java +++ b/gmail/snippets/src/main/java/UpdateSmimeCerts.java @@ -60,7 +60,7 @@ public static String updateSmimeCerts(String userId, TODO(developer) - See https://developers.google.com/identity for guides on implementing OAuth2 for your application. */ GoogleCredentials credentials = GoogleCredentials.getApplicationDefault() - .createScoped(Collections.singletonList(GmailScopes.GMAIL_SETTINGS_SHARING)); + .createScoped(GmailScopes.GMAIL_SETTINGS_SHARING); HttpRequestInitializer requestInitializer = new HttpCredentialsAdapter( credentials);