10 * show a list of available users to edit them
11 * message the header message???
12 * preselect which user should be selected in the browser
14 void select_user_to_edit(char *message, char *preselect)
16 output_headers(1, 0, 0, 0, 1, 0);
17 do_template("edituser_select", NULL);
22 typedef struct _UserListEntry {
31 /* Just available for Single users to view: */
37 UserListEntry* NewUserListOneEntry(StrBuf *SerializedUser)
41 if (StrLength(SerializedUser) < 8)
44 ul = (UserListEntry*) malloc(sizeof(UserListEntry));
45 ul->UserName = NewStrBuf();
46 ul->Passvoid = NewStrBuf();
48 StrBufExtract_token(ul->UserName, SerializedUser, 0, '|');
49 StrBufExtract_token(ul->Passvoid, SerializedUser, 1, '|');
50 ul->Flags = (unsigned int)StrBufExtract_long(SerializedUser, 2, '|');
51 ul->nLogons = StrBufExtract_int(SerializedUser, 3, '|');
52 ul->nPosts = StrBufExtract_int(SerializedUser, 4, '|');
53 ul->AccessLevel = StrBufExtract_int(SerializedUser, 5, '|');
54 ul->UID = StrBufExtract_int(SerializedUser, 6, '|');
55 ul->LastLogonT = StrBufExtract_long(SerializedUser, 7, '|');
56 ul->DaysTillPurge = StrBufExtract_int(SerializedUser, 8, '|');
60 void DeleteUserListEntry(void *vUserList)
62 UserListEntry *ul = (UserListEntry*) vUserList;
63 FreeStrBuf(&ul->UserName);
64 FreeStrBuf(&ul->Passvoid);
68 UserListEntry* NewUserListEntry(StrBuf *SerializedUserList)
72 if (StrLength(SerializedUserList) < 8)
75 ul = (UserListEntry*) malloc(sizeof(UserListEntry));
76 ul->UserName = NewStrBuf();
77 ul->Passvoid = NewStrBuf();
79 StrBufExtract_token(ul->UserName, SerializedUserList, 0, '|');
80 ul->AccessLevel = StrBufExtract_int(SerializedUserList, 1, '|');
81 ul->UID = StrBufExtract_int(SerializedUserList, 2, '|');
82 ul->LastLogonT = StrBufExtract_long(SerializedUserList, 3, '|');
83 ul->nLogons = StrBufExtract_int(SerializedUserList, 4, '|');
84 ul->nPosts = StrBufExtract_int(SerializedUserList, 5, '|');
85 StrBufExtract_token(ul->Passvoid, SerializedUserList, 6, '|');
87 ul->DaysTillPurge = -1;
94 int CompareUserListName(const void *vUser1, const void *vUser2)
96 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
97 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
99 return strcmp(ChrPtr(u1->UserName), ChrPtr(u2->UserName));
101 int CompareUserListNameRev(const void *vUser1, const void *vUser2)
103 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
104 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
105 return strcmp(ChrPtr(u2->UserName), ChrPtr(u1->UserName));
107 int GroupchangeUserListName(const void *vUser1, const void *vUser2)
109 UserListEntry *u1 = (UserListEntry*) vUser1;
110 UserListEntry *u2 = (UserListEntry*) vUser2;
111 return ChrPtr(u2->UserName)[0] != ChrPtr(u1->UserName)[0];
115 * Sort by AccessLevel
117 int CompareAccessLevel(const void *vUser1, const void *vUser2)
119 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
120 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
122 return (u1->AccessLevel > u2->AccessLevel);
124 int CompareAccessLevelRev(const void *vUser1, const void *vUser2)
126 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
127 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
129 return (u2->AccessLevel > u1->AccessLevel);
131 int GroupchangeAccessLevel(const void *vUser1, const void *vUser2)
133 UserListEntry *u1 = (UserListEntry*) vUser1;
134 UserListEntry *u2 = (UserListEntry*) vUser2;
136 return u2->AccessLevel != u1->AccessLevel;
143 int CompareUID(const void *vUser1, const void *vUser2)
145 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
146 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
148 return (u1->UID > u2->UID);
150 int CompareUIDRev(const void *vUser1, const void *vUser2)
152 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
153 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
155 return (u2->UID > u1->UID);
157 int GroupchangeUID(const void *vUser1, const void *vUser2)
159 UserListEntry *u1 = (UserListEntry*) vUser1;
160 UserListEntry *u2 = (UserListEntry*) vUser2;
162 return (u2->UID / 10) != (u1->UID / 10);
166 * Sort By Date /// TODO!
168 int CompareLastLogon(const void *vUser1, const void *vUser2)
170 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
171 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
173 return (u1->LastLogonT > u2->LastLogonT);
175 int CompareLastLogonRev(const void *vUser1, const void *vUser2)
177 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
178 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
180 return (u2->LastLogonT > u1->LastLogonT);
182 int GroupchangeLastLogon(const void *vUser1, const void *vUser2)
184 UserListEntry *u1 = (UserListEntry*) vUser1;
185 UserListEntry *u2 = (UserListEntry*) vUser2;
187 return (u2->LastLogonT != u1->LastLogonT);
191 * Sort By Number of Logons
193 int ComparenLogons(const void *vUser1, const void *vUser2)
195 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
196 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
198 return (u1->nLogons > u2->nLogons);
200 int ComparenLogonsRev(const void *vUser1, const void *vUser2)
202 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
203 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
205 return (u2->nLogons > u1->nLogons);
207 int GroupchangenLogons(const void *vUser1, const void *vUser2)
209 UserListEntry *u1 = (UserListEntry*) vUser1;
210 UserListEntry *u2 = (UserListEntry*) vUser2;
212 return (u2->nLogons / 100) != (u1->nLogons / 100);
216 * Sort By Number of Posts
218 int ComparenPosts(const void *vUser1, const void *vUser2)
220 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
221 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
223 return (u1->nPosts > u2->nPosts);
225 int ComparenPostsRev(const void *vUser1, const void *vUser2)
227 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
228 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
230 return (u2->nPosts > u1->nPosts);
232 int GroupchangenPosts(const void *vUser1, const void *vUser2)
234 UserListEntry *u1 = (UserListEntry*) vUser1;
235 UserListEntry *u2 = (UserListEntry*) vUser2;
237 return (u2->nPosts / 100) != (u1->nPosts / 100);
241 HashList *iterate_load_userlist(StrBuf *Target, WCTemplputParams *TP)
251 WCTemplputParams SubTP;
253 memset(&SubTP, 0, sizeof(WCTemplputParams));
255 serv_getln(buf, sizeof buf);
257 Hash = NewHash(1, NULL);
260 while ((len = StrBuf_ServGetln(Buf),
261 strcmp(ChrPtr(Buf), "000"))) {
262 ul = NewUserListEntry(Buf);
265 nUsed = GetCount(Hash);
266 nUsed = snprintf(nnn, sizeof(nnn), "%d", nUsed+1);
267 Put(Hash, nnn, nUsed, ul, DeleteUserListEntry);
270 SubTP.Filter.ContextType = CTX_USERLIST;
271 SortIt = RetrieveSort(&SubTP, HKEY("USER"), HKEY("user:uid"), 0);
273 SortByPayload(Hash, SortIt);
275 SortByPayload(Hash, CompareUID);
282 void tmplput_USERLIST_UserName(StrBuf *Target, WCTemplputParams *TP)
284 UserListEntry *ul = (UserListEntry*) CTX;
285 StrBufAppendTemplate(Target, TP, ul->UserName, 0);
288 void tmplput_USERLIST_Password(StrBuf *Target, WCTemplputParams *TP)
290 UserListEntry *ul = (UserListEntry*) CTX;
291 StrBufAppendTemplate(Target, TP, ul->Passvoid, 0);
294 void tmplput_USERLIST_AccessLevelNo(StrBuf *Target, WCTemplputParams *TP)
296 UserListEntry *ul = (UserListEntry*) CTX;
298 StrBufAppendPrintf(Target, "%d", ul->AccessLevel, 0);
301 void tmplput_USERLIST_AccessLevelStr(StrBuf *Target, WCTemplputParams *TP)
303 UserListEntry *ul = (UserListEntry*) CTX;
305 StrBufAppendBufPlain(Target, _(axdefs[ul->AccessLevel]), -1, 0);
308 void tmplput_USERLIST_UID(StrBuf *Target, WCTemplputParams *TP)
310 UserListEntry *ul = (UserListEntry*) CTX;
312 StrBufAppendPrintf(Target, "%d", ul->UID, 0);
315 void tmplput_USERLIST_LastLogonNo(StrBuf *Target, WCTemplputParams *TP)
317 UserListEntry *ul = (UserListEntry*) CTX;
319 StrBufAppendPrintf(Target,"%ld", ul->LastLogonT, 0);
321 void tmplput_USERLIST_LastLogonStr(StrBuf *Target, WCTemplputParams *TP)
323 UserListEntry *ul = (UserListEntry*) CTX;
324 StrEscAppend(Target, NULL, asctime(localtime(&ul->LastLogonT)), 0, 0);
327 void tmplput_USERLIST_nLogons(StrBuf *Target, WCTemplputParams *TP)
329 UserListEntry *ul = (UserListEntry*) CTX;
331 StrBufAppendPrintf(Target, "%d", ul->nLogons, 0);
334 void tmplput_USERLIST_nPosts(StrBuf *Target, WCTemplputParams *TP)
336 UserListEntry *ul = (UserListEntry*) CTX;
338 StrBufAppendPrintf(Target, "%d", ul->nPosts, 0);
341 void tmplput_USERLIST_Flags(StrBuf *Target, WCTemplputParams *TP)
343 UserListEntry *ul = (UserListEntry*) CTX;
345 StrBufAppendPrintf(Target, "%d", ul->Flags, 0);
348 void tmplput_USERLIST_DaysTillPurge(StrBuf *Target, WCTemplputParams *TP)
350 UserListEntry *ul = (UserListEntry*) CTX;
352 StrBufAppendPrintf(Target, "%d", ul->DaysTillPurge, 0);
355 int ConditionalUser(StrBuf *Target, WCTemplputParams *TP)
357 UserListEntry *ul = (UserListEntry*) CTX;
358 if (havebstr("usernum")) {
359 return ibstr("usernum") == ul->UID;
361 else if (havebstr("username")) {
362 return strcmp(bstr("username"), ChrPtr(ul->UserName)) == 0;
368 int ConditionalFlagINetEmail(StrBuf *Target, WCTemplputParams *TP)
370 UserListEntry *ul = (UserListEntry*) CTX;
371 return (ul->Flags & US_INTERNET) != 0;
374 int ConditionalUserAccess(StrBuf *Target, WCTemplputParams *TP)
376 UserListEntry *ul = (UserListEntry*) CTX;
378 if (TP->Tokens->Params[3]->Type == TYPE_LONG)
379 return (TP->Tokens->Params[3]->lvalue == ul->AccessLevel);
385 * Locate the message number of a user's vCard in the current room
386 * Returns the message id of his vcard
388 long locate_user_vcard_in_this_room() {
390 long vcard_msgnum = (-1L);
391 char content_type[SIZ];
393 int already_tried_creating_one = 0;
396 struct stuff_t *next;
400 struct stuff_t *stuff = NULL;
404 /** Search for the user's vCard */
405 serv_puts("MSGS ALL");
406 serv_getln(buf, sizeof buf);
407 if (buf[0] == '1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
408 ptr = malloc(sizeof(struct stuff_t));
409 ptr->msgnum = atol(buf);
414 /** Iterate through the message list looking for vCards */
415 while (stuff != NULL) {
416 serv_printf("MSG0 %ld|2", stuff->msgnum);
417 serv_getln(buf, sizeof buf);
419 while(serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
420 if (!strncasecmp(buf, "part=", 5)) {
421 extract_token(partnum, &buf[5], 2, '|', sizeof partnum);
422 extract_token(content_type, &buf[5], 4, '|', sizeof content_type);
423 if ( (!strcasecmp(content_type, "text/x-vcard"))
424 || (!strcasecmp(content_type, "text/vcard")) ) {
425 vcard_msgnum = stuff->msgnum;
436 /** If there's no vcard, create one */
437 if ((vcard_msgnum < 0) && (already_tried_creating_one == 0)) {
438 already_tried_creating_one = 1;
439 serv_puts("ENT0 1|||4");
440 serv_getln(buf, sizeof buf);
442 serv_puts("Content-type: text/x-vcard");
444 serv_puts("begin:vcard");
445 serv_puts("end:vcard");
451 return(vcard_msgnum);
456 * Display the form for editing a user's address book entry
457 * username the name of the user
458 * usernum the citadel-uid of the user
460 void display_edit_address_book_entry(char *username, long usernum) {
463 char error_message[SIZ];
464 long vcard_msgnum = (-1L);
466 /** Locate the user's config room, creating it if necessary */
467 sprintf(roomname, "%010ld.%s", usernum, USERCONFIGROOM);
468 serv_printf("GOTO %s||1", roomname);
469 serv_getln(buf, sizeof buf);
471 serv_printf("CRE8 1|%s|5|||1|", roomname);
472 serv_getln(buf, sizeof buf);
473 serv_printf("GOTO %s||1", roomname);
474 serv_getln(buf, sizeof buf);
476 sprintf(error_message,
477 "<img src=\"static/error.gif\" align=center>"
478 "%s<br /><br />\n", &buf[4]);
479 select_user_to_edit(error_message, username);
484 vcard_msgnum = locate_user_vcard_in_this_room();
486 if (vcard_msgnum < 0) {
487 sprintf(error_message,
488 "<img src=\"static/error.gif\" align=center>%s<br /><br />\n",
489 _("An error occurred while trying to create or edit this address book entry.")
491 select_user_to_edit(error_message, username);
495 do_edit_vcard(vcard_msgnum, "1", "select_user_to_edit", roomname);
499 void display_edituser(char *supplied_username, int is_new) {
502 char error_message[1024];
506 if (supplied_username != NULL) {
507 safestrncpy(username, supplied_username, sizeof username);
510 safestrncpy(username, bstr("username"), sizeof username);
514 serv_printf("AGUP %s", username);
515 StrBuf_ServGetln(Buf);
516 MajorStatus = ChrPtr(Buf)[0];
517 StrBufCutLeft(Buf, 4);
518 if (MajorStatus != '2') {
519 /*TODO ImportantMessage */
520 sprintf(error_message,
521 "<img src=\"static/error.gif\" align=center>"
522 "%s<br /><br />\n", ChrPtr(Buf));
523 select_user_to_edit(error_message, username);
528 UL = NewUserListOneEntry(Buf);
529 if (havebstr("edit_abe_button")) {
530 display_edit_address_book_entry(username, UL->UID);
532 else if (havebstr("delete_button")) {
533 delete_user(username);
536 WCTemplputParams SubTP;
537 memset(&SubTP, 0, sizeof(WCTemplputParams));
538 SubTP.Filter.ContextType = CTX_USERLIST;
540 output_headers(1, 0, 0, 0, 1, 0);
541 DoTemplate(HKEY("userlist_detailview"), NULL, &SubTP);
544 DeleteUserListEntry(UL);
551 * do the backend operation of the user edit on the server
553 void edituser(void) {
557 unsigned int flags = 0;
560 is_new = ibstr("is_new");
561 safestrncpy(message, "", sizeof message);
562 username = bstr("username");
564 if (!havebstr("ok_button")) {
565 safestrncpy(message, _("Changes were not saved."), sizeof message);
569 flags = ibstr("flags");
570 if (yesbstr("inetmail")) {
571 flags |= US_INTERNET;
574 flags &= ~US_INTERNET ;
577 if ((havebstr("newname")) && (strcasecmp(bstr("username"), bstr("newname")))) {
578 serv_printf("RENU %s|%s", bstr("username"), bstr("newname"));
579 serv_getln(buf, sizeof buf);
581 sprintf(&message[strlen(message)],
582 "<img src=\"static/error.gif\" align=center>"
583 "%s<br /><br />\n", &buf[4]);
586 username = bstr("newname");
590 serv_printf("ASUP %s|%s|%d|%s|%s|%s|%s|%s|%s|",
601 serv_getln(buf, sizeof buf);
603 sprintf(&message[strlen(message)],
604 "<img src=\"static/error.gif\" align=center>"
605 "%s<br /><br />\n", &buf[4]);
610 * If we are in the middle of creating a new user, move on to
611 * the vCard edit screen.
614 display_edit_address_book_entry(username, lbstr("usernum") );
617 select_user_to_edit(message, username);
623 * username the name of the user to remove
625 void delete_user(char *username) {
629 serv_printf("ASUP %s|0|0|0|0|0|", username);
630 serv_getln(buf, sizeof buf);
633 "<img src=\"static/error.gif\" align=center>"
634 "%s<br /><br />\n", &buf[4]);
637 safestrncpy(message, "", sizeof message);
639 select_user_to_edit(message, bstr("username"));
646 * take the web environment username and create it on the citadel server
648 void create_user(void) {
650 char error_message[SIZ];
653 safestrncpy(username, bstr("username"), sizeof username);
655 serv_printf("CREU %s", username);
656 serv_getln(buf, sizeof buf);
659 sprintf(WC->ImportantMessage, _("A new user has been created."));
660 display_edituser(username, 1);
662 else if (!strncmp(buf, "570", 3)) {
663 sprintf(error_message,
664 "<img src=\"static/error.gif\" align=center>"
666 _("You are attempting to create a new user from within Citadel "
667 "while running in host based authentication mode. In this mode, "
668 "you must create new users on the host system, not within Citadel.")
670 select_user_to_edit(error_message, NULL);
673 sprintf(error_message,
674 "<img src=\"static/error.gif\" align=center>"
675 "%s<br /><br />\n", &buf[4]);
676 select_user_to_edit(error_message, NULL);
682 void _select_user_to_edit(void){select_user_to_edit(NULL, NULL);}
683 void _display_edituser(void) {display_edituser(NULL, 0);}
689 WebcitAddUrlHandler(HKEY("select_user_to_edit"), _select_user_to_edit, 0);
690 WebcitAddUrlHandler(HKEY("display_edituser"), _display_edituser, 0);
691 WebcitAddUrlHandler(HKEY("edituser"), edituser, 0);
692 WebcitAddUrlHandler(HKEY("create_user"), create_user, 0);
694 RegisterNamespace("USERLIST:USERNAME", 0, 1, tmplput_USERLIST_UserName, CTX_USERLIST);
695 RegisterNamespace("USERLIST:PASSWD", 0, 1, tmplput_USERLIST_Password, CTX_USERLIST);
696 RegisterNamespace("USERLIST:ACCLVLNO", 0, 0, tmplput_USERLIST_AccessLevelNo, CTX_USERLIST);
697 RegisterNamespace("USERLIST:ACCLVLSTR", 0, 0, tmplput_USERLIST_AccessLevelStr, CTX_USERLIST);
698 RegisterNamespace("USERLIST:UID", 0, 0, tmplput_USERLIST_UID, CTX_USERLIST);
699 RegisterNamespace("USERLIST:LASTLOGON:STR", 0, 0, tmplput_USERLIST_LastLogonStr, CTX_USERLIST);
700 RegisterNamespace("USERLIST:LASTLOGON:NO", 0, 0, tmplput_USERLIST_LastLogonNo, CTX_USERLIST);
701 RegisterNamespace("USERLIST:NLOGONS", 0, 0, tmplput_USERLIST_nLogons, CTX_USERLIST);
702 RegisterNamespace("USERLIST:NPOSTS", 0, 0, tmplput_USERLIST_nPosts, CTX_USERLIST);
704 RegisterNamespace("USERLIST:FLAGS", 0, 0, tmplput_USERLIST_Flags, CTX_USERLIST);
705 RegisterNamespace("USERLIST:DAYSTILLPURGE", 0, 0, tmplput_USERLIST_DaysTillPurge, CTX_USERLIST);
707 RegisterConditional(HKEY("COND:USERNAME"), 0, ConditionalUser, CTX_USERLIST);
708 RegisterConditional(HKEY("COND:USERACCESS"), 0, ConditionalUserAccess, CTX_USERLIST);
709 RegisterConditional(HKEY("COND:USERLIST:FLAG:USE_INTERNET"), 0, ConditionalFlagINetEmail, CTX_USERLIST);
711 RegisterIterator("USERLIST", 0, NULL, iterate_load_userlist, NULL, DeleteHash, CTX_USERLIST, CTX_NONE, IT_NOFLAG);
714 RegisterSortFunc(HKEY("user:name"),
717 CompareUserListNameRev,
718 GroupchangeUserListName,
720 RegisterSortFunc(HKEY("user:accslvl"),
723 CompareAccessLevelRev,
724 GroupchangeAccessLevel,
727 RegisterSortFunc(HKEY("user:nlogons"),
734 RegisterSortFunc(HKEY("user:uid"),
741 RegisterSortFunc(HKEY("user:lastlogon"),
745 GroupchangeLastLogon,
748 RegisterSortFunc(HKEY("user:nmsgposts"),