/* * 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 "adduser.h" #include "core/misc.h" #include "functions/functions.h" namespace Winix { namespace Fun { AddUser::AddUser() { fun.url = L"adduser"; need_ssl = true; } /* checking whether a login consists of allowed characters */ bool AddUser::HasLoginCorrectChars(const std::wstring & login) { for(size_t i=0 ; i WINIX_ACCOUNT_MAX_LOGIN_SIZE ) { log << log2 << "AddUser: login can't be longer than: " << WINIX_ACCOUNT_MAX_LOGIN_SIZE << " characters" << logend; if( use_ses_log ) slog << logerror << T("adduser_err_login_too_big") << " " << WINIX_ACCOUNT_MAX_LOGIN_SIZE << " " << T("adduser_err_login_too_big2") << logend; return false; } if( !HasLoginCorrectChars(login) ) { log << log2 << "AddUser: incorrect login characters" << logend; if( use_ses_log ) slog << logerror << T("adduser_err_login_incorrect_chars") << logend; return false; } if( system->users.IsUser(login) ) { log << log2 << "AddUser: such user already exists" << logend; if( use_ses_log ) slog << logerror << T("adduser_err_user_exists") << logend; return false; } return true; } bool AddUser::IsEmailCorrect(const std::wstring & email, bool use_ses_log) { if( email.size() > WINIX_ACCOUNT_MAX_EMAIL_SIZE ) { log << log2 << "AddUser: email can't be longer than: " << WINIX_ACCOUNT_MAX_EMAIL_SIZE << " characters" << logend; if( use_ses_log ) slog << logerror << T("adduser_err_email_too_big") << " " << WINIX_ACCOUNT_MAX_EMAIL_SIZE << " " << T("adduser_err_email_too_big2") << logend; return false; } if( !ValidateEmail(email) ) { log << log2 << "AddUser: email: " << email << " does not seem to be correct" << logend; if( use_ses_log ) slog << logerror << T(L"adduser_err_email_incorrect") << logend; return false; } return true; } // !! IMPROVE ME // may it should be moved to passwd winix function /* adding a new account this method doesn't check whether the login or password is correct (consist of allowed characters) input: user - all fields from User struct without 'id' pass - user's password output: result: true when the account has been successfully created and user.id will be set */ bool AddUser::AddNewUser(User & user, const std::wstring & pass) { user.has_pass = true; user.password = pass; system->crypt.PassHashCrypt(user); if( user.insert() ) { if( system->users.AddUser(user) ) { log << log2 << "AddUser: added a new user: " << user.name << logend; return true; } else { log << log1 << "AddUser: I can't add to system->users: " << user.name << " but the user was added to the db correctly" << logend; } } else { log << log1 << "AddUser: I cannot add a user -- database error" << logend; } return false; } /* adding a new account this method doesn't check whether the login or password is correct (consist of allowed characters) input: login - account login name pass - password email - email address autoactivate - if true then the account will be created with WINIX_ACCOUNT_READY flag (an email will not be sent) if false then the flag depends on config->account_need_email_verification try_login - if true then if there is no a user logged (in this session) and if the account is ready (has WINIX_ACCOUNT_READY flag) the the new user will be logged in use_ses_log - when true the session logger will be used (info about sending an email) */ bool AddUser::AddNewUser(const std::wstring & login, const std::wstring & pass, const std::wstring & email, bool autoactivate, bool try_login, bool use_ses_log) { user.set_connector(model_connector); user.clear(); //user.Clear(); user.name = login; user.email = email; user.super_user = false; user.notify = 0; user.locale_id = config->locale_default_id; user.time_zone_id = config->time_zone_default_id; user.status = (config->account_need_email_verification)? WINIX_ACCOUNT_NOT_ACTIVATED : WINIX_ACCOUNT_READY; long code = 0; if( autoactivate ) user.status = WINIX_ACCOUNT_READY; if( user.status == WINIX_ACCOUNT_NOT_ACTIVATED ) { code = std::rand(); user.aenv.add(L"activation_code", code); } if( AddNewUser(user, pass) ) { if( try_login && !cur->session->puser && user.status == WINIX_ACCOUNT_READY ) { system->users.LoginUser(user.id, false); log << log2 << "AddUser: now logged as: " << user.name << logend; plugin->Call(WINIX_USER_LOGGED); } if( user.status == WINIX_ACCOUNT_NOT_ACTIVATED ) { system->notify.ActivateAccount(user.name, user.email, code); if( use_ses_log ) slog << loginfo << T(L"account_email_sent") << logend; } return true; } return false; } void AddUser::MakePost() { const std::wstring & login = cur->request->PostVar(L"login"); const std::wstring & pass = cur->request->PostVar(L"password"); const std::wstring & conf_pass = cur->request->PostVar(L"passwordconfirm"); const std::wstring & email = cur->request->PostVar(L"email"); bool autoactivate = false; // for slog and locale from fun_passwd to work correctly // but in the future IsPasswordCorrect will be moved to User class // or some other place functions->fun_passwd.set_dependency(this); if( !IsLoginCorrect(login, true) || !IsEmailCorrect(email, true) || !functions->fun_passwd.IsPasswordCorrect(pass, conf_pass, true) ) return; if( cur->session->puser && cur->session->puser->super_user ) { autoactivate = cur->request->IsPostVar(L"autoactivate"); if( autoactivate ) log << log2 << "AddUser: account activated by an admin" << logend; } if( AddNewUser(login, pass, email, autoactivate, true, true) ) system->RedirectToLastItem(); } void AddUser::MakeGet() { } } // namespace } // namespace Winix