2 * Copyright (c) 1996-2017 by the citadel.org team
4 * This program is open source software. You can redistribute it and/or
5 * modify it under the terms of the GNU General Public License, version 3.
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
14 #include "webserver.h"
16 CtxType CTX_USERLIST = CTX_NONE;
18 * show a list of available users to edit them
19 * message the header message???
20 * preselect = which user should be selected in the browser
22 void select_user_to_edit(const char *preselect)
24 output_headers(1, 0, 0, 0, 1, 0);
25 do_template("aide_edituser_select");
30 typedef struct _UserListEntry {
39 /* Just available for Single users to view: */
50 UserListEntry* NewUserListOneEntry(StrBuf *SerializedUser, const char *Pos)
54 if (StrLength(SerializedUser) < 8)
57 ul = (UserListEntry*) malloc(sizeof(UserListEntry));
58 ul->UserName = NewStrBuf();
59 ul->Passvoid = NewStrBuf();
60 ul->PrimaryEmail = NewStrBuf();
61 ul->OtherEmails = NewStrBuf();
63 StrBufExtract_NextToken(ul->UserName, SerializedUser, &Pos, '|');
64 StrBufExtract_NextToken(ul->Passvoid, SerializedUser, &Pos, '|');
65 ul->Flags = StrBufExtractNext_unsigned_long(SerializedUser, &Pos, '|');
66 ul->nLogons = StrBufExtractNext_int( SerializedUser, &Pos, '|');
67 ul->nPosts = StrBufExtractNext_int( SerializedUser, &Pos, '|');
68 ul->AccessLevel = StrBufExtractNext_int( SerializedUser, &Pos, '|');
69 ul->UID = StrBufExtractNext_int( SerializedUser, &Pos, '|');
70 ul->LastLogonT = StrBufExtractNext_long( SerializedUser, &Pos, '|');
71 ul->DaysTillPurge = StrBufExtractNext_int( SerializedUser, &Pos, '|');
75 void DeleteUserListEntry(void *vUserList)
77 UserListEntry *ul = (UserListEntry*) vUserList;
79 FreeStrBuf(&ul->UserName);
80 FreeStrBuf(&ul->Passvoid);
81 FreeStrBuf(&ul->PrimaryEmail);
82 FreeStrBuf(&ul->OtherEmails);
86 UserListEntry* NewUserListEntry(StrBuf *SerializedUserList)
88 const char *Pos = NULL;
91 if (StrLength(SerializedUserList) < 8)
94 ul = (UserListEntry*) malloc(sizeof(UserListEntry));
95 ul->UserName = NewStrBuf();
96 ul->Passvoid = NewStrBuf();
97 ul->PrimaryEmail = NewStrBuf();
98 ul->OtherEmails = NewStrBuf();
100 StrBufExtract_NextToken(ul->UserName, SerializedUserList, &Pos, '|');
101 ul->AccessLevel = StrBufExtractNext_int( SerializedUserList, &Pos, '|');
102 ul->UID = StrBufExtractNext_int( SerializedUserList, &Pos, '|');
103 ul->LastLogonT = StrBufExtractNext_long(SerializedUserList, &Pos, '|');
104 ul->nLogons = StrBufExtractNext_int( SerializedUserList, &Pos, '|');
105 ul->nPosts = StrBufExtractNext_int( SerializedUserList, &Pos, '|');
106 StrBufExtract_NextToken(ul->Passvoid, SerializedUserList, &Pos, '|');
109 ul->DaysTillPurge = -1;
116 int CompareUserListName(const void *vUser1, const void *vUser2)
118 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
119 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
121 return strcmp(ChrPtr(u1->UserName), ChrPtr(u2->UserName));
124 int CompareUserListNameRev(const void *vUser1, const void *vUser2)
126 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
127 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
128 return strcmp(ChrPtr(u2->UserName), ChrPtr(u1->UserName));
131 int GroupchangeUserListName(const void *vUser1, const void *vUser2)
133 UserListEntry *u1 = (UserListEntry*) vUser1;
134 UserListEntry *u2 = (UserListEntry*) vUser2;
135 return ChrPtr(u2->UserName)[0] != ChrPtr(u1->UserName)[0];
139 * Sort by access level
141 int CompareAccessLevel(const void *vUser1, const void *vUser2)
143 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
144 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
146 return (u1->AccessLevel > u2->AccessLevel);
149 int CompareAccessLevelRev(const void *vUser1, const void *vUser2)
151 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
152 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
154 return (u2->AccessLevel > u1->AccessLevel);
157 int GroupchangeAccessLevel(const void *vUser1, const void *vUser2)
159 UserListEntry *u1 = (UserListEntry*) vUser1;
160 UserListEntry *u2 = (UserListEntry*) vUser2;
162 return u2->AccessLevel != u1->AccessLevel;
168 int CompareUID(const void *vUser1, const void *vUser2)
170 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
171 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
173 return (u1->UID > u2->UID);
176 int CompareUIDRev(const void *vUser1, const void *vUser2)
178 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
179 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
181 return (u2->UID > u1->UID);
184 int GroupchangeUID(const void *vUser1, const void *vUser2)
186 UserListEntry *u1 = (UserListEntry*) vUser1;
187 UserListEntry *u2 = (UserListEntry*) vUser2;
189 return (u2->UID / 10) != (u1->UID / 10);
193 * Sort By Date /// TODO!
195 int CompareLastLogon(const void *vUser1, const void *vUser2)
197 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
198 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
200 return (u1->LastLogonT > u2->LastLogonT);
203 int CompareLastLogonRev(const void *vUser1, const void *vUser2)
205 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
206 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
208 return (u2->LastLogonT > u1->LastLogonT);
211 int GroupchangeLastLogon(const void *vUser1, const void *vUser2)
213 UserListEntry *u1 = (UserListEntry*) vUser1;
214 UserListEntry *u2 = (UserListEntry*) vUser2;
216 return (u2->LastLogonT != u1->LastLogonT);
220 * Sort By Number of Logons
222 int ComparenLogons(const void *vUser1, const void *vUser2)
224 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
225 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
227 return (u1->nLogons > u2->nLogons);
230 int ComparenLogonsRev(const void *vUser1, const void *vUser2)
232 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
233 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
235 return (u2->nLogons > u1->nLogons);
238 int GroupchangenLogons(const void *vUser1, const void *vUser2)
240 UserListEntry *u1 = (UserListEntry*) vUser1;
241 UserListEntry *u2 = (UserListEntry*) vUser2;
243 return (u2->nLogons / 100) != (u1->nLogons / 100);
247 * Sort By Number of Posts
249 int ComparenPosts(const void *vUser1, const void *vUser2)
251 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
252 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
254 return (u1->nPosts > u2->nPosts);
257 int ComparenPostsRev(const void *vUser1, const void *vUser2)
259 UserListEntry *u1 = (UserListEntry*) GetSearchPayload(vUser1);
260 UserListEntry *u2 = (UserListEntry*) GetSearchPayload(vUser2);
262 return (u2->nPosts > u1->nPosts);
265 int GroupchangenPosts(const void *vUser1, const void *vUser2)
267 UserListEntry *u1 = (UserListEntry*) vUser1;
268 UserListEntry *u2 = (UserListEntry*) vUser2;
270 return (u2->nPosts / 100) != (u1->nPosts / 100);
274 HashList *iterate_load_userlist(StrBuf *Target, WCTemplputParams *TP)
278 HashList *Hash = NULL;
284 WCTemplputParams SubTP;
286 memset(&SubTP, 0, sizeof(WCTemplputParams));
289 StrBuf_ServGetln(Buf);
290 if (GetServerStatus(Buf, NULL) == 1) {
291 Hash = NewHash(1, Flathash);
294 len = StrBuf_ServGetln(Buf);
297 !strcmp(ChrPtr(Buf), "000")))
302 ul = NewUserListEntry(Buf);
306 Put(Hash, IKEY(ul->UID), ul, DeleteUserListEntry);
310 StrBuf_ServGetln(Buf);
311 if (GetServerStatus(Buf, NULL) == 1)
314 len = StrBuf_ServGetln(Buf);
315 if ((len <0) || ((len == 3) && !strcmp(ChrPtr(Buf), "000")))
320 UID = atoi(ChrPtr(Buf));
321 if (GetHash(Hash, IKEY(UID), &vData) && vData != 0)
323 ul = (UserListEntry*)vData;
327 SubTP.Filter.ContextType = CTX_USERLIST;
328 SortIt = RetrieveSort(&SubTP, HKEY("USER"), HKEY("user:uid"), 0);
330 SortByPayload(Hash, SortIt);
332 SortByPayload(Hash, CompareUID);
339 void tmplput_USERLIST_UserName(StrBuf *Target, WCTemplputParams *TP)
341 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
342 StrBufAppendTemplate(Target, TP, ul->UserName, 0);
345 void tmplput_USERLIST_Password(StrBuf *Target, WCTemplputParams *TP)
347 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
348 StrBufAppendTemplate(Target, TP, ul->Passvoid, 0);
351 void tmplput_USERLIST_PrimaryEmail(StrBuf *Target, WCTemplputParams *TP)
353 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
354 StrBufAppendTemplate(Target, TP, ul->PrimaryEmail, 0);
357 void tmplput_USERLIST_OtherEmails(StrBuf *Target, WCTemplputParams *TP)
359 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
360 StrBufAppendTemplate(Target, TP, ul->OtherEmails, 0);
363 void tmplput_USERLIST_AccessLevelNo(StrBuf *Target, WCTemplputParams *TP)
365 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
367 StrBufAppendPrintf(Target, "%d", ul->AccessLevel, 0);
370 void tmplput_USERLIST_AccessLevelStr(StrBuf *Target, WCTemplputParams *TP)
372 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
374 StrBufAppendBufPlain(Target, _(axdefs[ul->AccessLevel]), -1, 0);
377 void tmplput_USERLIST_UID(StrBuf *Target, WCTemplputParams *TP)
379 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
381 StrBufAppendPrintf(Target, "%d", ul->UID, 0);
384 void tmplput_USERLIST_LastLogonNo(StrBuf *Target, WCTemplputParams *TP)
386 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
388 StrBufAppendPrintf(Target,"%ld", ul->LastLogonT, 0);
390 void tmplput_USERLIST_LastLogonStr(StrBuf *Target, WCTemplputParams *TP)
392 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
393 StrEscAppend(Target, NULL, asctime(localtime(&ul->LastLogonT)), 0, 0);
396 void tmplput_USERLIST_nLogons(StrBuf *Target, WCTemplputParams *TP)
398 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
400 StrBufAppendPrintf(Target, "%d", ul->nLogons, 0);
403 void tmplput_USERLIST_nPosts(StrBuf *Target, WCTemplputParams *TP)
405 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
407 StrBufAppendPrintf(Target, "%d", ul->nPosts, 0);
410 void tmplput_USERLIST_Flags(StrBuf *Target, WCTemplputParams *TP)
412 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
414 StrBufAppendPrintf(Target, "%d", ul->Flags, 0);
417 void tmplput_USERLIST_DaysTillPurge(StrBuf *Target, WCTemplputParams *TP)
419 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
421 StrBufAppendPrintf(Target, "%d", ul->DaysTillPurge, 0);
424 int ConditionalUser(StrBuf *Target, WCTemplputParams *TP)
426 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
427 if (havebstr("usernum")) {
428 return ibstr("usernum") == ul->UID;
430 else if (havebstr("username")) {
431 return strcmp(bstr("username"), ChrPtr(ul->UserName)) == 0;
437 int ConditionalFlagINetEmail(StrBuf *Target, WCTemplputParams *TP)
439 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
440 return (ul->Flags & US_INTERNET) != 0;
443 int ConditionalUserAccess(StrBuf *Target, WCTemplputParams *TP)
445 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
450 return GetTemplateTokenNumber(Target,
457 int ConditionalHaveBIO(StrBuf *Target, WCTemplputParams *TP)
459 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
466 void tmplput_USER_BIO(StrBuf *Target, WCTemplputParams *TP)
473 GetTemplateTokenString(Target, TP, 0, &who, &len);
475 who = ChrPtr(WC->wc_fullname);
479 serv_printf("RBIO %s", who);
480 StrBuf_ServGetln(Buf);
481 if (GetServerStatus(Buf, NULL) == 1) {
482 StrBuf *BioBuf = NewStrBufPlain(NULL, SIZ);
483 while (!Done && StrBuf_ServGetln(Buf)>=0) {
484 if ( (StrLength(Buf)==3) &&
485 !strcmp(ChrPtr(Buf), "000"))
488 StrBufAppendBuf(BioBuf, Buf, 0);
489 StrBufAppendBufPlain(BioBuf, HKEY("\n"), 0);
492 StrBufAppendTemplate(Target, TP, BioBuf, 1);
499 int Conditional_USER_HAS_PIC(StrBuf *Target, WCTemplputParams *TP)
501 // ajc 2016apr10 this needs to be re-evaluated with the new protocol
507 * Locate the message number of a user's vCard in the current room
508 * Returns the message id of his vcard
510 long locate_user_vcard_in_this_room(message_summary **VCMsg, wc_mime_attachment **VCAtt)
518 message_summary *Msg;
519 wc_mime_attachment *Att;
521 long vcard_msgnum = (-1L);
522 int already_tried_creating_one = 0;
523 StrBuf *FoundCharset = NewStrBuf();
524 StrBuf *Error = NULL;
525 SharedMessageStatus Stat;
530 memset(&Stat, 0, sizeof(SharedMessageStatus));
531 Stat.maxload = 10000;
532 Stat.lowest_found = (-1);
533 Stat.highest_found = (-1);
534 /* Search for the user's vCard */
535 if (load_msg_ptrs("MSGS ALL||||1", NULL, NULL, &Stat, NULL, NULL, NULL, NULL, 0) > 0) {
536 at = GetNewHashPos(WCC->summ, 0);
537 while (GetNextHashPos(WCC->summ, at, &HKLen, &HashKey, &vMsg)) {
538 Msg = (message_summary*) vMsg;
539 Msg->MsgBody = (wc_mime_attachment*) malloc(sizeof(wc_mime_attachment));
540 memset(Msg->MsgBody, 0, sizeof(wc_mime_attachment));
541 Msg->MsgBody->msgnum = Msg->msgnum;
543 load_message(Msg, FoundCharset, &Error);
545 if (Msg->AllAttach != NULL) {
546 att = GetNewHashPos(Msg->AllAttach, 0);
547 while (GetNextHashPos(Msg->AllAttach, att, &HKLen, &HashKey, &vMsg) &&
548 (vcard_msgnum == -1)) {
549 Att = (wc_mime_attachment*) vMsg;
551 (strcasecmp(ChrPtr(Att->ContentType), "text/x-vcard") == 0)
552 || (strcasecmp(ChrPtr(Att->ContentType), "text/vcard") == 0)
556 vcard_msgnum = Msg->msgnum;
557 if (Att->Data == NULL) {
564 FreeStrBuf(&Error); /* don't care... */
570 /* If there's no vcard, create one */
571 if ((*VCMsg == NULL) && (already_tried_creating_one == 0)) {
573 already_tried_creating_one = 1;
574 serv_puts("ENT0 1|||4");
575 StrBuf_ServGetln(Buf);
576 if (GetServerStatus(Buf, NULL) == 4) {
577 serv_puts("Content-type: text/x-vcard");
579 serv_puts("begin:vcard");
580 serv_puts("end:vcard");
584 syslog(LOG_WARNING, "Error while creating user vcard: %s\n", ChrPtr(Buf));
588 FreeStrBuf(&FoundCharset);
590 return(vcard_msgnum);
595 * Display the form for editing a user's address book entry
596 * username the name of the user
597 * usernum the citadel-uid of the user
599 void display_edit_address_book_entry(const char *username, long usernum) {
600 message_summary *VCMsg = NULL;
601 wc_mime_attachment *VCAtt = NULL;
604 long vcard_msgnum = (-1L);
606 /* Locate the user's config room, creating it if necessary */
608 roomname = NewStrBuf();
609 StrBufPrintf(roomname, "%010ld.%s", usernum, USERCONFIGROOM);
610 serv_printf("GOTO %s||1", ChrPtr(roomname));
611 StrBuf_ServGetln(Buf);
612 if (GetServerStatus(Buf, NULL) != 2) {
613 serv_printf("CRE8 1|%s|5|||1|", ChrPtr(roomname));
614 StrBuf_ServGetln(Buf);
615 GetServerStatus(Buf, NULL);
616 serv_printf("GOTO %s||1", ChrPtr(roomname));
617 StrBuf_ServGetln(Buf);
618 if (GetServerStatusMsg(Buf, NULL, 1, 2) != 2) {
619 select_user_to_edit(username);
621 FreeStrBuf(&roomname);
627 locate_user_vcard_in_this_room(&VCMsg, &VCAtt);
630 AppendImportantMessage(_("An error occurred while trying to create or edit this address book entry."), -1);
631 select_user_to_edit(username);
632 FreeStrBuf(&roomname);
636 do_edit_vcard(vcard_msgnum, "1",
639 "select_user_to_edit",
641 FreeStrBuf(&roomname);
646 * username the name of the user to remove
648 void delete_user(char *username) {
652 serv_printf("ASUP %s|0|0|0|0|0|", username);
653 StrBuf_ServGetln(Buf);
654 GetServerStatusMsg(Buf, NULL, 1, 2);
656 select_user_to_edit( bstr("username"));
661 void display_edituser(const char *supplied_username, int is_new) {
668 if (supplied_username != NULL) {
669 safestrncpy(username, supplied_username, sizeof username);
672 safestrncpy(username, bstr("username"), sizeof username);
676 serv_printf("AGUP %s", username);
677 StrBuf_ServGetln(Buf);
678 if (GetServerStatusMsg(Buf, NULL, 1, 2) != 2) {
679 select_user_to_edit(username);
684 Pos = ChrPtr(Buf) + 4;
685 UL = NewUserListOneEntry(Buf, Pos);
686 if ((UL != NULL) && havebstr("edit_abe_button")) {
687 display_edit_address_book_entry(username, UL->UID);
689 else if ((UL != NULL) && havebstr("delete_button")) {
690 delete_user(username);
692 else if (UL != NULL) {
694 serv_printf("AGEA %s", username);
695 StrBuf_ServGetln(Buf);
696 if (GetServerStatusMsg(Buf, NULL, 1, 2) == 1) {
697 while(StrBuf_ServGetln(Buf) , strcmp(ChrPtr(Buf), "000")) {
699 StrBufAppendPrintf(UL->PrimaryEmail, "%s", ChrPtr(Buf));
702 StrBufAppendPrintf(UL->OtherEmails, ",");
705 StrBufAppendPrintf(UL->OtherEmails, "%s", ChrPtr(Buf));
711 WCTemplputParams SubTP;
712 memset(&SubTP, 0, sizeof(WCTemplputParams));
713 SubTP.Filter.ContextType = CTX_USERLIST;
715 output_headers(1, 0, 0, 0, 1, 0);
716 DoTemplate(HKEY("aide_edituser_detailview"), NULL, &SubTP);
719 DeleteUserListEntry(UL);
726 * do the backend operation of the user edit on the server
728 void edituser(void) {
730 unsigned int flags = 0;
731 const char *username;
733 is_new = ibstr("is_new");
734 username = bstr("username");
736 if (!havebstr("ok_button")) {
737 AppendImportantMessage(_("Changes were not saved."), -1);
740 StrBuf *Buf = NewStrBuf();
742 flags = ibstr("flags");
743 if (yesbstr("inetmail")) {
744 flags |= US_INTERNET;
747 flags &= ~US_INTERNET ;
750 if ((havebstr("newname")) && (strcasecmp(bstr("username"), bstr("newname")))) {
751 serv_printf("RENU %s|%s", bstr("username"), bstr("newname"));
752 StrBuf_ServGetln(Buf);
753 if (GetServerStatusMsg(Buf, NULL, 1, 2) != 2) {
754 username = bstr("newname");
758 /* Send the new account parameters */
759 serv_printf("ASUP %s|%s|%d|%s|%s|%s|%s|%s|%s|",
770 StrBuf_ServGetln(Buf);
771 GetServerStatusMsg(Buf, NULL, 1, 2);
773 /* Send the new email addresses. First make up a delimited list... */
774 char all_the_emails[512];
775 snprintf(all_the_emails, sizeof all_the_emails, "%s,%s", bstr("primaryemail"), bstr("otheremails"));
777 /* Replace any commas, semicolons, or spaces with newlines */
779 for (pos=all_the_emails; *pos!=0; ++pos) {
780 if ((*pos == ',') || (*pos == ';') || (*pos == ' ')) *pos = '\n' ;
783 /* Remove any naughty inappropriate whitespace */
784 striplt(all_the_emails);
785 while (pos = strstr(all_the_emails, "\n,"), (pos != NULL)) {
788 while (pos = strstr(all_the_emails, ",\n"), (pos != NULL)) {
789 strcpy(pos+1, pos+2);
791 while (pos = strstr(all_the_emails, "\n\n"), (pos != NULL)) {
792 strcpy(pos+1, pos+2);
795 /* Now send it to the server. */
796 serv_printf("ASEA %s", username);
797 StrBuf_ServGetln(Buf);
798 if (GetServerStatusMsg(Buf, NULL, 1, 2) == 4) {
799 serv_printf("%s\n000", all_the_emails);
806 * If we are in the middle of creating a new user, move on to
807 * the vCard edit screen.
810 display_edit_address_book_entry(username, lbstr("usernum") );
813 select_user_to_edit(username);
821 * take the web environment username and create it on the citadel server
823 void create_user(void) {
826 const char *username;
829 username = bstr("username");
830 serv_printf("CREU %s", username);
831 StrBuf_ServGetln(Buf);
832 if (GetServerStatus(Buf, &FullState) == 2) {
833 AppendImportantMessage(_("A new user has been created."), -1);
834 display_edituser(username, 1);
836 else if (FullState == 570) {
837 AppendImportantMessage(_("You are attempting to create a new user from within Citadel "
838 "while running in host based authentication mode. In this mode, "
839 "you must create new users on the host system, not within Citadel."),
841 select_user_to_edit(NULL);
844 AppendImportantMessage(ChrPtr(Buf) + 4, StrLength(Buf) - 4);
845 select_user_to_edit(NULL);
851 void display_userpic(void) {
853 StrBuf *Buf = NewStrBuf();
854 const char *username = bstr("user");
855 serv_printf("DLUI %s", username);
856 StrBuf_ServGetln(Buf);
857 if (GetServerStatus(Buf, NULL) == 6) {
858 StrBufCutLeft(Buf, 4);
859 bytes = StrBufExtract_long(Buf, 0, '|');
860 StrBuf *content_type = NewStrBuf();
861 StrBufExtract_token(content_type, Buf, 3, '|');
862 WC->WBuf = NewStrBuf();
863 StrBuf_ServGetBLOBBuffered(WC->WBuf, bytes);
864 http_transmit_thing(ChrPtr(content_type), 0);
865 FreeStrBuf(&content_type);
868 output_error_pic("", "");
874 void _select_user_to_edit(void) {
875 select_user_to_edit(NULL);
879 void _display_edituser(void) {
880 display_edituser(NULL, 0);
887 RegisterCTX(CTX_USERLIST);
888 WebcitAddUrlHandler(HKEY("select_user_to_edit"), "", 0, _select_user_to_edit, 0);
889 WebcitAddUrlHandler(HKEY("display_edituser"), "", 0, _display_edituser, 0);
890 WebcitAddUrlHandler(HKEY("edituser"), "", 0, edituser, 0);
891 WebcitAddUrlHandler(HKEY("create_user"), "", 0, create_user, 0);
892 WebcitAddUrlHandler(HKEY("userpic"), "", 0, display_userpic, 0);
894 RegisterNamespace("USERLIST:USERNAME", 0, 1, tmplput_USERLIST_UserName, NULL, CTX_USERLIST);
895 RegisterNamespace("USERLIST:PASSWD", 0, 1, tmplput_USERLIST_Password, NULL, CTX_USERLIST);
896 RegisterNamespace("USERLIST:ACCLVLNO", 0, 0, tmplput_USERLIST_AccessLevelNo, NULL, CTX_USERLIST);
897 RegisterNamespace("USERLIST:ACCLVLSTR", 0, 0, tmplput_USERLIST_AccessLevelStr, NULL, CTX_USERLIST);
898 RegisterNamespace("USERLIST:UID", 0, 0, tmplput_USERLIST_UID, NULL, CTX_USERLIST);
899 RegisterNamespace("USERLIST:LASTLOGON:STR", 0, 0, tmplput_USERLIST_LastLogonStr, NULL, CTX_USERLIST);
900 RegisterNamespace("USERLIST:LASTLOGON:NO", 0, 0, tmplput_USERLIST_LastLogonNo, NULL, CTX_USERLIST);
901 RegisterNamespace("USERLIST:NLOGONS", 0, 0, tmplput_USERLIST_nLogons, NULL, CTX_USERLIST);
902 RegisterNamespace("USERLIST:NPOSTS", 0, 0, tmplput_USERLIST_nPosts, NULL, CTX_USERLIST);
903 RegisterNamespace("USERLIST:PRIMARYEMAIL", 0, 1, tmplput_USERLIST_PrimaryEmail, NULL, CTX_USERLIST);
904 RegisterNamespace("USERLIST:OTHEREMAILS", 0, 1, tmplput_USERLIST_OtherEmails, NULL, CTX_USERLIST);
905 RegisterNamespace("USERLIST:FLAGS", 0, 0, tmplput_USERLIST_Flags, NULL, CTX_USERLIST);
906 RegisterNamespace("USERLIST:DAYSTILLPURGE", 0, 0, tmplput_USERLIST_DaysTillPurge, NULL, CTX_USERLIST);
908 RegisterNamespace("USER:BIO", 1, 2, tmplput_USER_BIO, NULL, CTX_NONE);
910 RegisterConditional("COND:USERNAME", 0, ConditionalUser, CTX_USERLIST);
911 RegisterConditional("COND:USERACCESS", 0, ConditionalUserAccess, CTX_USERLIST);
912 RegisterConditional("COND:USERLIST:FLAG:USE_INTERNET", 0, ConditionalFlagINetEmail, CTX_USERLIST);
913 RegisterConditional("COND:USERLIST:HAVEBIO", 0, ConditionalHaveBIO, CTX_USERLIST);
915 RegisterConditional("COND:USER:PIC", 1, Conditional_USER_HAS_PIC, CTX_NONE);
917 RegisterIterator("USERLIST", 0, NULL, iterate_load_userlist, NULL, DeleteHash, CTX_USERLIST, CTX_NONE, IT_FLAG_DETECT_GROUPCHANGE);
921 RegisterSortFunc(HKEY("user:name"),
924 CompareUserListNameRev,
925 GroupchangeUserListName,
927 RegisterSortFunc(HKEY("user:accslvl"),
930 CompareAccessLevelRev,
931 GroupchangeAccessLevel,
934 RegisterSortFunc(HKEY("user:nlogons"),
941 RegisterSortFunc(HKEY("user:uid"),
948 RegisterSortFunc(HKEY("user:lastlogon"),
952 GroupchangeLastLogon,
955 RegisterSortFunc(HKEY("user:nmsgposts"),
962 REGISTERTokenParamDefine(AxDeleted);
963 REGISTERTokenParamDefine(AxNewU);
964 REGISTERTokenParamDefine(AxProbU);
965 REGISTERTokenParamDefine(AxLocU);
966 REGISTERTokenParamDefine(AxNetU);
967 REGISTERTokenParamDefine(AxPrefU);
968 REGISTERTokenParamDefine(AxAideU);