Merge remote-tracking branch 'origin/feature/hibernate' into nonInstance

This commit is contained in:
Zaxar163 2019-06-03 13:12:10 +03:00
commit 05e98bcad6
23 changed files with 574 additions and 5 deletions

View file

@ -53,6 +53,7 @@ bundle project(':Radon')
bundle 'commons-codec:commons-codec:1.12' bundle 'commons-codec:commons-codec:1.12'
bundle 'org.javassist:javassist:3.25.0-GA' bundle 'org.javassist:javassist:3.25.0-GA'
bundle 'io.netty:netty-all:4.1.36.Final' bundle 'io.netty:netty-all:4.1.36.Final'
bundle 'org.hibernate:hibernate-core:5.4.3.Final'
bundle 'org.slf4j:slf4j-simple:1.7.25' bundle 'org.slf4j:slf4j-simple:1.7.25'
bundle 'org.slf4j:slf4j-api:1.7.25' bundle 'org.slf4j:slf4j-api:1.7.25'

View file

@ -66,6 +66,7 @@
import pro.gravit.launchserver.components.AuthLimiterComponent; import pro.gravit.launchserver.components.AuthLimiterComponent;
import pro.gravit.launchserver.components.Component; import pro.gravit.launchserver.components.Component;
import pro.gravit.launchserver.config.LaunchServerRuntimeConfig; import pro.gravit.launchserver.config.LaunchServerRuntimeConfig;
import pro.gravit.launchserver.dao.UserService;
import pro.gravit.launchserver.legacy.Response; import pro.gravit.launchserver.legacy.Response;
import pro.gravit.launchserver.manangers.LaunchServerGsonManager; import pro.gravit.launchserver.manangers.LaunchServerGsonManager;
import pro.gravit.launchserver.manangers.MirrorManager; import pro.gravit.launchserver.manangers.MirrorManager;
@ -458,6 +459,8 @@ public static void main(String... args) throws Throwable {
public final ModulesManager modulesManager; public final ModulesManager modulesManager;
public final UserService userService;
public final MirrorManager mirrorManager; public final MirrorManager mirrorManager;
public final ReloadManager reloadManager; public final ReloadManager reloadManager;
@ -611,6 +614,7 @@ public LaunchServer(Path dir, boolean testEnv, String[] args) throws IOException
socketHookManager = new SocketHookManager(); socketHookManager = new SocketHookManager();
authHookManager = new AuthHookManager(); authHookManager = new AuthHookManager();
configManager = new ConfigManager(); configManager = new ConfigManager();
userService = new UserService(this);
GarbageManager.registerNeedGC(sessionManager); GarbageManager.registerNeedGC(sessionManager);
reloadManager.registerReloadable("launchServer", this); reloadManager.registerReloadable("launchServer", this);
registerObject("permissionsHandler", config.permissionsHandler); registerObject("permissionsHandler", config.permissionsHandler);

View file

@ -24,7 +24,7 @@ public AuthProviderPair(AuthProvider provider, AuthHandler handler, TextureProvi
public void init(LaunchServer srv) { public void init(LaunchServer srv) {
provider.init(srv); provider.init(srv);
handler.init(); handler.init(srv);
} }
public void close() throws IOException { public void close() throws IOException {

View file

@ -3,10 +3,12 @@
import java.io.IOException; import java.io.IOException;
import java.util.UUID; import java.util.UUID;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.auth.AuthException; import pro.gravit.launchserver.auth.AuthException;
import pro.gravit.launchserver.auth.provider.AuthProviderResult; import pro.gravit.launchserver.auth.provider.AuthProviderResult;
import pro.gravit.utils.ProviderMap; import pro.gravit.utils.ProviderMap;
public abstract class AuthHandler implements AutoCloseable { public abstract class AuthHandler implements AutoCloseable {
public static ProviderMap<AuthHandler> providers = new ProviderMap<>("AuthHandler"); public static ProviderMap<AuthHandler> providers = new ProviderMap<>("AuthHandler");
private static boolean registredHandl = false; private static boolean registredHandl = false;
@ -23,10 +25,13 @@ public static void registerHandlers() {
providers.register("memory", MemoryAuthHandler.class); providers.register("memory", MemoryAuthHandler.class);
providers.register("mysql", MySQLAuthHandler.class); providers.register("mysql", MySQLAuthHandler.class);
providers.register("request", RequestAuthHandler.class); providers.register("request", RequestAuthHandler.class);
providers.register("hibernate", HibernateAuthHandler.class);
registredHandl = true; registredHandl = true;
} }
} }
protected transient LaunchServer srv;
public abstract UUID auth(AuthProviderResult authResult) throws IOException; public abstract UUID auth(AuthProviderResult authResult) throws IOException;
public abstract UUID checkServer(String username, String serverID) throws IOException; public abstract UUID checkServer(String username, String serverID) throws IOException;
@ -43,7 +48,7 @@ public static void registerHandlers() {
public abstract String uuidToUsername(UUID uuid) throws IOException; public abstract String uuidToUsername(UUID uuid) throws IOException;
public void init() { public void init(LaunchServer srv) {
this.srv = srv;
} }
} }

View file

@ -0,0 +1,43 @@
package pro.gravit.launchserver.auth.handler;
import java.io.IOException;
import java.util.UUID;
import pro.gravit.launchserver.dao.User;
public class HibernateAuthHandler extends CachedAuthHandler {
@Override
protected Entry fetchEntry(String username) throws IOException {
User user = srv.userService.findUserByUsername(username);
if(user == null) return null;
return new Entry(user.uuid, username, user.getAccessToken(), user.serverID);
}
@Override
protected Entry fetchEntry(UUID uuid) throws IOException {
User user = srv.userService.findUserByUUID(uuid);
if(user == null) return null;
return new Entry(user.uuid, user.username, user.getAccessToken(), user.serverID);
}
@Override
protected boolean updateAuth(UUID uuid, String username, String accessToken) throws IOException {
User user = srv.userService.findUserByUUID(uuid);
user.setAccessToken(accessToken);
srv.userService.updateUser(user);
return true;
}
@Override
protected boolean updateServerID(UUID uuid, String serverID) throws IOException {
User user = srv.userService.findUserByUUID(uuid);
user.serverID = serverID;
srv.userService.updateUser(user);
return true;
}
@Override
public void close() throws IOException {
}
}

View file

@ -7,6 +7,7 @@
import java.sql.SQLException; import java.sql.SQLException;
import java.util.UUID; import java.util.UUID;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.auth.MySQLSourceConfig; import pro.gravit.launchserver.auth.MySQLSourceConfig;
import pro.gravit.utils.helper.LogHelper; import pro.gravit.utils.helper.LogHelper;
@ -25,7 +26,8 @@ public final class MySQLAuthHandler extends CachedAuthHandler {
private transient String updateServerIDSQL; private transient String updateServerIDSQL;
@Override @Override
public void init() { public void init(LaunchServer srv) {
super.init(srv);
//Verify //Verify
if (mySQLHolder == null) LogHelper.error("[Verify][AuthHandler] mySQLHolder cannot be null"); if (mySQLHolder == null) LogHelper.error("[Verify][AuthHandler] mySQLHolder cannot be null");
if (uuidColumn == null) LogHelper.error("[Verify][AuthHandler] uuidColumn cannot be null"); if (uuidColumn == null) LogHelper.error("[Verify][AuthHandler] uuidColumn cannot be null");

View file

@ -4,6 +4,7 @@
import java.net.URL; import java.net.URL;
import java.util.UUID; import java.util.UUID;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.utils.helper.CommonHelper; import pro.gravit.utils.helper.CommonHelper;
import pro.gravit.utils.helper.IOHelper; import pro.gravit.utils.helper.IOHelper;
import pro.gravit.utils.helper.LogHelper; import pro.gravit.utils.helper.LogHelper;
@ -19,7 +20,8 @@ public final class RequestAuthHandler extends CachedAuthHandler {
private String goodResponse = "OK"; private String goodResponse = "OK";
@Override @Override
public void init() { public void init(LaunchServer srv) {
super.init(srv);
if (usernameFetch == null) if (usernameFetch == null)
LogHelper.error("[Verify][AuthHandler] usernameFetch cannot be null"); LogHelper.error("[Verify][AuthHandler] usernameFetch cannot be null");
if (uuidFetch == null) if (uuidFetch == null)

View file

@ -22,6 +22,7 @@ public static void registerProviders() {
providers.register("mysql", MySQLAuthProvider.class); providers.register("mysql", MySQLAuthProvider.class);
providers.register("request", RequestAuthProvider.class); providers.register("request", RequestAuthProvider.class);
providers.register("json", JsonAuthProvider.class); providers.register("json", JsonAuthProvider.class);
providers.register("hibernate", HibernateAuthProvider.class);
registredProv = true; registredProv = true;
} }
} }

View file

@ -0,0 +1,25 @@
package pro.gravit.launchserver.auth.provider;
import java.io.IOException;
import pro.gravit.launchserver.auth.AuthException;
import pro.gravit.launchserver.dao.User;
import pro.gravit.utils.helper.SecurityHelper;
public class HibernateAuthProvider extends AuthProvider {
@Override
public AuthProviderResult auth(String login, String password, String ip) throws Exception {
User user = srv.userService.findUserByUsername(login);
if(user == null || !user.verifyPassword(password))
{
if(user ==null) throw new AuthException("Username incorrect");
else throw new AuthException("Username or password incorrect");
}
return new AuthProviderResult(login, SecurityHelper.randomStringToken(), srv);
}
@Override
public void close() throws IOException {
}
}

View file

@ -0,0 +1,33 @@
package pro.gravit.launchserver.command.dao;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.command.Command;
import pro.gravit.launchserver.dao.User;
import pro.gravit.utils.helper.LogHelper;
public class GetAllUsersCommand extends Command {
public GetAllUsersCommand(LaunchServer server) {
super(server);
}
@Override
public String getArgsDescription() {
return "";
}
@Override
public String getUsageDescription() {
return "get all users information";
}
@Override
public void invoke(String... args) throws Exception {
int count = 0;
for(User user : server.userService.findAllUsers())
{
LogHelper.subInfo("[%s] UUID: %s", user.username, user.uuid.toString());
count++;
}
LogHelper.info("Print %d users", count);
}
}

View file

@ -0,0 +1,34 @@
package pro.gravit.launchserver.command.dao;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.command.Command;
import pro.gravit.launchserver.dao.User;
import pro.gravit.utils.helper.LogHelper;
public class GetUserCommand extends Command {
public GetUserCommand(LaunchServer server) {
super(server);
}
@Override
public String getArgsDescription() {
return "[username]";
}
@Override
public String getUsageDescription() {
return "get user information";
}
@Override
public void invoke(String... args) throws Exception {
verifyArgs(args, 1);
User user = server.userService.findUserByUsername(args[0]);
if(user == null)
{
LogHelper.error("User %s not found", args[0]);
return;
}
LogHelper.info("[%s] UUID: %s", user.username, user.uuid.toString());
}
}

View file

@ -0,0 +1,35 @@
package pro.gravit.launchserver.command.dao;
import java.util.UUID;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.command.Command;
import pro.gravit.launchserver.dao.User;
import pro.gravit.utils.helper.LogHelper;
public class RegisterCommand extends Command {
public RegisterCommand(LaunchServer server) {
super(server);
}
@Override
public String getArgsDescription() {
return "[login] [password]";
}
@Override
public String getUsageDescription() {
return "Register new user";
}
@Override
public void invoke(String... args) throws Exception {
verifyArgs(args, 2);
User user = new User();
user.username = args[0];
user.setPassword(args[1]);
user.uuid = UUID.randomUUID();
server.userService.saveUser(user);
LogHelper.info("User %s registered. UUID: %s", user.username, user.uuid.toString());
}
}

View file

@ -0,0 +1,37 @@
package pro.gravit.launchserver.command.dao;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.command.Command;
import pro.gravit.launchserver.dao.User;
import pro.gravit.utils.helper.LogHelper;
public class SetUserPasswordCommand extends Command {
public SetUserPasswordCommand(LaunchServer server) {
super(server);
}
@Override
public String getArgsDescription() {
return "[username] [new password]";
}
@Override
public String getUsageDescription() {
return "Set user password";
}
@Override
public void invoke(String... args) throws Exception {
verifyArgs(args, 2);
User user = server.userService.findUserByUsername(args[0]);
if(user == null)
{
LogHelper.error("User %s not found", args[1]);
return;
}
user.setPassword(args[1]);
server.userService.updateUser(user);
LogHelper.info("[%s] UUID: %s | New Password: %s", user.username, user.uuid.toString(), args[1]);
}
}

View file

@ -17,6 +17,10 @@
import pro.gravit.launchserver.command.basic.StopCommand; import pro.gravit.launchserver.command.basic.StopCommand;
import pro.gravit.launchserver.command.basic.TestCommand; import pro.gravit.launchserver.command.basic.TestCommand;
import pro.gravit.launchserver.command.basic.VersionCommand; import pro.gravit.launchserver.command.basic.VersionCommand;
import pro.gravit.launchserver.command.dao.GetAllUsersCommand;
import pro.gravit.launchserver.command.dao.GetUserCommand;
import pro.gravit.launchserver.command.dao.RegisterCommand;
import pro.gravit.launchserver.command.dao.SetUserPasswordCommand;
import pro.gravit.launchserver.command.dump.DumpEntryCacheCommand; import pro.gravit.launchserver.command.dump.DumpEntryCacheCommand;
import pro.gravit.launchserver.command.dump.DumpSessionsCommand; import pro.gravit.launchserver.command.dump.DumpSessionsCommand;
import pro.gravit.launchserver.command.hash.DownloadAssetCommand; import pro.gravit.launchserver.command.hash.DownloadAssetCommand;
@ -82,6 +86,15 @@ public static void registerCommands(pro.gravit.utils.command.CommandHandler hand
Category updatesCategory = new Category(updates, "updates", "Update and Sync Management"); Category updatesCategory = new Category(updates, "updates", "Update and Sync Management");
handler.registerCategory(updatesCategory); handler.registerCategory(updatesCategory);
//Register dao commands
BaseCommandCategory dao = new BaseCommandCategory();
dao.registerCommand("register", new RegisterCommand(server));
dao.registerCommand("setUserPassword", new SetUserPasswordCommand(server));
dao.registerCommand("getUser", new GetUserCommand(server));
dao.registerCommand("getAllUsers", new GetAllUsersCommand(server));
Category daoCategory = new Category(dao, "DAO", "Data Management");
handler.registerCategory(daoCategory);
// Register auth commands // Register auth commands
BaseCommandCategory auth = new BaseCommandCategory(); BaseCommandCategory auth = new BaseCommandCategory();
auth.registerCommand("auth", new AuthCommand(server)); auth.registerCommand("auth", new AuthCommand(server));

View file

@ -11,6 +11,7 @@ public static void registerComponents() {
if (!registredComp) { if (!registredComp) {
providers.register("authLimiter", AuthLimiterComponent.class); providers.register("authLimiter", AuthLimiterComponent.class);
providers.register("commandRemover", CommandRemoverComponent.class); providers.register("commandRemover", CommandRemoverComponent.class);
providers.register("hibernate", HibernateConfiguratorComponent.class);
registredComp = true; registredComp = true;
} }
} }

View file

@ -0,0 +1,61 @@
package pro.gravit.launchserver.components;
import java.nio.file.Paths;
import org.hibernate.cfg.Configuration;
import pro.gravit.launchserver.LaunchServer;
import pro.gravit.launchserver.dao.LaunchServerDaoFactory;
import pro.gravit.launchserver.dao.User;
import pro.gravit.launchserver.dao.impl.HibernateUserDAOImpl;
import pro.gravit.launchserver.hibernate.HibernateManager;
import pro.gravit.utils.helper.CommonHelper;
public class HibernateConfiguratorComponent extends Component {
public String driver;
public String url;
public String username;
public String password;
public String pool_size;
public String hibernateConfig;
public boolean parallelHibernateInit;
@Override
public void preInit(LaunchServer launchServer) {
LaunchServerDaoFactory.setUserDaoProvider(HibernateUserDAOImpl::new);
Runnable init = () -> {
Configuration cfg = new Configuration()
.addAnnotatedClass(User.class)
.setProperty("hibernate.connection.driver_class", driver)
.setProperty("hibernate.connection.url", url)
.setProperty("hibernate.connection.username", username)
.setProperty("hibernate.connection.password", password)
.setProperty("hibernate.connection.pool_size", pool_size);
if(hibernateConfig != null)
cfg.configure(Paths.get(hibernateConfig).toFile());
HibernateManager.sessionFactory = cfg.buildSessionFactory();
};
if(parallelHibernateInit)
CommonHelper.newThread("Hibernate Thread", true, init);
else
init.run();
}
@Override
public void init(LaunchServer launchServer) {
}
@Override
public void postInit(LaunchServer launchServer) {
//UserService service = new UserService();
//List<User> users = service.findAllUsers();
//User newUser = new User();
//newUser.username = "VeryTestUser";
//newUser.setPassword("12345");
//service.saveUser(newUser);
//for(User u : users)
//{
// LogHelper.info("Found User %s", u.username);
//}
}
}

View file

@ -0,0 +1,18 @@
package pro.gravit.launchserver.dao;
import java.util.function.Supplier;
import pro.gravit.launchserver.dao.impl.DefaultUserDAOImpl;
public class LaunchServerDaoFactory {
private static Supplier<UserDAO> getUserDao = DefaultUserDAOImpl::new;
public static void setUserDaoProvider(Supplier<UserDAO> getDao) {
LaunchServerDaoFactory.getUserDao = getDao;
}
public static UserDAO createUserDao()
{
return getUserDao.get();
}
}

View file

@ -0,0 +1,68 @@
package pro.gravit.launchserver.dao;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.UUID;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import pro.gravit.utils.helper.LogHelper;
import pro.gravit.utils.helper.SecurityHelper;
@Entity
@Table(name = "users")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(unique = true)
public String username;
@Column(unique = true)
public UUID uuid;
@Column(name = "password")
private byte[] password;
private String accessToken;
public String serverID;
private String password_salt;
public void setPassword(String password)
{
password_salt = SecurityHelper.randomStringAESKey();
MessageDigest digest;
try {
digest = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
LogHelper.error(e);
return;
}
this.password = digest.digest(password.concat(password_salt).getBytes(StandardCharsets.UTF_8));
}
public boolean verifyPassword(String password)
{
MessageDigest digest;
try {
digest = MessageDigest.getInstance("SHA-256");
} catch (NoSuchAlgorithmException e) {
LogHelper.error(e);
return false;
}
byte[] enpassword = digest.digest(password.concat(password_salt).getBytes(StandardCharsets.UTF_8));
LogHelper.info(Arrays.toString(enpassword));
LogHelper.info(Arrays.toString(this.password));
return Arrays.equals(enpassword, this.password);
}
public String getAccessToken() {
return accessToken;
}
public void setAccessToken(String accessToken) {
this.accessToken = accessToken;
}
}

View file

@ -0,0 +1,14 @@
package pro.gravit.launchserver.dao;
import java.util.List;
import java.util.UUID;
public interface UserDAO {
User findById(int id);
User findByUsername(String username);
User findByUUID(UUID uuid);
void save(User user);
void update(User user);
void delete(User user);
List<User> findAll();
}

View file

@ -0,0 +1,44 @@
package pro.gravit.launchserver.dao;
import java.util.List;
import java.util.UUID;
import pro.gravit.launchserver.LaunchServer;
public class UserService {
private final UserDAO usersDao;
public UserService(LaunchServer server) {
usersDao = LaunchServerDaoFactory.createUserDao();
}
public User findUser(int id) {
return usersDao.findById(id);
}
public User findUserByUsername(String username) {
return usersDao.findByUsername(username);
}
public User findUserByUUID(UUID uuid) {
return usersDao.findByUUID(uuid);
}
public void saveUser(User user) {
usersDao.save(user);
}
public void deleteUser(User user) {
usersDao.delete(user);
}
public void updateUser(User user) {
usersDao.update(user);
}
public List<User> findAllUsers() {
return usersDao.findAll();
}
}

View file

@ -0,0 +1,45 @@
package pro.gravit.launchserver.dao.impl;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import pro.gravit.launchserver.dao.User;
import pro.gravit.launchserver.dao.UserDAO;
public class DefaultUserDAOImpl implements UserDAO {
@Override
public User findById(int id) {
return null;
}
@Override
public User findByUsername(String username) {
return null;
}
@Override
public User findByUUID(UUID uuid) {
return null;
}
@Override
public void save(User user) {
throw new UnsupportedOperationException();
}
@Override
public void update(User user) {
throw new UnsupportedOperationException();
}
@Override
public void delete(User user) {
throw new UnsupportedOperationException();
}
@Override
public List<User> findAll() {
return new ArrayList<>();
}
}

View file

@ -0,0 +1,76 @@
package pro.gravit.launchserver.dao.impl;
import java.util.List;
import java.util.UUID;
import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import org.hibernate.Session;
import org.hibernate.Transaction;
import pro.gravit.launchserver.dao.User;
import pro.gravit.launchserver.dao.UserDAO;
import pro.gravit.launchserver.hibernate.HibernateManager;
public class HibernateUserDAOImpl implements UserDAO {
public User findById(int id) {
return HibernateManager.sessionFactory.openSession().get(User.class, id);
}
public User findByUsername(String username) {
EntityManager em = HibernateManager.sessionFactory.createEntityManager();
em.getTransaction().begin();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> personCriteria = cb.createQuery(User.class);
Root<User> rootUser = personCriteria.from(User.class);
personCriteria.select(rootUser).where(cb.equal(rootUser.get("username"), username));
List<User> ret = em.createQuery(personCriteria).getResultList();
em.close();
return ret.size() == 0 ? null : ret.get(0);
}
public User findByUUID(UUID uuid) {
EntityManager em = HibernateManager.sessionFactory.createEntityManager();
em.getTransaction().begin();
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> personCriteria = cb.createQuery(User.class);
Root<User> rootUser = personCriteria.from(User.class);
personCriteria.select(rootUser).where(cb.equal(rootUser.get("uuid"), uuid));
List<User> ret = em.createQuery(personCriteria).getResultList();
em.close();
return ret.size() == 0 ? null : ret.get(0);
}
public void save(User user) {
Session session = HibernateManager.sessionFactory.openSession();
Transaction tx1 = session.beginTransaction();
session.save(user);
tx1.commit();
session.close();
}
public void update(User user) {
Session session = HibernateManager.sessionFactory.openSession();
Transaction tx1 = session.beginTransaction();
session.update(user);
tx1.commit();
session.close();
}
public void delete(User user) {
Session session = HibernateManager.sessionFactory.openSession();
Transaction tx1 = session.beginTransaction();
session.delete(user);
tx1.commit();
session.close();
}
@SuppressWarnings("unchecked")
public List<User> findAll() {
return (List<User>) HibernateManager.sessionFactory.openSession().createQuery("From User").list();
}
}

View file

@ -0,0 +1,7 @@
package pro.gravit.launchserver.hibernate;
import org.hibernate.SessionFactory;
public class HibernateManager {
public static SessionFactory sessionFactory;
}