From b7007da5a911a6e8be92750073048f700bcc271c Mon Sep 17 00:00:00 2001 From: Tomasz Sowa Date: Fri, 9 Mar 2012 22:56:54 +0000 Subject: [PATCH] fixed: misc: ValidateEmail() buffer overflow added: notifications for resetting a user's password (there is no a winix function for this yet) git-svn-id: svn://ttmath.org/publicrep/winix/trunk@817 e52654a7-88a9-db11-a3e9-0013d4bc506e --- core/config.cpp | 20 ++++- core/config.h | 14 +++- core/misc.cpp | 75 +++++++++++-------- core/misc.h | 3 +- core/pluginmsg.h | 2 +- db/db.cpp | 6 +- db/db.h | 2 +- functions/Makefile.dep | 1 + functions/adduser.cpp | 45 ++---------- functions/adduser.h | 1 - functions/passwd.cpp | 131 +++++++++++++++++++++++++-------- functions/passwd.h | 7 +- functions/pw.cpp | 134 +++++++++++++++++++++++++++++++++- functions/pw.h | 7 ++ html/fun_pw.html | 66 +++++++++++------ locale/en | 17 ++++- locale/pl | 11 +++ notify/notify.cpp | 34 +++++++-- notify/notify.h | 3 + notify/notifypool.h | 1 + notify/notifythread.cpp | 3 +- templates/Makefile.dep | 23 ++++++ templates/Makefile.o.dep | 2 +- templates/pw.cpp | 38 ++++++++++ templates/templates.cpp | 7 ++ templates/templates.h | 7 ++ txt/notify_reset_password.txt | 25 +++++++ 27 files changed, 540 insertions(+), 145 deletions(-) create mode 100755 templates/pw.cpp create mode 100755 txt/notify_reset_password.txt diff --git a/core/config.cpp b/core/config.cpp index 3988b81..c290307 100755 --- a/core/config.cpp +++ b/core/config.cpp @@ -234,7 +234,8 @@ void Config::AssignValues(bool stdout_is_closed) ezc_max_elements = Size(L"ezc_max_elements", 50000); ezc_max_loop_elements = Size(L"ezc_max_loop_elements", 5000); - account_need_email_verification = Bool(L"account_need_email_verification", true); + account_need_email_verification = Bool(L"account_need_email_verification", true); + reset_password_code_expiration_time = Long(L"reset_password_code_expiration_time", 86400); } @@ -366,6 +367,23 @@ int Config::Int(const std::wstring & name, int def) } +long Config::Long(const wchar_t * name) +{ + return space.Long(name); +} + +long Config::Long(const wchar_t * name, long def) +{ + return space.Long(name, def); +} + +long Config::Long(const std::wstring & name, long def) +{ + return space.Long(name, def); +} + + + size_t Config::Size(const wchar_t * name) { return space.Size(name); diff --git a/core/config.h b/core/config.h index 763ab39..bc26976 100755 --- a/core/config.h +++ b/core/config.h @@ -472,6 +472,11 @@ public: // default: true bool account_need_email_verification; + // when a user forgot his password we are able to send an email to him + // with a link to the page where there is a html form for setting a new password + // this option tells how long (in seconds) the link is valid + // default: 86400 (24 hours) + long reset_password_code_expiration_time; Config(); @@ -484,9 +489,12 @@ public: std::string & AText(const wchar_t * name, const char * def); std::string & AText(const std::wstring & name, const char * def); - int Int(const wchar_t *); - int Int(const wchar_t * name, int def); - int Int(const std::wstring & name, int def); + int Int(const wchar_t *); + int Int(const wchar_t * name, int def); + int Int(const std::wstring & name, int def); + long Long(const wchar_t *); + long Long(const wchar_t * name, long def); + long Long(const std::wstring & name, long def); size_t Size(const wchar_t *); size_t Size(const wchar_t * name, size_t def); size_t Size(const std::wstring & name, size_t def); diff --git a/core/misc.cpp b/core/misc.cpp index ef3c134..ee7534f 100755 --- a/core/misc.cpp +++ b/core/misc.cpp @@ -622,48 +622,65 @@ std::wstring::size_type i; } + +bool IsEmailCorrectChar(wchar_t c) +{ +bool correct = false; + + const wchar_t * allowed_chars = L"@.!#$%&'*+-/=?^_`{|}~"; -bool ValidateEmail(const std::wstring & email) -{ - if( email.empty() ) - return false; - - bool correct = true; - size_t i; - wchar_t allowed_chars[] = L"!#$%&'*+-/=?^_`{|}~.@"; - int at = 0; - - for(i=0 ; i= 'A' && c<='Z') || + (c >= 'a' && c<='z') || + (c >= '0' && c<='9') ) { - correct = false; - - if( (email[i] >= 'A' && email[i]<='Z') || - (email[i] >= 'a' && email[i]<='z') || - (email[i] >= '0' && email[i]<='9') ) + correct = true; + } + else + { + for(size_t a=0 ; allowed_chars[a] != 0 ; ++a) { - correct = true; - } - else - { - for(size_t a=0 ; a < sizeof(allowed_chars)-1 ; ++a) + if( c == allowed_chars[a] ) { - if( email[i] == allowed_chars[a] ) - { - correct = true; - break; - } + correct = true; + break; } } - + } + +return correct; +} + + + +bool ValidateEmail(const wchar_t * email) +{ + int at = 0; // how many '@' + int dots_after_at = 0; // how many dots in the domain part + + for(size_t i=0 ; email[i] != 0 ; ++i) + { + if( !IsEmailCorrectChar(email[i]) ) + return false; + if( email[i] == '@' ) ++at; + + if( email[i] == '.' && at > 0 ) + ++dots_after_at; } - if( at != 1 ) + if( at != 1 || dots_after_at == 0 ) return false; -return correct; +return true; } + + +bool ValidateEmail(const std::wstring & email) +{ + return ValidateEmail(email.c_str()); +} + diff --git a/core/misc.h b/core/misc.h index 01acd56..1c7a570 100755 --- a/core/misc.h +++ b/core/misc.h @@ -591,7 +591,8 @@ return str + i; - +bool IsEmailCorrectChar(wchar_t c); +bool ValidateEmail(const wchar_t * email); bool ValidateEmail(const std::wstring & email); bool IsFile(const wchar_t * file); diff --git a/core/pluginmsg.h b/core/pluginmsg.h index 5892794..997fae5 100755 --- a/core/pluginmsg.h +++ b/core/pluginmsg.h @@ -54,7 +54,7 @@ #define WINIX_SESSION_CHANGED 30020 // the winix is closing -// the is not any session available (cur->session is null) +// there is not any sessions available (cur->session is null) #define WINIX_CLOSE 30040 // preparing to remove a file (rm function) diff --git a/db/db.cpp b/db/db.cpp index f65866c..20e867e 100755 --- a/db/db.cpp +++ b/db/db.cpp @@ -117,7 +117,7 @@ return status; -Error Db::ChangeUserPass(const std::wstring & login, const UserPass & up) +Error Db::ChangeUserPass(long user_id, const UserPass & up) { query.Clear(); query << R("update core.user set(password, pass_encrypted," @@ -133,8 +133,8 @@ Error Db::ChangeUserPass(const std::wstring & login, const UserPass & up) query << up.pass_type << up.pass_hash_salted - << R(") where login=") - << login + << R(") where id=") + << user_id << R(";"); return DoCommand(query); diff --git a/db/db.h b/db/db.h index b321164..af98b41 100755 --- a/db/db.h +++ b/db/db.h @@ -46,7 +46,7 @@ public: bool GetUserPass(const std::wstring & login, long & user_id, UserPass & up); Error AddUser(User & user, const UserPass & up); - Error ChangeUserPass(const std::wstring & login, const UserPass & up); + Error ChangeUserPass(long user_id, const UserPass & up); Error ChangeUserEnv(long user_id, const PT::Space & space); Error ChangeUserAdminEnv(long user_id, const PT::Space & space); Error ChangeUserStatus(long user_id, int status); diff --git a/functions/Makefile.dep b/functions/Makefile.dep index 256eb13..957e7c3 100755 --- a/functions/Makefile.dep +++ b/functions/Makefile.dep @@ -848,6 +848,7 @@ pw.o: ../core/lastcontainer.h ../core/mounts.h ../core/mountparser.h pw.o: ../core/crypt.h ../core/users.h ../core/groups.h ../core/group.h pw.o: ../core/loadavg.h ../core/image.h ../core/basethread.h pw.o: ../core/threadmanager.h ../core/synchro.h ../core/log.h ../core/misc.h +pw.o: ../functions/functions.h reload.o: reload.h functionbase.h ../core/item.h ../db/db.h ../db/dbbase.h reload.o: ../db/dbconn.h ../db/dbtextstream.h ../core/textstream.h reload.o: ../core/misc.h ../core/item.h ../core/requesttypes.h diff --git a/functions/adduser.cpp b/functions/adduser.cpp index d4232b4..b045a5f 100755 --- a/functions/adduser.cpp +++ b/functions/adduser.cpp @@ -12,7 +12,7 @@ #include "core/slog.h" #include "core/plugin.h" #include "core/misc.h" - +#include "functions/functions.h" namespace Fun @@ -113,44 +113,8 @@ bool AddUser::IsEmailCorrect(const std::wstring & email, bool use_ses_log) return true; } - -bool AddUser::IsPasswordCorrect(const std::wstring & pass, const std::wstring & conf_pass, bool use_ses_log) -{ - if( pass != conf_pass ) - { - log << log2 << "AddUser: passwords are different" << logend; - - if( use_ses_log ) - slog << logerror << T("adduser_err_passwords_different") << logend; - - return false; - } - - if( pass.size() < config->pass_min_size ) - { - log << log2 << "AddUser: password is too small" << logend; - - if( use_ses_log ) - slog << logerror << T("adduser_err_password_too_small") << " " - << config->pass_min_size << " " << T("adduser_err_password_too_small2") << logend; - - return false; - } - - if( pass.size() > WINIX_ACCOUNT_MAX_PASSWORD_SIZE ) - { - log << log2 << "AddUser: password can't be longer than: " << WINIX_ACCOUNT_MAX_PASSWORD_SIZE << " characters" << logend; - - if( use_ses_log ) - slog << logerror << T("adduser_err_password_too_big") << " " << WINIX_ACCOUNT_MAX_PASSWORD_SIZE - << " " << T("adduser_err_password_too_big2") << logend; - - return false; - } - - -return true; -} +// !! IMPROVE ME +// may it should be moved to passwd winix function /* @@ -203,7 +167,8 @@ void AddUser::MakePost() const std::wstring & email = cur->request->PostVar(L"email"); long code = 0; - if( !IsLoginCorrect(login, true) || !IsEmailCorrect(email, true) || !IsPasswordCorrect(pass, conf_pass, true) ) + if( !IsLoginCorrect(login, true) || !IsEmailCorrect(email, true) || + !functions->fun_passwd.IsPasswordCorrect(pass, conf_pass, true) ) return; user.name = login; diff --git a/functions/adduser.h b/functions/adduser.h index 861c291..3b39451 100755 --- a/functions/adduser.h +++ b/functions/adduser.h @@ -27,7 +27,6 @@ public: void MakeGet(); bool IsLoginCorrect(const std::wstring & login, bool use_ses_log = false); - bool IsPasswordCorrect(const std::wstring & pass, const std::wstring & conf_pass, bool use_ses_log = false); bool IsEmailCorrect(const std::wstring & email, bool use_ses_log = false); bool HasLoginCorrectChars(const std::wstring & login); diff --git a/functions/passwd.cpp b/functions/passwd.cpp index f20cb94..0538a9f 100755 --- a/functions/passwd.cpp +++ b/functions/passwd.cpp @@ -30,13 +30,97 @@ bool Passwd::HasAccess() -bool Passwd::ChangePassword(const std::wstring & login, const std::wstring & new_password) +bool Passwd::IsPasswordCorrect(const std::wstring & pass, const std::wstring & conf_pass, bool use_ses_log) { - up.pass = new_password; - system->crypt.PassHashCrypt(up); - Error res = db->ChangeUserPass(login, up); + if( pass != conf_pass ) + { + log << log2 << "Passwd: passwords are different" << logend; -return res == WINIX_ERR_OK; + if( use_ses_log ) + slog << logerror << T("adduser_err_passwords_different") << logend; + + return false; + } + + if( pass.size() < config->pass_min_size ) + { + log << log2 << "Passwd: password is too small" << logend; + + if( use_ses_log ) + slog << logerror << T("adduser_err_password_too_small") << " " + << config->pass_min_size << " " << T("adduser_err_password_too_small2") << logend; + + return false; + } + + if( pass.size() > WINIX_ACCOUNT_MAX_PASSWORD_SIZE ) + { + log << log2 << "Passwd: password can't be longer than: " << WINIX_ACCOUNT_MAX_PASSWORD_SIZE << " characters" << logend; + + if( use_ses_log ) + slog << logerror << T("adduser_err_password_too_big") << " " << WINIX_ACCOUNT_MAX_PASSWORD_SIZE + << " " << T("adduser_err_password_too_big2") << logend; + + return false; + } + + +return true; +} + + + +bool Passwd::ChangePassword(long user_id, const std::wstring & new_password) +{ +bool result = false; + + User * puser = system->users.GetUser(user_id); + + if( puser ) + { + up.pass = new_password; + system->crypt.PassHashCrypt(up); + result = (db->ChangeUserPass(user_id, up) == WINIX_ERR_OK); + + if( result ) + log << log2 << "Passwd: password for user " << puser->name << " has been changed" << logend; + else + log << log1 << "Passwd: I cannot change password -- database problem" << logend; + } + else + { + log << log1 << "Passwd: there is no a user with id: " << user_id << logend; + } + +return result; +} + + + + +void Passwd::ChangePassword(User * puser) +{ +long user_id; + + const std::wstring & pass_cur = cur->request->PostVar(L"passwordcur"); + const std::wstring & pass_new = cur->request->PostVar(L"passwordnew"); + const std::wstring & pass_conf = cur->request->PostVar(L"passwordconfirm"); + + if( !cur->session->puser->super_user && !functions->fun_login.CheckUserPass(puser->name, pass_cur, user_id) ) + { + log << log3 << "Passwd: incorrect current password" << logend; + slog << logerror << T("passwd_err_bad_current_password") << logend; + return; + } + + if( !IsPasswordCorrect(pass_new, pass_conf) ) + return; + + if( ChangePassword(cur->session->puser->id, pass_new) ) + { + slog << loginfo << T("passwd_password_changed") << logend; + system->RedirectToLastItem(); + } } @@ -49,38 +133,21 @@ return res == WINIX_ERR_OK; */ void Passwd::MakePost() { -long user_id; const std::wstring * plogin; - if( !cur->session->puser ) - return; - - bool is_root = cur->session->puser->super_user; - - if( is_root ) - plogin = &cur->request->PostVar(L"login"); - else - plogin = &cur->session->puser->name; - - const std::wstring & pass_cur = cur->request->PostVar(L"passwordcur"); - const std::wstring & pass_new = cur->request->PostVar(L"passwordnew"); - const std::wstring & pass_conf = cur->request->PostVar(L"passwordconfirm"); - - if( !is_root && !functions->fun_login.CheckUserPass(*plogin, pass_cur, user_id) ) + if( cur->session->puser ) { - log << log3 << "Passwd: incorrect current password" << logend; - slog << logerror << T("passwd_err_bad_current_password") << logend; - return; - } + if( cur->session->puser->super_user ) + plogin = &cur->request->PostVar(L"login"); + else + plogin = &cur->session->puser->name; - if( !functions->fun_adduser.IsPasswordCorrect(pass_new, pass_conf) ) - return; + User * puser = system->users.GetUser(*plogin); - if( ChangePassword(*plogin, pass_new) ) - { - log << log2 << "Passwd: password for " << plogin << " has been changed" << logend; - slog << loginfo << T("passwd_password_changed") << logend; - system->RedirectToLastItem(); + if( puser ) + ChangePassword(puser); + else + log << log1 << "Passwd: there is no such a user: " << *plogin << logend; } } diff --git a/functions/passwd.h b/functions/passwd.h index 08e87ac..b5cb190 100755 --- a/functions/passwd.h +++ b/functions/passwd.h @@ -25,11 +25,16 @@ public: Passwd(); bool HasAccess(); void MakePost(); - bool ChangePassword(const std::wstring & login, const std::wstring & new_password); + + bool IsPasswordCorrect(const std::wstring & pass, const std::wstring & conf_pass, bool use_ses_log = false); + bool ChangePassword(long user_id, const std::wstring & new_password); private: UserPass up; + + void ChangePassword(User * puser); + }; diff --git a/functions/pw.cpp b/functions/pw.cpp index e054e55..cedf22a 100755 --- a/functions/pw.cpp +++ b/functions/pw.cpp @@ -10,6 +10,7 @@ #include "pw.h" #include "core/log.h" #include "core/misc.h" +#include "functions/functions.h" namespace Fun @@ -38,9 +39,10 @@ bool Pw::ActivateAccount(User * puser, long code, bool use_ses_log) { if( db->ChangeUserStatus(puser->id, WINIX_ACCOUNT_READY) == WINIX_ERR_OK ) { - // !! IMPROVE ME - // remove 'activation_code' value from admin environment for the user + puser->aenv.Remove(L"activation_code"); + db->ChangeUserAdminEnv(puser->id, puser->aenv); puser->status = WINIX_ACCOUNT_READY; + log << log2 << "Pw: account: " << puser->name << " activated" << logend; if( use_ses_log ) @@ -113,10 +115,138 @@ void Pw::ActivateAccount() +bool Pw::SetNewPassword(User * puser, bool use_ses_log) +{ +bool result = false; + + const std::wstring & pass = cur->request->PostVar(L"passwordnew"); + const std::wstring & pass_conf = cur->request->PostVar(L"passwordconfirm"); + + if( functions->fun_passwd.IsPasswordCorrect(pass, pass_conf, use_ses_log) ) + { + if( functions->fun_passwd.ChangePassword(puser->id, pass) ) + { + result = true; + + if( use_ses_log ) + slog << loginfo << T("pw_password_changed") << logend; + } + else + { + if( use_ses_log ) + slog << logerror << T("service_unavailable") << logend; + } + } + +return result; +} + + + +bool Pw::ResetPassword(User * puser, long code, bool use_ses_log, bool only_check_access) +{ + std::wstring * user_code_str = puser->aenv.GetValue(L"password_change_code"); + + if( user_code_str ) + { + if( Tol(*user_code_str) == code ) + { + if( only_check_access ) + return true; + else + return SetNewPassword(puser, use_ses_log); + } + else + { + log << log2 << "Pw: incorrect change password code" << logend; + + if( use_ses_log ) + slog << logerror << T(L"incorrect_change_password_code") << logend; + } + } + else + { + log << log1 << "Pw: there is no change password code in admin environment" << logend; + + if( use_ses_log ) + slog << loginfo << T(L"password_cannot_be_changed") << logend; + } + +return false; +} + + +bool Pw::ResetPassword(const std::wstring & login, long code, bool use_ses_log, bool only_check_access) +{ + bool result = false; + User * puser = system->users.GetUser(login); + + if( puser ) + { + long t = static_cast(cur->request->start_time); + + if( puser->aenv.Long(L"password_change_time") + config->reset_password_code_expiration_time > t ) + { + result = ResetPassword(puser, code, use_ses_log, only_check_access); + } + else + { + log << log2 << "Pw: the code has expired" << logend; + + if( use_ses_log ) + slog << logerror << T(L"code_expired") << logend; + } + } + else + { + log << log1 << "Pw: there is no a user: " << login << logend; + } + +return result; +} + + +void Pw::ResetPassword() +{ + const std::wstring & login = cur->request->PostVar(L"login"); + long code = Tol(cur->request->PostVar(L"code")); + + ResetPassword(login, code, true, false); + system->RedirectToLastItem(); +} + + +void Pw::ShowResetPasswordForm() +{ + const std::wstring & login = cur->request->ParamValue(L"login"); + long code = Tol(cur->request->ParamValue(L"code")); + + if( !login.empty() ) + { + if( !ResetPassword(login, code, true, true) ) + system->RedirectToLastItem(); + } + else + { + system->RedirectToLastItem(); + } +} + + +void Pw::MakePost() +{ + if( cur->request->IsParam(L"resetpassword") ) + ResetPassword(); +} + + void Pw::MakeGet() { if( cur->request->IsParam(L"activate") ) ActivateAccount(); + else + if( cur->request->IsParam(L"resetpassword") ) + ShowResetPasswordForm(); } diff --git a/functions/pw.h b/functions/pw.h index ce5fc3b..9a97678 100755 --- a/functions/pw.h +++ b/functions/pw.h @@ -24,14 +24,21 @@ public: Pw(); bool HasAccess(); + void MakePost(); void MakeGet(); bool ActivateAccount(const std::wstring & login, long code, bool use_ses_log = false); + bool ResetPassword(const std::wstring & login, long code, bool use_ses_log = false, bool only_check_access = false); private: bool ActivateAccount(User * puser, long code, bool use_ses_log); + bool ResetPassword(User * puser, long code, bool use_ses_log); void ActivateAccount(); + bool SetNewPassword(User * puser, bool use_ses_log); + bool ResetPassword(User * puser, long code, bool use_ses_log, bool only_check_access); + void ResetPassword(); + void ShowResetPasswordForm(); }; diff --git a/html/fun_pw.html b/html/fun_pw.html index 6c325cf..d53e074 100755 --- a/html/fun_pw.html +++ b/html/fun_pw.html @@ -1,27 +1,51 @@

Pw

-[if user_tab] - - - - - - - - - - - [for user_tab] - - - - - - - +[if winix_function_param_is "resetpassword"] + + +
+ {passwd_form_legend} + + + + +

{passwd_new_password}:

+ + +

{passwd_confirm_new_password}:

+ + + +
+ + + + +[else] + + [if user_tab] +
{pw_table_no}{pw_table_login}{pw_table_is_root}{pw_table_is_active}{pw_table_is_suspended}{pw_table_is_banned}
[user_tab_index][user_tab_name][if user_tab_is_super_user]{pw_table_yes}[end][if user_tab_is_active]{pw_table_yes}[end][if user_tab_is_suspended]{pw_table_yes}[end][if user_tab_is_blocked]{pw_table_yes}[end]
+ + + + + + + + + [for user_tab] + + + + + + + + + [end] +
{pw_table_no}{pw_table_login}{pw_table_is_root}{pw_table_is_active}{pw_table_is_suspended}{pw_table_is_banned}
[user_tab_index][user_tab_name][if user_tab_is_super_user]{pw_table_yes}[end][if user_tab_is_active]{pw_table_yes}[end][if user_tab_is_suspended]{pw_table_yes}[end][if user_tab_is_blocked]{pw_table_yes}[end]
[end] - + [end] - diff --git a/locale/en b/locale/en index 8e08dba..b618938 100755 --- a/locale/en +++ b/locale/en @@ -10,11 +10,15 @@ account_banned = This account has been banned account_activated = Your account has been activated incorrect_activation_code = Incorrect activation code account_already_activated = This account is already activated -account_cannot_be_activated = This account cannot be activated, please contact with system administrator +account_cannot_be_activated = This account cannot be activated, please contact with the system administrator account_email_sent = An email with an activation link has been sent to you -service_unavailable = We are sorry, this service is temporarily unavailable +code_expired = The code has expired +password_cannot_be_changed = The password cannot be changed, please contact with the system administrator +incorrect_change_password_code = Incorrect code for changing your password +service_unavailable = We are sorry, this service is temporarily unavailable +email_sent_to = An email has been sent to: logout = logout @@ -187,6 +191,7 @@ pw_table_is_suspended = Is suspended pw_table_is_banned = Is banned pw_table_yes = yes pw_table_no = no +pw_password_changed = Your password has been changed reload_header = Reload @@ -422,6 +427,7 @@ notify_new = News notify_change = Changes notify_reply = Reply notify_confirm_account = Confirm your account +notify_reset_password = Reset your password notify_from_name = winix notifications notify_from_email = dontreply@winix.org notify_content_type = text/plain; charset="UTF-8" @@ -441,11 +447,18 @@ notify_msg9b = Have a good day. Bye. notify_msg10 = This email is sent to you because you are in the process of creating a new account in our service. notify_msg11 = In order to activate your account click on the link below: notify_msg12 = If you did not request an account in our service just ignore the email. +notify_msg13 = This email is sent to you because you are requested to change your password. +notify_msg14 = In order to set a new password please visit following page: +notify_msg15 = If you did not request to change the password just ignore the email. notify_footer1 = http://www.winix.org notify_footer2 = This message has been sent automatically - do not answer please. notify_footer3 = If you do not want to receive such messages you can switch them off notify_footer4 = in your user control panel. + + + + # errors winix_err_default = An error occured, error code: diff --git a/locale/pl b/locale/pl index 267e58a..841e467 100755 --- a/locale/pl +++ b/locale/pl @@ -13,8 +13,14 @@ account_already_activated = To konto jest już aktywowane account_cannot_be_activated = To konto nie może być aktywowane, proszę skontaktować się z administratorem account_email_sent = Wysłaliśmy Tobie email z linkiem aktywacyjnym +code_expired = Ten kod stracił już swoją ważność +password_cannot_be_changed = Niestety nie możemy zmienić hasła dla tego konta, proszę skontaktować się z administratorem +incorrect_change_password_code = Nieprawidłowy kod do zmiany hasła + service_unavailable = Przepraszamy, serwis tymczasowo niedostępny +email_sent_to = Wiadomość została wysłana do: + logout = wyloguj @@ -208,6 +214,7 @@ pw_table_is_suspended = Wstrzymany pw_table_is_banned = Zbanowany pw_table_yes = tak pw_table_no = nie +pw_password_changed = Twoje hasło zostało zmienione reload_header = Przeładuj @@ -440,6 +447,7 @@ notify_new = Coś nowego notify_change = Zmiany notify_reply = Odpowiedź notify_confirm_account = Potwierdź swoje konto +notify_reset_password = Ustaw swoje hasło notify_from_name = winix notifications notify_from_email = dontreply@winix.org notify_content_type = text/plain; charset="UTF-8" @@ -459,6 +467,9 @@ notify_msg9b = "" notify_msg10 = Otrzymujesz ten email dlatego że jesteś w trakcie procesu zakładania konta w naszym serwisie. notify_msg11 = W celu aktywowania konta prosimy o odwiedzenie poniższego linku: notify_msg12 = Jeśli jednak otrzymałeś ten email przez przypadek prosimy o zignorowanie go. +notify_msg13 = Otrzymujesz ten email dlatego że poprosiłeś o ponowne ustawienie swojego hasła w naszym serwisie. +notify_msg14 = W celu ustawienia nowego hasła prosimy o wejście na poniższą stronę: +notify_msg15 = Jeśli jednak nie prosiłeś o zmianę hasła to poprostu zignoruj ten email. notify_footer1 = http://www.winix.org notify_footer2 = Ta wiadomość została wysłana automatycznie - prosimy na nią nie odpowiadać. notify_footer3 = Jeśli nie chcesz dostawać więcej takich wiadomości możesz je wyłączyć diff --git a/notify/notify.cpp b/notify/notify.cpp index 49c99ce..d7f8d09 100755 --- a/notify/notify.cpp +++ b/notify/notify.cpp @@ -17,16 +17,11 @@ - Notify::Notify() { } - - - - void Notify::SetCur(Cur * pcur) { cur = pcur; @@ -70,6 +65,7 @@ void Notify::Init() notify_template_cms = AddTemplate(L"notify_email_cms.txt"); notify_template_activate_account = AddTemplate(L"notify_confirm_account.txt"); + notify_template_reset_password = AddTemplate(L"notify_reset_password.txt"); plugin.Call(WINIX_NOTIFY_ADD_TEMPLATE); } @@ -124,6 +120,21 @@ void Notify::ActivateAccount(const std::wstring & name, const std::wstring & ema } +void Notify::ResetPassword(const std::wstring & name, const std::wstring & email, long code) +{ + msg.Clear(); + msg.code = WINIX_NOTIFY_CODE_RESET_PASSWORD; + msg.name = name; + msg.email = email; + msg.lang = 0; // !! IMPROVE ME a better language can be chose + msg.activate_code = code; + msg.template_index = notify_template_reset_password; + CreateResetPasswordLink(name, code, msg.item_link); + + notify_pool.Add(msg); + notify_thread.WakeUpThread(); // we are in the first locked thread +} + size_t Notify::AddTemplate(const std::wstring & file_name) { @@ -171,3 +182,16 @@ wchar_t buff[50]; Toa(code, buff, sizeof(buff)/sizeof(wchar_t)); link += buff; } + +void Notify::CreateResetPasswordLink(const std::wstring & name, long code, std::wstring & link) +{ +wchar_t buff[50]; + + link = config->url_proto; + link += config->base_url; + link += L"/pw/resetpassword/login:"; + UrlEncode(name, link, false); + link += L"/code:"; + Toa(code, buff, sizeof(buff)/sizeof(wchar_t)); + link += buff; +} diff --git a/notify/notify.h b/notify/notify.h index e709e5f..523967f 100755 --- a/notify/notify.h +++ b/notify/notify.h @@ -45,6 +45,7 @@ public: void ItemChanged(int notify_code, const Item & item); void ItemChanged(const NotifyMsg & msg); void ActivateAccount(const std::wstring & name, const std::wstring & email, long code); + void ResetPassword(const std::wstring & name, const std::wstring & email, long code); private: @@ -62,11 +63,13 @@ private: size_t notify_template_cms; size_t notify_template_activate_account; + size_t notify_template_reset_password; Patterns patterns; void CreateItemLink(const Item & item, std::wstring & link, std::wstring & dir_link); void CreateActivateLink(const std::wstring & name, long code, std::wstring & link); + void CreateResetPasswordLink(const std::wstring & name, long code, std::wstring & link); }; diff --git a/notify/notifypool.h b/notify/notifypool.h index a28cbd0..c5ae222 100755 --- a/notify/notifypool.h +++ b/notify/notifypool.h @@ -20,6 +20,7 @@ #define WINIX_NOTIFY_CODE_DELETE 4 #define WINIX_NOTIFY_CODE_REPLY 8 #define WINIX_NOTIFY_CODE_CONFIRM_ACCOUNT 16 +#define WINIX_NOTIFY_CODE_RESET_PASSWORD 32 diff --git a/notify/notifythread.cpp b/notify/notifythread.cpp index 4da48dc..fb94670 100755 --- a/notify/notifythread.cpp +++ b/notify/notifythread.cpp @@ -94,7 +94,8 @@ bool res = false; TemplatesNotifyFunctions::notify_msg = notify_pool->GetFirst(); notify_pool->DeleteFirst(); - if( TemplatesNotifyFunctions::notify_msg.code == WINIX_NOTIFY_CODE_CONFIRM_ACCOUNT ) + if( TemplatesNotifyFunctions::notify_msg.code == WINIX_NOTIFY_CODE_CONFIRM_ACCOUNT || + TemplatesNotifyFunctions::notify_msg.code == WINIX_NOTIFY_CODE_RESET_PASSWORD ) { msg.email = TemplatesNotifyFunctions::notify_msg.email; msg.name = TemplatesNotifyFunctions::notify_msg.name; diff --git a/templates/Makefile.dep b/templates/Makefile.dep index 8db01f4..3c28f56 100755 --- a/templates/Makefile.dep +++ b/templates/Makefile.dep @@ -495,6 +495,29 @@ priv.o: ../functions/sort.h ../functions/specialdefault.h ../functions/stat.h priv.o: ../functions/subject.h ../functions/template.h ../functions/tinymce.h priv.o: ../functions/uname.h ../functions/upload.h ../functions/uptime.h priv.o: ../functions/who.h ../functions/vim.h +pw.o: templates.h ../../ezc/src/ezc.h ../../ezc/src/generator.h +pw.o: ../../ezc/src/pattern.h ../../ezc/src/item.h ../../ezc/src/funinfo.h +pw.o: ../../ezc/src/functions.h ../../ezc/src/stringconv.h misc.h +pw.o: localefilter.h locale.h htmltextstream.h ../core/textstream.h +pw.o: patterncacher.h ../core/item.h indexpatterns.h patterns.h +pw.o: changepatterns.h ../core/config.h ../core/htmlfilter.h ../core/cur.h +pw.o: ../core/request.h ../core/requesttypes.h ../core/error.h +pw.o: ../core/config.h ../core/textstream.h ../templates/htmltextstream.h +pw.o: ../core/session.h ../core/user.h ../core/plugindata.h ../core/rebus.h +pw.o: ../core/mount.h ../core/system.h ../core/dirs.h ../core/dircontainer.h +pw.o: ../db/db.h ../db/dbbase.h ../db/dbconn.h ../db/dbtextstream.h +pw.o: ../core/error.h ../db/dbitemquery.h ../db/dbitemcolumns.h +pw.o: ../core/user.h ../core/group.h ../core/dircontainer.h +pw.o: ../core/ugcontainer.h ../core/log.h ../core/logmanipulators.h +pw.o: ../core/slog.h ../core/cur.h ../templates/locale.h ../notify/notify.h +pw.o: ../notify/notifypool.h ../templates/patterns.h ../notify/notifythread.h +pw.o: ../core/basethread.h ../core/synchro.h ../notify/templatesnotify.h +pw.o: ../core/users.h ../core/ugcontainer.h ../core/lastcontainer.h +pw.o: ../core/mounts.h ../core/mountparser.h ../core/crypt.h ../core/run.h +pw.o: ../core/users.h ../core/groups.h ../core/group.h ../core/loadavg.h +pw.o: ../core/image.h ../core/basethread.h ../core/threadmanager.h +pw.o: ../core/sessionmanager.h ../core/sessioncontainer.h ../core/system.h +pw.o: ../core/htmlfilter.h ../core/request.h ../core/misc.h rebus.o: ../core/request.h templates.h ../../ezc/src/ezc.h rebus.o: ../../ezc/src/generator.h ../../ezc/src/pattern.h rebus.o: ../../ezc/src/item.h ../../ezc/src/funinfo.h diff --git a/templates/Makefile.o.dep b/templates/Makefile.o.dep index 97ff70a..be149e8 100755 --- a/templates/Makefile.o.dep +++ b/templates/Makefile.o.dep @@ -1 +1 @@ -o = adduser.o changepatterns.o config.o dir.o doc.o env.o filters.o htmltextstream.o indexpatterns.o insert.o item.o last.o locale.o localefilter.o login.o ls.o man.o misc.o miscspace.o mount.o patterncacher.o patterns.o priv.o rebus.o slog.o stat.o sys.o template.o templates.o upload.o uptime.o user.o who.o winix.o +o = adduser.o changepatterns.o config.o dir.o doc.o env.o filters.o htmltextstream.o indexpatterns.o insert.o item.o last.o locale.o localefilter.o login.o ls.o man.o misc.o miscspace.o mount.o patterncacher.o patterns.o priv.o pw.o rebus.o slog.o stat.o sys.o template.o templates.o upload.o uptime.o user.o who.o winix.o diff --git a/templates/pw.cpp b/templates/pw.cpp new file mode 100755 index 0000000..8f19394 --- /dev/null +++ b/templates/pw.cpp @@ -0,0 +1,38 @@ +/* + * This file is a part of Winix + * and is not publicly distributed + * + * Copyright (c) 2012, Tomasz Sowa + * All rights reserved. + * + */ + +#include "templates.h" +#include "core/request.h" +#include "core/misc.h" + + + +namespace TemplatesFunctions +{ + + +// change password code provided by a user +// we don't know whether it is valid or not +void pw_users_change_password_code(Info & i) +{ + i.out << cur->request->ParamValue(L"code"); +} + + +void pw_change_password_login(Info & i) +{ + i.out << cur->request->ParamValue(L"login"); +} + + + +} // namespace TemplatesFunctions + + + diff --git a/templates/templates.cpp b/templates/templates.cpp index 747523b..f5830b3 100755 --- a/templates/templates.cpp +++ b/templates/templates.cpp @@ -431,6 +431,13 @@ void Templates::CreateFunctions() ezc_functions.Insert("priv_show_form_chmod", priv_show_form_chmod); + /* + pw + */ + ezc_functions.Insert("pw_users_change_password_code", pw_users_change_password_code); + ezc_functions.Insert("pw_change_password_login", pw_change_password_login); + + /* rebus */ diff --git a/templates/templates.h b/templates/templates.h index f05f41d..5f3c5f4 100755 --- a/templates/templates.h +++ b/templates/templates.h @@ -349,6 +349,13 @@ namespace TemplatesFunctions void priv_show_form_chmod(Info & i); + /* + pw + */ + void pw_users_change_password_code(Info & i); + void pw_change_password_login(Info & i); + + /* rebus */ diff --git a/txt/notify_reset_password.txt b/txt/notify_reset_password.txt new file mode 100755 index 0000000..ec0ce8b --- /dev/null +++ b/txt/notify_reset_password.txt @@ -0,0 +1,25 @@ +Subject: [filter fil_qencode]{notify_reset_password}[end]\n +From: [filter fil_qencode]{notify_from_name}[end] <{notify_from_email}>\n +To: [filter fil_qencode][notify_to_name][end] <[notify_to_email]>\n +Content-Transfer-Encoding: 8bit\n +Content-Type: {notify_content_type} +\n\n + +{notify_header} +\n\n + +{notify_msg13}\n +{notify_msg14}\n +[notify_item_link]\n + +\n +\n +{notify_msg15}\n +\n +{notify_msg9b}\n +\n +-- \n +{notify_footer1}\n +{notify_footer2}\n +{notify_footer3}\n +{notify_footer4}\n