/* * This file is a part of Winix * and is distributed under the 2-Clause BSD licence. * Author: Tomasz Sowa */ /* * Copyright (c) 2008-2021, Tomasz Sowa * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * 1. Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * */ #include #include "users.h" #include "sessionmanager.h" #include "slog.h" namespace Winix { Users::Users() { how_many_logged = 0; // !! CHECK ME may it should be moved to Clear() method? // table.set_dependency(this); Clear(); } void Users::fields() { field(L"users", table.table); } //void Users::set_dependency(WinixModelDeprecated * winix_model) //{ // WinixModelDeprecated::set_dependency(winix_model); // table.set_dependency(winix_model); // last.set_dependency(winix_model); //} //void Users::SetCur(Cur * pcur) //{ // cur = pcur; //} //void Users::SetSessionManager(SessionManager * sm) //{ // session_manager = sm; //} void Users::Clear() { table.Clear(); } void Users::ReadUsers(Db * db) { Clear(); morm::Finder finder(model_connector); std::list users_tmp = finder. select(). get_list(); for(User & user : users_tmp) { table.PushBack(user, user.login); } } bool Users::AddUser(const User & user) { Table::Iterator i = table.PushBack(user, user.login); return (i != table.End()); } bool Users::IsUser(const std::wstring & name) { return table.Is(name); } User * Users::GetUser(long user_id) { Table::Iterator i = table.FindId(user_id); if( i == table.End() ) return 0; return &(*i); } User * Users::GetUser(const std::wstring & name) { Table::Iterator i = table.FindName(name); if( i == table.End() ) return 0; return &(*i); } long Users::GetUserId(const std::wstring & name) { User * puser = GetUser(name); if( !puser ) return -1; return puser->id; } Users::Iterator Users::Begin() { return table.Begin(); } Users::Iterator Users::End() { return table.End(); } Users::SizeType Users::Size() { return table.Size(); } bool Users::Remove(long user_id) { bool result = false; User * puser = GetUser(user_id); if( puser ) { LogoutUser(user_id); // plugin->Call(WINIX_PREPARE_TO_REMOVE_USER, puser); FIXME result = table.Remove(user_id); // if( result ) // plugin->Call(WINIX_USER_REMOVED, user_id); FIXME } return result; } // private bool Users::LoginUserCheckSession(bool use_ses_log) { Session * session = get_session(); Log * log = get_logger(); SLog * slog = get_session_logger(); if( !session ) return false; if( session->id == 0 ) { if( log ) (*log) << log1 << "Users: I cannot login a user on a temporary session" << logend; if( slog && use_ses_log ) (*slog) << logerror << T(L"service_unavailable") << logend; return false; } return true; } // private User * Users::LoginUserCheckStatus(long user_id, bool use_ses_log) { User * puser = GetUser(user_id); Log * log = get_logger(); SLog * slog = get_session_logger(); if( !puser ) { if( log ) (*log) << log1 << "Users: user id: " << user_id << " is not in system.users table" << logend; if( slog && use_ses_log ) (*slog) << logerror << T(L"service_unavailable") << logend; return 0; } if( puser->status != WINIX_ACCOUNT_READY ) { (*log) << log1 << "Users: user id: " << user_id << " is not ready for logging in (status: " << puser->status << ")" << logend; if( slog && use_ses_log ) { if( puser->status == WINIX_ACCOUNT_NOT_ACTIVATED ) (*slog) << logerror << T(L"account_not_activated") << logend; else if( puser->status == WINIX_ACCOUNT_SUSPENDED ) (*slog) << logerror << T(L"account_suspended") << logend; else if( puser->status == WINIX_ACCOUNT_BLOCKED ) (*slog) << logerror << T(L"account_banned") << logend; } return 0; } return puser; } bool Users::LoginUser(long user_id, bool remember_me, bool use_ses_log) { if( !LoginUserCheckSession(use_ses_log) ) return false; User * puser = LoginUserCheckStatus(user_id, use_ses_log); Log * log = get_logger(); Session * session = get_session(); SessionManager * session_manager = get_session_manager(); Request * request = get_request(); if( !puser || !session || !session_manager || !request ) return false; PluginRes res; //PluginRes res = plugin->Call(WINIX_PREPARE_USER_TO_LOGIN, puser); FIXME if( res.res_false > 0 ) { if( log ) (*log) << log3 << "Users: login prevented by a plugin" << logend; return false; } if( session->puser ) LogoutCurrentUser(); session->puser = puser; session->spam_score = 0; session->remember_me = remember_me; // change session id before last.UserLogin() if( !session->new_session ) session_manager->ChangeSessionId(session->id); last.UserLogin(user_id, session->puser->login, request->ip, session->id); how_many_logged += 1; if( log ) (*log) << log2 << "Users: user " << session->puser->login << " (id: " << user_id << ") logged" << logend; //plugin->Call(WINIX_USER_LOGGED); FIXME return true; } size_t Users::LogoutUser(long user_id) { size_t how_many = 0; User * puser = GetUser(user_id); Log * log = get_logger(); SessionManager * session_manager = get_session_manager(); if( puser && session_manager ) { if( log ) { (*log) << log2 << "Users: logging out user " << puser->login << ", id: " << puser->id << " from all sessions" << logend; } // WINIX_PREPARE_USER_TO_LOGOUT will be sent by MarkAllSessionsToRemove() how_many = session_manager->MarkAllSessionsToRemove(user_id); how_many_logged -= how_many; if( how_many ) { if( log ) (*log) << log3 << "Users: " << how_many << " user(s) were logged out" << logend; } } return how_many; } void Users::LogoutCurrentUser() { Log * log = get_logger(); Session * session = get_session(); if( !session || !session->puser ) return; if( log ) { (*log) << log2 << "Users: user " << session->puser->login << ", id: " << session->puser->id << " logged out" << logend; } //plugin->Call(WINIX_PREPARE_USER_TO_LOGOUT, cur->session->puser); // FIXME last.UserLogout(session->puser->id, session->id); if( how_many_logged > 0 ) // for safety how_many_logged -= 1; session->puser = 0; session->remember_me = false; } void Users::IncrementLoggedUsers() { how_many_logged += 1; } long Users::HowManyLogged() { return how_many_logged; } } // namespace Winix