Add authentication flow, UI menu routing, and application config

<UserStory>AUTH001 : Login </UserStory>

<Changes>
- Introduced ApplicationConfig for default configuration values
- Implemented authentication flow in AuthenticationManagementService
- Added login and logout handling in ZenvyController
- Updated enums to include INVALID values and TEAM employee type
- Implemented login UI flow with role-based menu routing
</Changes>

<Review>
Smitha Mohan
</Review>
This commit is contained in:
2026-04-06 11:49:57 +05:30
parent 02c4f1a954
commit d76def42e9
12 changed files with 194 additions and 16 deletions
@@ -146,6 +146,7 @@
<ClCompile Include="models\Team.cpp" /> <ClCompile Include="models\Team.cpp" />
<ClCompile Include="models\TeamExecutive.cpp" /> <ClCompile Include="models\TeamExecutive.cpp" />
<ClCompile Include="models\Ticket.cpp" /> <ClCompile Include="models\Ticket.cpp" />
<ClCompile Include="services\ApplicationConfig.cpp" />
<ClCompile Include="services\AttendanceManagementService.cpp" /> <ClCompile Include="services\AttendanceManagementService.cpp" />
<ClCompile Include="services\AuthenticationManagementService.cpp" /> <ClCompile Include="services\AuthenticationManagementService.cpp" />
<ClCompile Include="services\BookingManagementService.cpp" /> <ClCompile Include="services\BookingManagementService.cpp" />
@@ -199,6 +200,7 @@
<ClInclude Include="models\Team.h" /> <ClInclude Include="models\Team.h" />
<ClInclude Include="models\TeamExecutive.h" /> <ClInclude Include="models\TeamExecutive.h" />
<ClInclude Include="models\Ticket.h" /> <ClInclude Include="models\Ticket.h" />
<ClInclude Include="services\ApplicationConfig.h" />
<ClInclude Include="services\AttendanceManagementService.h" /> <ClInclude Include="services\AttendanceManagementService.h" />
<ClInclude Include="services\AuthenticationManagementService.h" /> <ClInclude Include="services\AuthenticationManagementService.h" />
<ClInclude Include="services\BookingManagementService.h" /> <ClInclude Include="services\BookingManagementService.h" />
@@ -1 +1,15 @@
#include "ZenvyController.h" #include "ZenvyController.h"
//Authentication
AuthenticationContext ZenvyController::login(const std::string& email, const std::string& password)
{
return m_authenticationManagementService->login(email, password);
}
void ZenvyController::logout()
{
}
void AuthenticationManagementService::changePassword()
{
}
@@ -11,6 +11,9 @@
#include "TalentAcquisitionManagementService.h" #include "TalentAcquisitionManagementService.h"
#include "TeamManagementService.h" #include "TeamManagementService.h"
#include "TicketManagementService.h" #include "TicketManagementService.h"
#include "Enums.h"
using AuthenticationContext = std::tuple<Enums::LoginStatus, Enums::EmployeeType, Enums::EmployeeDesignation>;
class ZenvyController class ZenvyController
{ {
@@ -37,5 +40,9 @@ public:
m_talentAcquisitionManagementService(std::make_shared<TalentAcquisitionManagementService>()), m_talentAcquisitionManagementService(std::make_shared<TalentAcquisitionManagementService>()),
m_teamManagementService(std::make_shared<TeamManagementService>()), m_teamManagementService(std::make_shared<TeamManagementService>()),
m_ticketManagementService(std::make_shared<TicketManagementService>()) {}; m_ticketManagementService(std::make_shared<TicketManagementService>()) {};
//Authentication
AuthenticationContext login(const std::string& email, const std::string& password);
void logout();
}; };
@@ -11,6 +11,11 @@ logMap& DataStore::getLogs()
return m_logs; return m_logs;
} }
void DataStore::setAuthenticatedEmployee(std::shared_ptr<Employee> authenticatedEmployee)
{
m_authenticatedEmployee = authenticatedEmployee;
}
employeeMap& DataStore::getEmployees() employeeMap& DataStore::getEmployees()
{ {
return m_employees; return m_employees;
@@ -37,4 +37,5 @@ public:
DataStore& operator=(DataStore&&) = delete; DataStore& operator=(DataStore&&) = delete;
employeeMap& getEmployees(); employeeMap& getEmployees();
logMap& getLogs(); logMap& getLogs();
void setAuthenticatedEmployee(std::shared_ptr < Employee>);
}; };
@@ -0,0 +1 @@
#include "ApplicationConfig.h"
@@ -0,0 +1,6 @@
#pragma once
namespace Config
{
constexpr const char* DEFAULT_PASSWORD = "password";
}
@@ -1,2 +1,48 @@
#include <stdexcept>
#include "AuthenticationManagementService.h" #include "AuthenticationManagementService.h"
#include "ApplicationConfig.h"
std::tuple<Enums::LoginStatus, Enums::EmployeeType, Enums::EmployeeDesignation> AuthenticationManagementService::login(const std::string& email, const std::string& password)
{
employeeMap& employees = m_dataStore.getEmployees();
Enums::LoginStatus loginStatus = Enums::LoginStatus::USER_NOT_FOUND;
Enums::EmployeeType employeeType = Enums::EmployeeType::INVALID;
Enums::EmployeeDesignation employeeDesignation = Enums::EmployeeDesignation::INVALID;
for (const auto& employee : employees)
{
if (employee.second->getEmployeeEmail() == email)
{
if (employee.second->getEmployeePassword() == password)
{
if (password == Config::DEFAULT_PASSWORD)
{
loginStatus = Enums::LoginStatus::FIRST_LOGIN;
}
else
{
loginStatus = Enums::LoginStatus::SUCCESS;
}
employeeType = employee.second->getEmployeeType();
if (employeeType == Enums::EmployeeType::GENERAL)
{
std::shared_ptr<GeneralEmployee> generalEmployee = std::dynamic_pointer_cast<GeneralEmployee>(employee.second);
if (generalEmployee)
{
employeeDesignation = generalEmployee->getDesignation();
}
else
{
throw std::runtime_error("Invalid Employee Type");
}
}
m_dataStore.setAuthenticatedEmployee(employee.second);
}
else
{
loginStatus = Enums::LoginStatus::INVALID_PASSWORD;
}
break;
}
}
return std::make_tuple(loginStatus, employeeType, employeeDesignation);
}
@@ -3,6 +3,7 @@
#include <map> #include <map>
#include <utility> #include <utility>
#include "DataStore.h" #include "DataStore.h"
#include "Enums.h"
class AuthenticationManagementService class AuthenticationManagementService
{ {
@@ -10,6 +11,7 @@ private:
DataStore& m_dataStore; DataStore& m_dataStore;
public: public:
AuthenticationManagementService() : m_dataStore(DataStore::getInstance()) {}; AuthenticationManagementService() : m_dataStore(DataStore::getInstance()) {};
std::tuple<Enums::LoginStatus, Enums::EmployeeType, Enums::EmployeeDesignation> login(const std::string& username, const std::string& password);
void logout(); void logout();
void changePassword(); void changePassword();
}; };
@@ -66,7 +66,8 @@ namespace Enums {
{ {
JUNIOR, JUNIOR,
SENIOR, SENIOR,
TEAM_LEAD TEAM_LEAD,
INVALID
}; };
enum class EmployeeType enum class EmployeeType
@@ -76,6 +77,7 @@ namespace Enums {
FINANCE, FINANCE,
TAG, TAG,
HR, HR,
TEAM,
ADMIN, ADMIN,
INVALID INVALID
}; };
@@ -1,4 +1,19 @@
#include <iostream>
#include <utility>
#include <memory>
#include <stdexcept>
#include "UserInterface.h" #include "UserInterface.h"
#include "AdminMenu.h"
#include "EmployeeMenu.h"
#include "FinanceExecutiveMenu.h"
#include "HRManagerMenu.h"
#include "ITExecutiveMenu.h"
#include "TalentExecutiveMenu.h"
#include "TeamExecutiveMenu.h"
#include "TeamLeadMenu.h"
#include "ZenvyController.h"
#include "InputHelper.h"
#include "OutputHelper.h"
void UserInterface::run() void UserInterface::run()
{ {
@@ -42,4 +57,95 @@ bool UserInterface::handleOperation(int choice)
void UserInterface::login() void UserInterface::login()
{ {
} std::string email, password;
util::clear();
std::cout << "Enter email: ";
util::read(email);
std::cout << "Enter password: ";
util::read(password);
AuthenticationContext authenticationContext = m_controller->login(email, password);
Enums::LoginStatus loginStatus = std::get<0>(authenticationContext);
Enums::EmployeeType employeeType = std::get<1>(authenticationContext);
Enums::EmployeeDesignation employeeDesignation = std::get<2>(authenticationContext);
if (loginStatus == Enums::LoginStatus::USER_NOT_FOUND)
{
std::cout << "Error: User Not Found! Try Again\n";
util::pressEnter();
return;
}
if (loginStatus == Enums::LoginStatus::INVALID_PASSWORD)
{
std::cout << "Error: Invalid Password! Try Again\n";
util::pressEnter();
return;
}
if (loginStatus == Enums::LoginStatus::FIRST_LOGIN)
{
util::clear();
std::cout
<< "Warning: You're using the default password!\n"
<< "Please change it.\n";
// TODO: Password reset flow (to be implemented)
util::pressEnter();
}
util::clear();
// Route to appropriate menu
switch (employeeType)
{
case Enums::EmployeeType::ADMIN:
{
AdminMenu menu;
menu.run();
break;
}
case Enums::EmployeeType::HR:
{
HRManagerMenu menu;
menu.run();
break;
}
case Enums::EmployeeType::FINANCE:
{
FinanceExecutiveMenu menu;
menu.run();
break;
}
case Enums::EmployeeType::IT:
{
ITExecutiveMenu menu;
menu.run();
break;
}
case Enums::EmployeeType::TEAM:
{
TeamExecutiveMenu menu;
menu.run();
break;
}
case Enums::EmployeeType::TAG:
{
TalentExecutiveMenu menu;
menu.run();
break;
}
case Enums::EmployeeType::GENERAL:
{
if (employeeDesignation == Enums::EmployeeDesignation::TEAM_LEAD)
{
TeamLeadMenu menu;
menu.run();
}
else
{
EmployeeMenu menu;
menu.run();
}
break;
}
default:
throw std::runtime_error("Error: Unsupported employee type!\n");
util::pressEnter();
break;
}
m_controller->logout();
}
@@ -1,18 +1,4 @@
#pragma once #pragma once
#include <iostream>
#include <memory>
#include <utility>
#include "AdminMenu.h"
#include "EmployeeMenu.h"
#include "FinanceExecutiveMenu.h"
#include "HRManagerMenu.h"
#include "ITExecutiveMenu.h"
#include "TalentExecutiveMenu.h"
#include "TeamExecutiveMenu.h"
#include "TeamLeadMenu.h"
#include "ZenvyController.h"
#include "InputHelper.h"
#include "OutputHelper.h"
class UserInterface class UserInterface
{ {