/* * 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 "db.h" #include "core/log.h" #include "core/misc.h" namespace Winix { //void Db::PostgreSQLsmallerThan10(bool is_smaller_than_10) //{ // is_postgresql_smaller_than_10 = is_smaller_than_10; // // if( is_postgresql_smaller_than_10 ) // { // postgrsql_row_statement.clear(); // } // else // { // postgrsql_row_statement = L"ROW"; // } //} /* bool Db::GetUserPass(const std::wstring & login, long & user_id, UserPass & up) { PGresult * r = 0; bool user_ok = false; user_id = -1; try { query.Clear(); query << R("select id, has_pass, password, pass_encrypted, pass_type, pass_hash_salted from core.user where login=") << login << R(";"); r = AssertQuery(query); AssertResult(r, PGRES_TUPLES_OK); int rows = Rows(r); if( rows == 0 ) throw Error(WINIX_ERR_DB_INCORRECT_LOGIN); if( rows > 1 ) { log << log1 << "Db: there is more than one user: " << login << logend; throw Error(WINIX_ERR_DB_MORE_THAN_ONE_LOGIN); } int cuser_id = AssertColumn(r, "id"); int chas_pass = AssertColumn(r, "has_pass"); int cpass_type = AssertColumn(r, "pass_type"); int csalted = AssertColumn(r, "pass_hash_salted"); int cpassword = AssertColumn(r, "password"); int cpass_encrypted = AssertColumn(r, "pass_encrypted"); user_ok = true; user_id = AssertValueLong(r, 0, cuser_id); up.has_pass = AssertValueBool(r, 0, chas_pass); up.pass_type = AssertValueInt(r, 0, cpass_type); up.pass_hash_salted = AssertValueBool(r, 0, csalted); AssertValueWide(r, 0, cpassword, up.pass); AssertValueBin(r, 0, cpass_encrypted, up.pass_encrypted); } catch(const Error &) { } ClearResult(r); return user_ok; } Error Db::AddUser(User & user, const UserPass & up) { PGresult * r = 0; Error status = WINIX_ERR_OK; try { query.Clear(); query << R("insert into core.user (login, has_pass, password, pass_encrypted, super_user, email," "notify, pass_type, pass_hash_salted, env, aenv, status, locale_id, time_zone_id) values (") << user.name << up.has_pass; // for safety we put up.pass only if there is not an encrypted version // someone could have forgotten to clear up.pass if( up.pass_encrypted.empty() ) query << up.pass; else query << ""; query.EPutBin(up.pass_encrypted); query << user.super_user << user.email << user.notify << up.pass_type << up.pass_hash_salted << user.env << user.aenv << user.status << user.locale_id << user.time_zone_id << R(");"); r = AssertQuery(query); AssertResult(r, PGRES_COMMAND_OK); user.id = AssertCurrval("core.user_id_seq"); } catch(const Error & e) { status = e; } ClearResult(r); return status; } Error Db::ChangeUserPass(long user_id, const UserPass & up) { query.Clear(); query << R("update core.user set(has_pass, password, pass_encrypted," "pass_type, pass_hash_salted) = ") << R(postgrsql_row_statement) << R("(") << up.has_pass; // for safety if( up.pass_encrypted.empty() ) query << up.pass; else query << ""; query.EPutBin(up.pass_encrypted); query << up.pass_type << up.pass_hash_salted << R(") where id=") << user_id << R(";"); return DoCommand(query); } Error Db::ChangeUserEnv(long user_id, const PT::Space & space) { query.Clear(); query << R("update core.user set(env) = ") << R(postgrsql_row_statement) << R("(") << space << R(") where id = ") << user_id << R(";"); return DoCommand(query); } Error Db::ChangeUserAdminEnv(long user_id, const PT::Space & space) { query.Clear(); query << R("update core.user set(aenv) = ") << R(postgrsql_row_statement) << R("(") << space << R(") where id = ") << user_id << R(";"); return DoCommand(query); } Error Db::ChangeUserStatus(long user_id, int status) { query.Clear(); query << R("update core.user set(status) = ") << R(postgrsql_row_statement) << R("(") << status << R(") where id = ") << user_id << R(";"); return DoCommand(query); } Error Db::ChangeUserEmail(long user_id, const std::wstring & email) { query.Clear(); query << R("update core.user set(email) = ") << R(postgrsql_row_statement) << R("(") << email << R(") where id = ") << user_id << R(";"); return DoCommand(query); } Error Db::ChangeUserLocale(long user_id, size_t locale_id) { query.Clear(); query << R("update core.user set(locale_id) = ") << R(postgrsql_row_statement) << R("(") << locale_id << R(") where id = ") << user_id << R(";"); return DoCommand(query); } Error Db::ChangeUserTimeZone(long user_id, size_t time_zone_id) { query.Clear(); query << R("update core.user set(time_zone_id) = ") << R(postgrsql_row_statement) << R("(") << time_zone_id << R(") where id = ") << user_id << R(";"); return DoCommand(query); } Error Db::RemoveUser(long user_id) { query.Clear(); query << R("delete from core.user where id = ") << user_id << R(";"); return DoCommand(query); } void Db::GetUsers(UGContainer & user_tab) { PGresult * r = 0; try { query.Clear(); query << R("select id, login, super_user, group_id, email, notify," " env, aenv, status, locale_id, time_zone_id" " from core.user left outer join core.group_mem on" " core.user.id = core.group_mem.user_id order by id asc;"); r = AssertQuery(query); AssertResult(r, PGRES_TUPLES_OK); int rows = Rows(r); int cid = AssertColumn(r, "id"); int cname = AssertColumn(r, "login"); int csuper_user = AssertColumn(r, "super_user"); int cgroup_id = AssertColumn(r, "group_id"); int cemail = AssertColumn(r, "email"); int cnotify = AssertColumn(r, "notify"); int cenv = AssertColumn(r, "env"); int caenv = AssertColumn(r, "aenv"); int cstatus = AssertColumn(r, "status"); int clocale_id = AssertColumn(r, "locale_id"); int ctzone_id = AssertColumn(r, "time_zone_id"); User u; long last_id = -1; UGContainer::Iterator iter = user_tab.End(); for(int i=0 ; igroups.push_back(group_id); log << log3 << "Db: user:" << iter->name << " is a member of group_id: " << group_id << logend; } } } catch(const Error &) { } ClearResult(r); } void Db::GetGroups(UGContainer & group_tab) { PGresult * r = 0; try { query.Clear(); query << R("select id, core.group.group, user_id from core.group left outer join" " core.group_mem on core.group.id = core.group_mem.group_id order by id asc;"); r = AssertQuery(query); AssertResult(r, PGRES_TUPLES_OK); int rows = Rows(r); int cid = AssertColumn(r, "id"); int cname = AssertColumn(r, "group"); int cuser_id = AssertColumn(r, "user_id"); Group g; long last_id = -1; UGContainer::Iterator iter; for(int i = 0 ; imembers.push_back(user_id); log << log3 << "Db: get group member: user_id: " << user_id << logend; } } } catch(const Error &) { } ClearResult(r); } */ } // namespace Winix