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 * username the plaintext name of the user
370 * usernum the number of the user on the citadel server
371 * \return the message id of his vcard
373 long locate_user_vcard(char *username, long usernum) {
375 long vcard_msgnum = (-1L);
376 char content_type[SIZ];
378 int already_tried_creating_one = 0;
381 struct stuff_t *next;
385 struct stuff_t *stuff = NULL;
389 /** Search for the user's vCard */
390 serv_puts("MSGS ALL");
391 serv_getln(buf, sizeof buf);
392 if (buf[0] == '1') while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
393 ptr = malloc(sizeof(struct stuff_t));
394 ptr->msgnum = atol(buf);
399 /** Iterate through the message list looking for vCards */
400 while (stuff != NULL) {
401 serv_printf("MSG0 %ld|2", stuff->msgnum);
402 serv_getln(buf, sizeof buf);
404 while(serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
405 if (!strncasecmp(buf, "part=", 5)) {
406 extract_token(partnum, &buf[5], 2, '|', sizeof partnum);
407 extract_token(content_type, &buf[5], 4, '|', sizeof content_type);
408 if ( (!strcasecmp(content_type, "text/x-vcard"))
409 || (!strcasecmp(content_type, "text/vcard")) ) {
410 vcard_msgnum = stuff->msgnum;
421 /** If there's no vcard, create one */
422 if ((vcard_msgnum < 0) && (already_tried_creating_one == 0)) {
423 already_tried_creating_one = 1;
424 serv_puts("ENT0 1|||4");
425 serv_getln(buf, sizeof buf);
427 serv_puts("Content-type: text/x-vcard");
429 serv_puts("begin:vcard");
430 serv_puts("end:vcard");
436 return(vcard_msgnum);
441 * Display the form for editing a user's address book entry
442 * username the name of the user
443 * usernum the citadel-uid of the user
445 void display_edit_address_book_entry(char *username, long usernum) {
448 char error_message[SIZ];
449 long vcard_msgnum = (-1L);
451 /** Locate the user's config room, creating it if necessary */
452 sprintf(roomname, "%010ld.%s", usernum, USERCONFIGROOM);
453 serv_printf("GOTO %s||1", roomname);
454 serv_getln(buf, sizeof buf);
456 serv_printf("CRE8 1|%s|5|||1|", roomname);
457 serv_getln(buf, sizeof buf);
458 serv_printf("GOTO %s||1", roomname);
459 serv_getln(buf, sizeof buf);
461 sprintf(error_message,
462 "<img src=\"static/error.gif\" align=center>"
463 "%s<br /><br />\n", &buf[4]);
464 select_user_to_edit(error_message, username);
469 vcard_msgnum = locate_user_vcard(username, usernum);
471 if (vcard_msgnum < 0) {
472 sprintf(error_message,
473 "<img src=\"static/error.gif\" align=center>%s<br /><br />\n",
474 _("An error occurred while trying to create or edit this address book entry.")
476 select_user_to_edit(error_message, username);
480 do_edit_vcard(vcard_msgnum, "1", "select_user_to_edit", roomname);
484 void display_edituser(char *supplied_username, int is_new) {
487 char error_message[1024];
491 if (supplied_username != NULL) {
492 safestrncpy(username, supplied_username, sizeof username);
495 safestrncpy(username, bstr("username"), sizeof username);
499 serv_printf("AGUP %s", username);
500 StrBuf_ServGetln(Buf);
501 MajorStatus = ChrPtr(Buf)[0];
502 StrBufCutLeft(Buf, 4);
503 if (MajorStatus != '2') {
504 /*TODO ImportantMessage */
505 sprintf(error_message,
506 "<img src=\"static/error.gif\" align=center>"
507 "%s<br /><br />\n", ChrPtr(Buf));
508 select_user_to_edit(error_message, username);
513 UL = NewUserListOneEntry(Buf);
514 if (havebstr("edit_abe_button")) {
515 display_edit_address_book_entry(username, UL->UID);
517 else if (havebstr("delete_button")) {
518 delete_user(username);
521 output_headers(1, 0, 0, 0, 1, 0);
522 DoTemplate(HKEY("userlist_detailview"), NULL, (void*) UL, CTX_USERLIST);
525 DeleteUserListEntry(UL);
532 * do the backend operation of the user edit on the server
534 void edituser(void) {
538 unsigned int flags = 0;
541 is_new = ibstr("is_new");
542 safestrncpy(message, "", sizeof message);
543 username = bstr("username");
545 if (!havebstr("ok_button")) {
546 safestrncpy(message, _("Changes were not saved."), sizeof message);
550 flags = ibstr("flags");
551 if (yesbstr("inetmail")) {
552 flags |= US_INTERNET;
555 flags &= ~US_INTERNET ;
558 if ((havebstr("newname")) && (strcasecmp(bstr("username"), bstr("newname")))) {
559 serv_printf("RENU %s|%s", bstr("username"), bstr("newname"));
560 serv_getln(buf, sizeof buf);
562 sprintf(&message[strlen(message)],
563 "<img src=\"static/error.gif\" align=center>"
564 "%s<br /><br />\n", &buf[4]);
567 username = bstr("newname");
571 serv_printf("ASUP %s|%s|%d|%s|%s|%s|%s|%s|%s|",
582 serv_getln(buf, sizeof buf);
584 sprintf(&message[strlen(message)],
585 "<img src=\"static/error.gif\" align=center>"
586 "%s<br /><br />\n", &buf[4]);
591 * If we are in the middle of creating a new user, move on to
592 * the vCard edit screen.
595 display_edit_address_book_entry(username, lbstr("usernum") );
598 select_user_to_edit(message, username);
604 * username the name of the user to remove
606 void delete_user(char *username) {
610 serv_printf("ASUP %s|0|0|0|0|0|", username);
611 serv_getln(buf, sizeof buf);
614 "<img src=\"static/error.gif\" align=center>"
615 "%s<br /><br />\n", &buf[4]);
618 safestrncpy(message, "", sizeof message);
620 select_user_to_edit(message, bstr("username"));
627 * take the web environment username and create it on the citadel server
629 void create_user(void) {
631 char error_message[SIZ];
634 safestrncpy(username, bstr("username"), sizeof username);
636 serv_printf("CREU %s", username);
637 serv_getln(buf, sizeof buf);
640 sprintf(WC->ImportantMessage, _("A new user has been created."));
641 display_edituser(username, 1);
643 else if (!strncmp(buf, "570", 3)) {
644 sprintf(error_message,
645 "<img src=\"static/error.gif\" align=center>"
647 _("You are attempting to create a new user from within Citadel "
648 "while running in host based authentication mode. In this mode, "
649 "you must create new users on the host system, not within Citadel.")
651 select_user_to_edit(error_message, NULL);
654 sprintf(error_message,
655 "<img src=\"static/error.gif\" align=center>"
656 "%s<br /><br />\n", &buf[4]);
657 select_user_to_edit(error_message, NULL);
663 void _select_user_to_edit(void){select_user_to_edit(NULL, NULL);}
664 void _display_edituser(void) {display_edituser(NULL, 0);}
670 WebcitAddUrlHandler(HKEY("select_user_to_edit"), _select_user_to_edit, 0);
671 WebcitAddUrlHandler(HKEY("display_edituser"), _display_edituser, 0);
672 WebcitAddUrlHandler(HKEY("edituser"), edituser, 0);
673 WebcitAddUrlHandler(HKEY("create_user"), create_user, 0);
675 RegisterNamespace("USERLIST:USERNAME", 0, 1, tmplput_USERLIST_UserName, CTX_USERLIST);
676 RegisterNamespace("USERLIST:ACCLVLNO", 0, 0, tmplput_USERLIST_AccessLevelNo, CTX_USERLIST);
677 RegisterNamespace("USERLIST:ACCLVLSTR", 0, 0, tmplput_USERLIST_AccessLevelStr, CTX_USERLIST);
678 RegisterNamespace("USERLIST:UID", 0, 0, tmplput_USERLIST_UID, CTX_USERLIST);
679 RegisterNamespace("USERLIST:LASTLOGON:STR", 0, 0, tmplput_USERLIST_LastLogonStr, CTX_USERLIST);
680 RegisterNamespace("USERLIST:LASTLOGON:NO", 0, 0, tmplput_USERLIST_LastLogonNo, CTX_USERLIST);
681 RegisterNamespace("USERLIST:NLOGONS", 0, 0, tmplput_USERLIST_nLogons, CTX_USERLIST);
682 RegisterNamespace("USERLIST:NPOSTS", 0, 0, tmplput_USERLIST_nPosts, CTX_USERLIST);
684 RegisterNamespace("USERLIST:FLAGS", 0, 0, tmplput_USERLIST_Flags, CTX_USERLIST);
685 RegisterNamespace("USERLIST:DAYSTILLPURGE", 0, 0, tmplput_USERLIST_DaysTillPurge, CTX_USERLIST);
687 RegisterConditional(HKEY("COND:USERNAME"), 0, ConditionalUser, CTX_USERLIST);
688 RegisterConditional(HKEY("COND:USERACCESS"), 0, ConditionalUserAccess, CTX_USERLIST);
689 RegisterConditional(HKEY("COND:USERLIST:FLAG:USE_INTERNET"), 0, ConditionalFlagINetEmail, CTX_USERLIST);
691 RegisterIterator("USERLIST", 0, NULL, iterate_load_userlist, NULL, DeleteHash, CTX_USERLIST, CTX_NONE, IT_NOFLAG);