Skip to content

Commit

Permalink
chore: merge pull request #53 from ygor-sena/test/client-irc-connection
Browse files Browse the repository at this point in the history
refactor: add finished README and UTs formatting
  • Loading branch information
ygor-sena authored Jun 3, 2024
2 parents d820dfd + de9f944 commit 197c53e
Show file tree
Hide file tree
Showing 19 changed files with 299 additions and 96 deletions.
134 changes: 132 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,132 @@
# 42cursus-ft-irc
The 12th project of 42's curriculum is about creating our own IRC server. An actual IRC client will be used to connect to the server and test it. nternet is ruled by solid standards protocols that allow connected computers to interact with each other. It’s always a good thing to know.
<p align="center">
<img src="https://github.com/ygor-sena/42cursus-ft-irc/assets/102881479/51bb7248-3bc7-4fb0-9e41-c71bedb7b3d4">
</p>

<p align="center">
<img src="https://img.shields.io/badge/OS-Linux-blue" alt="OS">
<img src="https://img.shields.io/badge/Language-C%2B%2B98-blue.svg" alt="Language">
<img src="https://img.shields.io/badge/Grade-125%2F125-brightgreen.svg" alt="Grade">
<img src="https://img.shields.io/badge/Status-Completed-brightgreen.svg" alt="Status">
</p>


📣 Introduction
---------------
The 12th project of 42's curriculum is about creating our own IRC server. An actual IRC client will be used to connect to the server and test it. Internet is ruled by solid standards protocols that allow connected computers to interact with each other. It’s always a good thing to know.

📜 Requirements
---------------

We have implemented both the mandatory and bonus requirements of this project. The following table summarizes all the possible commands that our IRC server is capable of processing.

|Command|Usage|Flags|Description|
|:--|:--|:--|:--|
|`PASS`| `PASS <password> `|- |Connect to the IRC server by providing a password.|
|`USER`| `USER <username> `| - | Create a new username. |
|`NICK`|`NICK <nickname> ` | - | Create a new nickname.|
|`JOIN`|`JOIN <channel> [<key>]` | - | Join a channel, if it already exists, otherwise create a new channel. It's also possible to provide a key (password) to access the channel.|
|`INVITE`|`INVITE <nickname> <channel>` | - | Invite a client to a channel.|
|`TOPIC`| `TOPIC <channel> [<topic>]`| - | Change or view the channel topic.|
|`PRIVMSG`| `PRIVMSG <receiver>{,<receiver>} <text to be sent>`| - | Sends a message to one or more clients or channels. If there are more than one receiver, they must be separated by `,`.|
|`MODE`| `MODE <channel> <flag> [<limit>] [<user>]`| `+i` or `-i` | Change the channel's mode. This flag sets/removes Invite-only channel.|
|`MODE`| `MODE <channel> <flag> [<limit>] [<user>]`| `+t` or `-t` | Change the channel's mode. This flag sets/removes the restrictions of the `TOPIC` command to channel operators. |
|`MODE`| `MODE <channel> <flag> [<limit>] [<user>]`| `+k` or `-k` | Change the channel's mode. This flag sets/removes the channel key. |
|`MODE`| `MODE <channel> <flag> [<limit>] [<user>]`| `+o` or `-o` | Change the channel's mode. This flag gives/takes channel operator privilege. |
|`MODE`| `MODE <channel> <flag> [<limit>] [<user>]`| `+l` or `-l` | Change the channel's mode. This flag sets/removes the user limit to channel. |
|`PART`| `PART <channel>`| - | Leave a channel.|
|`KICK`| `KICK <channel> <user> [<comment>]`| - | Eject a client from the channel. It's also possible to provide a commentary.|
|`QUIT`| `QUIT`| - | Closes the IRC server connection.|
|`MARVINBOT`| `MARVINBOT <flag>` |`marvin`| Marvin presents himself!|
|`MARVINBOT`| `MARVINBOT <flag>`| `quote` | Marvin recites a philosophy quote!|
|`MARVINBOT`| `MARVINBOT <flag>`| `time` | Marvin answers the current time.|
|`MARVINBOT`| `MARVINBOT <flag>`| `whoami` | Marvin answers who you are.|
|`MARVINBOT`| `MARVINBOT <flag>` |`whois` | Marvin gets information about other clients logged on the IRC server.|

>[!IMPORTANT]
> Some command have to meet some requirements for its usage by the client:
> - To execute the command `KICK` and `MODE`, the client must have channel operator privileges.
> - To execute the command `MARVINBOT`, the client must have joined at least one channel.
> - If the command requires a channel, the channel name must begin with `#`.
⚒️ How to compile and run the project
-------------------------------------

#### 1) Copy this repository to your local workstation

```
git clone https://github.com/ygor-sena/42cursus-miniRT.git
```

#### 2) Install the required libraries to run the project and the unit tests

```
sudo apt-get install libcriterion-dev
```

>[!NOTE]
>If your operating system is different than Ubuntu `version >= 21.04`, then check the official documentation about how to proceed with Criterion framework installation [here](https://github.com/Snaipe/Criterion.git).
#### 3) Compile the project with Makefile

```
make
```

To compile and execute the tests, just run `make` inside the folder `42-IRC/tests`.

#### 4) Launch the IRC server

To launch the IRC server, you must provide a port number and a password. For example, the command below launches the IRC server to listen to port number `4444` and the password to access it is `12345`.

```
./ircserv 4444 12345
```

#### 5) Connect one or more clients to the IRC server and have fun!

There are two ways to connect a client to the IRC server: via CLI or IRC client of your choice.

> [!NOTE]
> We used [Hexchat](https://hexchat.github.io/) as **our** IRC client of reference. Therefore, we recommend that you use it as well if you want to connect to the IRC server using a GUI. Check its official documentation about how to install Hexchat IRC client on you local machine [here](https://hexchat.github.io/downloads.html).
To connect to the IRC server on port number 4444 using the command line, open a new terminal and run the following command:

```
nc localhost 4444
```

To use the server, you will have to authenticate the client connection by providing a password and registering the client on the server by creating an username and a nickname. For example:

```
PASS 12345
USER username
NICK nickname
```

After that, the client is allowed to use all the other IRC command implemented for this project as specified [here](https://github.com/ygor-sena/42cursus-ft-irc?tab=readme-ov-file#-requirements).

To connect to the IRC server using Hexchat, you have to create a new network called `localhost/4444` and select the following options:
- [X] Connect to selected server only
- [X] Connect to this network automatically
- [X] Accept invalid SSL certificates
- Login method: Server password (/PASS password)
- Last but not least, fill the fields `Nick name`, `Second choice`, `Real name`, `User name` and `Password`

After the setting, you can click on `Connect` to connect with the IRC server and use the implemented commands on the prompt command line. Since the file management is done by IRC clients, it's possible to send a file from a client to another one if both clients are using Hexchat.

📖 References
--------------

Main references:
- [Internet Relay Chat](https://chi.cs.uchicago.edu/chirc/irc.html) by The UChicago χ-Projects.
- [RFC 1459 - Internet Relay Chat Protocol](https://datatracker.ietf.org/doc/html/rfc1459#section-4.2.7) by J. Oikarinen and D. Reed.
- [Small IRC Server \[ft_irc 42 network\]](https://medium.com/@afatir.ahmedfatir/small-irc-server-ft-irc-42-network-7cee848de6f9) by Ahmed Fatir.

About network programming:
- [Beej's Guide to Network Programming](https://beej.us/guide/bgnet/html/split-wide/index.html) by Brian “Beej Jorgensen” Hall.
- [Sockets and Network Programming in C](https://www.codequoi.com/en/sockets-and-network-programming-in-c/) by Mia Combeau.
- [Sockets in Computer Network](https://www.geeksforgeeks.org/socket-in-computer-network/) by [GeeksforGeeks](https://www.geeksforgeeks.org/).

About recommended design patterns for this project:
- Many-to-many relationships: [Mediator Design Pattern in C++](https://www.vishalchovatiya.com/mediator-design-pattern-in-modern-cpp/) by [Vishal Chovativa](https://www.vishalchovatiya.com/)
- One-to-many relationships: [Observer Design Pattern in C++](https://www.vishalchovatiya.com/observer-design-pattern-in-modern-cpp/) by [Vishal Chovativa](https://www.vishalchovatiya.com/)
4 changes: 2 additions & 2 deletions include/Channel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
* @class Channel
* @brief Represents a channel in an IRC server.
*
* The Channel class provides functionality to manage clients, set channel properties,
* and perform various operations within the channel.
* The Channel class provides functionality to manage clients, set channel
* properties, and perform various operations within the channel.
*/
class Channel
{
Expand Down
16 changes: 8 additions & 8 deletions include/Client.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,16 @@
* @brief The Client class represents a client connected to the IRC server.
*
* This class provides methods to get and set various properties of the client,
* such as file descriptor, login status, operator status, authentication status,
* buffer, nickname, username, password, hostname, IP address, registration status,
* and channels invited.
* such as file descriptor, login status, operator status, authentication
* status, buffer, nickname, username, password, hostname, IP address,
* registration status, and channels invited.
*
* It also provides methods to check if the client is invited to a specific channel,
* add a channel to the list of invited channels, and remove a channel from the list
* of invited channels.
* It also provides methods to check if the client is invited to a specific
* channel, add a channel to the list of invited channels, and remove a channel
* from the list of invited channels.
*
* Additionally, it provides a method to broadcast a message to all clients except
* the sender.
* Additionally, it provides a method to broadcast a message to all clients
* except the sender.
*/
class Client
{
Expand Down
11 changes: 6 additions & 5 deletions include/MarvinBot.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,18 @@
* @class MarvinBot
* @brief Represents a MarvinBot object.
*
* The MarvinBot class is responsible for managing quotes and returning a random quote from a predefined list.
* The MarvinBot class is responsible for managing quotes and returning a random
* quote from a predefined list.
*/
class MarvinBot
{
public:
MarvinBot();
~MarvinBot();

/**
* @brief Enum for quotes.
*/
/**
* @brief Enum for quotes.
*/
enum EnumMarvinBotQuotes
{
QUOTE_SOCRATES_KNOWLEDGE,
Expand All @@ -60,7 +61,7 @@ class MarvinBot
QUOTE_HUME_SCIENCE,
QUOTE_HEIDEGGER_BEING,
QUOTE_ROUSSEAU_FREEDOM,
QUOTES_COUNT
QUOTES_COUNT
};

const char* marvin_bot_quotes[QUOTES_COUNT];
Expand Down
5 changes: 3 additions & 2 deletions include/Server.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,9 @@
* @class Server
* @brief Represents an IRC server.
*
* The Server class provides functionality to initialize and manage an IRC server.
* It handles client connections, IRC commands, channels, and server operations.
* The Server class provides functionality to initialize and manage an IRC
* server. It handles client connections, IRC commands, channels, and server
* operations.
*/
class Server
{
Expand Down
6 changes: 2 additions & 4 deletions src/commands/Quit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
/* ::: :::::::: */
/* Quit.cpp :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: gilmar <gilmar@student.42.fr> +#+ +:+ +#+ */
/* By: yde-goes <yde-goes@student.42sp.org.br> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2024/05/21 08:29:45 by gilmar #+# #+# */
/* Updated: 2024/06/01 09:02:49 by gilmar ### ########.fr */
/* Updated: 2024/06/03 13:21:27 by yde-goes ### ########.fr */
/* */
/* ************************************************************************** */

Expand Down Expand Up @@ -43,8 +43,6 @@ void Server::_handler_client_quit(const std::string& /* buffer */, const int fd)
if (channel->has_client(client))
{
channel->quit(client);
if (channel->get_channel_clients().size() == 0)
delete channel;
}
}

Expand Down
3 changes: 2 additions & 1 deletion tests/TestInvite.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,8 @@ Test(InviteCommand, err_nosuchnick)
}

/**
* @brief Test case for the error when the client does not have sufficient privileges.
* @brief Test case for the error when the client does not have sufficient
* privileges.
*/
Test(InviteCommand, err_noprivileges)
{
Expand Down
21 changes: 14 additions & 7 deletions tests/TestJoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,8 @@ Test(JoinCommand, channel_created)
}

/**
* @brief Test case for the JOIN command when the client is already in the channel.
* @brief Test case for the JOIN command when the client is already in the
* channel.
*/
Test(JoinCommand, err_alreadyregistered)
{
Expand Down Expand Up @@ -236,7 +237,8 @@ Test(JoinCommand, err_inviteonlychan_not_invited)
}

/**
* @brief Test case for the JOIN command when the client is not invited to the invite-only channel.
* @brief Test case for the JOIN command when the client is not invited to the
* invite-only channel.
*/
Test(JoinCommand, inviteonlychan_invited)
{
Expand Down Expand Up @@ -268,7 +270,8 @@ Test(JoinCommand, inviteonlychan_invited)
}

/**
* @brief Test case for the JOIN command when the client is not invited to the invite-only channel.
* @brief Test case for the JOIN command when the client is not invited to the
* invite-only channel.
*/
Test(JoinCommand, inviteonlychan_invited_with_key)
{
Expand Down Expand Up @@ -301,7 +304,8 @@ Test(JoinCommand, inviteonlychan_invited_with_key)
}

/**
* @brief Test case for the JOIN command when the client is invited to the invite-only channel.
* @brief Test case for the JOIN command when the client is invited to the
* invite-only channel.
*/
Test(JoinCommand, err_invite_only_badchannelkey)
{
Expand Down Expand Up @@ -334,7 +338,8 @@ Test(JoinCommand, err_invite_only_badchannelkey)
}

/**
* @brief Test case for the JOIN command when the client enters the invite-only channel with the correct key.
* @brief Test case for the JOIN command when the client enters the invite-only
* channel with the correct key.
*/
Test(JoinCommand, err_badchannelkey)
{
Expand Down Expand Up @@ -363,7 +368,8 @@ Test(JoinCommand, err_badchannelkey)
}

/**
* @brief Test case for the JOIN command when the client enters the channel with a key.
* @brief Test case for the JOIN command when the client enters the channel with
* a key.
*/
Test(JoinCommand, channel_with_key)
{
Expand Down Expand Up @@ -392,7 +398,8 @@ Test(JoinCommand, channel_with_key)
}

/**
* @brief Test case for the JOIN command when the client enters the channel without a key.
* @brief Test case for the JOIN command when the client enters the channel
* without a key.
*/
Test(JoinCommand, channel_without_key)
{
Expand Down
3 changes: 2 additions & 1 deletion tests/TestMarvinBot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ Client* mockClient()
}

/**
* @brief Test case for the MarvinBotCommand when the user is not in any channel.
* @brief Test case for the MarvinBotCommand when the user is not in any
* channel.
*/
Test(MarvinBotCommand, user_is_not_in_any_channel)
{
Expand Down
Loading

0 comments on commit 197c53e

Please sign in to comment.