Move mail [skip]
This commit is contained in:
parent
90a58dc070
commit
f88713c9b0
@ -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" }
|
||||||
@ -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
|
||||||
|
|||||||
@ -2,19 +2,19 @@ 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
|
||||||
implementation("org.bstats:bstats-bukkit:3.0.2")
|
implementation("org.bstats:bstats-bukkit:3.0.2")
|
||||||
// ProtocolLib
|
// ProtocolLib
|
||||||
compileOnly("com.comphenix.protocol:ProtocolLib:5.1.0")
|
compileOnly("com.comphenix.protocol:ProtocolLib:5.1.0")
|
||||||
// LuckPerms plugin
|
// LuckPerms plugin
|
||||||
compileOnly("net.luckperms:api:5.4")
|
compileOnly("net.luckperms:api:5.4")
|
||||||
// PermissionsEx plugin
|
// PermissionsEx plugin
|
||||||
compileOnly("ru.tehkode:PermissionsEx:1.23.5-SNAPSHOT")
|
compileOnly("ru.tehkode:PermissionsEx:1.23.5-SNAPSHOT")
|
||||||
// Hooks - End
|
// Hooks - End
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -27,12 +27,15 @@ 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")
|
||||||
.appendLiteral(']')
|
.appendLiteral(']')
|
||||||
.toFormatter();
|
.toFormatter();
|
||||||
|
|
||||||
// Outside references
|
// Outside references
|
||||||
private static File logFile;
|
private static File logFile;
|
||||||
@ -168,7 +171,7 @@ public final class ConsoleLogger {
|
|||||||
* Log the DEBUG message.
|
* Log the DEBUG message.
|
||||||
*
|
*
|
||||||
* @param message the message
|
* @param message the message
|
||||||
* @param param1 parameter to replace in the message
|
* @param param1 parameter to replace in the message
|
||||||
*/
|
*/
|
||||||
// Avoids array creation if DEBUG level is disabled
|
// Avoids array creation if DEBUG level is disabled
|
||||||
public void debug(String message, Object param1) {
|
public void debug(String message, Object param1) {
|
||||||
@ -181,8 +184,8 @@ public final class ConsoleLogger {
|
|||||||
* Log the DEBUG message.
|
* Log the DEBUG message.
|
||||||
*
|
*
|
||||||
* @param message the message
|
* @param message the message
|
||||||
* @param param1 first param to replace in message
|
* @param param1 first param to replace in message
|
||||||
* @param param2 second param to replace in message
|
* @param param2 second param to replace in message
|
||||||
*/
|
*/
|
||||||
// Avoids array creation if DEBUG level is disabled
|
// Avoids array creation if DEBUG level is disabled
|
||||||
public void debug(String message, Object param1, Object param2) {
|
public void debug(String message, Object param1, Object param2) {
|
||||||
@ -195,7 +198,7 @@ public final class ConsoleLogger {
|
|||||||
* Log the DEBUG message.
|
* Log the DEBUG message.
|
||||||
*
|
*
|
||||||
* @param message the message
|
* @param message the message
|
||||||
* @param params the params to replace in the message
|
* @param params the params to replace in the message
|
||||||
*/
|
*/
|
||||||
public void debug(String message, Object... params) {
|
public void debug(String message, Object... params) {
|
||||||
if (logLevel.includes(LogLevel.DEBUG)) {
|
if (logLevel.includes(LogLevel.DEBUG)) {
|
||||||
|
|||||||
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -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");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -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 {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -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" };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -10,19 +10,19 @@ public final class BackupSettings implements SettingsHolder {
|
|||||||
|
|
||||||
@Comment("General configuration for backups: if false, no backups are possible")
|
@Comment("General configuration for backups: if false, no backups are possible")
|
||||||
public static final Property<Boolean> ENABLED =
|
public static final Property<Boolean> ENABLED =
|
||||||
newProperty("BackupSystem.ActivateBackup", false);
|
newProperty("BackupSystem.ActivateBackup", false);
|
||||||
|
|
||||||
@Comment("Create backup at every start of server")
|
@Comment("Create backup at every start of server")
|
||||||
public static final Property<Boolean> ON_SERVER_START =
|
public static final Property<Boolean> ON_SERVER_START =
|
||||||
newProperty("BackupSystem.OnServerStart", false);
|
newProperty("BackupSystem.OnServerStart", false);
|
||||||
|
|
||||||
@Comment("Create backup at every stop of server")
|
@Comment("Create backup at every stop of server")
|
||||||
public static final Property<Boolean> ON_SERVER_STOP =
|
public static final Property<Boolean> ON_SERVER_STOP =
|
||||||
newProperty("BackupSystem.OnServerStop", true);
|
newProperty("BackupSystem.OnServerStop", true);
|
||||||
|
|
||||||
@Comment("Windows only: MySQL installation path")
|
@Comment("Windows only: MySQL installation path")
|
||||||
public static final Property<String> MYSQL_WINDOWS_PATH =
|
public static final Property<String> MYSQL_WINDOWS_PATH =
|
||||||
newProperty("BackupSystem.MysqlWindowsPath", "C:\\Program Files\\MySQL\\MySQL Server 5.1\\");
|
newProperty("BackupSystem.MysqlWindowsPath", "C:\\Program Files\\MySQL\\MySQL Server 5.1\\");
|
||||||
|
|
||||||
private BackupSettings() {
|
private BackupSettings() {
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1 +1,6 @@
|
|||||||
dependencies {}
|
dependencies {
|
||||||
|
compileOnly(project(":project:module-configuration"))
|
||||||
|
compileOnly(project(":project:module-logger"))
|
||||||
|
// ConfigMe
|
||||||
|
compileOnly(libs.configme)
|
||||||
|
}
|
||||||
@ -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")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -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
|
||||||
|
|||||||
@ -15,9 +15,9 @@ final class LogFilterHelper {
|
|||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static final List<String> COMMANDS_TO_SKIP = withAndWithoutAuthMePrefix(
|
static final List<String> COMMANDS_TO_SKIP = withAndWithoutAuthMePrefix(
|
||||||
"/login ", "/l ", "/log ", "/register ", "/reg ", "/unregister ", "/unreg ",
|
"/login ", "/l ", "/log ", "/register ", "/reg ", "/unregister ", "/unreg ",
|
||||||
"/changepassword ", "/cp ", "/changepass ", "/authme register ", "/authme reg ", "/authme r ",
|
"/changepassword ", "/cp ", "/changepass ", "/authme register ", "/authme reg ", "/authme r ",
|
||||||
"/authme changepassword ", "/authme password ", "/authme changepass ", "/authme cp ", "/email setpassword ");
|
"/authme changepassword ", "/authme password ", "/authme changepass ", "/authme cp ", "/email setpassword ");
|
||||||
|
|
||||||
private static final String ISSUED_COMMAND_TEXT = "issued server command:";
|
private static final String ISSUED_COMMAND_TEXT = "issued server command:";
|
||||||
|
|
||||||
@ -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) {
|
||||||
|
|||||||
@ -40,7 +40,7 @@ public class EmailService {
|
|||||||
return sendMailSsl.hasAllInformation();
|
return sendMailSsl.hasAllInformation();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean sendNewPasswordMail(String name, String mailAddress, String newPass,String ip,String time) {
|
public boolean sendNewPasswordMail(String name, String mailAddress, String newPass, String ip, String time) {
|
||||||
HtmlEmail email;
|
HtmlEmail email;
|
||||||
try {
|
try {
|
||||||
email = sendMailSsl.initializeMail(mailAddress);
|
email = sendMailSsl.initializeMail(mailAddress);
|
||||||
@ -49,7 +49,7 @@ public class EmailService {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String mailText = replaceTagsForPasswordMail(settings.getNewPasswordEmailMessage(), name, newPass,ip,time);
|
String mailText = replaceTagsForPasswordMail(settings.getNewPasswordEmailMessage(), name, newPass, ip, time);
|
||||||
File file = null;
|
File file = null;
|
||||||
if (settings.getProperty(EmailSettings.PASSWORD_AS_IMAGE)) {
|
if (settings.getProperty(EmailSettings.PASSWORD_AS_IMAGE)) {
|
||||||
try {
|
try {
|
||||||
@ -57,7 +57,7 @@ public class EmailService {
|
|||||||
mailText = embedImageIntoEmailContent(file, email, mailText);
|
mailText = embedImageIntoEmailContent(file, email, mailText);
|
||||||
} catch (IOException | EmailException e) {
|
} catch (IOException | EmailException e) {
|
||||||
logger.logException(
|
logger.logException(
|
||||||
"Unable to send new password as image for email " + mailAddress + ":", e);
|
"Unable to send new password as image for email " + mailAddress + ":", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,9 +69,9 @@ public class EmailService {
|
|||||||
/**
|
/**
|
||||||
* Sends an email to the user with his new password.
|
* Sends an email to the user with his new password.
|
||||||
*
|
*
|
||||||
* @param name the name of the player
|
* @param name the name of the player
|
||||||
* @param mailAddress the player's email
|
* @param mailAddress the player's email
|
||||||
* @param newPass the new password
|
* @param newPass the new password
|
||||||
* @return true if email could be sent, false otherwise
|
* @return true if email could be sent, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean sendPasswordMail(String name, String mailAddress, String newPass, String time) {
|
public boolean sendPasswordMail(String name, String mailAddress, String newPass, String time) {
|
||||||
@ -88,7 +88,7 @@ public class EmailService {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
String mailText = replaceTagsForPasswordMail(settings.getPasswordEmailMessage(), name, newPass,time);
|
String mailText = replaceTagsForPasswordMail(settings.getPasswordEmailMessage(), name, newPass, time);
|
||||||
// Generate an image?
|
// Generate an image?
|
||||||
File file = null;
|
File file = null;
|
||||||
if (settings.getProperty(EmailSettings.PASSWORD_AS_IMAGE)) {
|
if (settings.getProperty(EmailSettings.PASSWORD_AS_IMAGE)) {
|
||||||
@ -97,7 +97,7 @@ public class EmailService {
|
|||||||
mailText = embedImageIntoEmailContent(file, email, mailText);
|
mailText = embedImageIntoEmailContent(file, email, mailText);
|
||||||
} catch (IOException | EmailException e) {
|
} catch (IOException | EmailException e) {
|
||||||
logger.logException(
|
logger.logException(
|
||||||
"Unable to send new password as image for email " + mailAddress + ":", e);
|
"Unable to send new password as image for email " + mailAddress + ":", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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.
|
||||||
*
|
*
|
||||||
@ -127,16 +128,16 @@ public class EmailService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String mailText = replaceTagsForVerificationEmail(settings.getVerificationEmailMessage(), name, code,
|
String mailText = replaceTagsForVerificationEmail(settings.getVerificationEmailMessage(), name, code,
|
||||||
settings.getProperty(SecuritySettings.VERIFICATION_CODE_EXPIRATION_MINUTES),time);
|
settings.getProperty(SecuritySettings.VERIFICATION_CODE_EXPIRATION_MINUTES), time);
|
||||||
sendMailSsl.sendEmail(mailText, email);
|
sendMailSsl.sendEmail(mailText, email);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sends an email to the user with a recovery code for the password recovery process.
|
* Sends an email to the user with a recovery code for the password recovery process.
|
||||||
*
|
*
|
||||||
* @param name the name of the player
|
* @param name the name of the player
|
||||||
* @param email the player's email address
|
* @param email the player's email address
|
||||||
* @param code the recovery code
|
* @param code the recovery code
|
||||||
* @return true if email could be sent, false otherwise
|
* @return true if email could be sent, false otherwise
|
||||||
*/
|
*/
|
||||||
public boolean sendRecoveryCode(String name, String email, String code, String time) {
|
public boolean sendRecoveryCode(String name, String email, String code, String time) {
|
||||||
@ -149,7 +150,7 @@ public class EmailService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String message = replaceTagsForRecoveryCodeMail(settings.getRecoveryCodeEmailMessage(),
|
String message = replaceTagsForRecoveryCodeMail(settings.getRecoveryCodeEmailMessage(),
|
||||||
name, code, settings.getProperty(SecuritySettings.RECOVERY_CODE_HOURS_VALID),time);
|
name, code, settings.getProperty(SecuritySettings.RECOVERY_CODE_HOURS_VALID), time);
|
||||||
return sendMailSsl.sendEmail(message, htmlEmail);
|
return sendMailSsl.sendEmail(message, htmlEmail);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -174,50 +175,51 @@ public class EmailService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static String embedImageIntoEmailContent(File image, HtmlEmail email, String content)
|
private static String embedImageIntoEmailContent(File image, HtmlEmail email, String content)
|
||||||
throws EmailException {
|
throws EmailException {
|
||||||
DataSource source = new FileDataSource(image);
|
DataSource source = new FileDataSource(image);
|
||||||
String tag = email.embed(source, image.getName());
|
String tag = email.embed(source, image.getName());
|
||||||
return content.replace("<image />", "<img src=\"cid:" + tag + "\">");
|
return content.replace("<image />", "<img src=\"cid:" + tag + "\">");
|
||||||
}
|
}
|
||||||
|
|
||||||
private String replaceTagsForPasswordMail(String mailText, String name, String newPass,String ip,String time) {
|
private String replaceTagsForPasswordMail(String mailText, String name, String newPass, String ip, String time) {
|
||||||
return mailText
|
return mailText
|
||||||
.replace("<playername />", name)
|
.replace("<playername />", name)
|
||||||
.replace("<servername />", settings.getProperty(PluginSettings.SERVER_NAME))
|
.replace("<servername />", settings.getProperty(PluginSettings.SERVER_NAME))
|
||||||
.replace("<generatedpass />", newPass)
|
.replace("<generatedpass />", newPass)
|
||||||
.replace("<playerip />", ip)
|
.replace("<playerip />", ip)
|
||||||
.replace("<time />", time);
|
.replace("<time />", time);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String replaceTagsForPasswordMail(String mailText, String name, String newPass, String time) {
|
private String replaceTagsForPasswordMail(String mailText, String name, String newPass, String time) {
|
||||||
return mailText
|
return mailText
|
||||||
.replace("<playername />", name)
|
.replace("<playername />", name)
|
||||||
.replace("<servername />", settings.getProperty(PluginSettings.SERVER_NAME))
|
.replace("<servername />", settings.getProperty(PluginSettings.SERVER_NAME))
|
||||||
.replace("<generatedpass />", newPass)
|
.replace("<generatedpass />", newPass)
|
||||||
.replace("<time />", time);
|
.replace("<time />", time);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String replaceTagsForVerificationEmail(String mailText, String name, String code, int minutesValid, String time) {
|
private String replaceTagsForVerificationEmail(String mailText, String name, String code, int minutesValid, String time) {
|
||||||
return mailText
|
return mailText
|
||||||
.replace("<playername />", name)
|
.replace("<playername />", name)
|
||||||
.replace("<servername />", settings.getProperty(PluginSettings.SERVER_NAME))
|
.replace("<servername />", settings.getProperty(PluginSettings.SERVER_NAME))
|
||||||
.replace("<generatedcode />", code)
|
.replace("<generatedcode />", code)
|
||||||
.replace("<minutesvalid />", String.valueOf(minutesValid))
|
.replace("<minutesvalid />", String.valueOf(minutesValid))
|
||||||
.replace("<time />", time);
|
.replace("<time />", time);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String replaceTagsForRecoveryCodeMail(String mailText, String name, String code, int hoursValid, String time) {
|
private String replaceTagsForRecoveryCodeMail(String mailText, String name, String code, int hoursValid, String time) {
|
||||||
return mailText
|
return mailText
|
||||||
.replace("<playername />", name)
|
.replace("<playername />", name)
|
||||||
.replace("<servername />", settings.getProperty(PluginSettings.SERVER_NAME))
|
.replace("<servername />", settings.getProperty(PluginSettings.SERVER_NAME))
|
||||||
.replace("<recoverycode />", code)
|
.replace("<recoverycode />", code)
|
||||||
.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))
|
||||||
.replace("<time />", time);
|
.replace("<time />", time);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -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"))
|
||||||
|
}
|
||||||
@ -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")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@ -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;
|
||||||
|
|
||||||
@ -19,7 +18,7 @@ import static java.lang.String.format;
|
|||||||
public final class FileUtils {
|
public final class FileUtils {
|
||||||
|
|
||||||
private static final DateTimeFormatter CURRENT_DATE_STRING_FORMATTER =
|
private static final DateTimeFormatter CURRENT_DATE_STRING_FORMATTER =
|
||||||
DateTimeFormatter.ofPattern("yyyyMMdd_HHmm");
|
DateTimeFormatter.ofPattern("yyyyMMdd_HHmm");
|
||||||
|
|
||||||
private static ConsoleLogger logger = ConsoleLoggerFactory.get(FileUtils.class);
|
private static ConsoleLogger logger = ConsoleLoggerFactory.get(FileUtils.class);
|
||||||
|
|
||||||
@ -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) {
|
||||||
@ -46,14 +44,14 @@ public final class FileUtils {
|
|||||||
try (InputStream is = getResourceFromJar(resourcePath)) {
|
try (InputStream is = getResourceFromJar(resourcePath)) {
|
||||||
if (is == null) {
|
if (is == null) {
|
||||||
logger.warning(format("Cannot copy resource '%s' to file '%s': cannot load resource",
|
logger.warning(format("Cannot copy resource '%s' to file '%s': cannot load resource",
|
||||||
resourcePath, destinationFile.getPath()));
|
resourcePath, destinationFile.getPath()));
|
||||||
} else {
|
} else {
|
||||||
java.nio.file.Files.copy(is, destinationFile.toPath());
|
java.nio.file.Files.copy(is, destinationFile.toPath());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
logger.logException(format("Cannot copy resource '%s' to file '%s':",
|
logger.logException(format("Cannot copy resource '%s' to file '%s':",
|
||||||
resourcePath, destinationFile.getPath()), e);
|
resourcePath, destinationFile.getPath()), e);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -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) {
|
||||||
@ -166,8 +171,9 @@ public final class FileUtils {
|
|||||||
*/
|
*/
|
||||||
public static String createBackupFilePath(File file) {
|
public static String createBackupFilePath(File file) {
|
||||||
String filename = "backup_" + Files.getNameWithoutExtension(file.getName())
|
String filename = "backup_" + Files.getNameWithoutExtension(file.getName())
|
||||||
+ "_" + createCurrentTimeString()
|
+ "_" + createCurrentTimeString()
|
||||||
+ "." + Files.getFileExtension(file.getName());
|
+ "." + Files.getFileExtension(file.getName());
|
||||||
return makePath(file.getParent(), filename);
|
return makePath(file.getParent(), filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user