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")))
321 UID = atoi(ChrPtr(Buf));
322 if (GetHash(Hash, IKEY(UID), &vData) && vData != 0)
324 ul = (UserListEntry*)vData;
328 SubTP.Filter.ContextType = CTX_USERLIST;
329 SortIt = RetrieveSort(&SubTP, HKEY("USER"), HKEY("user:uid"), 0);
331 SortByPayload(Hash, SortIt);
333 SortByPayload(Hash, CompareUID);
340 void tmplput_USERLIST_UserName(StrBuf *Target, WCTemplputParams *TP)
342 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
343 StrBufAppendTemplate(Target, TP, ul->UserName, 0);
346 void tmplput_USERLIST_Password(StrBuf *Target, WCTemplputParams *TP)
348 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
349 StrBufAppendTemplate(Target, TP, ul->Passvoid, 0);
352 void tmplput_USERLIST_PrimaryEmail(StrBuf *Target, WCTemplputParams *TP)
354 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
355 StrBufAppendTemplate(Target, TP, ul->PrimaryEmail, 0);
358 void tmplput_USERLIST_OtherEmails(StrBuf *Target, WCTemplputParams *TP)
360 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
361 StrBufAppendTemplate(Target, TP, ul->OtherEmails, 0);
364 void tmplput_USERLIST_AccessLevelNo(StrBuf *Target, WCTemplputParams *TP)
366 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
368 StrBufAppendPrintf(Target, "%d", ul->AccessLevel, 0);
371 void tmplput_USERLIST_AccessLevelStr(StrBuf *Target, WCTemplputParams *TP)
373 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
375 StrBufAppendBufPlain(Target, _(axdefs[ul->AccessLevel]), -1, 0);
378 void tmplput_USERLIST_UID(StrBuf *Target, WCTemplputParams *TP)
380 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
382 StrBufAppendPrintf(Target, "%d", ul->UID, 0);
385 void tmplput_USERLIST_LastLogonNo(StrBuf *Target, WCTemplputParams *TP)
387 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
389 StrBufAppendPrintf(Target,"%ld", ul->LastLogonT, 0);
391 void tmplput_USERLIST_LastLogonStr(StrBuf *Target, WCTemplputParams *TP)
393 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
394 StrEscAppend(Target, NULL, asctime(localtime(&ul->LastLogonT)), 0, 0);
397 void tmplput_USERLIST_nLogons(StrBuf *Target, WCTemplputParams *TP)
399 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
401 StrBufAppendPrintf(Target, "%d", ul->nLogons, 0);
404 void tmplput_USERLIST_nPosts(StrBuf *Target, WCTemplputParams *TP)
406 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
408 StrBufAppendPrintf(Target, "%d", ul->nPosts, 0);
411 void tmplput_USERLIST_Flags(StrBuf *Target, WCTemplputParams *TP)
413 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
415 StrBufAppendPrintf(Target, "%d", ul->Flags, 0);
418 void tmplput_USERLIST_DaysTillPurge(StrBuf *Target, WCTemplputParams *TP)
420 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
422 StrBufAppendPrintf(Target, "%d", ul->DaysTillPurge, 0);
425 int ConditionalUser(StrBuf *Target, WCTemplputParams *TP)
427 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
428 if (havebstr("usernum")) {
429 return ibstr("usernum") == ul->UID;
431 else if (havebstr("username")) {
432 return strcmp(bstr("username"), ChrPtr(ul->UserName)) == 0;
438 int ConditionalFlagINetEmail(StrBuf *Target, WCTemplputParams *TP)
440 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
441 return (ul->Flags & US_INTERNET) != 0;
444 int ConditionalUserAccess(StrBuf *Target, WCTemplputParams *TP)
446 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
451 return GetTemplateTokenNumber(Target,
458 int ConditionalHaveBIO(StrBuf *Target, WCTemplputParams *TP)
460 UserListEntry *ul = (UserListEntry*) CTX(CTX_USERLIST);
467 void tmplput_USER_BIO(StrBuf *Target, WCTemplputParams *TP)
474 GetTemplateTokenString(Target, TP, 0, &who, &len);
476 who = ChrPtr(WC->wc_fullname);
480 serv_printf("RBIO %s", who);
481 StrBuf_ServGetln(Buf);
482 if (GetServerStatus(Buf, NULL) == 1) {
483 StrBuf *BioBuf = NewStrBufPlain(NULL, SIZ);
484 while (!Done && StrBuf_ServGetln(Buf)>=0) {
485 if ( (StrLength(Buf)==3) &&
486 !strcmp(ChrPtr(Buf), "000"))
489 StrBufAppendBuf(BioBuf, Buf, 0);
490 StrBufAppendBufPlain(BioBuf, HKEY("\n"), 0);
493 StrBufAppendTemplate(Target, TP, BioBuf, 1);
500 int Conditional_USER_HAS_PIC(StrBuf *Target, WCTemplputParams *TP)
502 // ajc 2016apr10 this needs to be re-evaluated with the new protocol
508 * Locate the message number of a user's vCard in the current room
509 * Returns the message id of his vcard
511 long locate_user_vcard_in_this_room(message_summary **VCMsg, wc_mime_attachment **VCAtt)
519 message_summary *Msg;
520 wc_mime_attachment *Att;
522 long vcard_msgnum = (-1L);
523 int already_tried_creating_one = 0;
524 StrBuf *FoundCharset = NewStrBuf();
525 StrBuf *Error = NULL;
526 SharedMessageStatus Stat;
531 memset(&Stat, 0, sizeof(SharedMessageStatus));
532 Stat.maxload = 10000;
533 Stat.lowest_found = (-1);
534 Stat.highest_found = (-1);
535 /* Search for the user's vCard */
536 if (load_msg_ptrs("MSGS ALL||||1", NULL, NULL, &Stat, NULL, NULL, NULL, NULL, 0) > 0) {
537 at = GetNewHashPos(WCC->summ, 0);
538 while (GetNextHashPos(WCC->summ, at, &HKLen, &HashKey, &vMsg)) {
539 Msg = (message_summary*) vMsg;
540 Msg->MsgBody = (wc_mime_attachment*) malloc(sizeof(wc_mime_attachment));
541 memset(Msg->MsgBody, 0, sizeof(wc_mime_attachment));
542 Msg->MsgBody->msgnum = Msg->msgnum;
544 load_message(Msg, FoundCharset, &Error);
546 if (Msg->AllAttach != NULL) {
547 att = GetNewHashPos(Msg->AllAttach, 0);
548 while (GetNextHashPos(Msg->AllAttach, att, &HKLen, &HashKey, &vMsg) &&
549 (vcard_msgnum == -1)) {
550 Att = (wc_mime_attachment*) vMsg;
552 (strcasecmp(ChrPtr(Att->ContentType), "text/x-vcard") == 0)
553 || (strcasecmp(ChrPtr(Att->ContentType), "text/vcard") == 0)
557 vcard_msgnum = Msg->msgnum;
558 if (Att->Data == NULL) {
565 FreeStrBuf(&Error); /* don't care... */
571 /* If there's no vcard, create one */
572 if ((*VCMsg == NULL) && (already_tried_creating_one == 0)) {
574 already_tried_creating_one = 1;
575 serv_puts("ENT0 1|||4");
576 StrBuf_ServGetln(Buf);
577 if (GetServerStatus(Buf, NULL) == 4) {
578 serv_puts("Content-type: text/x-vcard");
580 serv_puts("begin:vcard");
581 serv_puts("end:vcard");
585 syslog(LOG_WARNING, "Error while creating user vcard: %s\n", ChrPtr(Buf));
589 FreeStrBuf(&FoundCharset);
591 return(vcard_msgnum);
596 * Display the form for editing a user's address book entry
597 * username the name of the user
598 * usernum the citadel-uid of the user
600 void display_edit_address_book_entry(const char *username, long usernum) {
601 message_summary *VCMsg = NULL;
602 wc_mime_attachment *VCAtt = NULL;
605 long vcard_msgnum = (-1L);
607 /* Locate the user's config room, creating it if necessary */
609 roomname = NewStrBuf();
610 StrBufPrintf(roomname, "%010ld.%s", usernum, USERCONFIGROOM);
611 serv_printf("GOTO %s||1", ChrPtr(roomname));
612 StrBuf_ServGetln(Buf);
613 if (GetServerStatus(Buf, NULL) != 2) {
614 serv_printf("CRE8 1|%s|5|||1|", ChrPtr(roomname));
615 StrBuf_ServGetln(Buf);
616 GetServerStatus(Buf, NULL);
617 serv_printf("GOTO %s||1", ChrPtr(roomname));
618 StrBuf_ServGetln(Buf);
619 if (GetServerStatusMsg(Buf, NULL, 1, 2) != 2) {
620 select_user_to_edit(username);
622 FreeStrBuf(&roomname);
628 locate_user_vcard_in_this_room(&VCMsg, &VCAtt);
631 AppendImportantMessage(_("An error occurred while trying to create or edit this address book entry."), -1);
632 select_user_to_edit(username);
633 FreeStrBuf(&roomname);
637 do_edit_vcard(vcard_msgnum, "1",
640 "select_user_to_edit",
642 FreeStrBuf(&roomname);
647 * username the name of the user to remove
649 void delete_user(char *username) {
653 serv_printf("ASUP %s|0|0|0|0|0|", username);
654 StrBuf_ServGetln(Buf);
655 GetServerStatusMsg(Buf, NULL, 1, 2);
657 select_user_to_edit( bstr("username"));
662 void display_edituser(const char *supplied_username, int is_new) {
669 if (supplied_username != NULL) {
670 safestrncpy(username, supplied_username, sizeof username);
673 safestrncpy(username, bstr("username"), sizeof username);
677 serv_printf("AGUP %s", username);
678 StrBuf_ServGetln(Buf);
679 if (GetServerStatusMsg(Buf, NULL, 1, 2) != 2) {
680 select_user_to_edit(username);
685 Pos = ChrPtr(Buf) + 4;
686 UL = NewUserListOneEntry(Buf, Pos);
687 if ((UL != NULL) && havebstr("edit_abe_button")) {
688 display_edit_address_book_entry(username, UL->UID);
690 else if ((UL != NULL) && havebstr("delete_button")) {
691 delete_user(username);
693 else if (UL != NULL) {
695 serv_printf("AGEA %s", username);
696 StrBuf_ServGetln(Buf);
697 if (GetServerStatusMsg(Buf, NULL, 1, 2) == 1) {
698 while(StrBuf_ServGetln(Buf) , strcmp(ChrPtr(Buf), "000")) {
700 StrBufAppendPrintf(UL->PrimaryEmail, "%s", ChrPtr(Buf));
703 StrBufAppendPrintf(UL->OtherEmails, ",");
706 StrBufAppendPrintf(UL->OtherEmails, "%s", ChrPtr(Buf));
712 WCTemplputParams SubTP;
713 memset(&SubTP, 0, sizeof(WCTemplputParams));
714 SubTP.Filter.ContextType = CTX_USERLIST;
716 output_headers(1, 0, 0, 0, 1, 0);
717 DoTemplate(HKEY("aide_edituser_detailview"), NULL, &SubTP);
720 DeleteUserListEntry(UL);
727 * do the backend operation of the user edit on the server
729 void edituser(void) {
731 unsigned int flags = 0;
732 const char *username;
734 is_new = ibstr("is_new");
735 username = bstr("username");
737 if (!havebstr("ok_button")) {
738 AppendImportantMessage(_("Changes were not saved."), -1);
741 StrBuf *Buf = NewStrBuf();
743 flags = ibstr("flags");
744 if (yesbstr("inetmail")) {
745 flags |= US_INTERNET;
748 flags &= ~US_INTERNET ;
751 if ((havebstr("newname")) && (strcasecmp(bstr("username"), bstr("newname")))) {
752 serv_printf("RENU %s|%s", bstr("username"), bstr("newname"));
753 StrBuf_ServGetln(Buf);
754 if (GetServerStatusMsg(Buf, NULL, 1, 2) != 2) {
755 username = bstr("newname");
759 /* Send the new account parameters */
760 serv_printf("ASUP %s|%s|%d|%s|%s|%s|%s|%s|%s|",
771 StrBuf_ServGetln(Buf);
772 GetServerStatusMsg(Buf, NULL, 1, 2);
774 /* Send the new email addresses. First make up a delimited list... */
775 char all_the_emails[512];
776 snprintf(all_the_emails, sizeof all_the_emails, "%s,%s", bstr("primaryemail"), bstr("otheremails"));
778 /* Replace any commas, semicolons, or spaces with newlines */
780 for (pos=all_the_emails; *pos!=0; ++pos) {
781 if ((*pos == ',') || (*pos == ';') || (*pos == ' ')) *pos = '\n' ;
784 /* Remove any naughty inappropriate whitespace */
785 striplt(all_the_emails);
786 while (pos = strstr(all_the_emails, "\n,"), (pos != NULL)) {
789 while (pos = strstr(all_the_emails, ",\n"), (pos != NULL)) {
790 strcpy(pos+1, pos+2);
792 while (pos = strstr(all_the_emails, "\n\n"), (pos != NULL)) {
793 strcpy(pos+1, pos+2);
796 /* Now send it to the server. */
797 serv_printf("ASEA %s", username);
798 StrBuf_ServGetln(Buf);
799 if (GetServerStatusMsg(Buf, NULL, 1, 2) == 4) {
800 serv_printf("%s\n000", all_the_emails);
807 * If we are in the middle of creating a new user, move on to
808 * the vCard edit screen.
811 display_edit_address_book_entry(username, lbstr("usernum") );
814 select_user_to_edit(username);
822 * take the web environment username and create it on the citadel server
824 void create_user(void) {
827 const char *username;
830 username = bstr("username");
831 serv_printf("CREU %s", username);
832 StrBuf_ServGetln(Buf);
833 if (GetServerStatus(Buf, &FullState) == 2) {
834 AppendImportantMessage(_("A new user has been created."), -1);
835 display_edituser(username, 1);
837 else if (FullState == 570) {
838 AppendImportantMessage(_("You are attempting to create a new user from within Citadel "
839 "while running in host based authentication mode. In this mode, "
840 "you must create new users on the host system, not within Citadel."),
842 select_user_to_edit(NULL);
845 AppendImportantMessage(ChrPtr(Buf) + 4, StrLength(Buf) - 4);
846 select_user_to_edit(NULL);
852 void display_userpic(void) {
854 StrBuf *Buf = NewStrBuf();
855 const char *username = bstr("user");
856 serv_printf("DLUI %s", username);
857 StrBuf_ServGetln(Buf);
858 if (GetServerStatus(Buf, NULL) == 6) {
859 StrBufCutLeft(Buf, 4);
860 bytes = StrBufExtract_long(Buf, 0, '|');
861 StrBuf *content_type = NewStrBuf();
862 StrBufExtract_token(content_type, Buf, 3, '|');
863 WC->WBuf = NewStrBuf();
864 StrBuf_ServGetBLOBBuffered(WC->WBuf, bytes);
865 http_transmit_thing(ChrPtr(content_type), 0);
866 FreeStrBuf(&content_type);
869 output_error_pic("", "");
875 void _select_user_to_edit(void) {
876 select_user_to_edit(NULL);
880 void _display_edituser(void) {
881 display_edituser(NULL, 0);
888 RegisterCTX(CTX_USERLIST);
889 WebcitAddUrlHandler(HKEY("select_user_to_edit"), "", 0, _select_user_to_edit, 0);
890 WebcitAddUrlHandler(HKEY("display_edituser"), "", 0, _display_edituser, 0);
891 WebcitAddUrlHandler(HKEY("edituser"), "", 0, edituser, 0);
892 WebcitAddUrlHandler(HKEY("create_user"), "", 0, create_user, 0);
893 WebcitAddUrlHandler(HKEY("userpic"), "", 0, display_userpic, 0);
895 RegisterNamespace("USERLIST:USERNAME", 0, 1, tmplput_USERLIST_UserName, NULL, CTX_USERLIST);
896 RegisterNamespace("USERLIST:PASSWD", 0, 1, tmplput_USERLIST_Password, NULL, CTX_USERLIST);
897 RegisterNamespace("USERLIST:ACCLVLNO", 0, 0, tmplput_USERLIST_AccessLevelNo, NULL, CTX_USERLIST);
898 RegisterNamespace("USERLIST:ACCLVLSTR", 0, 0, tmplput_USERLIST_AccessLevelStr, NULL, CTX_USERLIST);
899 RegisterNamespace("USERLIST:UID", 0, 0, tmplput_USERLIST_UID, NULL, CTX_USERLIST);
900 RegisterNamespace("USERLIST:LASTLOGON:STR", 0, 0, tmplput_USERLIST_LastLogonStr, NULL, CTX_USERLIST);
901 RegisterNamespace("USERLIST:LASTLOGON:NO", 0, 0, tmplput_USERLIST_LastLogonNo, NULL, CTX_USERLIST);
902 RegisterNamespace("USERLIST:NLOGONS", 0, 0, tmplput_USERLIST_nLogons, NULL, CTX_USERLIST);
903 RegisterNamespace("USERLIST:NPOSTS", 0, 0, tmplput_USERLIST_nPosts, NULL, CTX_USERLIST);
904 RegisterNamespace("USERLIST:PRIMARYEMAIL", 0, 1, tmplput_USERLIST_PrimaryEmail, NULL, CTX_USERLIST);
905 RegisterNamespace("USERLIST:OTHEREMAILS", 0, 1, tmplput_USERLIST_OtherEmails, NULL, CTX_USERLIST);
906 RegisterNamespace("USERLIST:FLAGS", 0, 0, tmplput_USERLIST_Flags, NULL, CTX_USERLIST);
907 RegisterNamespace("USERLIST:DAYSTILLPURGE", 0, 0, tmplput_USERLIST_DaysTillPurge, NULL, CTX_USERLIST);
909 RegisterNamespace("USER:BIO", 1, 2, tmplput_USER_BIO, NULL, CTX_NONE);
911 RegisterConditional("COND:USERNAME", 0, ConditionalUser, CTX_USERLIST);
912 RegisterConditional("COND:USERACCESS", 0, ConditionalUserAccess, CTX_USERLIST);
913 RegisterConditional("COND:USERLIST:FLAG:USE_INTERNET", 0, ConditionalFlagINetEmail, CTX_USERLIST);
914 RegisterConditional("COND:USERLIST:HAVEBIO", 0, ConditionalHaveBIO, CTX_USERLIST);
916 RegisterConditional("COND:USER:PIC", 1, Conditional_USER_HAS_PIC, CTX_NONE);
918 RegisterIterator("USERLIST", 0, NULL, iterate_load_userlist, NULL, DeleteHash, CTX_USERLIST, CTX_NONE, IT_FLAG_DETECT_GROUPCHANGE);
922 RegisterSortFunc(HKEY("user:name"),
925 CompareUserListNameRev,
926 GroupchangeUserListName,
928 RegisterSortFunc(HKEY("user:accslvl"),
931 CompareAccessLevelRev,
932 GroupchangeAccessLevel,
935 RegisterSortFunc(HKEY("user:nlogons"),
942 RegisterSortFunc(HKEY("user:uid"),
949 RegisterSortFunc(HKEY("user:lastlogon"),
953 GroupchangeLastLogon,
956 RegisterSortFunc(HKEY("user:nmsgposts"),
963 REGISTERTokenParamDefine(AxDeleted);
964 REGISTERTokenParamDefine(AxNewU);
965 REGISTERTokenParamDefine(AxProbU);
966 REGISTERTokenParamDefine(AxLocU);
967 REGISTERTokenParamDefine(AxNetU);
968 REGISTERTokenParamDefine(AxPrefU);
969 REGISTERTokenParamDefine(AxAideU);