* All OS-level includes are now included from webcit.h instead of from
[citadel.git] / webcit / useredit.c
1 /*
2  * $Id$
3  *
4  * Administrative screen to add/change/delete user accounts
5  *
6  */
7
8
9 #include "webcit.h"
10 #include "webserver.h"
11
12
13 void select_user_to_edit(char *message, char *preselect)
14 {
15         char buf[SIZ];
16         char username[SIZ];
17
18         output_headers(1, 1, 2, 0, 1, 0, 0);
19         wprintf("<div id=\"banner\">\n");
20         wprintf("<table width=100%% border=0 bgcolor=#444455><tr>"
21                 "<td>"
22                 "<span class=\"titlebar\">"
23                 "<img src=\"/static/usermanag_48x.gif\">"
24                 "Edit or delete users"
25                 "</span></td></tr></table>\n"
26                 "</div>\n<div id=\"content\">\n"
27         );
28
29         if (message != NULL) wprintf(message);
30
31         wprintf("<TABLE border=0 CELLSPACING=10><TR VALIGN=TOP><TD>\n");
32
33         svprintf("BOXTITLE", WCS_STRING, "Add users");
34         do_template("beginbox");
35
36         wprintf("To create a new user account, enter the desired "
37                 "user name in the box below and click 'Create'.<br /><br />");
38
39         wprintf("<CENTER><FORM METHOD=\"POST\" ACTION=\"/create_user\">\n");
40         wprintf("New user: ");
41         wprintf("<input type=text name=username><br />\n"
42                 "<input type=submit value=\"Create\">"
43                 "</FORM></CENTER>\n");
44
45         do_template("endbox");
46
47         wprintf("</TD><TD>");
48
49         svprintf("BOXTITLE", WCS_STRING, "Edit or Delete users");
50         do_template("beginbox");
51
52         wprintf("To edit an existing user account, select the user "
53                 "name from the list and click 'Edit'.<br /><br />");
54         
55         wprintf("<CENTER>"
56                 "<FORM METHOD=\"POST\" ACTION=\"/display_edituser\">\n");
57         wprintf("<SELECT NAME=\"username\" SIZE=10 STYLE=\"width:100%%\">\n");
58         serv_puts("LIST");
59         serv_getln(buf, sizeof buf);
60         if (buf[0] == '1') {
61                 while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
62                         extract_token(username, buf, 0, '|', sizeof username);
63                         wprintf("<OPTION");
64                         if (preselect != NULL)
65                            if (!strcasecmp(username, preselect))
66                               wprintf(" SELECTED");
67                         wprintf(">");
68                         escputs(username);
69                         wprintf("\n");
70                 }
71         }
72         wprintf("</SELECT><br />\n");
73
74         wprintf("<input type=submit name=sc value=\"Edit configuration\">");
75         wprintf("<input type=submit name=sc value=\"Edit address book entry\">");
76         wprintf("<input type=submit name=sc value=\"Delete user\" "
77                 "onClick=\"return confirm('Delete this user?');\">");
78         wprintf("</FORM></CENTER>\n");
79         do_template("endbox");
80
81         wprintf("</TD></TR></TABLE>\n");
82
83         wDumpContent(1);
84 }
85
86
87
88 /* 
89  * Locate the message number of a user's vCard in the current room
90  */
91 long locate_user_vcard(char *username, long usernum) {
92         char buf[SIZ];
93         long vcard_msgnum = (-1L);
94         char content_type[SIZ];
95         char partnum[SIZ];
96         int already_tried_creating_one = 0;
97
98         struct stuff_t {
99                 struct stuff_t *next;
100                 long msgnum;
101         };
102
103         struct stuff_t *stuff = NULL;
104         struct stuff_t *ptr;
105
106 TRYAGAIN:
107         /* Search for the user's vCard */
108         serv_puts("MSGS ALL");
109         serv_getln(buf, sizeof buf);
110         if (buf[0] == '1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
111                 ptr = malloc(sizeof(struct stuff_t));
112                 ptr->msgnum = atol(buf);
113                 ptr->next = stuff;
114                 stuff = ptr;
115         }
116
117         /* Iterate through the message list looking for vCards */
118         while (stuff != NULL) {
119                 serv_printf("MSG0 %ld|2", stuff->msgnum);
120                 serv_getln(buf, sizeof buf);
121                 if (buf[0]=='1') {
122                         while(serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
123                                 if (!strncasecmp(buf, "part=", 5)) {
124                                         extract_token(partnum, &buf[5], 2, '|', sizeof partnum);
125                                         extract_token(content_type, &buf[5], 4, '|', sizeof content_type);
126                                         if (!strcasecmp(content_type,
127                                            "text/x-vcard")) {
128                                                 vcard_msgnum = stuff->msgnum;
129                                         }
130                                 }
131                         }
132                 }
133
134                 ptr = stuff->next;
135                 free(stuff);
136                 stuff = ptr;
137         }
138
139         /* If there's no vcard, create one */
140         if (vcard_msgnum < 0) if (already_tried_creating_one == 0) {
141                 already_tried_creating_one = 1;
142                 serv_puts("ENT0 1|||4");
143                 serv_getln(buf, sizeof buf);
144                 if (buf[0] == '4') {
145                         serv_puts("Content-type: text/x-vcard");
146                         serv_puts("");
147                         serv_puts("begin:vcard");
148                         serv_puts("end:vcard");
149                         serv_puts("000");
150                 }
151                 goto TRYAGAIN;
152         }
153
154         return(vcard_msgnum);
155 }
156
157
158 /* 
159  * Display the form for editing a user's address book entry
160  */
161 void display_edit_address_book_entry(char *username, long usernum) {
162         char roomname[SIZ];
163         char buf[SIZ];
164         char error_message[SIZ];
165         long vcard_msgnum = (-1L);
166
167         /* Locate the user's config room, creating it if necessary */
168         sprintf(roomname, "%010ld.%s", usernum, USERCONFIGROOM);
169         serv_printf("GOTO %s||1", roomname);
170         serv_getln(buf, sizeof buf);
171         if (buf[0] != '2') {
172                 serv_printf("CRE8 1|%s|5|||1|", roomname);
173                 serv_getln(buf, sizeof buf);
174                 serv_printf("GOTO %s||1", roomname);
175                 serv_getln(buf, sizeof buf);
176                 if (buf[0] != '2') {
177                         sprintf(error_message,
178                                 "<IMG SRC=\"static/error.gif\" ALIGN=CENTER>"
179                                 "%s<br /><br />\n", &buf[4]);
180                         select_user_to_edit(error_message, username);
181                         return;
182                 }
183         }
184
185         vcard_msgnum = locate_user_vcard(username, usernum);
186
187         if (vcard_msgnum < 0) {
188                 sprintf(error_message,
189                         "<IMG SRC=\"static/error.gif\" ALIGN=CENTER>"
190                         "Could not create/edit vCard"
191                         "<br /><br />\n"
192                 );
193                 select_user_to_edit(error_message, username);
194                 return;
195         }
196
197         do_edit_vcard(vcard_msgnum, "1", "/select_user_to_edit");
198 }
199
200
201
202
203 /*
204  * Edit a user.  If supplied_username is null, look in the "username"
205  * web variable for the name of the user to edit.
206  * 
207  * If "is_new" is set to nonzero, this screen will set the web variables
208  * to send the user to the vCard editor next.
209  */
210 void display_edituser(char *supplied_username, int is_new) {
211         char buf[SIZ];
212         char error_message[SIZ];
213         time_t now;
214
215         char username[SIZ];
216         char password[SIZ];
217         unsigned int flags;
218         int timescalled;
219         int msgsposted;
220         int axlevel;
221         long usernum;
222         time_t lastcall;
223         int purgedays;
224         int i;
225
226         if (supplied_username != NULL) {
227                 safestrncpy(username, supplied_username, sizeof username);
228         }
229         else {
230                 safestrncpy(username, bstr("username"), sizeof username);
231         }
232
233         serv_printf("AGUP %s", username);
234         serv_getln(buf, sizeof buf);
235         if (buf[0] != '2') {
236                 sprintf(error_message,
237                         "<IMG SRC=\"static/error.gif\" ALIGN=CENTER>"
238                         "%s<br /><br />\n", &buf[4]);
239                 select_user_to_edit(error_message, username);
240                 return;
241         }
242
243         extract_token(username, &buf[4], 0, '|', sizeof username);
244         extract_token(password, &buf[4], 1, '|', sizeof password);
245         flags = extract_int(&buf[4], 2);
246         timescalled = extract_int(&buf[4], 3);
247         msgsposted = extract_int(&buf[4], 4);
248         axlevel = extract_int(&buf[4], 5);
249         usernum = extract_long(&buf[4], 6);
250         lastcall = extract_long(&buf[4], 7);
251         purgedays = extract_long(&buf[4], 8);
252
253         if (!strcmp(bstr("sc"), "Edit address book entry")) {
254                 display_edit_address_book_entry(username, usernum);
255                 return;
256         }
257
258         if (!strcmp(bstr("sc"), "Delete user")) {
259                 delete_user(username);
260                 return;
261         }
262
263         output_headers(1, 1, 2, 0, 0, 0, 0);
264         wprintf("<div id=\"banner\">\n");
265         wprintf("<TABLE WIDTH=100%% BORDER=0 BGCOLOR=\"#444455\"><TR><TD>");
266         wprintf("<SPAN CLASS=\"titlebar\">"
267                 "Edit user account: ");
268         escputs(username);
269         wprintf("</SPAN></TD></TR></TABLE>\n");
270         wprintf("</div>\n<div id=\"content\">\n");
271
272         wprintf("<div id=\"fix_scrollbar_bug\">"
273                 "<table border=0 width=100%% bgcolor=\"#ffffff\"><tr><td>\n");
274         wprintf("<FORM METHOD=\"POST\" ACTION=\"/edituser\">\n"
275                 "<INPUT TYPE=\"hidden\" NAME=\"username\" VALUE=\"");
276         escputs(username);
277         wprintf("\">\n");
278         wprintf("<INPUT TYPE=\"hidden\" NAME=\"is_new\" VALUE=\"%d\">\n"
279                 "<INPUT TYPE=\"hidden\" NAME=\"usernum\" VALUE=\"%ld\">\n",
280                 is_new, usernum);
281
282         wprintf("<INPUT TYPE=\"hidden\" NAME=\"flags\" VALUE=\"%d\">\n", flags);
283
284         wprintf("<CENTER><TABLE>");
285
286         wprintf("<TR><TD>Password</TD><TD>"
287                 "<INPUT TYPE=\"password\" NAME=\"password\" VALUE=\"");
288         escputs(password);
289         wprintf("\" MAXLENGTH=\"20\"></TD></TR>\n");
290
291         wprintf("<TR><TD>Times logged in</TD><TD>"
292                 "<INPUT TYPE=\"text\" NAME=\"timescalled\" VALUE=\"");
293         wprintf("%d", timescalled);
294         wprintf("\" MAXLENGTH=\"6\"></TD></TR>\n");
295
296         wprintf("<TR><TD>Messages posted</TD><TD>"
297                 "<INPUT TYPE=\"text\" NAME=\"msgsposted\" VALUE=\"");
298         wprintf("%d", msgsposted);
299         wprintf("\" MAXLENGTH=\"6\"></TD></TR>\n");
300
301         wprintf("<TR><TD>Access level</TD><TD>"
302                 "<SELECT NAME=\"axlevel\">\n");
303         for (i=0; i<7; ++i) {
304                 wprintf("<OPTION ");
305                 if (axlevel == i) {
306                         wprintf("SELECTED ");
307                 }
308                 wprintf("VALUE=\"%d\">%d - %s</OPTION>\n",
309                         i, i, axdefs[i]);
310         }
311         wprintf("</SELECT></TD></TR>\n");
312
313         wprintf("<TR><TD>User ID number</TD><TD>"
314                 "<INPUT TYPE=\"text\" NAME=\"usernum\" VALUE=\"");
315         wprintf("%ld", usernum);
316         wprintf("\" MAXLENGTH=\"7\"></TD></TR>\n");
317
318         now = time(NULL);
319         wprintf("<TR><TD>Date/time of last login</TD><TD>"
320                 "<SELECT NAME=\"lastcall\">\n");
321
322         wprintf("<OPTION SELECTED VALUE=\"%ld\">", lastcall);
323         escputs(asctime(localtime(&lastcall)));
324         wprintf("</OPTION>\n");
325
326         wprintf("<OPTION VALUE=\"%ld\">", now);
327         escputs(asctime(localtime(&now)));
328         wprintf("</OPTION>\n");
329
330         wprintf("</SELECT></TD></TR>");
331
332         wprintf("<TR><TD>Auto-purge after days</TD><TD>"
333                 "<INPUT TYPE=\"text\" NAME=\"purgedays\" VALUE=\"");
334         wprintf("%d", purgedays);
335         wprintf("\" MAXLENGTH=\"5\"></TD></TR>\n");
336
337         wprintf("</TABLE>\n");
338
339         wprintf("<INPUT type=\"submit\" NAME=\"action\" VALUE=\"OK\">\n"
340                 "&nbsp;"
341                 "<INPUT type=\"submit\" NAME=\"action\" VALUE=\"Cancel\">\n"
342                 "<br /><br /></FORM>\n");
343
344         wprintf("</CENTER>\n");
345         wprintf("</td></tr></table></div>\n");
346         wDumpContent(1);
347
348 }
349
350
351
352 void edituser(void) {
353         char message[SIZ];
354         char buf[SIZ];
355         int is_new = 0;
356
357         is_new = atoi(bstr("is_new"));
358
359         if (strcasecmp(bstr("action"), "OK")) {
360                 safestrncpy(message, "Edit user cancelled.", sizeof message);
361         }
362
363         else {
364
365                 serv_printf("ASUP %s|%s|%s|%s|%s|%s|%s|%s|%s|",
366                         bstr("username"),
367                         bstr("password"),
368                         bstr("flags"),
369                         bstr("timescalled"),
370                         bstr("msgsposted"),
371                         bstr("axlevel"),
372                         bstr("usernum"),
373                         bstr("lastcall"),
374                         bstr("purgedays")
375                 );
376                 serv_getln(buf, sizeof buf);
377                 if (buf[0] != '2') {
378                         sprintf(message,
379                                 "<IMG SRC=\"static/error.gif\" ALIGN=CENTER>"
380                                 "%s<br /><br />\n", &buf[4]);
381                 }
382                 else {
383                         safestrncpy(message, "", sizeof message);
384                 }
385         }
386
387         /* If we are in the middle of creating a new user, move on to
388          * the vCard edit screen.
389          */
390         if (is_new) {
391                 display_edit_address_book_entry( bstr("username"), atol(bstr("usernum")) );
392         }
393         else {
394                 select_user_to_edit(message, bstr("username"));
395         }
396 }
397
398
399 void delete_user(char *username) {
400         char buf[SIZ];
401         char message[SIZ];
402
403         serv_printf("ASUP %s|0|0|0|0|0|", username);
404         serv_getln(buf, sizeof buf);
405         if (buf[0] != '2') {
406                 sprintf(message,
407                         "<IMG SRC=\"static/error.gif\" ALIGN=CENTER>"
408                         "%s<br /><br />\n", &buf[4]);
409         }
410         else {
411                 safestrncpy(message, "", sizeof message);
412         }
413         select_user_to_edit(message, bstr("username"));
414 }
415                 
416
417
418
419 void create_user(void) {
420         char buf[SIZ];
421         char error_message[SIZ];
422         char username[SIZ];
423
424         safestrncpy(username, bstr("username"), sizeof username);
425
426         serv_printf("CREU %s", username);
427         serv_getln(buf, sizeof buf);
428
429         if (buf[0] == '2') {
430                 /* sprintf(error_message, "<b>User has been created.</b>");
431                 select_user_to_edit(error_message, username); */
432                 display_edituser(username, 1);
433         }
434         else {
435                 sprintf(error_message,
436                         "<IMG SRC=\"static/error.gif\" ALIGN=CENTER>"
437                         "%s<br /><br />\n", &buf[4]);
438                 select_user_to_edit(error_message, NULL);
439         }
440
441 }
442