source: trunk/gsdl/src/recpt/usersaction.cpp@ 671

Last change on this file since 671 was 551, checked in by cs025, 25 years ago

Added a cast to (char *) of (..:..?..) on output to avoid type
error at compile time.

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