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

Last change on this file since 21758 was 15589, checked in by mdewsnip, 16 years ago

(Adding new DB support) Replacing almost all "gdbmhome" with "dbhome".

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