Skip to content

Commit

Permalink
Merge branch 'master' into 6-comando-join
Browse files Browse the repository at this point in the history
  • Loading branch information
jdomingu98 committed Mar 22, 2024
2 parents 729e3c5 + d376398 commit 0c841f1
Show file tree
Hide file tree
Showing 22 changed files with 158 additions and 69 deletions.
18 changes: 18 additions & 0 deletions .github/workflows/doesItCompile.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
name: Makefile CI

on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3

- name: Compile it
run: make
4 changes: 4 additions & 0 deletions includes/Server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
# define BUFFER_SIZE 512
# define MAX_CLIENTS 42

class User;
class Channel;

/**
* A class that represents the server.
*/
Expand Down Expand Up @@ -55,6 +58,7 @@ class Server {
bool isNicknameInUse(const std::string& nickname);
bool userHasCheckedPassword(int clientFd);
void removeUser(int clientFd);
void attemptUserRegistration(int clientFd);

void addChannel(Channel channel);
void removeChannel(std::string channelName);
Expand Down
9 changes: 9 additions & 0 deletions includes/User.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@

# include "libsUtils.hpp"
# include "Channel.hpp"
# include "Server.hpp"

# define MAX_CHANNELS 10

class Channel;
class Server;

/**
* A class that represents an user.
Expand All @@ -15,11 +17,13 @@ class User {
private:
int _fd;
bool _passwordChecked;
bool _registered;
std::string _username;
std::string _hostname;
std::string _serverName;
std::string _realName;
std::string _nickname;
std::string _password;
std::vector<Channel> _channels;

std::vector<Channel>::const_iterator findChannel(std::string channelName) const;
Expand All @@ -33,19 +37,24 @@ class User {
// Getters
int getFd() const;
std::string getNickname() const;
std::string getUsername() const;
bool isPasswordChecked() const;
bool isUserInMaxChannels() const;
bool isAlreadyInChannel(std::string channelName) const;
bool isRegistered() const;

// Setters
void setUsername(const std::string& username);
void setHostname(const std::string& hostname);
void setServerName(const std::string& serverName);
void setRealName(const std::string& realName);
void setNickname(const std::string& nickname);
void setPassword(const std::string& password);

// Operations
void checkPassword();
void makeRegistration(Server &server);
bool canRegister();
void joinChannel(Channel channel);
void leaveChannel(std::string channelName);
};
Expand Down
5 changes: 4 additions & 1 deletion includes/commands/ICommand.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ class Server;
* An interface that represents a command that can be executed by the server.
*/
class ICommand {
protected:
bool _needValidate;
public:
virtual void execute(Server &server, int fd) = 0;
virtual void execute(Server &server, int clientFd) = 0;
ICommand(bool needValidate) : _needValidate(needValidate) {};
};

#endif
2 changes: 1 addition & 1 deletion includes/commands/NickCommand.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ class NickCommand : public ICommand {
NickCommand(const std::string& nickname);
~NickCommand();

void execute(Server &server, int fd);
void execute(Server &server, int clientFd);
};

#endif
2 changes: 1 addition & 1 deletion includes/commands/PassCommand.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class PassCommand : public ICommand {
PassCommand(const std::string& password);
~PassCommand();

void execute(Server &server, int fd);
void execute(Server &server, int clientFd);
};

#endif
2 changes: 1 addition & 1 deletion includes/commands/UserCommand.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class UserCommand : public ICommand {
public:
UserCommand();
UserCommand(const std::string& username, const std::string& hostname, const std::string& serverName, const std::string& realName);
void execute(Server &server, int fd);
void execute(Server &server, int clientFd);
~UserCommand();
};

Expand Down
2 changes: 1 addition & 1 deletion includes/exceptions/IRCException.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ class IRCException : public std::exception {
std::string _message;

public:
IRCException(std::string errorCode, const std::string& msg): _errorCode(errorCode), _message(msg) {}
IRCException(std::string errorCode, const std::string& msg) : _errorCode(errorCode), _message(msg) {}
~IRCException() throw() {}

virtual const char* what() const throw() {
Expand Down
2 changes: 1 addition & 1 deletion includes/libsUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

# include "utils.hpp"

#include "exceptions.hpp"
# include "exceptions.hpp"

// =================================================================================

Expand Down
4 changes: 2 additions & 2 deletions includes/parser/CommandParser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ enum Commands {
class CommandParser {
private:
static std::vector<std::string> tokenize(const std::string& command);
static IParser* getParser(std::string command, int fd, Server &server);
static IParser* getParser(std::string command);

public:
static ICommand* parse(const std::string& command, int fd, Server &server);
static ICommand* parse(const std::string& command);
};

#endif
6 changes: 3 additions & 3 deletions includes/parser/QuitParser.hpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
#ifndef QUIT_PARSER_HPP
# define QUIT_PARSER_HPP

#include "IParser.hpp"
# include "IParser.hpp"

#include "QuitCommand.hpp"
# include "QuitCommand.hpp"

#include "libsUtils.hpp"
# include "libsUtils.hpp"

/**
* A class that is responsible for parsing the QUIT command.
Expand Down
15 changes: 12 additions & 3 deletions src/Server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ bool Server::isValidPort(const std::string port) {
*
* @throws `ServerException` if the port is out of range.
*/
Server::Server(const std::string port, const std::string password): _password(password) {
Server::Server(const std::string port, const std::string password) : _password(password) {
if (!this->isValidPort(port))
throw ServerException(PORT_OUT_OF_RANGE_ERR);
_port = std::atoi(port.c_str());
Expand Down Expand Up @@ -169,7 +169,7 @@ void Server::handleExistingConnection(int clientFd) {
return;

try {
ICommand* command = CommandParser::parse(std::string(buffer, readBytes), clientFd, *this);
ICommand* command = CommandParser::parse(std::string(buffer, readBytes));
command->execute(*this, clientFd);
} catch (IRCException& e) {
std::string clientNickname = getUserByFd(clientFd).getNickname();
Expand All @@ -185,7 +185,7 @@ void Server::handleExistingConnection(int clientFd) {
}

/**
* This function aims to validate the password provided by the client.
* This function validates if the user's password is the same as the server's password.
*
* @param password The password provided by the client.
* @return `true` if the password is valid, `false` otherwise.
Expand Down Expand Up @@ -256,6 +256,15 @@ void Server::removeUser(int fd) {
}
}

/**
* This function attempt to register a user.
*
* @param clientFd The file descriptor of the user.
*/
void Server::attemptUserRegistration(int clientFd) {
this->getUserByFd(clientFd).makeRegistration(*this);
}

/**
* This function aims to find a user by the file descriptor.
*
Expand Down
58 changes: 53 additions & 5 deletions src/User.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*
* @param fd The file descriptor of the user
*/
User::User(int fd): _fd(fd), _passwordChecked(false) {}
User::User(int fd) : _fd(fd), _passwordChecked(false) {}

/**
* User destructor
Expand Down Expand Up @@ -91,6 +91,15 @@ int User::getFd() const {

/**
* This function aims to get the username of the user.
*
* @return The username of the user.
*/
std::string User::getUsername() const {
return this->_username;
}

/**
* This function aims to set the username of the user.
*
* @param username The username of the user.
*/
Expand All @@ -99,7 +108,7 @@ void User::setUsername(const std::string& username) {
}

/**
* This function aims to get the hostname of the user.
* This function aims to set the hostname of the user.
*
* @param hostname The hostname of the user.
*/
Expand All @@ -108,7 +117,7 @@ void User::setHostname(const std::string& hostname) {
}

/**
* This function aims to get the server name of the user.
* This function aims to set the server name of the user.
*
* @param serverName The server name of the user.
*/
Expand All @@ -117,7 +126,7 @@ void User::setServerName(const std::string& serverName) {
}

/**
* This function aims to get the real name of the user.
* This function aims to set the real name of the user.
*
* @param realName The real name of the user.
*/
Expand All @@ -137,11 +146,50 @@ std::string User::getNickname() const {
/**
* This function aims to set the nickname of the user.
*
* @param nickname The nickname of the user.
*/
void User::setNickname(const std::string& nickname){
void User::setNickname(const std::string& nickname) {
this->_nickname = nickname;
}

/**
* This function aims to set the password of the user.
*
* @param password The password the user wants to use.
*/
void User::setPassword(const std::string& password) {
this->_password = password;
}

/**
* This function aims to check if the user can register.
*
* @return `true` if the user can register, `false` otherwise.
*/
bool User::canRegister() {
return !(this->_username.empty() || this->_hostname.empty() ||
this->_serverName.empty() || this->_realName.empty() || this->_nickname.empty());
}

/**
* This function try to register the user and verify that it is the same password as on the server.
*
* @param server The server where the user is trying to register.
*/
void User::makeRegistration(Server &server) {
if (!server.isValidPassword(_password))
throw PasswordMismatchException();
this->_registered = true;
}

/**
* This function aims to check if the user has registered.
*
* @return `true` if the user has registered, `false` otherwise.
*/
bool User::isRegistered() const {
return this->_registered;
}

/**
* This function aims to join a channel.
Expand Down
26 changes: 15 additions & 11 deletions src/commands/NickCommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
/**
* NickCommand default constructor.
*/
NickCommand::NickCommand(): _nickname("") {}
NickCommand::NickCommand() : ICommand(false), _nickname("") {}

/**
* NickCommand nickname constructor.
*
* @param nickname The nickname
*/
NickCommand::NickCommand(const std::string& nickname): _nickname(nickname) {}
NickCommand::NickCommand(const std::string& nickname) : ICommand(false), _nickname(nickname) {}

/**
* NickCommand destructor.
Expand All @@ -21,31 +21,35 @@ NickCommand::~NickCommand() {}
* Execute the command NICK.
*
* @param server The server where the command will be executed
* @param fd The socket file descriptor of the client
* @param clientFd The socket file descriptor of the client
*
* @throws `CommandException` If the nickname is empty, too long, already in use or invalid
* @throws `NoNicknameGivenException` If the nickname is empty
* @throws `ErroneousNicknameException` If the nickname is too long or invalid
* @throws `NickCollisionException` If the nickname is already in use and the user is not registered
* @throws `NicknameInUseException` If the nickname is already in use and the user is registered
*
*/
void NickCommand::execute(Server &server, int fd) {
void NickCommand::execute(Server &server, int clientFd) {
if (this->_nickname.empty())
throw NoNicknameGivenException();

if (this->_nickname.size() > MAX_NICKNAME_SIZE)
throw ErroneousNicknameException(this->_nickname);

if (server.isNicknameInUse(this->_nickname)) {
// TODO: If user is not registered, we throw NickCollisionException
throw NickCollisionException(this->_nickname);
// TODO: If user is registered, we throw NicknameInUseException
// throw NicknameInUseException(_nickname);
User &user = server.getUserByFd(clientFd);

if (server.isNicknameInUse(this->_nickname)) {
user.isRegistered()
? throw NicknameInUseException(this->_nickname)
: throw NickCollisionException(this->_nickname);
}

if (!NickCommand::isValidNickname())
throw ErroneousNicknameException(this->_nickname);

User user = server.getUserByFd(fd);
user.setNickname(this->_nickname);
if (user.canRegister())
server.attemptUserRegistration(clientFd);
}

/**
Expand Down
Loading

0 comments on commit 0c841f1

Please sign in to comment.