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

Last change on this file since 411 was 373, checked in by rjmcnab, 25 years ago

Initial revision.

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