mirror of
https://github.com/Leahnaya/UBFunkeysServer.git
synced 2026-03-22 01:34:26 -05:00
Added user registration and login | u_reg and a_lru
This commit is contained in:
parent
4d49a2755b
commit
1db3d51796
|
|
@ -1,30 +1,106 @@
|
|||
package com.icedberries.UBFunkeysServer.ArkOne;
|
||||
|
||||
import com.icedberries.UBFunkeysServer.ArkOne.Plugins.BasePlugin;
|
||||
import com.icedberries.UBFunkeysServer.ArkOne.Plugins.GalaxyPlugin;
|
||||
import com.icedberries.UBFunkeysServer.ArkOne.Plugins.UserPlugin;
|
||||
import javagrinko.spring.tcp.Connection;
|
||||
import javagrinko.spring.tcp.TcpController;
|
||||
import javagrinko.spring.tcp.TcpHandler;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@TcpController
|
||||
public class ArkOneController implements TcpHandler {
|
||||
|
||||
public static final String IP_ADDRESS = "127.0.0.1";
|
||||
|
||||
// Plugins
|
||||
@Autowired
|
||||
BasePlugin basePlugin;
|
||||
|
||||
@Autowired
|
||||
UserPlugin userPlugin;
|
||||
|
||||
@Autowired
|
||||
GalaxyPlugin galaxyPlugin;
|
||||
|
||||
@Override
|
||||
public void receiveData(Connection connection, byte[] data) {
|
||||
//TODO: IMPLEMENT PLUGIN CHECKING AND FORWARDING HERE
|
||||
//Currently just echos back the received data until implemented
|
||||
|
||||
// Log the received request
|
||||
String xmlData = new String(data);
|
||||
System.out.println("[ArkOne] New Request: " + xmlData);
|
||||
|
||||
//TODO: USE THAT FOR PASSWORD ENCRYPTION FOR STORING IN THE DB
|
||||
//TODO: SEE THIS ARTICLE FOR ENCODING: https://www.baeldung.com/spring-security-registration-password-encoding-bcrypt
|
||||
// Create a list of responses to send back
|
||||
ArrayList<String> responses = new ArrayList<>();
|
||||
|
||||
try {
|
||||
connection.send(xmlData.toUpperCase().getBytes());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
// Parse the incoming data into individual commands
|
||||
List<String> commands = ArkOneParser.ParseReceivedMessage(xmlData);
|
||||
|
||||
// Handle each command
|
||||
for (String command : commands) {
|
||||
try {
|
||||
Element commandInfo = (Element)ArkOneParser.ParseCommand(command);
|
||||
switch(commandInfo.getNodeName()) {
|
||||
// Plugin 0 - Core
|
||||
case "a_lgu":
|
||||
responses.add(basePlugin.LoginGuestUser());
|
||||
break;
|
||||
case "a_gpd":
|
||||
responses.add(basePlugin.GetPluginDetails(commandInfo.getAttribute("p")));
|
||||
break;
|
||||
case "a_gsd":
|
||||
responses.add(basePlugin.GetServiceDetails(commandInfo.getAttribute("s")));
|
||||
break;
|
||||
case "a_lru":
|
||||
responses.add(basePlugin.LoginRegisteredUser(commandInfo));
|
||||
break;
|
||||
|
||||
// Plugin 1 (User)
|
||||
case "u_reg":
|
||||
responses.add(userPlugin.RegisterUser(commandInfo));
|
||||
break;
|
||||
|
||||
// Plugin 7 (Galaxy)
|
||||
case "lpv":
|
||||
responses.add(galaxyPlugin.LoadProfileVersion());
|
||||
break;
|
||||
|
||||
// Plugin 10 (Trunk)
|
||||
|
||||
// Catch Unhandled Commands
|
||||
default:
|
||||
responses.add("<unknown />");
|
||||
System.out.println("[ArkOne][ERROR] Unhandled command: " + commandInfo.getNodeName());
|
||||
break;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("[ArkOne][ERROR] Unknown error occurred: ");
|
||||
e.printStackTrace();
|
||||
responses.add("<unknown />");
|
||||
}
|
||||
}
|
||||
|
||||
// Send the response
|
||||
for(String response : responses) {
|
||||
try {
|
||||
// Append a 0x00 to the end of the response
|
||||
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
outputStream.write(response.getBytes());
|
||||
outputStream.write((byte)0x00);
|
||||
byte[] combinedResponse = outputStream.toByteArray();
|
||||
|
||||
connection.send(combinedResponse);
|
||||
|
||||
System.out.println("[ArkOne] Response: " + response);
|
||||
} catch (IOException e) {
|
||||
System.out.println("[ArkOne][ERROR] Unknown error occurred: ");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,71 @@
|
|||
package com.icedberries.UBFunkeysServer.ArkOne;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import org.xml.sax.InputSource;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class ArkOneParser {
|
||||
|
||||
public static ArrayList<String> ParseReceivedMessage(String xmlCommand) {
|
||||
List<String> rawCommandsList = Arrays.stream(xmlCommand.split("\0"))
|
||||
.filter(str -> !isNullOrWhitespace(str))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
return new ArrayList<>(rawCommandsList);
|
||||
}
|
||||
|
||||
public static Node ParseCommand(String command) throws Exception {
|
||||
// Check to see if the command has a routing string at the end of it
|
||||
if (command.endsWith("#")) {
|
||||
command = command.substring(0, command.lastIndexOf(">") + 1);
|
||||
}
|
||||
|
||||
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
|
||||
Document doc = dBuilder.parse(new InputSource(new StringReader(command)));
|
||||
doc.getDocumentElement().normalize();
|
||||
|
||||
return doc.getFirstChild();
|
||||
}
|
||||
|
||||
public static String RemoveXMLTag(Document doc) throws TransformerException {
|
||||
DOMSource domSource = new DOMSource(doc);
|
||||
StringWriter writer = new StringWriter();
|
||||
StreamResult result = new StreamResult(writer);
|
||||
TransformerFactory tf = TransformerFactory.newInstance();
|
||||
Transformer transformer = tf.newTransformer();
|
||||
transformer.transform(domSource, result);
|
||||
return writer.toString().replaceAll("(<\\?xml.*?\\?>)","");
|
||||
}
|
||||
|
||||
public static boolean isNullOrWhitespace(String s) {
|
||||
return s == null || isWhitespace(s);
|
||||
}
|
||||
|
||||
private static boolean isWhitespace(String s) {
|
||||
int length = s.length();
|
||||
if (length > 0) {
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (!Character.isWhitespace(s.charAt(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,206 @@
|
|||
package com.icedberries.UBFunkeysServer.ArkOne.Plugins;
|
||||
|
||||
import com.icedberries.UBFunkeysServer.ArkOne.ArkOneController;
|
||||
import com.icedberries.UBFunkeysServer.ArkOne.ArkOneParser;
|
||||
import com.icedberries.UBFunkeysServer.domain.User;
|
||||
import com.icedberries.UBFunkeysServer.service.UserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
|
||||
@Service
|
||||
public class BasePlugin {
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
@Autowired
|
||||
private PasswordEncoder passwordEncoder;
|
||||
|
||||
private static final String PORT = "20502";
|
||||
|
||||
public String LoginGuestUser() throws ParserConfigurationException, TransformerException {
|
||||
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
|
||||
|
||||
// Create the root element
|
||||
Document doc = dBuilder.newDocument();
|
||||
Element rootElement = doc.createElement("a_lgu");
|
||||
|
||||
// Set attributes
|
||||
rootElement.setAttribute("r", "0");
|
||||
rootElement.setAttribute("u", "0");
|
||||
rootElement.setAttribute("n", "GUESTUSER");
|
||||
rootElement.setAttribute("p", "");
|
||||
rootElement.setAttribute("s", "1");
|
||||
|
||||
doc.appendChild(rootElement);
|
||||
|
||||
return ArkOneParser.RemoveXMLTag(doc);
|
||||
}
|
||||
|
||||
public String GetServiceDetails(String s) throws ParserConfigurationException, TransformerException {
|
||||
// Set some variables for the response
|
||||
String serverID = "1";
|
||||
|
||||
String xIPAddress = ArkOneController.IP_ADDRESS;
|
||||
String xPort = "80";
|
||||
|
||||
String bIPAddress = ArkOneController.IP_ADDRESS;
|
||||
String bPort = "80";
|
||||
|
||||
// Update the port for each server
|
||||
// ** This would be used if each routing plugin had their own server/port combo **
|
||||
switch (s){
|
||||
//User
|
||||
case "1":
|
||||
xPort = PORT;
|
||||
bPort = PORT;
|
||||
break;
|
||||
|
||||
//Galaxy
|
||||
case "7":
|
||||
xPort = PORT;
|
||||
bPort = PORT;
|
||||
break;
|
||||
|
||||
//Trunk
|
||||
case "10":
|
||||
xPort = PORT;
|
||||
bPort = PORT;
|
||||
break;
|
||||
}
|
||||
|
||||
// Build the response
|
||||
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
|
||||
|
||||
// Create the root element
|
||||
Document doc = dBuilder.newDocument();
|
||||
Element rootElement = doc.createElement("a_gsd");
|
||||
|
||||
// Set attributes
|
||||
rootElement.setAttribute("s", serverID);
|
||||
rootElement.setAttribute("xi", xIPAddress);
|
||||
rootElement.setAttribute("xp", xPort);
|
||||
rootElement.setAttribute("bi", bIPAddress);
|
||||
rootElement.setAttribute("bp", bPort);
|
||||
|
||||
doc.appendChild(rootElement);
|
||||
|
||||
return ArkOneParser.RemoveXMLTag(doc);
|
||||
}
|
||||
|
||||
public String GetPluginDetails(String p) throws ParserConfigurationException, TransformerException {
|
||||
// Set some variables for the response
|
||||
String serverID = "1";
|
||||
|
||||
String xIPAddress = ArkOneController.IP_ADDRESS;
|
||||
String xPort = "80";
|
||||
|
||||
String bIPAddress = ArkOneController.IP_ADDRESS;
|
||||
String bPort = "80";
|
||||
|
||||
// Update the port for each plugin
|
||||
// ** This would be used if each routing plugin had their own server/port combo **
|
||||
switch (p){
|
||||
//User
|
||||
case "1":
|
||||
xPort = PORT;
|
||||
bPort = PORT;
|
||||
break;
|
||||
|
||||
//Galaxy
|
||||
case "7":
|
||||
xPort = PORT;
|
||||
bPort = PORT;
|
||||
break;
|
||||
|
||||
//Trunk
|
||||
case "10":
|
||||
xPort = PORT;
|
||||
bPort = PORT;
|
||||
break;
|
||||
}
|
||||
|
||||
// Build the response
|
||||
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
|
||||
|
||||
// Create the root element
|
||||
Document doc = dBuilder.newDocument();
|
||||
Element rootElement = doc.createElement("a_gpd");
|
||||
|
||||
// Set attributes
|
||||
rootElement.setAttribute("s", serverID);
|
||||
rootElement.setAttribute("xi", xIPAddress);
|
||||
rootElement.setAttribute("xp", xPort);
|
||||
rootElement.setAttribute("bi", bIPAddress);
|
||||
rootElement.setAttribute("bp", bPort);
|
||||
rootElement.setAttribute("p", p);
|
||||
|
||||
doc.appendChild(rootElement);
|
||||
|
||||
return ArkOneParser.RemoveXMLTag(doc);
|
||||
}
|
||||
|
||||
public String LoginRegisteredUser(Element element) throws ParserConfigurationException, TransformerException {
|
||||
// Response r codes:
|
||||
// 0 - Accepted Login
|
||||
// 1 - Already exist in Terrapinia
|
||||
// 2 - Already exist in Terrapinia
|
||||
// 3 - Problem with your account, please call phone number
|
||||
// 4 - Password Incorrect
|
||||
// 5 - Funkey Name Not Found
|
||||
Integer responseCode = 0;
|
||||
|
||||
String username = element.getAttribute("n");
|
||||
String password = element.getAttribute("p");
|
||||
|
||||
// Get a funkey with that username
|
||||
User user = userService.findByUsername(username).orElse(null);
|
||||
String uuid = "";
|
||||
|
||||
// Check if null (no funkey with that name)
|
||||
if (user == null) {
|
||||
responseCode = 5;
|
||||
} else {
|
||||
// Funkey name exists - Verify Password
|
||||
if (!passwordEncoder.matches(password, user.getPassword())) {
|
||||
// Passwords don't match
|
||||
responseCode = 4;
|
||||
} else {
|
||||
// Login success
|
||||
uuid = String.valueOf(user.getUUID());
|
||||
}
|
||||
}
|
||||
|
||||
// Build response
|
||||
// Build the response
|
||||
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
|
||||
|
||||
// Create the root element
|
||||
Document doc = dBuilder.newDocument();
|
||||
Element rootElement = doc.createElement("a_lru");
|
||||
|
||||
// Set attributes
|
||||
rootElement.setAttribute("s", "1");
|
||||
rootElement.setAttribute("r", String.valueOf(responseCode));
|
||||
if (responseCode == 0) {
|
||||
// Only set the user id field if successfully found the user
|
||||
rootElement.setAttribute("u", uuid);
|
||||
}
|
||||
|
||||
doc.appendChild(rootElement);
|
||||
|
||||
return ArkOneParser.RemoveXMLTag(doc);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
package com.icedberries.UBFunkeysServer.ArkOne.Plugins;
|
||||
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
public class GalaxyPlugin {
|
||||
|
||||
public String LoadProfileVersion() {
|
||||
//TODO: IMPLEMENT THIS WITH PROFILE SAVING
|
||||
return "<h7_0><lpv /></h7_0>";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
package com.icedberries.UBFunkeysServer.ArkOne.Plugins;
|
||||
|
||||
import com.icedberries.UBFunkeysServer.ArkOne.ArkOneParser;
|
||||
import com.icedberries.UBFunkeysServer.domain.User;
|
||||
import com.icedberries.UBFunkeysServer.service.UserService;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.security.crypto.password.PasswordEncoder;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
|
||||
@Service
|
||||
public class UserPlugin {
|
||||
|
||||
@Autowired
|
||||
private PasswordEncoder passwordEncoder;
|
||||
|
||||
@Autowired
|
||||
private UserService userService;
|
||||
|
||||
public String RegisterUser(Element element) throws ParserConfigurationException, TransformerException {
|
||||
String username = element.getAttribute("l");
|
||||
String password = element.getAttribute("p");
|
||||
String securityQuestion = element.getAttribute("sq");
|
||||
String securityAnswer = element.getAttribute("sa");
|
||||
|
||||
User newUser = User.builder()
|
||||
.username(username)
|
||||
.password(passwordEncoder.encode(password))
|
||||
.securityQuestion(securityQuestion)
|
||||
.securityAnswer(securityAnswer)
|
||||
.build();
|
||||
|
||||
// 0 - Successfully registered
|
||||
// 1 - Name already exists
|
||||
// 2 - Issues connecting to server
|
||||
Integer responseCode = 0;
|
||||
|
||||
String uniqueId = "";
|
||||
|
||||
// First check if username doesn't already exist in the DB
|
||||
if (userService.existsByUsername(newUser.getUsername())) {
|
||||
// Username already exists
|
||||
responseCode = 1;
|
||||
} else {
|
||||
// Username doesn't exist - save it
|
||||
User newUserInDB = userService.save(newUser);
|
||||
|
||||
uniqueId = String.valueOf(newUserInDB.getUUID());
|
||||
}
|
||||
|
||||
// Build response
|
||||
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
|
||||
|
||||
// Create the root element
|
||||
Document doc = dBuilder.newDocument();
|
||||
Element rootElement = doc.createElement("u_reg");
|
||||
|
||||
// Set attributes
|
||||
rootElement.setAttribute("r", String.valueOf(responseCode));
|
||||
rootElement.setAttribute("u", uniqueId);
|
||||
|
||||
doc.appendChild(rootElement);
|
||||
|
||||
return ArkOneParser.RemoveXMLTag(doc);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
package com.icedberries.UBFunkeysServer.Galaxy;
|
||||
|
||||
import com.icedberries.UBFunkeysServer.ArkOne.ArkOneParser;
|
||||
import com.icedberries.UBFunkeysServer.domain.Crib;
|
||||
import com.icedberries.UBFunkeysServer.service.CribService;
|
||||
import com.icedberries.UBFunkeysServer.service.EmailService;
|
||||
|
|
@ -245,13 +246,7 @@ public class GalaxyServer {
|
|||
Node importedNode = newDocument.importNode(profileNode, true);
|
||||
newDocument.appendChild(importedNode);
|
||||
|
||||
DOMSource domSource = new DOMSource(newDocument);
|
||||
StringWriter writer = new StringWriter();
|
||||
StreamResult result = new StreamResult(writer);
|
||||
TransformerFactory tf = TransformerFactory.newInstance();
|
||||
Transformer transformer = tf.newTransformer();
|
||||
transformer.transform(domSource, result);
|
||||
profileData = writer.toString().replaceAll("(<\\?xml.*?\\?>)","");
|
||||
profileData = ArkOneParser.RemoveXMLTag(newDocument);
|
||||
} catch (ParserConfigurationException | TransformerException e) {
|
||||
System.out.println("[Galaxy][POST] Exception thrown when saving crib: ");
|
||||
e.printStackTrace();
|
||||
|
|
|
|||
|
|
@ -5,12 +5,9 @@ import lombok.Builder;
|
|||
import lombok.Getter;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.Setter;
|
||||
import org.hibernate.annotations.Type;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.GeneratedValue;
|
||||
import javax.persistence.GenerationType;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.Table;
|
||||
import javax.persistence.*;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
|
|
@ -29,5 +26,7 @@ public class Crib {
|
|||
|
||||
private String username;
|
||||
|
||||
@Column(columnDefinition = "MEDIUMTEXT")
|
||||
@Type(type = "org.hibernate.type.TextType")
|
||||
private String profileData;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,4 +15,9 @@ public interface UserRepository extends CrudRepository<User, Integer> {
|
|||
|
||||
@Query("select user from User user where user.UUID = :uuid")
|
||||
Optional<User> findByUUID(@Param("uuid") Integer uuid);
|
||||
|
||||
Boolean existsByUsername(String username);
|
||||
|
||||
@Query("select user from User user where user.username = :username")
|
||||
Optional<User> findByUsername(@Param("username") String username);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,5 +10,9 @@ public interface UserService {
|
|||
|
||||
Boolean existsByUUID(Integer uuid);
|
||||
|
||||
void save(User user);
|
||||
User save(User user);
|
||||
|
||||
Boolean existsByUsername(String username);
|
||||
|
||||
Optional<User> findByUsername(String username);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,7 +26,17 @@ public class UserServiceImpl implements UserService {
|
|||
}
|
||||
|
||||
@Override
|
||||
public void save(User user) {
|
||||
userRepository.save(user);
|
||||
public User save(User user) {
|
||||
return userRepository.save(user);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Boolean existsByUsername(String username) {
|
||||
return userRepository.existsByUsername(username);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<User> findByUsername(String username) {
|
||||
return userRepository.findByUsername(username);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ public class TcpConnection implements Connection {
|
|||
public void start() {
|
||||
new Thread(() -> {
|
||||
while (true) {
|
||||
byte buf[] = new byte[64 * 1024];
|
||||
byte[] buf = new byte[51200];
|
||||
try {
|
||||
int count = inputStream.read(buf);
|
||||
if (count > 0) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user