Move mail [skip]

This commit is contained in:
MC~蛟龙 2024-07-11 19:02:06 +08:00
parent 90a58dc070
commit f88713c9b0
18 changed files with 119 additions and 321 deletions

View File

@ -1,10 +1,12 @@
[versions] [versions]
guava = "33.2.1-jre" guava = "33.2.1-jre"
adventure = "4.17.0" configme = "1.3.1"
adventure-api = "4.17.0"
adventure-platform = "4.3.2" adventure-platform = "4.3.2"
[libraries] [libraries]
guava = { module = "com.google.guava:guava", version.ref = "guava" } guava = { module = "com.google.guava:guava", version.ref = "guava" }
adventure-text-minimessage = { module = "net.kyori:adventure-text-minimessage", version.ref = "adventure" } configme = { module = "ch.jalu:configme", version.ref = "configme" }
adventure-text-serializer-gson = { module = "net.kyori:adventure-text-serializer-gson", version.ref = "adventure" } adventure-text-minimessage = { module = "net.kyori:adventure-text-minimessage", version.ref = "adventure-api" }
adventure-text-serializer-gson = { module = "net.kyori:adventure-text-serializer-gson", version.ref = "adventure-api" }
adventure-platform-bukkit = { module = "net.kyori:adventure-platform-bukkit", version.ref = "adventure-platform" } adventure-platform-bukkit = { module = "net.kyori:adventure-platform-bukkit", version.ref = "adventure-platform" }

View File

@ -21,14 +21,16 @@ subprojects {
dependencies { dependencies {
// Modules // Modules
implementation(project(":project:module-common", "shadow"))
implementation(project(":project:module-util", "shadow"))
implementation(project(":project:module-logger", "shadow"))
implementation(project(":project:module-configuration", "shadow")) implementation(project(":project:module-configuration", "shadow"))
implementation(project(":project:module-logger", "shadow"))
implementation(project(":project:module-util", "shadow"))
implementation(project(":project:module-common", "shadow"))
implementation(project(":project:module-message", "shadow")) implementation(project(":project:module-message", "shadow"))
implementation(project(":project:module-database", "shadow"))
implementation(project(":project:module-mail", "shadow"))
// Adventure API // Adventure API
implementation("net.kyori:adventure-text-minimessage:4.17.0") implementation(rootProject.libs.adventure.text.minimessage)
implementation("net.kyori:adventure-text-serializer-gson:4.17.0") implementation(rootProject.libs.adventure.text.serializer.gson)
// Spigot API, https://www.spigotmc.org/ // Spigot API, https://www.spigotmc.org/
compileOnly("org.spigotmc:spigot-api:1.20.6-R0.1-SNAPSHOT") compileOnly("org.spigotmc:spigot-api:1.20.6-R0.1-SNAPSHOT")
// Java Libraries // Java Libraries
@ -42,8 +44,6 @@ subprojects {
} }
// Library for tar archives // Library for tar archives
implementation("javatar:javatar:2.5") implementation("javatar:javatar:2.5")
// Java Email Library
implementation("org.apache.commons:commons-email:1.6-SNAPSHOT")
// Log4J Logger (required by the console filter) TODO Remove // Log4J Logger (required by the console filter) TODO Remove
compileOnly("org.apache.logging.log4j:log4j-core:2.20.0") // Log4J version bundled in 1.12.2 compileOnly("org.apache.logging.log4j:log4j-core:2.20.0") // Log4J version bundled in 1.12.2
// Libby // Libby

View File

@ -3,7 +3,7 @@ description = "Fork of the first authentication plugin for the Bukkit API!"
dependencies { dependencies {
// Adventure Bukkit // Adventure Bukkit
implementation("net.kyori:adventure-platform-bukkit:4.3.2") implementation(libs.adventure.platform.bukkit)
// Hooks - Start // Hooks - Start
// bStats metrics // bStats metrics

View File

@ -27,7 +27,10 @@ import java.util.logging.Logger;
public final class ConsoleLogger { public final class ConsoleLogger {
private static final String NEW_LINE = System.lineSeparator(); private static final String NEW_LINE = System.lineSeparator();
/** Formatter which formats dates to something like "[08-16 21:18:46]" for any given LocalDateTime. */
/**
* Formatter which formats dates to something like "[08-16 21:18:46]" for any given LocalDateTime.
*/
private static final DateTimeFormatter DATE_FORMAT = new DateTimeFormatterBuilder() private static final DateTimeFormatter DATE_FORMAT = new DateTimeFormatterBuilder()
.appendLiteral('[') .appendLiteral('[')
.appendPattern("MM-dd HH:mm:ss") .appendPattern("MM-dd HH:mm:ss")

View File

@ -1,40 +0,0 @@
package fr.xephi.authme.mail;
import java.awt.*;
import java.awt.image.BufferedImage;
/**
*/
public class ImageGenerator {
private final String pass;
/**
* Constructor for ImageGenerator.
*
* @param pass String
*/
public ImageGenerator(String pass) {
this.pass = pass;
}
/**
* Method generateImage.
*
* @return BufferedImage
*/
public BufferedImage generateImage() {
BufferedImage image = new BufferedImage(200, 60, BufferedImage.TYPE_BYTE_INDEXED);
Graphics2D graphics = image.createGraphics();
graphics.setColor(Color.BLACK);
graphics.fillRect(0, 0, 200, 40);
GradientPaint gradientPaint = new GradientPaint(10, 5, Color.WHITE, 20, 10, Color.WHITE, true);
graphics.setPaint(gradientPaint);
Font font = new Font("Comic Sans MS", Font.BOLD, 30);
graphics.setFont(font);
graphics.drawString(pass, 5, 30);
graphics.dispose();
image.flush();
return image;
}
}

View File

@ -1,28 +0,0 @@
package fr.xephi.authme.mail;
import java.security.Provider;
/* Copyright 2012 Google Inc.
*
* 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
*
* http://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.
*/
public class OAuth2Provider extends Provider {
private static final long serialVersionUID = 1L;
public OAuth2Provider() {
super("Google OAuth2 Provider", 1.0,
"Provides the XOAUTH2 SASL Mechanism");
put("SaslClientFactory.XOAUTH2",
"fr.xephi.authme.mail.OAuth2SaslClientFactory");
}
}

View File

@ -1,98 +0,0 @@
/* Copyright 2012 Google Inc.
*
* 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
*
* http://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.
*/
package fr.xephi.authme.mail;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslException;
import java.io.IOException;
/**
* An OAuth2 implementation of SaslClient.
*/
class OAuth2SaslClient implements SaslClient {
private final String oauthToken;
private final CallbackHandler callbackHandler;
private boolean isComplete = false;
/**
* Creates a new instance of the OAuth2SaslClient. This will ordinarily only
* be called from OAuth2SaslClientFactory.
*/
public OAuth2SaslClient(String oauthToken,
CallbackHandler callbackHandler) {
this.oauthToken = oauthToken;
this.callbackHandler = callbackHandler;
}
public String getMechanismName() {
return "XOAUTH2";
}
public boolean hasInitialResponse() {
return true;
}
public byte[] evaluateChallenge(byte[] challenge) throws SaslException {
if (isComplete) {
// Empty final response from server, just ignore it.
return new byte[] { };
}
NameCallback nameCallback = new NameCallback("Enter name");
Callback[] callbacks = new Callback[] { nameCallback };
try {
callbackHandler.handle(callbacks);
} catch (UnsupportedCallbackException e) {
throw new SaslException("Unsupported callback: " + e);
} catch (IOException e) {
throw new SaslException("Failed to execute callback: " + e);
}
String email = nameCallback.getName();
byte[] response = String.format("user=%s\1auth=Bearer %s\1\1", email,
oauthToken).getBytes();
isComplete = true;
return response;
}
public boolean isComplete() {
return isComplete;
}
public byte[] unwrap(byte[] incoming, int offset, int len)
throws SaslException {
throw new IllegalStateException();
}
public byte[] wrap(byte[] outgoing, int offset, int len)
throws SaslException {
throw new IllegalStateException();
}
public Object getNegotiatedProperty(String propName) {
if (!isComplete()) {
throw new IllegalStateException();
}
return null;
}
public void dispose() throws SaslException {
}
}

View File

@ -1,57 +0,0 @@
/*
* Copyright 2012 Google Inc.
*
* 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
*
* http://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.
*/
package fr.xephi.authme.mail;
import javax.security.auth.callback.CallbackHandler;
import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslClientFactory;
import java.util.Map;
import java.util.logging.Logger;
/**
* A SaslClientFactory that returns instances of OAuth2SaslClient.
*
* <p>
* Only the "XOAUTH2" mechanism is supported. The {@code callbackHandler} is
* passed to the OAuth2SaslClient. Other parameters are ignored.
*/
public class OAuth2SaslClientFactory implements SaslClientFactory {
private static final Logger logger = Logger.getLogger(OAuth2SaslClientFactory.class.getName());
public static final String OAUTH_TOKEN_PROP = "mail.smpt.sasl.mechanisms.oauth2.oauthToken";
public SaslClient createSaslClient(String[] mechanisms,
String authorizationId, String protocol, String serverName,
Map<String, ?> props, CallbackHandler callbackHandler) {
boolean matchedMechanism = false;
for (int i = 0; i < mechanisms.length; ++i) {
if ("XOAUTH2".equalsIgnoreCase(mechanisms[i])) {
matchedMechanism = true;
break;
}
}
if (!matchedMechanism) {
logger.info("Failed to match any mechanisms");
return null;
}
return new OAuth2SaslClient((String) props.get(OAUTH_TOKEN_PROP), callbackHandler);
}
public String[] getMechanismNames(Map<String, ?> props) {
return new String[] { "XOAUTH2" };
}
}

View File

@ -1 +1,6 @@
dependencies {} dependencies {
compileOnly(project(":project:module-configuration"))
compileOnly(project(":project:module-logger"))
// ConfigMe
compileOnly(libs.configme)
}

View File

@ -12,11 +12,9 @@ dependencies {
} }
} }
tasks { tasks.shadowJar {
shadowJar {
// NightConfig // NightConfig
relocate("com.electronwill.nightconfig", "com.electronwill.nightconfig_3_6_7") relocate("com.electronwill.nightconfig", "com.electronwill.nightconfig_3_6_7")
// Snakeyaml // Snakeyaml
relocate("org.yaml.snakeyaml", "org.yaml.snakeyaml_2_2") relocate("org.yaml.snakeyaml", "org.yaml.snakeyaml_2_2")
} }
}

View File

@ -1,5 +1,6 @@
dependencies { dependencies {
compileOnly(project(":project:module-util")) compileOnly(project(":project:module-util"))
compileOnly(project(":project:module-common"))
compileOnly(libs.guava) compileOnly(libs.guava)
// Log4J Logger (required by the console filter) // Log4J Logger (required by the console filter)
compileOnly("org.apache.logging.log4j:log4j-core:2.20.0") // Log4J version bundled in 1.12.2 compileOnly("org.apache.logging.log4j:log4j-core:2.20.0") // Log4J version bundled in 1.12.2

View File

@ -29,7 +29,6 @@ final class LogFilterHelper {
* Validate a message and return whether the message contains a sensitive AuthMe command. * Validate a message and return whether the message contains a sensitive AuthMe command.
* *
* @param message The message to verify * @param message The message to verify
*
* @return True if it is a sensitive AuthMe command, false otherwise * @return True if it is a sensitive AuthMe command, false otherwise
*/ */
static boolean isSensitiveAuthMeCommand(String message) { static boolean isSensitiveAuthMeCommand(String message) {

View File

@ -105,6 +105,7 @@ public class EmailService {
FileUtils.delete(file); FileUtils.delete(file);
return couldSendEmail; return couldSendEmail;
} }
/** /**
* Sends an email to the user with the temporary verification code. * Sends an email to the user with the temporary verification code.
* *
@ -214,6 +215,7 @@ public class EmailService {
.replace("<hoursvalid />", String.valueOf(hoursValid)) .replace("<hoursvalid />", String.valueOf(hoursValid))
.replace("<time />", time); .replace("<time />", time);
} }
private String replaceTagsForShutDownMail(String mailText, String time) { private String replaceTagsForShutDownMail(String mailText, String time) {
return mailText return mailText
.replace("<servername />", settings.getProperty(PluginSettings.SERVER_NAME)) .replace("<servername />", settings.getProperty(PluginSettings.SERVER_NAME))

View File

@ -38,8 +38,8 @@ public class SendMailSsl {
* @return true if the necessary email settings are set, false otherwise * @return true if the necessary email settings are set, false otherwise
*/ */
public boolean hasAllInformation() { public boolean hasAllInformation() {
return !settings.getProperty(MAIL_ACCOUNT).isEmpty() return !settings.getProperty(EmailSettings.MAIL_ACCOUNT).isEmpty()
&& !settings.getProperty(MAIL_PASSWORD).isEmpty(); && !settings.getProperty(EmailSettings.MAIL_PASSWORD).isEmpty();
} }
/** /**

View File

@ -1 +1,7 @@
dependencies {} dependencies {
compileOnly(project(":project:module-common"))
compileOnly(project(":project:module-util"))
compileOnly(project(":project:module-logger"))
compileOnly(project(":project:module-configuration"))
compileOnly(project(":project:module-message"))
}

View File

@ -1,11 +1,10 @@
dependencies { dependencies {
compileOnly(project(":project:module-logger"))
compileOnly(libs.guava) compileOnly(libs.guava)
// String comparison library. Used for dynamic help system. // String comparison library. Used for dynamic help system.
implementation("net.ricecode:string-similarity:1.0.0") implementation("net.ricecode:string-similarity:1.0.0")
} }
tasks { tasks.shadowJar {
shadowJar {
relocate("net.ricecode.similarity", "${project.group}.libs.net.ricecode.similarity") relocate("net.ricecode.similarity", "${project.group}.libs.net.ricecode.similarity")
} }
}

View File

@ -1,7 +1,6 @@
package fr.xephi.authme.util; package fr.xephi.authme.util;
import com.google.common.io.Files; import com.google.common.io.Files;
import fr.xephi.authme.AuthMe;
import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.ConsoleLoggerFactory; import fr.xephi.authme.output.ConsoleLoggerFactory;
@ -32,7 +31,6 @@ public final class FileUtils {
* *
* @param destinationFile The file to check and copy to (outside of JAR) * @param destinationFile The file to check and copy to (outside of JAR)
* @param resourcePath Local path to the resource file (path to file within JAR) * @param resourcePath Local path to the resource file (path to file within JAR)
*
* @return False if the file does not exist and could not be copied, true otherwise * @return False if the file does not exist and could not be copied, true otherwise
*/ */
public static boolean copyFileFromResource(File destinationFile, String resourcePath) { public static boolean copyFileFromResource(File destinationFile, String resourcePath) {
@ -78,10 +76,18 @@ public final class FileUtils {
* @param path the local path (starting from resources project, e.g. "config.yml" for 'resources/config.yml') * @param path the local path (starting from resources project, e.g. "config.yml" for 'resources/config.yml')
* @return the stream if the file exists, or false otherwise * @return the stream if the file exists, or false otherwise
*/ */
public static InputStream getResourceFromJar(String path) { public static InputStream getResourceFromJar(String path, ClassLoader classLoader) {
// ClassLoader#getResourceAsStream does not deal with the '\' path separator: replace to '/' // ClassLoader#getResourceAsStream does not deal with the '\' path separator: replace to '/'
final String normalizedPath = path.replace("\\", "/"); final String normalizedPath = path.replace("\\", "/");
return AuthMe.class.getClassLoader().getResourceAsStream(normalizedPath); return classLoader.getResourceAsStream(normalizedPath);
}
/**
* Returns a JAR file as stream. Returns null if it doesn't exist.
* And it will find resources in the classLoader of FileUtils
*/
public static InputStream getResourceFromJar(String path) {
return getResourceFromJar(path, FileUtils.class.getClassLoader());
} }
/** /**
@ -140,7 +146,6 @@ public final class FileUtils {
* Construct a file path from the given elements, i.e. separate the given elements by the file separator. * Construct a file path from the given elements, i.e. separate the given elements by the file separator.
* *
* @param elements The elements to create a path with * @param elements The elements to create a path with
*
* @return The created path * @return The created path
*/ */
public static String makePath(String... elements) { public static String makePath(String... elements) {
@ -170,4 +175,5 @@ public final class FileUtils {
+ "." + Files.getFileExtension(file.getName()); + "." + Files.getFileExtension(file.getName());
return makePath(file.getParent(), filename); return makePath(file.getParent(), filename);
} }
} }