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

Last change on this file since 3036 was 2750, checked in by kjm18, 23 years ago

can now have spaces after the commas in the groups field of add user form -
these are removed before the entry is written to the db

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