Fork de wikipp, le moteur de wiki en c++, basé sur cppcms. Le fork ajoute la langue française
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

users.cpp 4.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. #include "users.h"
  2. #include "wiki.h"
  3. #include "users_content.h"
  4. #include <sys/time.h>
  5. #include <time.h>
  6. #include <cppcms/url_dispatcher.h>
  7. #include <cppcms/cache_interface.h>
  8. #include <cppcms/session_interface.h>
  9. #define _(X) ::cppcms::locale::translate(X)
  10. namespace content {
  11. login_form::login_form(apps::wiki *_w) :
  12. w(_w)
  13. {
  14. username.message(_("Username"));
  15. password.message(_("Password"));
  16. login.value(_("Login"));
  17. add(username);
  18. add(password);
  19. add(login);
  20. username.non_empty();
  21. password.non_empty();
  22. }
  23. bool login_form::validate()
  24. {
  25. if(!form::validate())
  26. return false;
  27. if(w->users.check_login(username.value(),password.value()))
  28. return true;
  29. password.valid(false);
  30. return false;
  31. }
  32. new_user_form::new_user_form(apps::wiki *_w):
  33. w(_w)
  34. {
  35. username.message(_("Username"));
  36. password1.message(_("Password"));
  37. password2.message(_("Confirm"));
  38. captcha.message(_("Solve"));
  39. submit.value(_("Submit"));
  40. add(username);
  41. add(password1);
  42. add(password2);
  43. add(captcha);
  44. add(submit);
  45. username.non_empty();
  46. password1.non_empty();
  47. password2.check_equal(password1);
  48. }
  49. void new_user_form::generate_captcha()
  50. {
  51. struct timeval tv;
  52. gettimeofday(&tv,NULL);
  53. unsigned seed=tv.tv_usec / 1000 % 100;
  54. int num1=rand_r(&seed) % 10+1;
  55. int num2=rand_r(&seed) % 10+1;
  56. int sol=num1+num2;
  57. captcha.help((booster::locale::format("{1} + {2}") % num1 % num2).str());
  58. w->session().set("captcha",sol);
  59. w->session().age(5*60); // at most 5 minutes
  60. }
  61. bool new_user_form::validate()
  62. {
  63. if(!form::validate())
  64. return false;
  65. if(!w->session().is_set("captcha") || captcha.value()!=w->session()["captcha"]) {
  66. w->session().erase("captcha");
  67. return false;
  68. }
  69. if(w->users.user_exists(username.value())) {
  70. username.error_message(_("This user exists"));
  71. username.valid(false);
  72. return false;
  73. }
  74. return true;
  75. }
  76. }
  77. namespace apps {
  78. users::users(wiki &w) : master(w)
  79. {
  80. wi.dispatcher().assign("^/login/?$",&users::login,this);
  81. disable_reg=settings().get("wikipp.disable_registration",true);
  82. if(!disable_reg){
  83. wi.dispatcher().assign("^/register/?$",&users::new_user,this);
  84. }
  85. reset();
  86. }
  87. void users::new_user()
  88. {
  89. content::new_user c(&wi);
  90. if(request().request_method()=="POST") {
  91. c.form.load(context());
  92. cppdb::session sql(conn);
  93. cppdb::transaction tr(sql);
  94. if(c.form.validate()) {
  95. sql<< "INSERT INTO users(username,password) "
  96. "VALUES(?,?)"
  97. << c.form.username.value()
  98. << c.form.password1.value()
  99. << cppdb::exec;
  100. tr.commit();
  101. wi.page.redirect(locale_name);
  102. session()["username"]=c.form.username.value();
  103. session().expose("username");
  104. session().default_age(); // return to default
  105. return;
  106. }
  107. tr.commit();
  108. }
  109. c.form.generate_captcha();
  110. ini(c);
  111. render("new_user",c);
  112. }
  113. void users::reset()
  114. {
  115. auth_done=auth_ok=false;
  116. }
  117. std::string users::login_url()
  118. {
  119. return wi.root()+"/login/";
  120. }
  121. bool users::user_exists(std::string u)
  122. {
  123. std::string key="user_exists_"+u;
  124. std::string tmp;
  125. if(cache().fetch_frame(key,tmp,true)) { // No triggers
  126. return true;
  127. }
  128. cppdb::result r;
  129. cppdb::session sql(conn);
  130. r=sql<<"SELECT id FROM users WHERE username=?" << u << cppdb::row;
  131. if(!r.empty()) {
  132. cache().store_frame(key,tmp);
  133. return true;
  134. }
  135. return false;
  136. }
  137. void users::login()
  138. {
  139. content::login c(&wi);
  140. if(request().request_method()=="POST") {
  141. c.form.load(context());
  142. if(c.form.validate()) {
  143. wi.page.redirect(locale_name);
  144. session()["username"]=c.form.username.value();
  145. session().expose("username");
  146. return;
  147. }
  148. }
  149. else {
  150. if(auth()) {
  151. response().set_redirect_header(request().http_referer());
  152. session().clear();
  153. return;
  154. }
  155. }
  156. ini(c);
  157. if(!disable_reg)
  158. c.new_user=wi.root()+"/register/";
  159. render("login",c);
  160. }
  161. bool users::check_login(std::string u,std::string p)
  162. {
  163. if(u.empty() || p.empty())
  164. return false;
  165. cppdb::result r;
  166. cppdb::session sql(conn);
  167. r=sql<< "SELECT password FROM users "
  168. "WHERE username=?" << u << cppdb::row;
  169. if(r.empty()) {
  170. return false;
  171. }
  172. std::string pass;
  173. r>>pass;
  174. if(p!=pass)
  175. return false;
  176. return true;
  177. }
  178. bool users::auth()
  179. {
  180. if(!auth_done)
  181. do_auth();
  182. return auth_ok;
  183. }
  184. void users::do_auth()
  185. {
  186. if(session().is_set("username") && user_exists(session()["username"])) {
  187. auth_ok=true;
  188. }
  189. else {
  190. auth_ok=false;
  191. }
  192. if(auth_ok)
  193. username=session()["username"];
  194. else
  195. username=request().remote_addr();
  196. auth_done=true;
  197. }
  198. void users::error_forbidden()
  199. {
  200. response().set_redirect_header(login_url());
  201. }
  202. }