#include "include/Utils/Utils.h" #include "boost/random.hpp" namespace SE { std::vector TSimpleAutorizator::UserPasswords; boost::mutex TSimpleAutorizator::UserPasswordsMutex; std::string TSimpleAutorizator::GenerateRandomPassword() { boost::random::mt19937 RandomGenerator; RandomGenerator.seed(static_cast(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 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("Login"); std::string password = pTree.get("Password"); int loginNum = boost::lexical_cast(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(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(new TSimpleAutorizator(server.IoService, Socket))) { } TConnectedUser::~TConnectedUser() { } void TConnectedUser::HandleAllowed(std::string login) { UserDataReader = boost::shared_ptr(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 authorizator = boost::get>(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(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 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 user, const boost::system::error_code& error) { if (!error) { UserArr.push_back(user); std::shared_ptr authorizator = boost::get>(user->Autorizator); authorizator->AllowedSignal.connect(boost::bind(&TConnectedUser::HandleAllowed, user, _1)); authorizator->ErrorSignal.connect(boost::bind(&TServerSocket::DeleteUser, this, user)); boost::get>(user->Autorizator)->StartListen(); } StartAccept(); } void TServerSocket::DeleteUser(boost::shared_ptr user) { std::vector>::iterator i = std::find(UserArr.begin(), UserArr.end(), user); user->DisconnectSlots(); OnUserDisconnectedSignal(user); UserArr.erase(i); } } //namspace SE