source: main/trunk/greenstone2/runtime-src/src/recpt/usersaction.cpp@ 28913

Last change on this file since 28913 was 28913, checked in by ak19, 10 years ago

6th commit for security of cgiargs. Looked over all occurrences of setmacro in *action.cpp files

  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 14.6 KB
RevLine 
[373]1/**********************************************************************
2 *
3 * usersaction.cpp -- managing users
4 * Copyright (C) 1999 DigiLib Systems Limited, New Zealand
5 *
[533]6 * A component of the Greenstone digital library software
7 * from the New Zealand Digital Library Project at the
8 * University of Waikato, New Zealand.
[373]9 *
[533]10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 *
[373]24 *********************************************************************/
25
[7375]26#include "gsdl_modules_cfg.h"
27#ifdef GSDL_USE_USERS_ACTION
28
[373]29#include "usersaction.h"
30#include "fileutil.h"
31
32
33///////////////
34// usersaction
35///////////////
36
37usersaction::usersaction () {
38 // this action uses cgi variable "a"
39 cgiarginfo arg_ainfo;
40 arg_ainfo.shortname = "a";
41 arg_ainfo.longname = "action";
42 arg_ainfo.multiplechar = true;
[22984]43 arg_ainfo.multiplevalue = false;
[373]44 arg_ainfo.defaultstatus = cgiarginfo::weak;
45 arg_ainfo.argdefault = "um"; // user management
46 arg_ainfo.savedarginfo = cgiarginfo::must;
47 argsinfo.addarginfo (NULL, arg_ainfo);
48
49 // "uma"
50 arg_ainfo.shortname = "uma";
51 arg_ainfo.longname = "user management action";
52 arg_ainfo.multiplechar = true;
[22984]53 arg_ainfo.multiplevalue = false;
[373]54 arg_ainfo.defaultstatus = cgiarginfo::weak;
55 arg_ainfo.argdefault = "listusers";
56 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
57 argsinfo.addarginfo (NULL, arg_ainfo);
58
59 // "umun"
60 arg_ainfo.shortname = "umun";
61 arg_ainfo.longname = "user management user name";
62 arg_ainfo.multiplechar = true;
[22984]63 arg_ainfo.multiplevalue = false;
[373]64 arg_ainfo.defaultstatus = cgiarginfo::weak;
[7381]65 arg_ainfo.argdefault = g_EmptyText;
[373]66 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
67 argsinfo.addarginfo (NULL, arg_ainfo);
68
69 // "umpw"
70 arg_ainfo.shortname = "umpw";
71 arg_ainfo.longname = "user management password";
72 arg_ainfo.multiplechar = true;
[22984]73 arg_ainfo.multiplevalue = false;
[373]74 arg_ainfo.defaultstatus = cgiarginfo::weak;
[7381]75 arg_ainfo.argdefault = g_EmptyText;
[373]76 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
77 argsinfo.addarginfo (NULL, arg_ainfo);
78
79 // "umnpw1"
80 arg_ainfo.shortname = "umnpw1";
81 arg_ainfo.longname = "user management new password 1";
82 arg_ainfo.multiplechar = true;
[22984]83 arg_ainfo.multiplevalue = false;
[373]84 arg_ainfo.defaultstatus = cgiarginfo::weak;
[7381]85 arg_ainfo.argdefault = g_EmptyText;
[373]86 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
87 argsinfo.addarginfo (NULL, arg_ainfo);
88
89 // "umnpw2"
90 arg_ainfo.shortname = "umnpw2";
91 arg_ainfo.longname = "user management new password 2";
92 arg_ainfo.multiplechar = true;
[22984]93 arg_ainfo.multiplevalue = false;
[373]94 arg_ainfo.defaultstatus = cgiarginfo::weak;
[7381]95 arg_ainfo.argdefault = g_EmptyText;
[373]96 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
97 argsinfo.addarginfo (NULL, arg_ainfo);
98
99 // "umus"
100 arg_ainfo.shortname = "umus";
101 arg_ainfo.longname = "user management account status";
102 arg_ainfo.multiplechar = true;
[22984]103 arg_ainfo.multiplevalue = false;
[373]104 arg_ainfo.defaultstatus = cgiarginfo::weak;
[7381]105 arg_ainfo.argdefault = g_EmptyText;
[373]106 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
107 argsinfo.addarginfo (NULL, arg_ainfo);
108
109 // "umug"
110 arg_ainfo.shortname = "umug";
111 arg_ainfo.longname = "user management groups"; // comma seperated list
112 arg_ainfo.multiplechar = true;
[22984]113 arg_ainfo.multiplevalue = false;
[373]114 arg_ainfo.defaultstatus = cgiarginfo::weak;
[7381]115 arg_ainfo.argdefault = g_EmptyText;
[373]116 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
117 argsinfo.addarginfo (NULL, arg_ainfo);
118
119 // "umc"
120 arg_ainfo.shortname = "umc";
121 arg_ainfo.longname = "user management comment";
122 arg_ainfo.multiplechar = true;
[22984]123 arg_ainfo.multiplevalue = false;
[373]124 arg_ainfo.defaultstatus = cgiarginfo::weak;
[7381]125 arg_ainfo.argdefault = g_EmptyText;
[373]126 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
127 argsinfo.addarginfo (NULL, arg_ainfo);
128
129 // "bcp"
130 arg_ainfo.shortname = "bcp";
131 arg_ainfo.longname = "change password submit button";
132 arg_ainfo.multiplechar = true;
[22984]133 arg_ainfo.multiplevalue = false;
[373]134 arg_ainfo.defaultstatus = cgiarginfo::weak;
[7381]135 arg_ainfo.argdefault = g_EmptyText;
[373]136 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
137 argsinfo.addarginfo (NULL, arg_ainfo);
138
139 // "beu"
140 arg_ainfo.shortname = "beu";
141 arg_ainfo.longname = "edit user submit button";
142 arg_ainfo.multiplechar = true;
[22984]143 arg_ainfo.multiplevalue = false;
[373]144 arg_ainfo.defaultstatus = cgiarginfo::weak;
[7381]145 arg_ainfo.argdefault = g_EmptyText;
[373]146 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
147 argsinfo.addarginfo (NULL, arg_ainfo);
148
149 // "cm"
150 arg_ainfo.shortname = "cm";
151 arg_ainfo.longname = "confirm an action";
152 arg_ainfo.multiplechar = true;
[22984]153 arg_ainfo.multiplevalue = false;
[373]154 arg_ainfo.defaultstatus = cgiarginfo::weak;
[7381]155 arg_ainfo.argdefault = g_EmptyText;
[373]156 arg_ainfo.savedarginfo = cgiarginfo::mustnot;
157 argsinfo.addarginfo (NULL, arg_ainfo);
158}
159
160void usersaction::configure (const text_t &key, const text_tarray &cfgline) {
161 action::configure (key, cfgline);
162}
163
[2212]164bool usersaction::init (ostream &logout) {
165
[15589]166 if (dbhome.empty()) {
167 logout << "ERROR (usersaction::init) dbhome is not set\n";
[2212]168 return false;
169 }
170
171 return action::init (logout);
172}
173
[373]174bool usersaction::check_cgiargs (cgiargsinfoclass &/*argsinfo*/, cgiargsclass &args,
[3733]175 recptprotolistclass * /*protos*/, ostream &/*logout*/) {
[373]176 args["uan"] = "1"; // user authentication is needed
177
178 if (args["uma"] == "changepasswd") {
179 // no particular group is needed to change a password
180 args["ug"].clear();
181 } else {
182 // administrator is needed for all other management tasks
183 args["ug"] = "administrator";
184 }
185
186 return true;
187}
188
[760]189void usersaction::get_cgihead_info (cgiargsclass &/*args*/, recptprotolistclass * /*protos*/,
190 response_t &response, text_t &response_data,
191 ostream &/*logout*/) {
[373]192 response = content;
193 response_data = "text/html";
194}
195
[760]196bool usersaction::do_action (cgiargsclass &args, recptprotolistclass * /*protos*/,
197 browsermapclass * /*browsers*/, displayclass &disp,
[421]198 outconvertclass &outconvert, ostream &textout,
199 ostream &logout) {
[760]200
[373]201 if (args["uma"] == "adduser" || args["uma"] == "edituser") {
202 // adduser is handled by edituser
[760]203 return do_edituser (args, disp, outconvert, textout, logout);
[373]204
205 } else if (args["uma"] == "deleteuser") {
[760]206 return do_deleteuser (args, disp, outconvert, textout, logout);
[373]207
208 } else if (args["uma"] == "changepasswd") {
[760]209 return do_changepasswd (args, disp, outconvert, textout, logout);
[373]210 }
211
212 // default
[760]213 return do_listusers (args, disp, outconvert, textout, logout);
[373]214}
215
[760]216bool usersaction::do_listusers (cgiargsclass &/*args*/, displayclass &disp,
217 outconvertclass &outconvert, ostream &textout,
218 ostream &/*logout*/) {
219
[373]220 textout << outconvert << disp
221 << "_userslistusers:header_\n_userslistusers:contentstart_\n";
222
223 text_tarray userlist;
[13844]224 // get user list
225 user_database->get_user_list (userlist);
[373]226
227 // sort the list
228 sort(userlist.begin(), userlist.end());
229
230 // output the information for each user
231 userinfo_t userinfo;
232 text_tarray::iterator users_here = userlist.begin();
233 text_tarray::iterator users_end = userlist.end();
234 while (users_here != users_end) {
[13844]235 if (user_database->get_user_info(*users_here, userinfo) == ERRNO_SUCCEED) {
[373]236 textout << outconvert << disp
[28899]237 << "<tr><td bgcolor=\"\\#eeeeee\">" << encodeForHTML(userinfo.username) << "</td>\n"
[551]238 << "<td bgcolor=\"\\#eeeeee\">" << (char *) (userinfo.enabled ? "enabled" : "disabled") << "</td>\n"
[28899]239 << "<td bgcolor=\"\\#eeeeee\">" << encodeForHTML(userinfo.groups) << "&nbsp;</td>\n"
240 << "<td bgcolor=\"\\#eeeeee\">" << encodeForHTML(userinfo.comment) << "&nbsp;</td>\n"
[373]241 << "<td><a href=\"_httpcurrentdocument_&a=um&uma=edituser&umun="
[28899]242 << encodeForHTML(userinfo.username) << "\">_userslistusers:textedituser_</a> "
[373]243 << "<a href=\"_httpcurrentdocument_&a=um&uma=deleteuser&umun="
[28899]244 << encodeForHTML(userinfo.username) << "\">_userslistusers:textdeleteuser_</a>"
[373]245 << "</td></tr>\n\n";
246
247 } else {
248 textout << outconvert << disp
249 << "<tr><td bgcolor=\"\\#eeeeee\">" << *users_here << "</td>\n"
250 << "<td bgcolor=\"\\#eeeeee\">&nbsp;</td>\n"
251 << "<td bgcolor=\"\\#eeeeee\">&nbsp;</td>\n"
252 << "<td bgcolor=\"\\#eeeeee\">&nbsp;</td>\n"
253 << "<td>&nbsp;</td></tr>\n\n";
254 }
255
[9620]256 ++users_here;
[373]257 }
258
259 textout << outconvert << disp
260 << "_userslistusers:contentend_\n_userslistusers:footer_\n";
261 return true;
262}
263
264void usersaction::define_user_macros (cgiargsclass &args, displayclass &disp) {
265 disp.setmacro ("usersargun", "users", args["umun"]);
266 disp.setmacro ("usersargpw", "users", args["umpw"]);
267 disp.setmacro ("usersargus", "users", args["umus"]);
268 disp.setmacro ("usersargug", "users", args["umug"]);
269 disp.setmacro ("usersargc", "users", args["umc"]);
[28913]270
271 disp.setmacro ("usersargunAttrsafe", "users", encodeForHTMLAttr(args["umun"]));
272 disp.setmacro ("usersargpwAttrsafe", "users", encodeForHTMLAttr(args["umpw"]));
273 disp.setmacro ("usersargusAttrsafe", "users", encodeForHTMLAttr(args["umus"])); // unused in users.dm or other macro files, but setting this attrsafe'd macro in parallel with the other usersarg* values here.
274 disp.setmacro ("usersargugAttrsafe", "users", encodeForHTMLAttr(args["umug"]));
275 disp.setmacro ("usersargcAttrsafe", "users", encodeForHTMLAttr(args["umc"]));
276
[373]277}
278
279
[760]280bool usersaction::do_edituser (cgiargsclass &args, displayclass &disp,
281 outconvertclass &outconvert, ostream &textout,
282 ostream &logout) {
[13844]283
[373]284 userinfo_t userinfo;
285 text_t messagestatus;
286 bool noproblems = true;
287
288 // fill in defaults from user database (if appropriate)
289 if (args["umun"].empty()) {
290 noproblems = false;
291
[13844]292 } else if (!userdbclass::username_ok (args["umun"])) {
[373]293 // problem with username
294 noproblems = false;
295 messagestatus += "_users:messageinvalidusername_";
296
[13844]297 } else if (user_database->get_user_info (args["umun"], userinfo) == ERRNO_SUCCEED) {
[373]298 if (args["uma"] == "adduser") {
299 // must not add a user that has the same name as another user
300 noproblems = false;
301 messagestatus += "_users:messageuserexists_";
302
303 } else {
304 // only fill in the data if there is no user status defined
305 if (args["umus"].empty()) {
306 args["umus"] = userinfo.enabled ? "enabled" : "disabled";
307 if (args["umug"].empty()) args["umug"] = userinfo.groups;
308 if (args["umc"].empty()) args["umc"] = userinfo.comment;
309 }
310 }
311 }
312
313 // fill in the user status default
314 if (args["umus"].empty()) {
315 noproblems = false;
316 args["umus"] = "enabled";
317 }
318
319 // make sure the password is ok
320 if (args["umpw"].empty()) {
321 // password must not be empty if none were supplied from database
322 // and we have had no other problems
323 if (userinfo.password.empty() && noproblems) {
324 noproblems = false;
325 messagestatus += "_users:messageemptypassword_";
326 }
327
[13844]328 } else if (!userdbclass::password_ok(args["umpw"])) {
[373]329 noproblems = false;
330 messagestatus += "_users:messageinvalidpassword_";
331 }
332
333 // set this info if no problems have been encounted
334 // and the submit button was pressed
335 if (noproblems && !args["beu"].empty()) {
336 userinfo.username = args["umun"];
337 if (!args["umpw"].empty()) {
338 // only set the password if it is not empty
[13844]339 userinfo.password = userdbclass::crypt_text(args["umpw"]);
[373]340 }
[2750]341 userinfo.enabled = (args["umus"] == "enabled");
[13844]342 userinfo.groups = userdbclass::format_user_groups(args["umug"]);
[373]343 userinfo.comment = args["umc"];
344
[13844]345 user_database->set_user_info (args["umun"], userinfo);
[373]346
347 // show list of users
[760]348 return do_listusers (args, disp, outconvert, textout, logout);
[373]349 }
350
351 // define the macros for the user
352 define_user_macros (args, disp);
353 disp.setmacro ("messagestatus", "users", messagestatus);
354
355 textout << outconvert << disp
356 << "_usersedituser:header_\n_usersedituser:content_\n_usersedituser:footer_\n";
357
358 return true;
359}
360
[760]361bool usersaction::do_deleteuser (cgiargsclass &args, displayclass &disp,
362 outconvertclass &outconvert, ostream &textout,
363 ostream &logout) {
[373]364 if (!args["cm"].empty()) {
365 if (args["cm"] == "yes" && !args["umun"].empty()) {
366 // user confirmed the deletion of the user
[13844]367 user_database->delete_user(args["umun"]);
[373]368 }
369
370 // redirect the user back to the listusers page
[760]371 return do_listusers (args, disp, outconvert, textout, logout);
[373]372 }
373
374 define_user_macros (args, disp);
375 textout << outconvert << disp
376 << "_usersdeleteuser:header_\n_usersdeleteuser:content_\n_usersdeleteuser:footer_\n";
377
378 return true;
379}
380
[760]381bool usersaction::do_changepasswd (cgiargsclass &args, displayclass &disp,
382 outconvertclass &outconvert, ostream &textout,
383 ostream &/*logout*/) {
[373]384 text_t messagestatus;
385
386 if (!args["bcp"].empty()) {
387 if (args["un"].empty()) {
388 messagestatus = "_users:messageusernameempty_";
389 } else if (args["umpw"].empty()) {
390 messagestatus = "_users:messagepasswordempty_";
391 } else if (args["umnpw1"].empty()) {
392 messagestatus = "_users:messagenewpass1empty_";
393 } else if (args["umnpw2"].empty()) {
394 messagestatus = "_users:messagenewpass2empty_";
395 } else if (args["umnpw1"] != args["umnpw2"]) {
396 messagestatus = "_users:messagenewpassmismatch_";
[13844]397 } else if (!userdbclass::password_ok(args["umnpw1"])) {
[373]398 messagestatus = "_users:messageinvalidpassword_";
399 } else {
400 userinfo_t userinfo;
[13844]401 if (user_database->get_user_info (args["un"], userinfo) == ERRNO_SUCCEED) {
[373]402 // check old password
[13844]403 if (userinfo.password != userdbclass::crypt_text(args["umpw"])) {
[373]404 messagestatus = "_users:messagefailed_";
405
406 } else {
[13844]407 userinfo.password = userdbclass::crypt_text(args["umnpw1"]);
408 if (user_database->set_user_info (args["un"], userinfo) == ERRNO_SUCCEED) {
[373]409 // everything is ok
410 textout << outconvert << disp
411 << "_userschangepasswdok:header_\n"
412 "_userschangepasswdok:content_\n"
413 "_userschangepasswdok:footer_\n";
414 return true;
415 }
416 }
417 }
418 }
419 }
420
421 disp.setmacro ("messagestatus", "users", messagestatus);
422
423 textout << outconvert << disp
424 << "_userschangepasswd:header_\n"
425 "_userschangepasswd:content_\n"
426 "_userschangepasswd:footer_\n";
427
428 return true;
429}
[7375]430
431#endif //GSDL_USE_USERS_ACTION
Note: See TracBrowser for help on using the repository browser.