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
This commit is contained in:
Tomasz Sowa 2012-03-09 22:56:54 +00:00
parent 489310ba1c
commit b7007da5a9
27 changed files with 540 additions and 145 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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<email.length() && correct ; ++i)
if( (c >= '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());
}

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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;
}
}

View File

@ -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);
};

View File

@ -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<long>(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();
}

View File

@ -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();
};

View File

@ -1,27 +1,51 @@
<h1>Pw</h1>
[if user_tab]
<table class="tablec">
<tr>
<th>{pw_table_no}</th>
<th>{pw_table_login}</th>
<th>{pw_table_is_root}</th>
<th>{pw_table_is_active}</th>
<th>{pw_table_is_suspended}</th>
<th>{pw_table_is_banned}</th>
</tr>
[for user_tab]
<tr class="[if-index odd]roweven[else]rowodd[end]">
<td>[user_tab_index]</td>
<td>[user_tab_name]</td>
<td>[if user_tab_is_super_user]{pw_table_yes}[end]</td>
<td>[if user_tab_is_active]{pw_table_yes}[end]</td>
<td>[if user_tab_is_suspended]{pw_table_yes}[end]</td>
<td>[if user_tab_is_blocked]{pw_table_yes}[end]</td>
[if winix_function_param_is "resetpassword"]
<form id="additem" method="post" action="[doc_base_url][dir]pw/resetpassword">
<fieldset>
<legend>{passwd_form_legend}</legend>
<input type="hidden" name="login" value="[pw_change_password_login]">
<input type="hidden" name="code" value="[pw_users_change_password_code]">
<p class="withnext">{passwd_new_password}:</p>
<input class="edit" type="password" name="passwordnew" value="">
<p class="withnext">{passwd_confirm_new_password}:</p>
<input class="edit" type="password" name="passwordconfirm" value="">
<input class="submit" type="submit" value="{passwd_submit}">
</fieldset>
</form>
[else]
[if user_tab]
<table class="tablec">
<tr>
<th>{pw_table_no}</th>
<th>{pw_table_login}</th>
<th>{pw_table_is_root}</th>
<th>{pw_table_is_active}</th>
<th>{pw_table_is_suspended}</th>
<th>{pw_table_is_banned}</th>
</tr>
[for user_tab]
<tr class="[if-index odd]roweven[else]rowodd[end]">
<td>[user_tab_index]</td>
<td>[user_tab_name]</td>
<td>[if user_tab_is_super_user]{pw_table_yes}[end]</td>
<td>[if user_tab_is_active]{pw_table_yes}[end]</td>
<td>[if user_tab_is_suspended]{pw_table_yes}[end]</td>
<td>[if user_tab_is_blocked]{pw_table_yes}[end]</td>
</tr>
[end]
</table>
[end]
</table>
[end]

View File

@ -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:

View File

@ -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ć

View File

@ -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;
}

View File

@ -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);
};

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -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

38
templates/pw.cpp Executable file
View File

@ -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

View File

@ -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
*/

View File

@ -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
*/

25
txt/notify_reset_password.txt Executable file
View File

@ -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