Fork de wikipp, le moteur de wiki en c++, basé sur cppcms. Le fork ajoute la langue française
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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