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*) vUser1;
97 UserListEntry *u2 = (UserListEntry*) vUser2;
99 return strcmp(ChrPtr(u1->UserName), ChrPtr(u2->UserName));
101 int CompareUserListNameRev(const void *vUser1, const void *vUser2)
103 UserListEntry *u1 = (UserListEntry*) vUser1;
104 UserListEntry *u2 = (UserListEntry*) vUser2;
105 return strcmp(ChrPtr(u2->UserName), ChrPtr(u1->UserName));
109 * Sort by AccessLevel
111 int CompareAccessLevel(const void *vUser1, const void *vUser2)
113 UserListEntry *u1 = (UserListEntry*) vUser1;
114 UserListEntry *u2 = (UserListEntry*) vUser2;
116 return (u1->AccessLevel > u2->AccessLevel);
118 int CompareAccessLevelRev(const void *vUser1, const void *vUser2)
120 UserListEntry *u1 = (UserListEntry*) vUser1;
121 UserListEntry *u2 = (UserListEntry*) vUser2;
123 return (u2->AccessLevel > u1->AccessLevel);
130 int CompareUID(const void *vUser1, const void *vUser2)
132 UserListEntry *u1 = (UserListEntry*) vUser1;
133 UserListEntry *u2 = (UserListEntry*) vUser2;
135 return (u1->UID > u2->UID);
137 int CompareUIDRev(const void *vUser1, const void *vUser2)
139 UserListEntry *u1 = (UserListEntry*) vUser1;
140 UserListEntry *u2 = (UserListEntry*) vUser2;
142 return (u2->UID > u1->UID);
146 * Sort By Date /// TODO!
148 int CompareLastLogon(const void *vUser1, const void *vUser2)
150 UserListEntry *u1 = (UserListEntry*) vUser1;
151 UserListEntry *u2 = (UserListEntry*) vUser2;
153 return (u1->LastLogonT > u2->LastLogonT);
155 int CompareLastLogonRev(const void *vUser1, const void *vUser2)
157 UserListEntry *u1 = (UserListEntry*) vUser1;
158 UserListEntry *u2 = (UserListEntry*) vUser2;
160 return (u2->LastLogonT > u1->LastLogonT);
164 * Sort By Number of Logons
166 int ComparenLogons(const void *vUser1, const void *vUser2)
168 UserListEntry *u1 = (UserListEntry*) vUser1;
169 UserListEntry *u2 = (UserListEntry*) vUser2;
171 return (u1->nLogons > u2->nLogons);
173 int ComparenLogonsRev(const void *vUser1, const void *vUser2)
175 UserListEntry *u1 = (UserListEntry*) vUser1;
176 UserListEntry *u2 = (UserListEntry*) vUser2;
178 return (u2->nLogons > u1->nLogons);
182 * Sort By Number of Posts
184 int ComparenPosts(const void *vUser1, const void *vUser2)
186 UserListEntry *u1 = (UserListEntry*) vUser1;
187 UserListEntry *u2 = (UserListEntry*) vUser2;
189 return (u1->nPosts > u2->nPosts);
191 int ComparenPostsRev(const void *vUser1, const void *vUser2)
193 UserListEntry *u1 = (UserListEntry*) vUser1;
194 UserListEntry *u2 = (UserListEntry*) vUser2;
196 return (u2->nPosts > u1->nPosts);
200 HashList *iterate_load_userlist(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
212 serv_getln(buf, sizeof buf);
214 Hash = NewHash(1, NULL);
217 while ((len = StrBuf_ServGetln(Buf),
218 strcmp(ChrPtr(Buf), "000"))) {
219 ul = NewUserListEntry(Buf);
222 nUsed = GetCount(Hash);
223 nUsed = snprintf(nnn, sizeof(nnn), "%d", nUsed+1);
224 Put(Hash, nnn, nUsed, ul, DeleteUserListEntry);
227 Order = ibstr("SortOrder");
228 switch (ibstr("SortBy")){
230 SortByPayload(Hash, (Order)?
232 CompareUserListNameRev);
234 case 2: /*AccessLevel*/
235 SortByPayload(Hash, (Order)?
237 CompareAccessLevelRev);
240 SortByPayload(Hash, (Order)?
245 SortByPayload(Hash, (Order)?
249 case 5: /*LastLogon*/
250 SortByPayload(Hash, (Order)?
252 CompareLastLogonRev);
254 case 6: /* nLogons */
255 SortByPayload(Hash, (Order)?
260 SortByPayload(Hash, (Order)?
271 void tmplput_USERLIST_UserName(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
273 UserListEntry *ul = (UserListEntry*) Context;
274 StrBufAppendTemplate(Target, nArgs, Tokens, Context, ContextType, ul->UserName, 0);
277 void tmplput_USERLIST_AccessLevelNo(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
279 UserListEntry *ul = (UserListEntry*) Context;
281 StrBufAppendPrintf(Target, "%d", ul->AccessLevel, 0);
284 void tmplput_USERLIST_AccessLevelStr(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
286 UserListEntry *ul = (UserListEntry*) Context;
288 StrBufAppendBufPlain(Target, _(axdefs[ul->AccessLevel]), -1, 0);
291 void tmplput_USERLIST_UID(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
293 UserListEntry *ul = (UserListEntry*) Context;
295 StrBufAppendPrintf(Target, "%d", ul->UID, 0);
298 void tmplput_USERLIST_LastLogonNo(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
300 UserListEntry *ul = (UserListEntry*) Context;
302 StrBufAppendPrintf(Target,"%ld", ul->LastLogonT, 0);
304 void tmplput_USERLIST_LastLogonStr(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
306 UserListEntry *ul = (UserListEntry*) Context;
307 StrEscAppend(Target, NULL, asctime(localtime(&ul->LastLogonT)), 0, 0);
310 void tmplput_USERLIST_nLogons(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
312 UserListEntry *ul = (UserListEntry*) Context;
314 StrBufAppendPrintf(Target, "%d", ul->nLogons, 0);
317 void tmplput_USERLIST_nPosts(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
319 UserListEntry *ul = (UserListEntry*) Context;
321 StrBufAppendPrintf(Target, "%d", ul->nPosts, 0);
324 void tmplput_USERLIST_Flags(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
326 UserListEntry *ul = (UserListEntry*) Context;
328 StrBufAppendPrintf(Target, "%d", ul->Flags, 0);
331 void tmplput_USERLIST_DaysTillPurge(StrBuf *Target, int nArgs, WCTemplateToken *Tokens, void *Context, int ContextType)
333 UserListEntry *ul = (UserListEntry*) Context;
335 StrBufAppendPrintf(Target, "%d", ul->DaysTillPurge, 0);
338 int ConditionalUser(WCTemplateToken *Tokens, void *Context, int ContextType)
340 UserListEntry *ul = (UserListEntry*) Context;
341 if (havebstr("usernum")) {
342 return ibstr("usernum") == ul->UID;
344 else if (havebstr("username")) {
345 return strcmp(bstr("username"), ChrPtr(ul->UserName)) == 0;
351 int ConditionalFlagINetEmail(WCTemplateToken *Tokens, void *Context, int ContextType)
353 UserListEntry *ul = (UserListEntry*) Context;
354 return (ul->Flags & US_INTERNET) != 0;
357 int ConditionalUserAccess(WCTemplateToken *Tokens, void *Context, int ContextType)
359 UserListEntry *ul = (UserListEntry*) Context;
361 if (Tokens->Params[3]->Type == TYPE_LONG)
362 return (Tokens->Params[3]->lvalue == ul->AccessLevel);
368 * Locate the message number of a user's vCard in the current room
369 * Returns the message id of his vcard
371 long locate_user_vcard_in_this_room() {
373 long vcard_msgnum = (-1L);
374 char content_type[SIZ];
376 int already_tried_creating_one = 0;
379 struct stuff_t *next;
383 struct stuff_t *stuff = NULL;
387 /** Search for the user's vCard */
388 serv_puts("MSGS ALL");
389 serv_getln(buf, sizeof buf);
390 if (buf[0] == '1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
391 ptr = malloc(sizeof(struct stuff_t));
392 ptr->msgnum = atol(buf);
397 /** Iterate through the message list looking for vCards */
398 while (stuff != NULL) {
399 serv_printf("MSG0 %ld|2", stuff->msgnum);
400 serv_getln(buf, sizeof buf);
402 while(serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
403 if (!strncasecmp(buf, "part=", 5)) {
404 extract_token(partnum, &buf[5], 2, '|', sizeof partnum);
405 extract_token(content_type, &buf[5], 4, '|', sizeof content_type);
406 if ( (!strcasecmp(content_type, "text/x-vcard"))
407 || (!strcasecmp(content_type, "text/vcard")) ) {
408 vcard_msgnum = stuff->msgnum;
419 /** If there's no vcard, create one */
420 if ((vcard_msgnum < 0) && (already_tried_creating_one == 0)) {
421 already_tried_creating_one = 1;
422 serv_puts("ENT0 1|||4");
423 serv_getln(buf, sizeof buf);
425 serv_puts("Content-type: text/x-vcard");
427 serv_puts("begin:vcard");
428 serv_puts("end:vcard");
434 return(vcard_msgnum);
439 * Display the form for editing a user's address book entry
440 * username the name of the user
441 * usernum the citadel-uid of the user
443 void display_edit_address_book_entry(char *username, long usernum) {
446 char error_message[SIZ];
447 long vcard_msgnum = (-1L);
449 /** Locate the user's config room, creating it if necessary */
450 sprintf(roomname, "%010ld.%s", usernum, USERCONFIGROOM);
451 serv_printf("GOTO %s||1", roomname);
452 serv_getln(buf, sizeof buf);
454 serv_printf("CRE8 1|%s|5|||1|", roomname);
455 serv_getln(buf, sizeof buf);
456 serv_printf("GOTO %s||1", roomname);
457 serv_getln(buf, sizeof buf);
459 sprintf(error_message,
460 "<img src=\"static/error.gif\" align=center>"
461 "%s<br /><br />\n", &buf[4]);
462 select_user_to_edit(error_message, username);
467 vcard_msgnum = locate_user_vcard_in_this_room();
469 if (vcard_msgnum < 0) {
470 sprintf(error_message,
471 "<img src=\"static/error.gif\" align=center>%s<br /><br />\n",
472 _("An error occurred while trying to create or edit this address book entry.")
474 select_user_to_edit(error_message, username);
478 do_edit_vcard(vcard_msgnum, "1", "select_user_to_edit", roomname);
482 void display_edituser(char *supplied_username, int is_new) {
485 char error_message[1024];
489 if (supplied_username != NULL) {
490 safestrncpy(username, supplied_username, sizeof username);
493 safestrncpy(username, bstr("username"), sizeof username);
497 serv_printf("AGUP %s", username);
498 StrBuf_ServGetln(Buf);
499 MajorStatus = ChrPtr(Buf)[0];
500 StrBufCutLeft(Buf, 4);
501 if (MajorStatus != '2') {
502 /*TODO ImportantMessage */
503 sprintf(error_message,
504 "<img src=\"static/error.gif\" align=center>"
505 "%s<br /><br />\n", ChrPtr(Buf));
506 select_user_to_edit(error_message, username);
511 UL = NewUserListOneEntry(Buf);
512 if (havebstr("edit_abe_button")) {
513 display_edit_address_book_entry(username, UL->UID);
515 else if (havebstr("delete_button")) {
516 delete_user(username);
519 output_headers(1, 0, 0, 0, 1, 0);
520 DoTemplate(HKEY("userlist_detailview"), NULL, (void*) UL, CTX_USERLIST);
523 DeleteUserListEntry(UL);
530 * do the backend operation of the user edit on the server
532 void edituser(void) {
536 unsigned int flags = 0;
539 is_new = ibstr("is_new");
540 safestrncpy(message, "", sizeof message);
541 username = bstr("username");
543 if (!havebstr("ok_button")) {
544 safestrncpy(message, _("Changes were not saved."), sizeof message);
548 flags = ibstr("flags");
549 if (yesbstr("inetmail")) {
550 flags |= US_INTERNET;
553 flags &= ~US_INTERNET ;
556 if ((havebstr("newname")) && (strcasecmp(bstr("username"), bstr("newname")))) {
557 serv_printf("RENU %s|%s", bstr("username"), bstr("newname"));
558 serv_getln(buf, sizeof buf);
560 sprintf(&message[strlen(message)],
561 "<img src=\"static/error.gif\" align=center>"
562 "%s<br /><br />\n", &buf[4]);
565 username = bstr("newname");
569 serv_printf("ASUP %s|%s|%d|%s|%s|%s|%s|%s|%s|",
580 serv_getln(buf, sizeof buf);
582 sprintf(&message[strlen(message)],
583 "<img src=\"static/error.gif\" align=center>"
584 "%s<br /><br />\n", &buf[4]);
589 * If we are in the middle of creating a new user, move on to
590 * the vCard edit screen.
593 display_edit_address_book_entry(username, lbstr("usernum") );
596 select_user_to_edit(message, username);
602 * username the name of the user to remove
604 void delete_user(char *username) {
608 serv_printf("ASUP %s|0|0|0|0|0|", username);
609 serv_getln(buf, sizeof buf);
612 "<img src=\"static/error.gif\" align=center>"
613 "%s<br /><br />\n", &buf[4]);
616 safestrncpy(message, "", sizeof message);
618 select_user_to_edit(message, bstr("username"));
625 * take the web environment username and create it on the citadel server
627 void create_user(void) {
629 char error_message[SIZ];
632 safestrncpy(username, bstr("username"), sizeof username);
634 serv_printf("CREU %s", username);
635 serv_getln(buf, sizeof buf);
638 sprintf(WC->ImportantMessage, _("A new user has been created."));
639 display_edituser(username, 1);
641 else if (!strncmp(buf, "570", 3)) {
642 sprintf(error_message,
643 "<img src=\"static/error.gif\" align=center>"
645 _("You are attempting to create a new user from within Citadel "
646 "while running in host based authentication mode. In this mode, "
647 "you must create new users on the host system, not within Citadel.")
649 select_user_to_edit(error_message, NULL);
652 sprintf(error_message,
653 "<img src=\"static/error.gif\" align=center>"
654 "%s<br /><br />\n", &buf[4]);
655 select_user_to_edit(error_message, NULL);
661 void _select_user_to_edit(void){select_user_to_edit(NULL, NULL);}
662 void _display_edituser(void) {display_edituser(NULL, 0);}
668 WebcitAddUrlHandler(HKEY("select_user_to_edit"), _select_user_to_edit, 0);
669 WebcitAddUrlHandler(HKEY("display_edituser"), _display_edituser, 0);
670 WebcitAddUrlHandler(HKEY("edituser"), edituser, 0);
671 WebcitAddUrlHandler(HKEY("create_user"), create_user, 0);
673 RegisterNamespace("USERLIST:USERNAME", 0, 1, tmplput_USERLIST_UserName, CTX_USERLIST);
674 RegisterNamespace("USERLIST:ACCLVLNO", 0, 0, tmplput_USERLIST_AccessLevelNo, CTX_USERLIST);
675 RegisterNamespace("USERLIST:ACCLVLSTR", 0, 0, tmplput_USERLIST_AccessLevelStr, CTX_USERLIST);
676 RegisterNamespace("USERLIST:UID", 0, 0, tmplput_USERLIST_UID, CTX_USERLIST);
677 RegisterNamespace("USERLIST:LASTLOGON:STR", 0, 0, tmplput_USERLIST_LastLogonStr, CTX_USERLIST);
678 RegisterNamespace("USERLIST:LASTLOGON:NO", 0, 0, tmplput_USERLIST_LastLogonNo, CTX_USERLIST);
679 RegisterNamespace("USERLIST:NLOGONS", 0, 0, tmplput_USERLIST_nLogons, CTX_USERLIST);
680 RegisterNamespace("USERLIST:NPOSTS", 0, 0, tmplput_USERLIST_nPosts, CTX_USERLIST);
682 RegisterNamespace("USERLIST:FLAGS", 0, 0, tmplput_USERLIST_Flags, CTX_USERLIST);
683 RegisterNamespace("USERLIST:DAYSTILLPURGE", 0, 0, tmplput_USERLIST_DaysTillPurge, CTX_USERLIST);
685 RegisterConditional(HKEY("COND:USERNAME"), 0, ConditionalUser, CTX_USERLIST);
686 RegisterConditional(HKEY("COND:USERACCESS"), 0, ConditionalUserAccess, CTX_USERLIST);
687 RegisterConditional(HKEY("COND:USERLIST:FLAG:USE_INTERNET"), 0, ConditionalFlagINetEmail, CTX_USERLIST);
689 RegisterIterator("USERLIST", 0, NULL, iterate_load_userlist, NULL, DeleteHash, CTX_USERLIST, CTX_NONE, IT_NOFLAG);