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

Last change on this file since 13017 was 9620, checked in by kjdon, 19 years ago

added some x++ -> ++x changes submitted by Emanuel Dejanu

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