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_AccessLevelNo(StrBuf *Target, WCTemplputParams *TP)
290 UserListEntry *ul = (UserListEntry*) CTX;
292 StrBufAppendPrintf(Target, "%d", ul->AccessLevel, 0);
295 void tmplput_USERLIST_AccessLevelStr(StrBuf *Target, WCTemplputParams *TP)
297 UserListEntry *ul = (UserListEntry*) CTX;
299 StrBufAppendBufPlain(Target, _(axdefs[ul->AccessLevel]), -1, 0);
302 void tmplput_USERLIST_UID(StrBuf *Target, WCTemplputParams *TP)
304 UserListEntry *ul = (UserListEntry*) CTX;
306 StrBufAppendPrintf(Target, "%d", ul->UID, 0);
309 void tmplput_USERLIST_LastLogonNo(StrBuf *Target, WCTemplputParams *TP)
311 UserListEntry *ul = (UserListEntry*) CTX;
313 StrBufAppendPrintf(Target,"%ld", ul->LastLogonT, 0);
315 void tmplput_USERLIST_LastLogonStr(StrBuf *Target, WCTemplputParams *TP)
317 UserListEntry *ul = (UserListEntry*) CTX;
318 StrEscAppend(Target, NULL, asctime(localtime(&ul->LastLogonT)), 0, 0);
321 void tmplput_USERLIST_nLogons(StrBuf *Target, WCTemplputParams *TP)
323 UserListEntry *ul = (UserListEntry*) CTX;
325 StrBufAppendPrintf(Target, "%d", ul->nLogons, 0);
328 void tmplput_USERLIST_nPosts(StrBuf *Target, WCTemplputParams *TP)
330 UserListEntry *ul = (UserListEntry*) CTX;
332 StrBufAppendPrintf(Target, "%d", ul->nPosts, 0);
335 void tmplput_USERLIST_Flags(StrBuf *Target, WCTemplputParams *TP)
337 UserListEntry *ul = (UserListEntry*) CTX;
339 StrBufAppendPrintf(Target, "%d", ul->Flags, 0);
342 void tmplput_USERLIST_DaysTillPurge(StrBuf *Target, WCTemplputParams *TP)
344 UserListEntry *ul = (UserListEntry*) CTX;
346 StrBufAppendPrintf(Target, "%d", ul->DaysTillPurge, 0);
349 int ConditionalUser(StrBuf *Target, WCTemplputParams *TP)
351 UserListEntry *ul = (UserListEntry*) CTX;
352 if (havebstr("usernum")) {
353 return ibstr("usernum") == ul->UID;
355 else if (havebstr("username")) {
356 return strcmp(bstr("username"), ChrPtr(ul->UserName)) == 0;
362 int ConditionalFlagINetEmail(StrBuf *Target, WCTemplputParams *TP)
364 UserListEntry *ul = (UserListEntry*) CTX;
365 return (ul->Flags & US_INTERNET) != 0;
368 int ConditionalUserAccess(StrBuf *Target, WCTemplputParams *TP)
370 UserListEntry *ul = (UserListEntry*) CTX;
372 if (TP->Tokens->Params[3]->Type == TYPE_LONG)
373 return (TP->Tokens->Params[3]->lvalue == ul->AccessLevel);
379 * Locate the message number of a user's vCard in the current room
380 * Returns the message id of his vcard
382 long locate_user_vcard_in_this_room() {
384 long vcard_msgnum = (-1L);
385 char content_type[SIZ];
387 int already_tried_creating_one = 0;
390 struct stuff_t *next;
394 struct stuff_t *stuff = NULL;
398 /** Search for the user's vCard */
399 serv_puts("MSGS ALL");
400 serv_getln(buf, sizeof buf);
401 if (buf[0] == '1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
402 ptr = malloc(sizeof(struct stuff_t));
403 ptr->msgnum = atol(buf);
408 /** Iterate through the message list looking for vCards */
409 while (stuff != NULL) {
410 serv_printf("MSG0 %ld|2", stuff->msgnum);
411 serv_getln(buf, sizeof buf);
413 while(serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
414 if (!strncasecmp(buf, "part=", 5)) {
415 extract_token(partnum, &buf[5], 2, '|', sizeof partnum);
416 extract_token(content_type, &buf[5], 4, '|', sizeof content_type);
417 if ( (!strcasecmp(content_type, "text/x-vcard"))
418 || (!strcasecmp(content_type, "text/vcard")) ) {
419 vcard_msgnum = stuff->msgnum;
430 /** If there's no vcard, create one */
431 if ((vcard_msgnum < 0) && (already_tried_creating_one == 0)) {
432 already_tried_creating_one = 1;
433 serv_puts("ENT0 1|||4");
434 serv_getln(buf, sizeof buf);
436 serv_puts("Content-type: text/x-vcard");
438 serv_puts("begin:vcard");
439 serv_puts("end:vcard");
445 return(vcard_msgnum);
450 * Display the form for editing a user's address book entry
451 * username the name of the user
452 * usernum the citadel-uid of the user
454 void display_edit_address_book_entry(char *username, long usernum) {
457 char error_message[SIZ];
458 long vcard_msgnum = (-1L);
460 /** Locate the user's config room, creating it if necessary */
461 sprintf(roomname, "%010ld.%s", usernum, USERCONFIGROOM);
462 serv_printf("GOTO %s||1", roomname);
463 serv_getln(buf, sizeof buf);
465 serv_printf("CRE8 1|%s|5|||1|", roomname);
466 serv_getln(buf, sizeof buf);
467 serv_printf("GOTO %s||1", roomname);
468 serv_getln(buf, sizeof buf);
470 sprintf(error_message,
471 "<img src=\"static/error.gif\" align=center>"
472 "%s<br /><br />\n", &buf[4]);
473 select_user_to_edit(error_message, username);
478 vcard_msgnum = locate_user_vcard_in_this_room();
480 if (vcard_msgnum < 0) {
481 sprintf(error_message,
482 "<img src=\"static/error.gif\" align=center>%s<br /><br />\n",
483 _("An error occurred while trying to create or edit this address book entry.")
485 select_user_to_edit(error_message, username);
489 do_edit_vcard(vcard_msgnum, "1", "select_user_to_edit", roomname);
493 void display_edituser(char *supplied_username, int is_new) {
496 char error_message[1024];
500 if (supplied_username != NULL) {
501 safestrncpy(username, supplied_username, sizeof username);
504 safestrncpy(username, bstr("username"), sizeof username);
508 serv_printf("AGUP %s", username);
509 StrBuf_ServGetln(Buf);
510 MajorStatus = ChrPtr(Buf)[0];
511 StrBufCutLeft(Buf, 4);
512 if (MajorStatus != '2') {
513 /*TODO ImportantMessage */
514 sprintf(error_message,
515 "<img src=\"static/error.gif\" align=center>"
516 "%s<br /><br />\n", ChrPtr(Buf));
517 select_user_to_edit(error_message, username);
522 UL = NewUserListOneEntry(Buf);
523 if (havebstr("edit_abe_button")) {
524 display_edit_address_book_entry(username, UL->UID);
526 else if (havebstr("delete_button")) {
527 delete_user(username);
530 WCTemplputParams SubTP;
531 memset(&SubTP, 0, sizeof(WCTemplputParams));
532 SubTP.Filter.ContextType = CTX_USERLIST;
534 output_headers(1, 0, 0, 0, 1, 0);
535 DoTemplate(HKEY("userlist_detailview"), NULL, &SubTP);
538 DeleteUserListEntry(UL);
545 * do the backend operation of the user edit on the server
547 void edituser(void) {
551 unsigned int flags = 0;
554 is_new = ibstr("is_new");
555 safestrncpy(message, "", sizeof message);
556 username = bstr("username");
558 if (!havebstr("ok_button")) {
559 safestrncpy(message, _("Changes were not saved."), sizeof message);
563 flags = ibstr("flags");
564 if (yesbstr("inetmail")) {
565 flags |= US_INTERNET;
568 flags &= ~US_INTERNET ;
571 if ((havebstr("newname")) && (strcasecmp(bstr("username"), bstr("newname")))) {
572 serv_printf("RENU %s|%s", bstr("username"), bstr("newname"));
573 serv_getln(buf, sizeof buf);
575 sprintf(&message[strlen(message)],
576 "<img src=\"static/error.gif\" align=center>"
577 "%s<br /><br />\n", &buf[4]);
580 username = bstr("newname");
584 serv_printf("ASUP %s|%s|%d|%s|%s|%s|%s|%s|%s|",
595 serv_getln(buf, sizeof buf);
597 sprintf(&message[strlen(message)],
598 "<img src=\"static/error.gif\" align=center>"
599 "%s<br /><br />\n", &buf[4]);
604 * If we are in the middle of creating a new user, move on to
605 * the vCard edit screen.
608 display_edit_address_book_entry(username, lbstr("usernum") );
611 select_user_to_edit(message, username);
617 * username the name of the user to remove
619 void delete_user(char *username) {
623 serv_printf("ASUP %s|0|0|0|0|0|", username);
624 serv_getln(buf, sizeof buf);
627 "<img src=\"static/error.gif\" align=center>"
628 "%s<br /><br />\n", &buf[4]);
631 safestrncpy(message, "", sizeof message);
633 select_user_to_edit(message, bstr("username"));
640 * take the web environment username and create it on the citadel server
642 void create_user(void) {
644 char error_message[SIZ];
647 safestrncpy(username, bstr("username"), sizeof username);
649 serv_printf("CREU %s", username);
650 serv_getln(buf, sizeof buf);
653 sprintf(WC->ImportantMessage, _("A new user has been created."));
654 display_edituser(username, 1);
656 else if (!strncmp(buf, "570", 3)) {
657 sprintf(error_message,
658 "<img src=\"static/error.gif\" align=center>"
660 _("You are attempting to create a new user from within Citadel "
661 "while running in host based authentication mode. In this mode, "
662 "you must create new users on the host system, not within Citadel.")
664 select_user_to_edit(error_message, NULL);
667 sprintf(error_message,
668 "<img src=\"static/error.gif\" align=center>"
669 "%s<br /><br />\n", &buf[4]);
670 select_user_to_edit(error_message, NULL);
676 void _select_user_to_edit(void){select_user_to_edit(NULL, NULL);}
677 void _display_edituser(void) {display_edituser(NULL, 0);}
683 WebcitAddUrlHandler(HKEY("select_user_to_edit"), _select_user_to_edit, 0);
684 WebcitAddUrlHandler(HKEY("display_edituser"), _display_edituser, 0);
685 WebcitAddUrlHandler(HKEY("edituser"), edituser, 0);
686 WebcitAddUrlHandler(HKEY("create_user"), create_user, 0);
688 RegisterNamespace("USERLIST:USERNAME", 0, 1, tmplput_USERLIST_UserName, CTX_USERLIST);
689 RegisterNamespace("USERLIST:ACCLVLNO", 0, 0, tmplput_USERLIST_AccessLevelNo, CTX_USERLIST);
690 RegisterNamespace("USERLIST:ACCLVLSTR", 0, 0, tmplput_USERLIST_AccessLevelStr, CTX_USERLIST);
691 RegisterNamespace("USERLIST:UID", 0, 0, tmplput_USERLIST_UID, CTX_USERLIST);
692 RegisterNamespace("USERLIST:LASTLOGON:STR", 0, 0, tmplput_USERLIST_LastLogonStr, CTX_USERLIST);
693 RegisterNamespace("USERLIST:LASTLOGON:NO", 0, 0, tmplput_USERLIST_LastLogonNo, CTX_USERLIST);
694 RegisterNamespace("USERLIST:NLOGONS", 0, 0, tmplput_USERLIST_nLogons, CTX_USERLIST);
695 RegisterNamespace("USERLIST:NPOSTS", 0, 0, tmplput_USERLIST_nPosts, CTX_USERLIST);
697 RegisterNamespace("USERLIST:FLAGS", 0, 0, tmplput_USERLIST_Flags, CTX_USERLIST);
698 RegisterNamespace("USERLIST:DAYSTILLPURGE", 0, 0, tmplput_USERLIST_DaysTillPurge, CTX_USERLIST);
700 RegisterConditional(HKEY("COND:USERNAME"), 0, ConditionalUser, CTX_USERLIST);
701 RegisterConditional(HKEY("COND:USERACCESS"), 0, ConditionalUserAccess, CTX_USERLIST);
702 RegisterConditional(HKEY("COND:USERLIST:FLAG:USE_INTERNET"), 0, ConditionalFlagINetEmail, CTX_USERLIST);
704 RegisterIterator("USERLIST", 0, NULL, iterate_load_userlist, NULL, DeleteHash, CTX_USERLIST, CTX_NONE, IT_NOFLAG);
707 RegisterSortFunc(HKEY("user:name"),
710 CompareUserListNameRev,
711 GroupchangeUserListName,
713 RegisterSortFunc(HKEY("user:accslvl"),
716 CompareAccessLevelRev,
717 GroupchangeAccessLevel,
720 RegisterSortFunc(HKEY("user:nlogons"),
727 RegisterSortFunc(HKEY("user:uid"),
734 RegisterSortFunc(HKEY("user:lastlogon"),
738 GroupchangeLastLogon,
741 RegisterSortFunc(HKEY("user:nmsgposts"),