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

Last change on this file since 546 was 543, checked in by rjmcnab, 25 years ago

removed some compiler warnings

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