241 lines
5.7 KiB
C++
241 lines
5.7 KiB
C++
#include "include/Utils/Utils.h"
|
|
#include "boost/random.hpp"
|
|
|
|
|
|
namespace SE
|
|
{
|
|
std::vector<std::string> TSimpleAutorizator::UserPasswords;
|
|
|
|
boost::mutex TSimpleAutorizator::UserPasswordsMutex;
|
|
|
|
|
|
std::string TSimpleAutorizator::GenerateRandomPassword()
|
|
{
|
|
boost::random::mt19937 RandomGenerator;
|
|
|
|
RandomGenerator.seed(static_cast<unsigned int>(std::time(0)));
|
|
|
|
static const int passwordLength = 18;
|
|
static const std::string symbols = "1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!()-=_+[]{};:,.?";
|
|
|
|
std::string result;
|
|
|
|
boost::random::uniform_int_distribution<> symbolRandom(0, symbols.size()-1);
|
|
|
|
for (size_t i = 0; i < passwordLength; i++)
|
|
{
|
|
result += symbols[symbolRandom(RandomGenerator)];
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
TSimpleAutorizator::TSimpleAutorizator(boost::asio::io_service& ioService, boost::asio::ip::tcp::socket& socket)
|
|
: IoService(ioService)
|
|
, Socket(socket)
|
|
{
|
|
|
|
}
|
|
|
|
|
|
void TSimpleAutorizator::StartListen()
|
|
{
|
|
boost::shared_ptr<TDataReader> dataReader(new TDataReader(Socket));
|
|
|
|
dataReader->DataReadSignalMap.AddSlot("Hello", boost::bind(&TSimpleAutorizator::HandleGetRegisterRequest, this, _1));
|
|
dataReader->DataReadSignalMap.AddSlot("HelloAgain", boost::bind(&TSimpleAutorizator::HandleGetLoginRequest, this, _1));
|
|
|
|
dataReader->ErrorSignal.connect(ErrorSignal);
|
|
|
|
dataReader->StartReadOnce();
|
|
|
|
}
|
|
|
|
|
|
void TSimpleAutorizator::HandleGetRegisterRequest(boost::property_tree::ptree pTree)
|
|
{
|
|
|
|
CreateNewUser();
|
|
}
|
|
|
|
void TSimpleAutorizator::HandleGetLoginRequest(boost::property_tree::ptree pTree)
|
|
{
|
|
std::string login = pTree.get<std::string>("Login");
|
|
std::string password = pTree.get<std::string>("Password");
|
|
|
|
int loginNum = boost::lexical_cast<int>(login);
|
|
|
|
bool loginIsValid = loginNum < UserPasswords.size();
|
|
|
|
if (!loginIsValid)
|
|
{
|
|
CreateNewUser();
|
|
return;
|
|
}
|
|
|
|
bool passwordIsValid = UserPasswords[loginNum] == password;
|
|
|
|
if (!passwordIsValid)
|
|
{
|
|
CreateNewUser();
|
|
return;
|
|
}
|
|
|
|
//Login and password are ok
|
|
boost::property_tree::ptree pt;
|
|
|
|
pt.put("OnHello.Login", login);
|
|
pt.put("OnHello.Password", password);
|
|
|
|
SendPropertyTree(IoService, Socket, pt);
|
|
|
|
AllowedSignal(login);
|
|
|
|
}
|
|
|
|
void TSimpleAutorizator::CreateNewUser()
|
|
{
|
|
|
|
std::string login = boost::lexical_cast<std::string>(UserPasswords.size());
|
|
std::string password = GenerateRandomPassword();
|
|
|
|
UserPasswordsMutex.lock();
|
|
UserPasswords.push_back(password);
|
|
UserPasswordsMutex.unlock();
|
|
|
|
boost::property_tree::ptree pt;
|
|
|
|
pt.put("OnHello.Login", login);
|
|
pt.put("OnHello.Password", password);
|
|
|
|
SendPropertyTree(IoService, Socket, pt);
|
|
|
|
AllowedSignal(login);
|
|
}
|
|
|
|
//================================
|
|
|
|
|
|
TConnectedUser::TConnectedUser(TServerSocket& server)
|
|
: Server(server)
|
|
, Socket(server.IoService)
|
|
, Autorizator(std::shared_ptr<TSimpleAutorizator>(new TSimpleAutorizator(server.IoService, Socket)))
|
|
{
|
|
}
|
|
|
|
TConnectedUser::~TConnectedUser()
|
|
{
|
|
|
|
}
|
|
|
|
void TConnectedUser::HandleAllowed(std::string login)
|
|
{
|
|
UserDataReader = boost::shared_ptr<TDataReader>(new TDataReader(Socket));
|
|
|
|
UserDataReader->ErrorSignal.connect(boost::bind(&TServerSocket::DeleteUser, &Server, shared_from_this()));
|
|
|
|
Login = login;
|
|
|
|
Server.OnUserAuthorizedSignal(shared_from_this());
|
|
|
|
UserDataReader->StartReadNonstop();
|
|
}
|
|
|
|
void TConnectedUser::SendPropertyTree(boost::property_tree::ptree pTree)
|
|
{
|
|
SE::SendPropertyTree(Server.IoService, Socket, pTree);
|
|
}
|
|
|
|
void TConnectedUser::DisconnectSlots()
|
|
{
|
|
UserDataReader->DataReadSignalMap.Clear();
|
|
UserDataReader->ErrorSignal.disconnect_all_slots();
|
|
|
|
std::shared_ptr<TSimpleAutorizator> authorizator = boost::get<std::shared_ptr<TSimpleAutorizator>>(Autorizator);
|
|
|
|
authorizator->ErrorSignal.disconnect_all_slots();
|
|
authorizator->AllowedSignal.disconnect_all_slots();
|
|
//authorizator->DeniedSignal.disconnect_all_slots();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
TServerSocket::TServerSocket()
|
|
{
|
|
}
|
|
|
|
TServerSocket::~TServerSocket()
|
|
{
|
|
}
|
|
|
|
void TServerSocket::Open(int port)
|
|
{
|
|
boost::asio::ip::tcp::endpoint endpoint(boost::asio::ip::tcp::v4(), port);
|
|
|
|
Acceptor = std::shared_ptr<boost::asio::ip::tcp::acceptor>(new boost::asio::ip::tcp::acceptor(IoService, endpoint));
|
|
|
|
StartAccept();
|
|
|
|
ServiceThread = boost::thread(boost::bind(&TServerSocket::UpdateInThread, this));
|
|
|
|
}
|
|
|
|
void TServerSocket::Close()
|
|
{
|
|
}
|
|
|
|
void TServerSocket::UpdateInThread()
|
|
{
|
|
IoService.run();
|
|
IoService.reset();
|
|
}
|
|
|
|
void TServerSocket::JoinServiceThread()
|
|
{
|
|
ServiceThread.join();
|
|
}
|
|
|
|
void TServerSocket::StartAccept()
|
|
{
|
|
boost::shared_ptr<TConnectedUser> newUser(new TConnectedUser(*this));
|
|
|
|
Acceptor->async_accept(newUser->Socket, boost::bind(&TServerSocket::HandleAccept, this, newUser, boost::asio::placeholders::error));
|
|
}
|
|
|
|
|
|
void TServerSocket::HandleAccept(boost::shared_ptr<TConnectedUser> user, const boost::system::error_code& error)
|
|
{
|
|
if (!error)
|
|
{
|
|
|
|
UserArr.push_back(user);
|
|
|
|
std::shared_ptr<TSimpleAutorizator> authorizator = boost::get<std::shared_ptr<TSimpleAutorizator>>(user->Autorizator);
|
|
|
|
authorizator->AllowedSignal.connect(boost::bind(&TConnectedUser::HandleAllowed, user, _1));
|
|
authorizator->ErrorSignal.connect(boost::bind(&TServerSocket::DeleteUser, this, user));
|
|
|
|
boost::get<std::shared_ptr<TSimpleAutorizator>>(user->Autorizator)->StartListen();
|
|
|
|
}
|
|
|
|
StartAccept();
|
|
}
|
|
|
|
void TServerSocket::DeleteUser(boost::shared_ptr<TConnectedUser> user)
|
|
{
|
|
std::vector<boost::shared_ptr<TConnectedUser>>::iterator i = std::find(UserArr.begin(), UserArr.end(), user);
|
|
|
|
user->DisconnectSlots();
|
|
|
|
OnUserDisconnectedSignal(user);
|
|
|
|
UserArr.erase(i);
|
|
}
|
|
|
|
|
|
} //namspace SE
|