added: flag has_pass to User structure

if false that means the user has not set a password yet 
       (this can be used by a plugins to create a new account without a password set)
       in order to login the user first has to set a new password
       (this can be done from a some kind of activation link send via email etc)
       



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@954 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2014-06-07 11:20:44 +00:00
parent 222955a2e7
commit 01892d2766
9 changed files with 60 additions and 26 deletions

View File

@ -3,10 +3,13 @@
include Makefile.dep include Makefile.dep
#ifndef CXX ifeq ($(OSTYPE), FreeBSD)
# temporarily workaround: forcing using clang (CXX is defined by the OS and is equal to g++) CXX = clang++
CXX = g++-4.8 else
#endif CXX = g++-4.8
endif
ifndef CXXFLAGS ifndef CXXFLAGS
CXXFLAGS = -Wall -O0 -g -fPIC -pthread -std=c++11 -I/usr/local/include -I/usr/include/postgresql -DEZC_USE_WINIX_LOGGER -DEZC_HAS_SPECIAL_STREAM CXXFLAGS = -Wall -O0 -g -fPIC -pthread -std=c++11 -I/usr/local/include -I/usr/include/postgresql -DEZC_USE_WINIX_LOGGER -DEZC_HAS_SPECIAL_STREAM

View File

@ -34,11 +34,11 @@ public:
// default: true // default: true
bool demonize; bool demonize;
// system user name (to which drop privileges) // system user's name to whom winix should drop privileges
// used only if winix is started as the root // used only if winix is started as the root
std::string user; std::string user;
// system group name (to which drop privileges) // system group's name to which drop privileges
// used only if winix is started as the root // used only if winix is started as the root
std::string group; std::string group;
@ -51,21 +51,23 @@ public:
// log file name, log file name for notifications (sending emails, etc) // log file name, log file name for notifications (sending emails, etc)
std::string log_file, log_notify_file; std::string log_file, log_notify_file;
// the log level (how much info should be inserted to logs)
// 1 - minimum // 1 - minimum
// 2 - (default) // 2 - (default)
// 3 - maximum - all logs // 3 - maximum - all logs
int log_level; int log_level;
// logging to stdout too // logging to stdout too
// only if demonize is 'false' // this option is valid only if 'demonize' option is set to 'false'
// default: false // default: false
bool log_stdout; bool log_stdout;
// how many requests should be saved in the same time // how many requests should be saved in the same time
// if you have a very busy server you can incrase this value
// default: 1 // default: 1
int log_request; int log_request;
// whether to save each line of the config (use it for debug purposes) // whether to save each line of the config (used for debugging purposes)
// default: false // default: false
bool log_save_each_line; bool log_save_each_line;
@ -80,6 +82,7 @@ public:
bool log_server_answer; bool log_server_answer;
// logging db queries // logging db queries
// warning: use it only on a developer's server as it logs the hashes of passwords too
// default: false // default: false
bool log_db_query; bool log_db_query;
@ -89,7 +92,7 @@ public:
// how many characters in values should be logged from POST parameters // how many characters in values should be logged from POST parameters
// default: 80 // default: 80
// set to 0 to turn off // set to 0 to turn it off
size_t log_post_value_size; size_t log_post_value_size;
// request delimiter in the log file, default "---------" // request delimiter in the log file, default "---------"
@ -132,39 +135,46 @@ public:
// default: index.html // default: index.html
std::wstring templates_index; std::wstring templates_index;
// if true then only root can use 'template' function // if true then only root can use 'template' winix function
// default: false // default: false
bool template_only_root_use_template_fun; bool template_only_root_use_template_fun;
// the database name, user name and a password for the PostgreSQL database
std::string db_database; std::string db_database;
std::string db_user; std::string db_user;
std::string db_pass; std::string db_pass;
// the name of the cookie which has the session identifier
std::wstring http_session_id_name; std::wstring http_session_id_name;
// string used in a place where is a user (or group) selected // string used in a place where is a user (or group) selected
// !! IMPROVE ME should be moved to locales
std::wstring priv_no_user; std::wstring priv_no_user;
std::wstring priv_no_group; std::wstring priv_no_group;
// time in seconds when the user will be automatically logged out (iddle time) // time in seconds when a user will be automatically logged out (iddle time)
// default: 10800 = 3 hours
int session_max_idle; int session_max_idle;
// time in seconds when the user will be automatically logged out (when he selected 'remember me' option) // time in seconds when a user will be automatically logged out
// when he has selected the 'remember me' option when logging in
// this time is usually greater than session_max_idle // this time is usually greater than session_max_idle
// default: 16070400 = 3 months
int session_remember_max_idle; int session_remember_max_idle;
// this file is used when the program is starting and ending // a file to which winix stores sessions info
// it is used when winix starts (boots) and quits
std::string session_file; std::string session_file;
// how many sessions can be (zero turn off this checking) // how many sessions can be (zero turn off this checking)
// default: 1000000 (one milion) // default: 1000000 (one milion)
size_t session_max; size_t session_max;
// allow the html output to be compressed // allow the winix output to be compressed
// default: true // default: true
bool compression; bool compression;
// if the output is shorter than this value then it will not be compressed // compress only if the output is greater or equal to this value
// default: 512 bytes // default: 512 bytes
size_t compression_page_min_size; size_t compression_page_min_size;
@ -191,12 +201,12 @@ public:
bool html_filter_trim_white; bool html_filter_trim_white;
// when long words should be broken (a space will be inserted) // when long words should be broken (a space will be inserted)
// default: after 60 non white characters will be put a space // default: after 60 non white characters there will be put a space
// set zero to turn off // set zero to turn off
size_t html_filter_break_word; size_t html_filter_break_word;
// when long lines should be broken (a new line character will be inserted) // when long lines should be broken (a new line character will be inserted)
// default: 80 // default: 110
// set zero to turn off // set zero to turn off
size_t html_filter_wrap_line; size_t html_filter_wrap_line;
@ -215,9 +225,11 @@ public:
HTMLFilter::OrphanMode html_filter_orphans_mode; HTMLFilter::OrphanMode html_filter_orphans_mode;
// the url of a new empty item (if there is not the subject too) // the url of a new empty item (if there is not the subject too)
// !! IMPROVE ME should be moved to locale
std::wstring item_url_empty; std::wstring item_url_empty;
// maximum length of a file send by post multipart form // maximum length of a file send by post multipart form
// default: 8388608 - 8MB
// 0 - not used // 0 - not used
size_t post_file_max; size_t post_file_max;

View File

@ -37,6 +37,7 @@ void User::Clear()
} }
bool User::IsMemberOf(long group) bool User::IsMemberOf(long group)
{ {
std::vector<long>::iterator i; std::vector<long>::iterator i;

View File

@ -32,6 +32,7 @@ namespace Winix
#define WINIX_ACCOUNT_NOT_ACTIVATED 1 #define WINIX_ACCOUNT_NOT_ACTIVATED 1
// 2 - a user clicked on the link in the mail and now can normally use his account // 2 - a user clicked on the link in the mail and now can normally use his account
// (if has a password set too)
#define WINIX_ACCOUNT_READY 2 #define WINIX_ACCOUNT_READY 2
// 3 - account was suspended // 3 - account was suspended
@ -41,6 +42,9 @@ namespace Winix
#define WINIX_ACCOUNT_BLOCKED 4 #define WINIX_ACCOUNT_BLOCKED 4
/* /*
a user can login only to an account which status is equal to WINIX_ACCOUNT_READY a user can login only to an account which status is equal to WINIX_ACCOUNT_READY
@ -62,6 +66,8 @@ namespace Winix
*/ */
struct UserPass struct UserPass
{ {
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) 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::wstring pass; // password hashed or plain text if pass_type==0
std::string pass_encrypted; // password encrypted std::string pass_encrypted; // password encrypted
@ -79,7 +85,6 @@ struct User
std::wstring email; std::wstring email;
int notify; int notify;
// environment variables which can be set by this user // environment variables which can be set by this user
// use 'env' winix function // use 'env' winix function
PT::Space env; PT::Space env;
@ -99,7 +104,6 @@ struct User
// time zone identifier // time zone identifier
size_t time_zone_id; size_t time_zone_id;
User(); User();
void Clear(); void Clear();

View File

@ -17,7 +17,7 @@ namespace Winix
#define WINIX_VER_MAJOR 0 #define WINIX_VER_MAJOR 0
#define WINIX_VER_MINOR 6 #define WINIX_VER_MINOR 6
#define WINIX_VER_REVISION 0 #define WINIX_VER_REVISION 1

View File

@ -27,7 +27,7 @@ bool Db::GetUserPass(const std::wstring & login, long & user_id, UserPass & up)
try try
{ {
query.Clear(); query.Clear();
query << R("select id, password, pass_encrypted, pass_type, pass_hash_salted from core.user where login=") query << R("select id, has_pass, password, pass_encrypted, pass_type, pass_hash_salted from core.user where login=")
<< login << login
<< R(";"); << R(";");
@ -46,6 +46,7 @@ bool Db::GetUserPass(const std::wstring & login, long & user_id, UserPass & up)
} }
int cuser_id = AssertColumn(r, "id"); int cuser_id = AssertColumn(r, "id");
int chas_pass = AssertColumn(r, "has_pass");
int cpass_type = AssertColumn(r, "pass_type"); int cpass_type = AssertColumn(r, "pass_type");
int csalted = AssertColumn(r, "pass_hash_salted"); int csalted = AssertColumn(r, "pass_hash_salted");
int cpassword = AssertColumn(r, "password"); int cpassword = AssertColumn(r, "password");
@ -53,6 +54,7 @@ bool Db::GetUserPass(const std::wstring & login, long & user_id, UserPass & up)
user_ok = true; user_ok = true;
user_id = AssertValueLong(r, 0, cuser_id); 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_type = AssertValueInt(r, 0, cpass_type);
up.pass_hash_salted = AssertValueBool(r, 0, csalted); up.pass_hash_salted = AssertValueBool(r, 0, csalted);
AssertValueWide(r, 0, cpassword, up.pass); AssertValueWide(r, 0, cpassword, up.pass);
@ -79,9 +81,10 @@ Error Db::AddUser(User & user, const UserPass & up)
try try
{ {
query.Clear(); query.Clear();
query << R("insert into core.user (login, password, pass_encrypted, super_user, email," 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 (") "notify, pass_type, pass_hash_salted, env, aenv, status, locale_id, time_zone_id) values (")
<< user.name; << user.name
<< up.has_pass;
// for safety we put up.pass only if there is not an encrypted version // for safety we put up.pass only if there is not an encrypted version
// someone could have forgotten to clear up.pass // someone could have forgotten to clear up.pass
@ -125,8 +128,9 @@ return status;
Error Db::ChangeUserPass(long user_id, const UserPass & up) Error Db::ChangeUserPass(long user_id, const UserPass & up)
{ {
query.Clear(); query.Clear();
query << R("update core.user set(password, pass_encrypted," query << R("update core.user set(has_pass, password, pass_encrypted,"
"pass_type, pass_hash_salted) = ("); "pass_type, pass_hash_salted) = (")
<< up.has_pass;
// for safety // for safety
if( up.pass_encrypted.empty() ) if( up.pass_encrypted.empty() )

View File

@ -139,6 +139,7 @@ return true;
*/ */
bool AddUser::AddNewUser(User & user, const std::wstring & pass) bool AddUser::AddNewUser(User & user, const std::wstring & pass)
{ {
up.has_pass = true;
up.pass = pass; up.pass = pass;
system->crypt.PassHashCrypt(up); system->crypt.PassHashCrypt(up);

View File

@ -91,7 +91,15 @@ bool result;
if( db->GetUserPass(login, user_id, up) ) if( db->GetUserPass(login, user_id, up) )
{ {
result = CheckPasswords(password); if( up.has_pass )
{
result = CheckPasswords(password);
}
else
{
log << log2 << "Login: this account has not a password set yet" << logend;
result = false;
}
} }
else else
{ {

View File

@ -85,6 +85,7 @@ bool result = false;
if( puser ) if( puser )
{ {
up.has_pass = true;
up.pass = new_password; up.pass = new_password;
system->crypt.PassHashCrypt(up); system->crypt.PassHashCrypt(up);
result = (db->ChangeUserPass(user_id, up) == WINIX_ERR_OK); result = (db->ChangeUserPass(user_id, up) == WINIX_ERR_OK);