Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Migration from other plugins #96

Draft
wants to merge 35 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
2706afb
Add import.yml
bivashy Oct 14, 2023
22d604e
Move import.yml fields into import section
bivashy Oct 16, 2023
e4f1650
Add MigrationSettings
bivashy Oct 16, 2023
c416c78
Implement PluginConfig#getMigrationSettings
bivashy Oct 16, 2023
1f3ad23
Add '/auth import' subcommand
bivashy Oct 16, 2023
86615b8
Remove redundant comments from config.yml
bivashy Oct 25, 2023
e2e1af9
Rename MigrationSettings into ImportingSettings
bivashy Oct 25, 2023
2d9b656
Add ImportingSettings
bivashy Oct 25, 2023
a8a08fc
Bump velocity-proxy version to 3.2.0-SNAPSHOT
bivashy Oct 25, 2023
df7c11f
Provide valid url to repository
bivashy Oct 25, 2023
58ab669
Add PortableAccount, ImportStatistics, ImportSource
bivashy Oct 25, 2023
8867dc2
Rename PortableAccount.LinkAccount to PortableLinkAccount
bivashy Oct 31, 2023
7186fdc
Merge branch 'main' into feature/60-migration-from-other-plugins
bivashy Nov 4, 2023
c192700
Merge branch 'main' into feature/60-migration-from-other-plugins
bivashy Nov 4, 2023
241ea06
Adapt PortableAccount, PortableLinkAccount into api types
bivashy Nov 9, 2023
112c57a
Basic implementation of importing
bivashy Nov 9, 2023
a3c0def
Create BaseAuthPlugin#getDatabaseHelper
bivashy Nov 11, 2023
b13be35
Add ImportingSourceSettings
bivashy Nov 11, 2023
866fb4a
Add DatabaseStream, ImportingException
bivashy Nov 11, 2023
e1fa685
Add LimboAuthImportSource
bivashy Nov 11, 2023
382f2d0
Initial support of LimboAuthImportSource in AuthCommand
bivashy Nov 15, 2023
a85765d
Add ImportingSourceSettings#getProperty(String)
bivashy Nov 22, 2023
c1e2d92
Add LOGIN_SECURITY ImportSourceType
bivashy Nov 22, 2023
4254c6e
Ignore invalid hashing algorithm in LoginSecurity
bivashy Nov 22, 2023
bc1b21b
fix: Replace LimboAuth occurrence in exception message
bivashy Nov 22, 2023
2c3c9af
chore: Change LoginSecurity jdbc-url from h2 to sqlite
bivashy Nov 22, 2023
d013a68
Use Supplier<Dao> in ImportExecutor
bivashy Feb 18, 2024
1f96f20
Driver url or type support in ImportingSourceSettings
bivashy Feb 18, 2024
a4f42ab
Merge branch 'main' into feature/60-migration-from-other-plugins
bivashy Feb 18, 2024
0674e76
Change default jdbc-url to consistent one
bivashy Feb 18, 2024
a0e256a
Add AuthMeImportSource
bivashy Feb 19, 2024
7d2f3d0
Throw IllegalArgumentException instead of NullPointerException
bivashy Feb 22, 2024
9a208d2
Handle empty, invalid UUID
bivashy Feb 24, 2024
124f21f
Handle empty, invalid UUID in #singleAccountWithLink
bivashy Feb 24, 2024
4340df0
Fix invalid H2 driver url
bivashy Apr 8, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.bivashy.auth.api.config.link.TelegramSettings;
import com.bivashy.auth.api.config.link.VKSettings;
import com.bivashy.auth.api.config.message.server.ServerMessages;
import com.bivashy.auth.api.config.importing.ImportingSettings;
import com.bivashy.auth.api.config.server.ConfigurationServer;
import com.bivashy.auth.api.crypto.CryptoProvider;
import com.bivashy.auth.api.database.DatabaseConnectionProvider;
Expand Down Expand Up @@ -81,6 +82,8 @@ public interface PluginConfig {

GoogleAuthenticatorSettings getGoogleAuthenticatorSettings();

ImportingSettings getImportingSettings();

TelegramSettings getTelegramSettings();

VKSettings getVKSettings();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.bivashy.auth.api.config.importing;

import java.util.Optional;

public interface ImportingSettings {

Optional<ImportingSourceSettings> sourceSettings(String sourceType);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.bivashy.auth.api.config.importing;

import java.io.File;
import java.util.Optional;

public interface ImportingSourceSettings {

File getDriverPath();

String getDriverDownloadUrl();

String getJdbcUrl();

String getUsername();

String getPassword();

Optional<String> getProperty(String key);

}
16 changes: 14 additions & 2 deletions core/src/main/java/me/mastercapexd/auth/BaseAuthPlugin.java
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
import me.mastercapexd.auth.crypto.belkaauth.UAuthCryptoProvider;
import me.mastercapexd.auth.database.AuthAccountDatabaseProxy;
import me.mastercapexd.auth.database.DatabaseHelper;
import me.mastercapexd.auth.database.importing.ImportExecutor;
import me.mastercapexd.auth.discord.command.DiscordCommandRegistry;
import me.mastercapexd.auth.discord.listener.DiscordLinkRoleModifierListener;
import me.mastercapexd.auth.hooks.BaseDiscordHook;
Expand Down Expand Up @@ -110,15 +111,16 @@ public class BaseAuthPlugin implements AuthPlugin {
private AudienceProvider audienceProvider;
private LibraryManagement libraryManagement;
private ServerCore core;
private File dataFolder;
private AuthenticatingAccountBucket accountBucket;
private EventBus eventBus = EventBusBuilder.asm().executor(Executors.newFixedThreadPool(4)).build();
private GoogleAuthenticator googleAuthenticator;
private PluginConfig config;
private AccountFactory accountFactory;
private LinkTypeProvider linkTypeProvider;
private DatabaseHelper databaseHelper;
private AccountDatabase accountDatabase;
private LoginManagement loginManagement;
private ImportExecutor importExecutor;

public BaseAuthPlugin(AudienceProvider audienceProvider, String version, File pluginFolder, ServerCore core, LibraryManagement libraryManagement) {
AuthPluginProvider.setPluginInstance(this);
Expand Down Expand Up @@ -155,8 +157,10 @@ private void initializeBasic() {
this.authenticationStepContextFactoryBucket = new BaseAuthenticationStepContextFactoryBucket(config.getAuthenticationSteps());
this.accountFactory = new AuthAccountFactory();
this.linkTypeProvider = BaseLinkTypeProvider.allLinks();
this.accountDatabase = new AuthAccountDatabaseProxy(new DatabaseHelper(this));
this.databaseHelper = new DatabaseHelper(this);
this.accountDatabase = new AuthAccountDatabaseProxy(databaseHelper);
this.loginManagement = new BaseLoginManagement(this);
this.importExecutor = new ImportExecutor(() -> databaseHelper.getAuthAccountDao());

this.registerAuthenticationSteps();

Expand Down Expand Up @@ -256,6 +260,10 @@ private void registerConfigurationProcessor() {
});
}

public DatabaseHelper getDatabaseHelper() {
return databaseHelper;
}

public BaseAuthPlugin eventBus(EventBus eventBus) {
this.eventBus = eventBus;
return this;
Expand Down Expand Up @@ -381,6 +389,10 @@ public File getFolder() {
return pluginFolder;
}

public ImportExecutor getImportExecutor() {
return importExecutor;
}

public <T extends PluginHook> void putHook(Class<? extends T> clazz, T instance) {
hooks.put(clazz, instance);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import com.bivashy.auth.api.config.link.TelegramSettings;
import com.bivashy.auth.api.config.link.VKSettings;
import com.bivashy.auth.api.config.message.server.ServerMessages;
import com.bivashy.auth.api.config.importing.ImportingSettings;
import com.bivashy.auth.api.config.server.ConfigurationServer;
import com.bivashy.auth.api.crypto.CryptoProvider;
import com.bivashy.auth.api.database.DatabaseConnectionProvider;
Expand All @@ -30,6 +31,7 @@
import me.mastercapexd.auth.config.bossbar.BaseBossBarSettings;
import me.mastercapexd.auth.config.discord.BaseDiscordSettings;
import me.mastercapexd.auth.config.google.BaseGoogleAuthenticatorSettings;
import me.mastercapexd.auth.config.importing.BaseImportingSettings;
import me.mastercapexd.auth.config.message.server.BaseServerMessages;
import me.mastercapexd.auth.config.resolver.RawURLProviderFieldResolverFactory.RawURLProvider;
import me.mastercapexd.auth.config.storage.BaseDatabaseConfiguration;
Expand Down Expand Up @@ -109,6 +111,8 @@ public abstract class PluginConfigTemplate implements PluginConfig {
private IntStream limboPortRange = IntStream.range(49152, 65535);
@ConfigField("authentication-steps")
private List<String> authenticationSteps = Arrays.asList("REGISTER", "LOGIN", "VK_LINK", "TELEGRAM_LINK", "GOOGLE_LINK", "ENTER_SERVER");
@ConfigField("import")
private BaseImportingSettings importingSettings;

public PluginConfigTemplate(AuthPlugin plugin) {
this.plugin = plugin;
Expand Down Expand Up @@ -303,6 +307,11 @@ public IntStream getLimboPortRange() {
return limboPortRange;
}

@Override
public ImportingSettings getImportingSettings() {
return importingSettings;
}

protected abstract ConfigurationSectionHolder createConfiguration(AuthPlugin plugin);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package me.mastercapexd.auth.config.importing;

import java.util.Optional;

import com.bivashy.auth.api.AuthPlugin;
import com.bivashy.auth.api.config.importing.ImportingSettings;
import com.bivashy.auth.api.config.importing.ImportingSourceSettings;
import com.bivashy.configuration.ConfigurationHolder;
import com.bivashy.configuration.annotation.ConfigField;
import com.bivashy.configuration.holder.ConfigurationSectionHolder;

import me.mastercapexd.auth.config.factory.ConfigurationHolderMapResolverFactory.ConfigurationHolderMap;

public class BaseImportingSettings implements ConfigurationHolder, ImportingSettings {

@ConfigField("sources")
private ConfigurationHolderMap<BaseImportingSourceSettings> sourceSettings;

public BaseImportingSettings(ConfigurationSectionHolder sectionHolder) {
AuthPlugin.instance().getConfigurationProcessor().resolve(sectionHolder, this);
}

@Override
public Optional<ImportingSourceSettings> sourceSettings(String sourceType) {
return Optional.ofNullable(sourceSettings.get(sourceType));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package me.mastercapexd.auth.config.importing;

import java.io.File;
import java.util.Optional;

import com.bivashy.auth.api.AuthPlugin;
import com.bivashy.auth.api.config.importing.ImportingSourceSettings;
import com.bivashy.auth.api.database.DatabaseConnectionProvider;
import com.bivashy.configuration.ConfigurationHolder;
import com.bivashy.configuration.annotation.ConfigField;
import com.bivashy.configuration.holder.ConfigurationSectionHolder;

public class BaseImportingSourceSettings implements ConfigurationHolder, ImportingSourceSettings {

private final ConfigurationSectionHolder sectionHolder;
@ConfigField("type")
private DatabaseConnectionProvider connectionProvider;
@ConfigField("driver-url")
private String driverUrl;
@ConfigField("cache-driver-path")
private File cacheDriverPath = new File(AuthPlugin.instance().getFolder(), "importing" + File.separator + "database-driver.jar");
@ConfigField("jdbc-url")
private String jdbcUrl;
@ConfigField("username")
private String username;
@ConfigField("password")
private String password;

public BaseImportingSourceSettings(ConfigurationSectionHolder sectionHolder) {
this.sectionHolder = sectionHolder;
AuthPlugin.instance().getConfigurationProcessor().resolve(sectionHolder, this);
}

@Override
public File getDriverPath() {
return cacheDriverPath;
}

@Override
public String getDriverDownloadUrl() {
if (connectionProvider != null)
return connectionProvider.getDriverDownloadUrl();
return driverUrl;
}

@Override
public String getJdbcUrl() {
return jdbcUrl;
}

@Override
public String getUsername() {
return username;
}

@Override
public String getPassword() {
return password;
}

public Optional<String> getProperty(String key) {
if (!sectionHolder.contains(key))
return Optional.empty();
return Optional.of(sectionHolder.getString(key));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package me.mastercapexd.auth.database.importing;

import java.util.concurrent.Callable;
import java.util.function.Supplier;

import me.mastercapexd.auth.database.dao.AuthAccountDao;
import me.mastercapexd.auth.database.dao.SupplierExceptionCatcher;
import me.mastercapexd.auth.database.importing.exception.ImportingException;

public class BatchOperationExecutor {

private final SupplierExceptionCatcher exceptionCatcher = new SupplierExceptionCatcher() {
@Override
public void processException(Throwable throwable) {
throw new ImportingException("Cannot execute batch operation", throwable);
}
};
private final Supplier<AuthAccountDao> dao;

public BatchOperationExecutor(Supplier<AuthAccountDao> dao) {
this.dao = dao;
}

public <T> T execute(Callable<T> callable) {
return exceptionCatcher.execute(() -> dao.get().callBatchTasks(callable));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
package me.mastercapexd.auth.database.importing;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.sql.SQLException;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;

import com.bivashy.auth.api.AuthPlugin;
import com.bivashy.auth.api.config.importing.ImportingSourceSettings;
import com.j256.ormlite.dao.Dao;
import com.j256.ormlite.dao.DaoManager;
import com.j256.ormlite.dao.GenericRawResults;
import com.j256.ormlite.dao.RawRowMapper;
import com.j256.ormlite.field.DatabaseField;
import com.j256.ormlite.jdbc.JdbcPooledConnectionSource;
import com.j256.ormlite.support.ConnectionSource;
import com.j256.ormlite.table.DatabaseTableConfig;

import me.mastercapexd.auth.database.importing.exception.ImportingException;
import me.mastercapexd.auth.util.DownloadUtil;
import me.mastercapexd.auth.util.DriverUtil;
import me.mastercapexd.auth.util.HashUtils;

public class DatabaseStream implements AutoCloseable {

private final ConnectionSource connectionSource;
private final Dao<?, ?> dao;

public DatabaseStream(ImportingSourceSettings settings) throws SQLException, IOException {
File driverFile = settings.getDriverPath();
URL downloadUrl = new URL(settings.getDriverDownloadUrl());
String cacheDriverCheckSum = HashUtils.getFileCheckSum(driverFile, HashUtils.getMD5());
if (!driverFile.exists() || cacheDriverCheckSum != null && !DownloadUtil.checkSum(HashUtils.mapToMd5URL(downloadUrl), cacheDriverCheckSum))
DownloadUtil.downloadFile(downloadUrl, driverFile);
DriverUtil.loadDriver(driverFile, AuthPlugin.instance().getClass().getClassLoader());

connectionSource = new JdbcPooledConnectionSource(settings.getJdbcUrl(), settings.getUsername(), settings.getPassword());
DatabaseTableConfig<DummyModel> tableConfig = new DatabaseTableConfig<>();
tableConfig.setDataClass(DummyModel.class);
dao = DaoManager.createDao(connectionSource, tableConfig);
}

public <T> Stream<T> execute(String query, RawRowMapper<T> rowMapper, String... args) throws SQLException {
GenericRawResults<T> results = dao.queryRaw(query, rowMapper, args);
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(results.iterator(), Spliterator.IMMUTABLE), false)
.onClose(() -> {
try {
results.close();
} catch (Exception e) {
throw new ImportingException("Cannot close GenericRawResults of query '" + query + "'", e);
}
});
}

public boolean tableExists(String tableName) throws SQLException {
return connectionSource.getReadOnlyConnection(tableName).isTableExists(tableName);
}

@Override
public void close() throws Exception {
connectionSource.close();
}

public static class DummyModel {

@DatabaseField(generatedId = true)
public long id;

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package me.mastercapexd.auth.database.importing;

import java.util.concurrent.CompletableFuture;
import java.util.function.Supplier;
import java.util.stream.Stream;

import me.mastercapexd.auth.database.dao.AuthAccountDao;
import me.mastercapexd.auth.database.importing.model.ImportStatistics;
import me.mastercapexd.auth.database.importing.model.PortableAccount;

public class ImportExecutor {

private final BatchOperationExecutor batchOperationExecutor;
private final Supplier<AuthAccountDao> daoSupplier;

public ImportExecutor(Supplier<AuthAccountDao> daoSupplier) {
batchOperationExecutor = new BatchOperationExecutor(daoSupplier);
this.daoSupplier = daoSupplier;
}

public CompletableFuture<ImportStatistics> performImport(ImportSource source) {
CompletableFuture<ImportStatistics> future = new CompletableFuture<>();
new Thread(() -> {
try {
future.complete(runImport(source));
} catch (Throwable ex) {
future.completeExceptionally(ex);
}
}, "mcAuth-Import").start();
return future;
}

ImportStatistics runImport(ImportSource source) {
ImportStatistics statistics = new ImportStatistics();
ImportSink sink = new ImportSink(batchOperationExecutor, statistics, daoSupplier.get());
transferAccounts(source, sink);
return statistics;
}

private void transferAccounts(ImportSource source, ImportSink sink) {
try (Stream<PortableAccount> accountStream = source.sourceAccounts()) {
accountStream.forEach(sink::addAccountAndLinks);
}
}

}
Loading