Archived
1
0
Fork 0

Add documentation to common package

This commit is contained in:
Ethanell 2022-01-19 09:17:32 +01:00
parent 6e05784eb7
commit f3813d23e2
12 changed files with 201 additions and 11 deletions

View file

@ -3,28 +3,52 @@ package fr.univ.lyon1.common;
import java.io.Serializable; import java.io.Serializable;
import java.util.UUID; import java.util.UUID;
/**
* The base type of chat channel
*/
public class Channel implements Serializable { public class Channel implements Serializable {
private final UUID uuid; private final UUID uuid;
private String name; private String name;
/**
* Create an existing channel
* @param uuid the channel unique id
* @param name the channel name
*/
public Channel(UUID uuid, String name) { public Channel(UUID uuid, String name) {
this.uuid = uuid; this.uuid = uuid;
this.name = name; this.name = name;
} }
/**
* Create a new channel
* @param name the new channel name
*/
public Channel(String name) { public Channel(String name) {
this.uuid = UUID.randomUUID(); this.uuid = UUID.randomUUID();
this.name = name; this.name = name;
} }
/**
* Get the channel unique id
* @return the channel unique id
*/
public UUID getUUID() { public UUID getUUID() {
return uuid; return uuid;
} }
/**
* Get the channel name
* @return the channel name
*/
public String getName() { public String getName() {
return name; return name;
} }
/**
* String version of the channel
* @return the channel name
*/
@Override @Override
public String toString() { public String toString() {
return name; return name;

View file

@ -10,12 +10,13 @@ import java.io.InputStream;
import java.security.*; import java.security.*;
import java.security.cert.CertificateException; import java.security.cert.CertificateException;
/* /**
keytool -genkeypair -alias server -keyalg EC \ * The SSL context for client/server communication
-sigalg SHA384withECDSA -keysize 256 -keystore servercert.p12 \ * A key store can be generated with this command:
-storetype pkcs12 -v -storepass abc123 -validity 10000 -ext san=ip:127.0.0.1 * keytool -genkeypair -alias server -keyalg EC \
* -sigalg SHA384withECDSA -keysize 256 -keystore servercert.p12 \
* -storetype pkcs12 -v -storepass abc123 -validity 10000 -ext san=ip:127.0.0.1
*/ */
public class ChatSSL { public class ChatSSL {
public static String trustStoreName = "servercert.p12"; public static String trustStoreName = "servercert.p12";
public static String keyStoreName = "servercert.p12"; public static String keyStoreName = "servercert.p12";
@ -23,25 +24,37 @@ public class ChatSSL {
private static char[] trustStorePassword = "abc123".toCharArray(); private static char[] trustStorePassword = "abc123".toCharArray();
private static char[] keyStorePassword = "abc123".toCharArray(); private static char[] keyStorePassword = "abc123".toCharArray();
/**
* Get the SSL context for communication
* @return the SSL context
*/
public static SSLContext getSSLContext() { public static SSLContext getSSLContext() {
try { try {
// Get the SSL trust store from package resources
KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType()); KeyStore trustStore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream tstore = Connection.class InputStream tstore = Connection.class
.getResourceAsStream("/" + trustStoreName); .getResourceAsStream("/" + trustStoreName);
trustStore.load(tstore, trustStorePassword); trustStore.load(tstore, trustStorePassword);
tstore.close(); tstore.close();
// Create a trust factory from the trust store
TrustManagerFactory tmf = TrustManagerFactory TrustManagerFactory tmf = TrustManagerFactory
.getInstance(TrustManagerFactory.getDefaultAlgorithm()); .getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(trustStore); tmf.init(trustStore);
// Get the SSL key store from package resources
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
InputStream kstore = Connection.class InputStream kstore = Connection.class
.getResourceAsStream("/" + keyStoreName); .getResourceAsStream("/" + keyStoreName);
keyStore.load(kstore, keyStorePassword); keyStore.load(kstore, keyStorePassword);
kstore.close();
// Create a key factory from the key store
KeyManagerFactory kmf = KeyManagerFactory KeyManagerFactory kmf = KeyManagerFactory
.getInstance(KeyManagerFactory.getDefaultAlgorithm()); .getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(keyStore, keyStorePassword); kmf.init(keyStore, keyStorePassword);
// Generate the SSL context
SSLContext ctx = SSLContext.getInstance("TLS"); SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(),
SecureRandom.getInstanceStrong()); SecureRandom.getInstanceStrong());

View file

@ -3,13 +3,21 @@ package fr.univ.lyon1.common;
import java.io.Serializable; import java.io.Serializable;
import java.util.UUID; import java.util.UUID;
/**
* The base type of message in client/server communication
*/
public class Message implements Serializable { public class Message implements Serializable {
private Channel channel; private Channel channel;
private User sender; private User sender;
private final String content; private final String content;
private final UUID uuid; private final UUID uuid;
/**
* Create a new message with a specified sender
* @param channel the target channel
* @param sender the sender
* @param content the content
*/
public Message(Channel channel, User sender, String content) { public Message(Channel channel, User sender, String content) {
this.uuid = UUID.randomUUID(); this.uuid = UUID.randomUUID();
this.channel = channel; this.channel = channel;
@ -17,6 +25,13 @@ public class Message implements Serializable {
this.content = content; this.content = content;
} }
/**
* Create an existing message
* @param uuid the unique id
* @param channel the channel
* @param sender the sender
* @param content the content
*/
public Message(UUID uuid, Channel channel, User sender, String content) { public Message(UUID uuid, Channel channel, User sender, String content) {
this.uuid = uuid; this.uuid = uuid;
this.channel = channel; this.channel = channel;
@ -24,32 +39,64 @@ public class Message implements Serializable {
this.content = content; this.content = content;
} }
/**
* Create a nex message without specifying the sender
* @param content the content
* @param channel the target channel
*/
public Message(String content, Channel channel) { public Message(String content, Channel channel) {
this.uuid = UUID.randomUUID(); this.uuid = UUID.randomUUID();
this.content = content; this.content = content;
this.channel = channel; this.channel = channel;
} }
/**
* Generate a reply if this message
* This use the same chanel of the original one
* @param user the sender
* @param content the content
* @return the message reply
*/
public Message repley(User user, String content) { public Message repley(User user, String content) {
return new Message(this.channel, user, content); return new Message(this.channel, user, content);
} }
/**
* Change the sender
* @param sender the new sender
*/
public void setSender(User sender) { public void setSender(User sender) {
this.sender = sender; this.sender = sender;
} }
/**
* Get the message channel
* @return the channel
*/
public Channel getChannel() { public Channel getChannel() {
return channel; return channel;
} }
/**
* Get the message sender
* @return the sender
*/
public User getSender() { public User getSender() {
return sender; return sender;
} }
/**
* Get the content of the message
* @return the message content
*/
public String getContent() { public String getContent() {
return content; return content;
} }
/**
* Printable version of the message
* @return the channel, sender and the content
*/
@Override @Override
public String toString() { public String toString() {
if (channel != null) if (channel != null)

View file

@ -2,19 +2,36 @@ package fr.univ.lyon1.common;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import java.io.*; import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Properties; import java.util.Properties;
/**
* The client server configuration
* ToDo should be in gui and not in common ?
*/
public record ServerConfiguration(@NotNull String address, int port) { public record ServerConfiguration(@NotNull String address, int port) {
@NotNull @NotNull
private static final File file = new File("connection.properties"); private static final File file = new File("connection.properties");
/**
* Create a configuration
* @param address the server address
* @param port the server port
*/
public ServerConfiguration(@NotNull String address, int port) { public ServerConfiguration(@NotNull String address, int port) {
this.address = address; this.address = address;
this.port = port; this.port = port;
} }
public static ServerConfiguration load() throws IOException, NumberFormatException { /**
* Load configuration from file
* @return the configuration
* @throws IOException if the file doesn't exist
*/
public static ServerConfiguration load() throws IOException {
// Check if file non exists, return error to launch server configuration // Check if file non exists, return error to launch server configuration
if (!file.exists()) { if (!file.exists()) {
System.out.println("File not exists"); System.out.println("File not exists");
@ -26,6 +43,10 @@ public record ServerConfiguration(@NotNull String address, int port) {
return new ServerConfiguration(properties.getProperty("address"), Integer.parseInt(properties.getProperty("port"))); return new ServerConfiguration(properties.getProperty("address"), Integer.parseInt(properties.getProperty("port")));
} }
/**
* Save configuration to file
* @throws IOException if fail to write the file
*/
public void save() throws IOException { public void save() throws IOException {
@NotNull final Properties properties = new Properties(); @NotNull final Properties properties = new Properties();
properties.setProperty("address", this.address); properties.setProperty("address", this.address);
@ -33,10 +54,18 @@ public record ServerConfiguration(@NotNull String address, int port) {
properties.store(new FileWriter(file), "Information needed to connect to the server"); properties.store(new FileWriter(file), "Information needed to connect to the server");
} }
/**
* Get the server address
* @return the server address
*/
public @NotNull String getAddress() { public @NotNull String getAddress() {
return address; return address;
} }
/**
* Get the server port
* @return the server port
*/
public int getPort() { public int getPort() {
return port; return port;
} }

View file

@ -3,28 +3,52 @@ package fr.univ.lyon1.common;
import java.io.Serializable; import java.io.Serializable;
import java.util.UUID; import java.util.UUID;
/**
* The base type of user for client/server communication
*/
public class User implements Serializable { public class User implements Serializable {
private final UUID uuid; private final UUID uuid;
private String username; private String username;
/**
* Create an existing user
* @param uuid the user unique id
* @param username the username
*/
public User(UUID uuid, String username) { public User(UUID uuid, String username) {
this.uuid = uuid; this.uuid = uuid;
this.username = username; this.username = username;
} }
/**
* Create a new user
* @param username the username
*/
public User(String username) { public User(String username) {
this.uuid = UUID.randomUUID(); this.uuid = UUID.randomUUID();
this.username = username; this.username = username;
} }
/**
* Get the user unique id
* @return thee unique id
*/
public UUID getUUID() { public UUID getUUID() {
return uuid; return uuid;
} }
/**
* Get the username
* @return the username
*/
public String getUsername() { public String getUsername() {
return username; return username;
} }
/**
* The user as a string
* @return the username
*/
@Override @Override
public String toString() { public String toString() {
return username; return username;

View file

@ -4,19 +4,37 @@ import java.io.Serializable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
/**
* Command is the base object transmitted between clients and server
*/
public class Command implements Serializable { public class Command implements Serializable {
private final CommandType type; private final CommandType type;
private final List<Object> args; private final List<Object> args;
/**
* Class need a type and a list of arguments
* @see CommandType
* @param type The type of the command
* @param args A list of arguments for the given command
*/
public Command(CommandType type, List<?> args) { public Command(CommandType type, List<?> args) {
this.type = type; this.type = type;
this.args = (List<Object>) args; this.args = (List<Object>) args;
} }
/**
* Get the type of the command
* @see CommandType
* @return the command type
*/
public CommandType getType() { public CommandType getType() {
return type; return type;
} }
/**
* Get the arguments of the command
* @return A list of arguments
*/
public List<Object> getArgs() { public List<Object> getArgs() {
return new ArrayList<>(args); return new ArrayList<>(args);
} }

View file

@ -2,6 +2,10 @@ package fr.univ.lyon1.common.command;
import java.io.Serializable; import java.io.Serializable;
/**
* List of command types
* @see Command
*/
public enum CommandType implements Serializable { public enum CommandType implements Serializable {
login("login", "Login to the server"), login("login", "Login to the server"),
message("message", "Send a message"), message("message", "Send a message"),
@ -12,15 +16,29 @@ public enum CommandType implements Serializable {
private final String name; private final String name;
private final String description; private final String description;
/**
* A command type is defined by a name and a description
* @param name the command name
* @param description the command description
*/
CommandType(String name, String description) { CommandType(String name, String description) {
this.name = name; this.name = name;
this.description = description; this.description = description;
} }
/**
* Get the name of the command
* @return the command name
*/
public String getName() { public String getName() {
return name; return name;
} }
/**
* Get the description of the command
* @return the command description
*/
public String getDescription() { public String getDescription() {
return description; return description;
} }

View file

@ -1,6 +1,13 @@
package fr.univ.lyon1.common.exception; package fr.univ.lyon1.common.exception;
/**
* Main exception of the chat system for client and server communication
*/
public class ChatException extends Exception { public class ChatException extends Exception {
/**
* This exception need only a message
* @param message the message
*/
public ChatException(String message) { public ChatException(String message) {
super(message); super(message);
} }

View file

@ -1,5 +1,8 @@
package fr.univ.lyon1.common.exception; package fr.univ.lyon1.common.exception;
/**
* Exception when a login/password is invalid
*/
public class LoginInvalid extends ChatException { public class LoginInvalid extends ChatException {
public LoginInvalid(String message) { public LoginInvalid(String message) {
super(message); super(message);

View file

@ -1,5 +1,8 @@
package fr.univ.lyon1.common.exception; package fr.univ.lyon1.common.exception;
/**
* Exception when the user is not logged
*/
public class LoginRequired extends ChatException { public class LoginRequired extends ChatException {
public LoginRequired() { public LoginRequired() {
super("Login required"); super("Login required");

View file

@ -2,6 +2,9 @@ package fr.univ.lyon1.common.exception;
import fr.univ.lyon1.common.Channel; import fr.univ.lyon1.common.Channel;
/**
* Exception sent to a client when he is not in the target channel
*/
public class NotInChannel extends ChatException { public class NotInChannel extends ChatException {
public NotInChannel(Channel channel) { public NotInChannel(Channel channel) {
super("Your not in channel "+channel); super("Your not in channel "+channel);

View file

@ -1,7 +1,8 @@
package fr.univ.lyon1.common.exception; package fr.univ.lyon1.common.exception;
import fr.univ.lyon1.common.command.Command; /**
* Exception when a command is not known by the client or server
*/
public class UnknownCommand extends ChatException { public class UnknownCommand extends ChatException {
public UnknownCommand() { public UnknownCommand() {
super("Command unknown"); super("Command unknown");