Fork de wikipp, le moteur de wiki en c++, basé sur cppcms. Le fork ajoute la langue française
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

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. }