start working on User and Group classes

- User and Group has been moved to 'models' directory
- removed UserPass struct (passwords fields were put to User struct)
not working yet, we need support for binary blobs in morm
This commit is contained in:
Tomasz Sowa 2021-04-30 01:34:48 +02:00
parent ccda2bc2fd
commit 4277f90bad
29 changed files with 363 additions and 200 deletions

View File

@ -297,6 +297,29 @@ bool App::Init()
} }
///////////// /////////////
morm::Finder<User> finder(model_connector);
User user = finder.
select().
where().
eq(L"id", 1).
get();
log << log1 << user << logend;
std::exit(0);
//////////////////////////////////
db_conn.SetConnParam(config.db_database, config.db_user, config.db_pass); db_conn.SetConnParam(config.db_database, config.db_user, config.db_pass);
db_conn.WaitForConnection(); db_conn.WaitForConnection();
db.PostgreSQLsmallerThan10(config.db_postgresql_smaller_than_10); db.PostgreSQLsmallerThan10(config.db_postgresql_smaller_than_10);

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2011-2018, Tomasz Sowa * Copyright (c) 2011-2021, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -267,28 +267,28 @@ bool Crypt::RSA(bool encrypt, const std::wstring & keypath, const std::string &
bool Crypt::PassHash(const std::wstring & salt, UserPass & up) bool Crypt::PassHash(const std::wstring & salt, User & user)
{ {
bool result = true; bool result = true;
up.pass_hash_salted = false; user.pass_hash_salted = false;
if( up.pass_type != WINIX_CRYPT_HASH_NONE ) if( user.pass_type != WINIX_CRYPT_HASH_NONE )
{ {
pass_org = up.pass; pass_org = user.password;
pass_salted = up.pass; pass_salted = user.password;
pass_salted += salt; pass_salted += salt;
if( HashHex(up.pass_type, pass_salted, up.pass) ) if( HashHex(user.pass_type, pass_salted, user.password) )
{ {
if( !salt.empty() ) if( !salt.empty() )
up.pass_hash_salted = true; user.pass_hash_salted = true;
} }
else else
{ {
log << log1 << "Crypt: problem with generating a hash, the password will not be hashed" << logend; log << log1 << "Crypt: problem with generating a hash, the password will not be hashed" << logend;
up.pass = pass_org; user.password = pass_org;
up.pass_type = WINIX_CRYPT_HASH_NONE; user.pass_type = WINIX_CRYPT_HASH_NONE;
result = false; result = false;
} }
@ -301,22 +301,22 @@ return result;
bool Crypt::PassCrypt(const std::wstring & path_to_rsa_private_key, UserPass & up) bool Crypt::PassCrypt(const std::wstring & path_to_rsa_private_key, User & user)
{ {
bool result = false; bool result = false;
ClearString(up.pass_encrypted); ClearString(user.pass_encrypted);
if( !path_to_rsa_private_key.empty() ) if( !path_to_rsa_private_key.empty() )
{ {
PT::WideToUTF8(up.pass, passa); PT::WideToUTF8(user.password, passa);
if( RSA(true, path_to_rsa_private_key, passa, up.pass_encrypted) ) if( RSA(true, path_to_rsa_private_key, passa, user.pass_encrypted) )
{ {
result = true; result = true;
} }
else else
{ {
ClearString(up.pass_encrypted); ClearString(user.pass_encrypted);
log << log1 << "AddUser: problem with encrypting, the password will not be encrypted!" << logend; log << log1 << "AddUser: problem with encrypting, the password will not be encrypted!" << logend;
} }
@ -327,27 +327,27 @@ return result;
} }
void Crypt::PassHashCrypt(const std::wstring & salt, const std::wstring & path_to_rsa_private_key, UserPass & up) void Crypt::PassHashCrypt(const std::wstring & salt, const std::wstring & path_to_rsa_private_key, User & user)
{ {
PassHash(salt, up); PassHash(salt, user);
PassCrypt(path_to_rsa_private_key, up); PassCrypt(path_to_rsa_private_key, user);
} }
void Crypt::PassHashCrypt(UserPass & up) void Crypt::PassHashCrypt(User & user)
{ {
up.pass_type = config->pass_type; user.pass_type = config->pass_type;
empty.clear(); empty.clear();
if( config->pass_hash_use_salt && !config->pass_hash_salt.empty() ) if( config->pass_hash_use_salt && !config->pass_hash_salt.empty() )
PassHash(config->pass_hash_salt, up); PassHash(config->pass_hash_salt, user);
else else
PassHash(empty, up); PassHash(empty, user);
if( config->pass_use_rsa && !config->pass_rsa_private_key.empty() ) if( config->pass_use_rsa && !config->pass_rsa_private_key.empty() )
PassCrypt(config->pass_rsa_private_key, up); PassCrypt(config->pass_rsa_private_key, user);
} }

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2011-2014, Tomasz Sowa * Copyright (c) 2011-2021, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -38,7 +38,7 @@
#include <string> #include <string>
#include "run.h" #include "run.h"
#include "config.h" #include "config.h"
#include "user.h" #include "models/user.h"
#include "winixbase.h" #include "winixbase.h"
@ -177,7 +177,7 @@ public:
if there is a problem with generating a hash the method stores a plain text password if there is a problem with generating a hash the method stores a plain text password
and changes up.pass_type to zero (plain text passwords are not salted) and changes up.pass_type to zero (plain text passwords are not salted)
*/ */
bool PassHash(const std::wstring & salt, UserPass & up); bool PassHash(const std::wstring & salt, User & user);
/* /*
@ -195,7 +195,7 @@ public:
if there is a problem (or the path to the key is empty) then up.pass_encrypted will be empty if there is a problem (or the path to the key is empty) then up.pass_encrypted will be empty
and the method returns false and the method returns false
*/ */
bool PassCrypt(const std::wstring & path_to_rsa_private_key, UserPass & up); bool PassCrypt(const std::wstring & path_to_rsa_private_key, User & user);
/* /*
@ -217,7 +217,7 @@ public:
up.pass_encrypted - encrypted password (if not empty) up.pass_encrypted - encrypted password (if not empty)
*/ */
void PassHashCrypt(const std::wstring & salt, const std::wstring & path_to_rsa_private_key, UserPass & up); void PassHashCrypt(const std::wstring & salt, const std::wstring & path_to_rsa_private_key, User & user);
/* /*
@ -232,7 +232,7 @@ public:
up.pass_hash_salted - true if the hash is salted (plain text are never salted) up.pass_hash_salted - true if the hash is salted (plain text are never salted)
up.pass_encrypted - encrypted password (if not empty) up.pass_encrypted - encrypted password (if not empty)
*/ */
void PassHashCrypt(UserPass & up); void PassHashCrypt(User & user);
/* /*

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2008-2018, Tomasz Sowa * Copyright (c) 2008-2021, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -63,7 +63,16 @@ void Groups::ReadGroups(Db * db)
{ {
Clear(); Clear();
db->GetGroups(table); morm::Finder<Group> finder(model_connector);
std::vector<Group> groups_tmp = finder.
select().
get_vector();
for(Group & group : groups_tmp)
{
table.PushBack(group);
}
} }

View File

@ -37,7 +37,7 @@
#include <map> #include <map>
#include "group.h" #include "models/group.h"
#include "ugcontainer.h" #include "ugcontainer.h"
#include "db/db.h" #include "db/db.h"
#include "winixmodel.h" #include "winixmodel.h"

View File

@ -205,6 +205,12 @@ Log & Log::operator<<(const PT::Date & date)
} }
Log & Log::operator<<(morm::Model & model)
{
PT::Log::operator<<(model);
return *this;
}
Log & Log::operator<<(LogManipulators m) Log & Log::operator<<(LogManipulators m)
{ {

View File

@ -78,6 +78,7 @@ public:
virtual Log & operator<<(const PT::Space & space); virtual Log & operator<<(const PT::Space & space);
virtual Log & operator<<(LogManipulators m); virtual Log & operator<<(LogManipulators m);
virtual Log & operator<<(const PT::Date & date); virtual Log & operator<<(const PT::Date & date);
virtual Log & operator<<(morm::Model & model);
virtual void PrintDate(const PT::Date & date); virtual void PrintDate(const PT::Date & date);

View File

@ -40,7 +40,7 @@
#include <ctime> #include <ctime>
#include <map> #include <map>
#include "error.h" #include "error.h"
#include "user.h" #include "models/user.h"
#include "plugindata.h" #include "plugindata.h"
#include "rebus.h" #include "rebus.h"
#include "textstream.h" #include "textstream.h"

View File

@ -79,8 +79,18 @@ void Users::Clear()
void Users::ReadUsers(Db * db) void Users::ReadUsers(Db * db)
{ {
Clear(); Clear();
db->GetUsers(table);
morm::Finder<User> finder(model_connector);
std::list<User> users_tmp = finder.
select().
get_list();
for(User & user : users_tmp)
{
table.PushBack(user);
}
} }

View File

@ -36,7 +36,7 @@
#define headerfile_winix_core_users #define headerfile_winix_core_users
#include <map> #include <map>
#include "user.h" #include "models/user.h"
#include "ugcontainer.h" #include "ugcontainer.h"
#include "lastcontainer.h" #include "lastcontainer.h"
#include "cur.h" #include "cur.h"

View File

@ -40,7 +40,6 @@
namespace Winix namespace Winix
{ {
void Db::PostgreSQLsmallerThan10(bool is_smaller_than_10) void Db::PostgreSQLsmallerThan10(bool is_smaller_than_10)
{ {
is_postgresql_smaller_than_10 = is_smaller_than_10; is_postgresql_smaller_than_10 = is_smaller_than_10;
@ -56,6 +55,7 @@ void Db::PostgreSQLsmallerThan10(bool is_smaller_than_10)
} }
/*
bool Db::GetUserPass(const std::wstring & login, long & user_id, UserPass & up) bool Db::GetUserPass(const std::wstring & login, long & user_id, UserPass & up)
{ {
PGresult * r = 0; PGresult * r = 0;
@ -406,7 +406,7 @@ void Db::GetGroups(UGContainer<Group> & group_tab)
ClearResult(r); ClearResult(r);
} }
*/
} // namespace Winix } // namespace Winix

View File

@ -41,8 +41,8 @@
#include <ctime> #include <ctime>
#include <cstring> #include <cstring>
#include "dbbase.h" #include "dbbase.h"
#include "core/user.h" #include "models/user.h"
#include "core/group.h" #include "models/group.h"
#include "core/dircontainer.h" #include "core/dircontainer.h"
#include "core/ugcontainer.h" #include "core/ugcontainer.h"
@ -55,6 +55,7 @@ class Db : public DbBase
{ {
public: public:
Db() Db()
{ {
is_postgresql_smaller_than_10 = false; is_postgresql_smaller_than_10 = false;
@ -62,6 +63,7 @@ public:
void PostgreSQLsmallerThan10(bool is_smaller_than_10); void PostgreSQLsmallerThan10(bool is_smaller_than_10);
/*
bool GetUserPass(const std::wstring & login, long & user_id, UserPass & up); bool GetUserPass(const std::wstring & login, long & user_id, UserPass & up);
Error AddUser(User & user, const UserPass & up); Error AddUser(User & user, const UserPass & up);
Error ChangeUserPass(long user_id, const UserPass & up); Error ChangeUserPass(long user_id, const UserPass & up);
@ -80,8 +82,12 @@ public:
protected: protected:
DbTextStream query, query_create_url; DbTextStream query, query_create_url;
bool is_postgresql_smaller_than_10; */
std::wstring postgrsql_row_statement; std::wstring postgrsql_row_statement;
bool is_postgresql_smaller_than_10;
}; };

View File

@ -61,12 +61,11 @@ bool Account::ActivateAccount(User * puser, long code, bool use_ses_log)
{ {
if( Tol(*user_code_str) == code ) if( Tol(*user_code_str) == code )
{ {
if( db->ChangeUserStatus(puser->id, WINIX_ACCOUNT_READY) == WINIX_ERR_OK ) puser->status = WINIX_ACCOUNT_READY;
{ puser->aenv.remove(L"activation_code");
puser->aenv.remove(L"activation_code");
db->ChangeUserAdminEnv(puser->id, puser->aenv);
puser->status = WINIX_ACCOUNT_READY;
if( puser->update() )
{
log << log2 << "Account: account: " << puser->name << " activated" << logend; log << log2 << "Account: account: " << puser->name << " activated" << logend;
if( use_ses_log ) if( use_ses_log )

View File

@ -162,11 +162,11 @@ return true;
*/ */
bool AddUser::AddNewUser(User & user, const std::wstring & pass) bool AddUser::AddNewUser(User & user, const std::wstring & pass)
{ {
up.has_pass = true; user.has_pass = true;
up.pass = pass; user.password = pass;
system->crypt.PassHashCrypt(up); system->crypt.PassHashCrypt(user);
if( db->AddUser(user, up) == WINIX_ERR_OK ) if( user.insert() )
{ {
if( system->users.AddUser(user) ) if( system->users.AddUser(user) )
{ {
@ -213,7 +213,10 @@ bool AddUser::AddNewUser(const std::wstring & login,
bool try_login, bool try_login,
bool use_ses_log) bool use_ses_log)
{ {
user.Clear(); user.set_connector(model_connector);
user.clear();
//user.Clear();
user.name = login; user.name = login;
user.email = email; user.email = email;
user.super_user = false; user.super_user = false;

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2010-2014, Tomasz Sowa * Copyright (c) 2010-2021, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -36,7 +36,7 @@
#define headerfile_winix_functions_adduser #define headerfile_winix_functions_adduser
#include "functionbase.h" #include "functionbase.h"
#include "core/user.h" #include "models/user.h"
namespace Winix namespace Winix
{ {
@ -69,7 +69,6 @@ public:
private: private:
UserPass up;
User user; User user;
}; };

View File

@ -47,7 +47,6 @@ Env::Env()
{ {
fun.url = L"env"; fun.url = L"env";
puser = 0; puser = 0;
req_id = 0;
} }
@ -64,9 +63,6 @@ bool Env::HasAccess()
return false; return false;
} }
if( !GetUser() )
return false;
return true; return true;
} }
@ -77,27 +73,24 @@ bool Env::Parse(const std::wstring & env_str)
space.clear(); space.clear();
conf_parser.SetSpace(space); conf_parser.SetSpace(space);
return (conf_parser.ParseSpace(env_str) == PT::SpaceParser::ok); return (conf_parser.ParseSpace(env_str) == PT::SpaceParser::ok);
} }
bool Env::EditAdminEnv(long user_id, const std::wstring & env_str, bool use_ses_log) bool Env::EditAdminEnv(const std::wstring & env_str, bool use_ses_log)
{ {
if( Parse(env_str) ) if( Parse(env_str) )
{ {
if( db->ChangeUserAdminEnv(user_id, space) == WINIX_ERR_OK ) puser->aenv = space;
if( puser->update() )
{ {
User * puser = system->users.GetUser(user_id);
if( puser )
puser->aenv = space;
return true; return true;
} }
else else
{ {
log << log1 << "Evn: a database problem with changing environment variables for user: " log << log1 << "Evn: a database problem with changing admin environment variables for user: "
<< cur->session->puser->name << ", id: " << cur->session->puser->id << logend; << puser->name << ", id: " << puser->id << logend;
} }
} }
else else
@ -112,23 +105,20 @@ return false;
} }
bool Env::EditEnv(long user_id, const std::wstring & env_str, bool use_ses_log) bool Env::EditEnv(const std::wstring & env_str, bool use_ses_log)
{ {
if( Parse(env_str) ) if( Parse(env_str) )
{ {
if( db->ChangeUserEnv(user_id, space) == WINIX_ERR_OK ) puser->env = space;
if( puser->update() )
{ {
User * puser = system->users.GetUser(user_id);
if( puser )
puser->env = space;
return true; return true;
} }
else else
{ {
log << log1 << "Evn: a database problem with changing admin environment variables for user: " log << log1 << "Evn: a database problem with changing admin environment variables for user: "
<< cur->session->puser->name << ", id: " << cur->session->puser->id << logend; << puser->name << ", id: " << puser->id << logend;
} }
} }
else else
@ -146,67 +136,62 @@ return false;
void Env::SaveEnv() void Env::SaveEnv()
{ {
if( GetUser() ) const std::wstring & env_str = cur->request->PostVar(L"envvar");
long user_id = puser->id;
bool status = false;
if( cur->request->IsParam(L"a") )
{ {
const std::wstring & env_str = cur->request->PostVar(L"envvar"); if( cur->session->puser->super_user )
long user_id = GetUser()->id; status = EditAdminEnv(env_str, true);
bool status = false;
if( cur->request->IsParam(L"a") )
{
if( cur->session->puser->super_user )
status = EditAdminEnv(user_id, env_str, true);
}
else
{
status = EditEnv(user_id, env_str, true);
}
if( status )
system->RedirectToLastItem();
} }
} else
User * Env::GetUser()
{
if( cur->request->id != req_id )
{ {
req_id = cur->request->id; status = EditEnv(env_str, true);
puser = 0;
if( cur->session->puser )
{
if( cur->session->puser->super_user && cur->request->IsPostVar(L"userid") )
{
long id = Tol(cur->request->PostVar(L"userid"));
puser = system->users.GetUser(id);
}
else
{
puser = cur->session->puser;
}
}
} }
return puser; if( status )
system->RedirectToLastItem();
} }
void Env::MakePost() void Env::MakePost()
{ {
puser = nullptr;
if( cur->session->puser ) if( cur->session->puser )
{ {
puser = cur->session->puser;
if( cur->request->IsPostVar(L"changeuser") ) if( cur->request->IsPostVar(L"changeuser") )
{ {
// show environments variables for the specified user // show environments variables for the specified user
if( GetUser() ) if( puser->super_user && cur->request->IsPostVar(L"userid") )
log << log2 << "Env: changing user to: " << GetUser()->name << ", id: " << GetUser()->id << logend; {
long id = Tol(cur->request->PostVar(L"userid"));
puser = system->users.GetUser(id);
if( puser )
{
log << log2 << "Env: changing user to: " << puser->name << ", id: " << puser->id << logend;
}
}
}
if( puser )
{
/*
* this puser should be set in a new struct (based on Model)
* and put to templates
*
*/
SaveEnv();
} }
else else
{ {
// save environment variables cur->request->status = WINIX_ERR_PERMISSION_DENIED;
SaveEnv();
} }
} }
} }

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2012-2014, Tomasz Sowa * Copyright (c) 2012-2021, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -52,22 +52,18 @@ public:
Env(); Env();
bool EditAdminEnv(long user_id, const std::wstring & env_str, bool use_ses_log = false);
bool EditEnv(long user_id, const std::wstring & env_str, bool use_ses_log = false);
bool HasAccess(); bool HasAccess();
void MakePost(); void MakePost();
// used mainly by templates
// can return a null pointer
User * GetUser();
private: private:
PT::SpaceParser conf_parser; PT::SpaceParser conf_parser;
PT::Space space; PT::Space space;
User * puser; User * puser;
size_t req_id;
bool EditAdminEnv(const std::wstring & env_str, bool use_ses_log = false);
bool EditEnv(const std::wstring & env_str, bool use_ses_log = false);
bool Parse(const std::wstring & env_str); bool Parse(const std::wstring & env_str);
void SaveEnv(); void SaveEnv();

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2012-2014, Tomasz Sowa * Copyright (c) 2012-2021, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -66,7 +66,7 @@ void Locale::MakePost()
if( TemplatesFunctions::locale.HasLanguage(locale_id) ) if( TemplatesFunctions::locale.HasLanguage(locale_id) )
{ {
cur->session->puser->locale_id = locale_id; cur->session->puser->locale_id = locale_id;
db->ChangeUserLocale(cur->session->puser->id, locale_id); cur->session->puser->update();
TemplatesFunctions::locale.SetCurLang(locale_id); TemplatesFunctions::locale.SetCurLang(locale_id);
} }
else else

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2008-2014, Tomasz Sowa * Copyright (c) 2008-2021, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -55,22 +55,21 @@ Login::Login()
void Login::ClearTmpStruct() void Login::ClearTmpStruct()
{ {
system->crypt.ClearString(pass_decrypted); system->crypt.ClearString(pass_decrypted);
system->crypt.ClearString(pass_hashed); // system->crypt.ClearString(up.pass);
system->crypt.ClearString(up.pass); // system->crypt.ClearString(up.pass_encrypted);
system->crypt.ClearString(up.pass_encrypted); // system->crypt.ClearString(up2.pass);
system->crypt.ClearString(up2.pass); // system->crypt.ClearString(up2.pass_encrypted);
system->crypt.ClearString(up2.pass_encrypted);
} }
bool Login::CheckPasswords(const std::wstring & password) bool Login::CheckPasswords(User & user, const std::wstring & password)
{ {
if( !up.pass_encrypted.empty() ) if( !user.pass_encrypted.empty() )
{ {
if( system->crypt.RSA(false, config->pass_rsa_private_key, up.pass_encrypted, pass_decrypted) ) if( system->crypt.RSA(false, config->pass_rsa_private_key, user.pass_encrypted, pass_decrypted) )
{ {
PT::UTF8ToWide(pass_decrypted, up.pass); PT::UTF8ToWide(pass_decrypted, user.password);
} }
else else
{ {
@ -79,22 +78,22 @@ bool Login::CheckPasswords(const std::wstring & password)
} }
} }
pass_hashed = password; std::wstring password_from_db = user.password;
up2.pass_type = up.pass_type; user.password = password;
up2.pass = password;
if( up.pass_hash_salted ) if( user.pass_hash_salted )
salt = config->pass_hash_salt; salt = config->pass_hash_salt;
else else
salt.clear(); salt.clear();
if( !system->crypt.PassHash(salt, up2) ) if( !system->crypt.PassHash(salt, user) )
{ {
log << log1 << "Login: I cannot hash a password, login failure" << logend; log << log1 << "Login: I cannot hash a password, login failure" << logend;
return false; return false;
} }
bool result = (up.pass == up2.pass); // compare char by char until the end of the strings (time attacks)
bool result = (user.password == password_from_db);
if( !result ) if( !result )
log << log2 << "Login: incorrect login/password" << logend; log << log2 << "Login: incorrect login/password" << logend;
@ -114,15 +113,25 @@ bool Login::CheckUserPass(const std::wstring & login, const std::wstring & passw
{ {
bool result; bool result;
if( db->GetUserPass(login, user_id, up) ) morm::Finder<User> finder(model_connector);
User user = finder.
select().
where().
eq(L"login", login).
get();
if( user.found() )
{ {
if( up.has_pass ) user_id = user.id;
if( user.has_pass )
{ {
result = CheckPasswords(password); result = CheckPasswords(user, password);
} }
else else
{ {
log << log2 << "Login: this account has not a password set yet" << logend; log << log2 << "Login: this account has no a password set yet" << logend;
result = false; result = false;
} }
} }

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2010-2014, Tomasz Sowa * Copyright (c) 2010-2021, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -36,7 +36,7 @@
#define headerfile_winix_functions_login #define headerfile_winix_functions_login
#include "functionbase.h" #include "functionbase.h"
#include "core/user.h" #include "models/user.h"
namespace Winix namespace Winix
{ {
@ -69,13 +69,11 @@ public:
private: private:
void ClearTmpStruct(); void ClearTmpStruct();
bool CheckPasswords(const std::wstring & password); bool CheckPasswords(User & user, const std::wstring & password);
void CheckBan(); void CheckBan();
bool CheckAbuse(); bool CheckAbuse();
UserPass up, up2;
std::string pass_decrypted; std::string pass_decrypted;
std::wstring pass_hashed;
std::wstring salt; std::wstring salt;
}; };

View File

@ -110,10 +110,11 @@ bool result = false;
if( puser ) if( puser )
{ {
up.has_pass = true; puser->has_pass = true;
up.pass = new_password; puser->password = new_password;
system->crypt.PassHashCrypt(up); system->crypt.PassHashCrypt(*puser);
result = (db->ChangeUserPass(user_id, up) == WINIX_ERR_OK);
result = puser->update();
if( result ) if( result )
log << log2 << "Passwd: password for user " << puser->name << " has been changed" << logend; log << log2 << "Passwd: password for user " << puser->name << " has been changed" << logend;

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2011-2014, Tomasz Sowa * Copyright (c) 2011-2021, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -36,7 +36,7 @@
#define headerfile_winix_functions_passwd #define headerfile_winix_functions_passwd
#include "functionbase.h" #include "functionbase.h"
#include "core/user.h" #include "models/user.h"
namespace Winix namespace Winix
{ {
@ -61,8 +61,6 @@ public:
private: private:
UserPass up;
void ChangePassword(User * puser); void ChangePassword(User * puser);
bool ResetPassword(User * puser, long code, bool use_ses_log); bool ResetPassword(User * puser, long code, bool use_ses_log);

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2012-2014, Tomasz Sowa * Copyright (c) 2012-2021, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -73,7 +73,7 @@ bool RmUser::RemoveUser(long user_id)
result = true; result = true;
log << log2 << "RmUser: user id: " << user_id << " name: " << name << " was removed" << logend; log << log2 << "RmUser: user id: " << user_id << " name: " << name << " was removed" << logend;
if( db->RemoveUser(user_id) != WINIX_ERR_OK ) if( !puser->remove() )
log << log1 << "RmUser: I cannot remove a user id: " << user_id << " from database" << logend; log << log1 << "RmUser: I cannot remove a user id: " << user_id << " from database" << logend;
} }
} }

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2012-2014, Tomasz Sowa * Copyright (c) 2012-2021, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -64,7 +64,7 @@ void TimeZone::MakePost()
if( system->time_zones.HasZone(tz_id) ) if( system->time_zones.HasZone(tz_id) )
{ {
cur->session->puser->time_zone_id = tz_id; cur->session->puser->time_zone_id = tz_id;
db->ChangeUserTimeZone(cur->session->puser->id, tz_id); cur->session->puser->update();
} }
else else
{ {

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2008-2014, Tomasz Sowa * Copyright (c) 2008-2021, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -32,11 +32,12 @@
* *
*/ */
#ifndef headerfile_winix_core_group #ifndef headerfile_winix_models_group
#define headerfile_winix_core_group #define headerfile_winix_models_group
#include <string> #include <string>
#include <vector> #include <vector>
#include "model.h"
namespace Winix namespace Winix
@ -44,23 +45,42 @@ namespace Winix
struct Group class Group : public morm::Model
{ {
public:
long id; long id;
std::wstring name; // group name std::wstring name; // group name
std::vector<long> members; // users id //std::vector<long> members; // users id
Group() Group()
{ {
Clear(); Clear();
} }
void map_fields()
{
field(L"id", id, morm::FT::no_insertable | morm::FT::no_updatable | morm::FT::primary_key);
field(L"name", name);
}
void prepare_table()
{
table(L"core", L"group");
}
void after_insert()
{
get_last_sequence_for_primary_key(L"core.group_id_seq", id);
}
void Clear() void Clear()
{ {
id = -1; id = -1;
name.clear(); name.clear();
members.clear(); //members.clear();
} }
}; };

View File

@ -33,6 +33,7 @@
*/ */
#include "user.h" #include "user.h"
#include "core/misc.h"
namespace Winix namespace Winix
@ -46,6 +47,50 @@ User::User()
} }
void User::map_fields()
{
field(L"id", id, morm::FT::no_insertable | morm::FT::no_updatable | morm::FT::primary_key);
field(L"login", name); // IMPROVEME set the same name, either 'login' or 'name'
field(L"super_user", super_user);
field(L"has_pass", has_pass);
field(L"pass_type", pass_type);
field(L"password", password);
field(L"pass_encrypted", pass_encrypted);
field(L"pass_hash_salted", pass_hash_salted);
field(L"email", email);
field(L"notify", notify);
field(L"env", env);
field(L"aenv", aenv);
field(L"status", status);
field(L"locale_id", locale_id);
field(L"time_zone_id", time_zone_id);
}
void User::prepare_table()
{
table(L"core", L"user");
}
void User::after_select()
{
}
void User::after_insert()
{
get_last_sequence_for_primary_key(L"core.user_id_seq", id);
}
void User::Clear() void User::Clear()
{ {
id = -1; id = -1;
@ -59,9 +104,26 @@ void User::Clear()
status = WINIX_ACCOUNT_BLOCKED; status = WINIX_ACCOUNT_BLOCKED;
locale_id = 0; locale_id = 0;
time_zone_id = 0; time_zone_id = 0;
has_pass = false;
pass_type = 0;
pass_hash_salted = false;
clear_passwords();
} }
void User::clear_passwords()
{
Overwrite(password);
password.clear();
Overwrite(pass_encrypted);
pass_encrypted.clear();
}
bool User::IsMemberOf(long group) bool User::IsMemberOf(long group)
{ {

View File

@ -5,7 +5,7 @@
*/ */
/* /*
* Copyright (c) 2008-2014, Tomasz Sowa * Copyright (c) 2008-2021, Tomasz Sowa
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -32,11 +32,12 @@
* *
*/ */
#ifndef headerfile_winix_core_user #ifndef headerfile_winix_models_user
#define headerfile_winix_core_user #define headerfile_winix_models_user
#include <string> #include <string>
#include <vector> #include <vector>
#include "model.h"
#include "space/space.h" #include "space/space.h"
#include "date/date.h" #include "date/date.h"
@ -84,29 +85,23 @@ namespace Winix
(when the pointer is not null then winix do not check what the value of 'status' is -- (when the pointer is not null then winix do not check what the value of 'status' is --
the status is only tested in 'login' function) the status is only tested in 'login' function)
*/ */
class User : public morm::Model
/*
a temporary struct used for hashing and encrypting a user's password
*/
struct UserPass
{ {
bool has_pass; // true if the user has a password set public:
// if false the user cannot login
int pass_type; // the kind of hash (WINIX_CRYPT_HASH_* see crypt.h)
std::wstring pass; // password hashed or plain text if pass_type==0
std::string pass_encrypted; // password encrypted
bool pass_hash_salted; // true when the hash was salted (plain text passwords are never salted)
};
struct User
{
long id; long id;
std::wstring name; std::wstring name;
bool super_user; bool super_user;
std::vector<long> groups;
bool has_pass; // true if the user has a password set
// if false the user cannot login
int pass_type; // the kind of hash (WINIX_CRYPT_HASH_* see crypt.h)
std::wstring password; // password hashed or plain text if pass_type==0
std::string pass_encrypted; // password encrypted
bool pass_hash_salted; // true when the hash was salted (plain text passwords are never salted)
std::wstring email; std::wstring email;
int notify; int notify;
@ -116,6 +111,7 @@ struct User
// environment variables set only by an administrator // environment variables set only by an administrator
// an administrator can use 'env' winix function with 'a' parameter // an administrator can use 'env' winix function with 'a' parameter
// IMPROVEME rename me to something better (env_admin?)
PT::Space aenv; PT::Space aenv;
// account status // account status
@ -129,13 +125,23 @@ struct User
// time zone identifier // time zone identifier
size_t time_zone_id; size_t time_zone_id;
std::vector<long> groups;
User(); User();
void Clear(); void map_fields();
void prepare_table();
void after_insert();
void after_select();
void Clear(); // IMPROVEME what about clear() from Model?
bool IsMemberOf(long group); bool IsMemberOf(long group);
bool ReadMonthDayTime(PT::Date & date, const wchar_t * str); bool ReadMonthDayTime(PT::Date & date, const wchar_t * str);
bool SetTzFromEnv(); bool SetTzFromEnv();
void clear_passwords();
}; };

View File

@ -147,8 +147,40 @@ void env_admin_tab_has_next(Info & i)
static size_t req_id = 0;
static User * puser = nullptr;
/*
* IMPROVEME
* in the future the user pointer will be set by the env controller
* a new struct will be added and put to templates (when new ezc object templates will be ready)
*
*/
User * env_get_user()
{
if( cur->request->id != req_id )
{
req_id = cur->request->id;
puser = 0;
if( cur->session->puser )
{
if( cur->session->puser->super_user && cur->request->IsPostVar(L"userid") )
{
long id = Tol(cur->request->PostVar(L"userid"));
puser = system->users.GetUser(id);
}
else
{
puser = cur->session->puser;
}
}
}
return puser;
}
void env_user_admin_env_str(Info & i) void env_user_admin_env_str(Info & i)
{ {
@ -156,7 +188,7 @@ void env_user_admin_env_str(Info & i)
if( cur->session->puser && cur->session->puser->super_user ) if( cur->session->puser && cur->session->puser->super_user )
{ {
User * puser = functions->fun_env.GetUser(); User * puser = env_get_user();
if( puser ) if( puser )
i.out << puser->aenv; i.out << puser->aenv;
@ -166,7 +198,7 @@ void env_user_admin_env_str(Info & i)
void env_user_env_str(Info & i) void env_user_env_str(Info & i)
{ {
User * puser = functions->fun_env.GetUser(); User * puser = env_get_user();
if( puser ) if( puser )
i.out << puser->env; i.out << puser->env;
@ -175,7 +207,7 @@ void env_user_env_str(Info & i)
void env_user_id(Info & i) void env_user_id(Info & i)
{ {
User * puser = functions->fun_env.GetUser(); User * puser = env_get_user();
if( puser ) if( puser )
i.out << puser->id; i.out << puser->id;
@ -184,7 +216,7 @@ void env_user_id(Info & i)
void env_user_name(Info & i) void env_user_name(Info & i)
{ {
User * puser = functions->fun_env.GetUser(); User * puser = env_get_user();
if( puser ) if( puser )
i.out << puser->name; i.out << puser->name;
@ -247,7 +279,7 @@ void env_user_tab_is_current(Info & i)
{ {
if( env_user_tab_init() ) if( env_user_tab_init() )
{ {
User * puser = functions->fun_env.GetUser(); User * puser = env_get_user();
if( puser ) if( puser )
i.res = (user_iter->id == puser->id ); i.res = (user_iter->id == puser->id );

View File

@ -36,7 +36,7 @@
#include "misc.h" #include "misc.h"
#include "core/misc.h" #include "core/misc.h"
#include "core/request.h" #include "core/request.h"
#include "core/user.h" #include "models/user.h"
namespace Winix namespace Winix
{ {