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\TeamExecutive.cpp" />
<ClCompile Include="models\Ticket.cpp" />
<ClCompile Include="services\ApplicationConfig.cpp" />
<ClCompile Include="services\AttendanceManagementService.cpp" />
<ClCompile Include="services\AuthenticationManagementService.cpp" />
<ClCompile Include="services\BookingManagementService.cpp" />
@@ -199,6 +200,7 @@
<ClInclude Include="models\Team.h" />
<ClInclude Include="models\TeamExecutive.h" />
<ClInclude Include="models\Ticket.h" />
<ClInclude Include="services\ApplicationConfig.h" />
<ClInclude Include="services\AttendanceManagementService.h" />
<ClInclude Include="services\AuthenticationManagementService.h" />
<ClInclude Include="services\BookingManagementService.h" />
@@ -1 +1,15 @@
#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 "TeamManagementService.h"
#include "TicketManagementService.h"
#include "Enums.h"
using AuthenticationContext = std::tuple<Enums::LoginStatus, Enums::EmployeeType, Enums::EmployeeDesignation>;
class ZenvyController
{
@@ -37,5 +40,9 @@ public:
m_talentAcquisitionManagementService(std::make_shared<TalentAcquisitionManagementService>()),
m_teamManagementService(std::make_shared<TeamManagementService>()),
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;
}
void DataStore::setAuthenticatedEmployee(std::shared_ptr<Employee> authenticatedEmployee)
{
m_authenticatedEmployee = authenticatedEmployee;
}
employeeMap& DataStore::getEmployees()
{
return m_employees;
@@ -37,4 +37,5 @@ public:
DataStore& operator=(DataStore&&) = delete;
employeeMap& getEmployees();
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 "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 <utility>
#include "DataStore.h"
#include "Enums.h"
class AuthenticationManagementService
{
@@ -10,6 +11,7 @@ private:
DataStore& m_dataStore;
public:
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 changePassword();
};
@@ -66,7 +66,8 @@ namespace Enums {
{
JUNIOR,
SENIOR,
TEAM_LEAD
TEAM_LEAD,
INVALID
};
enum class EmployeeType
@@ -76,6 +77,7 @@ namespace Enums {
FINANCE,
TAG,
HR,
TEAM,
ADMIN,
INVALID
};
@@ -1,4 +1,19 @@
#include <iostream>
#include <utility>
#include <memory>
#include <stdexcept>
#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()
{
@@ -42,4 +57,95 @@ bool UserInterface::handleOperation(int choice)
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
#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
{