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_Password(StrBuf
*Target
, WCTemplputParams
*TP
)
290 UserListEntry
*ul
= (UserListEntry
*) CTX
;
291 StrBufAppendTemplate(Target
, TP
, ul
->Passvoid
, 0);
294 void tmplput_USERLIST_AccessLevelNo(StrBuf
*Target
, WCTemplputParams
*TP
)
296 UserListEntry
*ul
= (UserListEntry
*) CTX
;
298 StrBufAppendPrintf(Target
, "%d", ul
->AccessLevel
, 0);
301 void tmplput_USERLIST_AccessLevelStr(StrBuf
*Target
, WCTemplputParams
*TP
)
303 UserListEntry
*ul
= (UserListEntry
*) CTX
;
305 StrBufAppendBufPlain(Target
, _(axdefs
[ul
->AccessLevel
]), -1, 0);
308 void tmplput_USERLIST_UID(StrBuf
*Target
, WCTemplputParams
*TP
)
310 UserListEntry
*ul
= (UserListEntry
*) CTX
;
312 StrBufAppendPrintf(Target
, "%d", ul
->UID
, 0);
315 void tmplput_USERLIST_LastLogonNo(StrBuf
*Target
, WCTemplputParams
*TP
)
317 UserListEntry
*ul
= (UserListEntry
*) CTX
;
319 StrBufAppendPrintf(Target
,"%ld", ul
->LastLogonT
, 0);
321 void tmplput_USERLIST_LastLogonStr(StrBuf
*Target
, WCTemplputParams
*TP
)
323 UserListEntry
*ul
= (UserListEntry
*) CTX
;
324 StrEscAppend(Target
, NULL
, asctime(localtime(&ul
->LastLogonT
)), 0, 0);
327 void tmplput_USERLIST_nLogons(StrBuf
*Target
, WCTemplputParams
*TP
)
329 UserListEntry
*ul
= (UserListEntry
*) CTX
;
331 StrBufAppendPrintf(Target
, "%d", ul
->nLogons
, 0);
334 void tmplput_USERLIST_nPosts(StrBuf
*Target
, WCTemplputParams
*TP
)
336 UserListEntry
*ul
= (UserListEntry
*) CTX
;
338 StrBufAppendPrintf(Target
, "%d", ul
->nPosts
, 0);
341 void tmplput_USERLIST_Flags(StrBuf
*Target
, WCTemplputParams
*TP
)
343 UserListEntry
*ul
= (UserListEntry
*) CTX
;
345 StrBufAppendPrintf(Target
, "%d", ul
->Flags
, 0);
348 void tmplput_USERLIST_DaysTillPurge(StrBuf
*Target
, WCTemplputParams
*TP
)
350 UserListEntry
*ul
= (UserListEntry
*) CTX
;
352 StrBufAppendPrintf(Target
, "%d", ul
->DaysTillPurge
, 0);
355 int ConditionalUser(StrBuf
*Target
, WCTemplputParams
*TP
)
357 UserListEntry
*ul
= (UserListEntry
*) CTX
;
358 if (havebstr("usernum")) {
359 return ibstr("usernum") == ul
->UID
;
361 else if (havebstr("username")) {
362 return strcmp(bstr("username"), ChrPtr(ul
->UserName
)) == 0;
368 int ConditionalFlagINetEmail(StrBuf
*Target
, WCTemplputParams
*TP
)
370 UserListEntry
*ul
= (UserListEntry
*) CTX
;
371 return (ul
->Flags
& US_INTERNET
) != 0;
374 int ConditionalUserAccess(StrBuf
*Target
, WCTemplputParams
*TP
)
376 UserListEntry
*ul
= (UserListEntry
*) CTX
;
378 if (TP
->Tokens
->Params
[3]->Type
== TYPE_LONG
)
379 return (TP
->Tokens
->Params
[3]->lvalue
== ul
->AccessLevel
);
385 * Locate the message number of a user's vCard in the current room
386 * Returns the message id of his vcard
388 long locate_user_vcard_in_this_room() {
390 long vcard_msgnum
= (-1L);
391 char content_type
[SIZ
];
393 int already_tried_creating_one
= 0;
396 struct stuff_t
*next
;
400 struct stuff_t
*stuff
= NULL
;
404 /** Search for the user's vCard */
405 serv_puts("MSGS ALL");
406 serv_getln(buf
, sizeof buf
);
407 if (buf
[0] == '1') while (serv_getln(buf
, sizeof buf
), strcmp(buf
, "000")) {
408 ptr
= malloc(sizeof(struct stuff_t
));
409 ptr
->msgnum
= atol(buf
);
414 /** Iterate through the message list looking for vCards */
415 while (stuff
!= NULL
) {
416 serv_printf("MSG0 %ld|2", stuff
->msgnum
);
417 serv_getln(buf
, sizeof buf
);
419 while(serv_getln(buf
, sizeof buf
), strcmp(buf
, "000")) {
420 if (!strncasecmp(buf
, "part=", 5)) {
421 extract_token(partnum
, &buf
[5], 2, '|', sizeof partnum
);
422 extract_token(content_type
, &buf
[5], 4, '|', sizeof content_type
);
423 if ( (!strcasecmp(content_type
, "text/x-vcard"))
424 || (!strcasecmp(content_type
, "text/vcard")) ) {
425 vcard_msgnum
= stuff
->msgnum
;
436 /** If there's no vcard, create one */
437 if ((vcard_msgnum
< 0) && (already_tried_creating_one
== 0)) {
438 already_tried_creating_one
= 1;
439 serv_puts("ENT0 1|||4");
440 serv_getln(buf
, sizeof buf
);
442 serv_puts("Content-type: text/x-vcard");
444 serv_puts("begin:vcard");
445 serv_puts("end:vcard");
451 return(vcard_msgnum
);
456 * Display the form for editing a user's address book entry
457 * username the name of the user
458 * usernum the citadel-uid of the user
460 void display_edit_address_book_entry(char *username
, long usernum
) {
463 char error_message
[SIZ
];
464 long vcard_msgnum
= (-1L);
466 /** Locate the user's config room, creating it if necessary */
467 sprintf(roomname
, "%010ld.%s", usernum
, USERCONFIGROOM
);
468 serv_printf("GOTO %s||1", roomname
);
469 serv_getln(buf
, sizeof buf
);
471 serv_printf("CRE8 1|%s|5|||1|", roomname
);
472 serv_getln(buf
, sizeof buf
);
473 serv_printf("GOTO %s||1", roomname
);
474 serv_getln(buf
, sizeof buf
);
476 sprintf(error_message
,
477 "<img src=\"static/error.gif\" align=center>"
478 "%s<br /><br />\n", &buf
[4]);
479 select_user_to_edit(error_message
, username
);
484 vcard_msgnum
= locate_user_vcard_in_this_room();
486 if (vcard_msgnum
< 0) {
487 sprintf(error_message
,
488 "<img src=\"static/error.gif\" align=center>%s<br /><br />\n",
489 _("An error occurred while trying to create or edit this address book entry.")
491 select_user_to_edit(error_message
, username
);
495 do_edit_vcard(vcard_msgnum
, "1", "select_user_to_edit", roomname
);
499 void display_edituser(char *supplied_username
, int is_new
) {
502 char error_message
[1024];
506 if (supplied_username
!= NULL
) {
507 safestrncpy(username
, supplied_username
, sizeof username
);
510 safestrncpy(username
, bstr("username"), sizeof username
);
514 serv_printf("AGUP %s", username
);
515 StrBuf_ServGetln(Buf
);
516 MajorStatus
= ChrPtr(Buf
)[0];
517 StrBufCutLeft(Buf
, 4);
518 if (MajorStatus
!= '2') {
519 /*TODO ImportantMessage */
520 sprintf(error_message
,
521 "<img src=\"static/error.gif\" align=center>"
522 "%s<br /><br />\n", ChrPtr(Buf
));
523 select_user_to_edit(error_message
, username
);
528 UL
= NewUserListOneEntry(Buf
);
529 if (havebstr("edit_abe_button")) {
530 display_edit_address_book_entry(username
, UL
->UID
);
532 else if (havebstr("delete_button")) {
533 delete_user(username
);
536 WCTemplputParams SubTP
;
537 memset(&SubTP
, 0, sizeof(WCTemplputParams
));
538 SubTP
.Filter
.ContextType
= CTX_USERLIST
;
540 output_headers(1, 0, 0, 0, 1, 0);
541 DoTemplate(HKEY("userlist_detailview"), NULL
, &SubTP
);
544 DeleteUserListEntry(UL
);
551 * do the backend operation of the user edit on the server
553 void edituser(void) {
557 unsigned int flags
= 0;
560 is_new
= ibstr("is_new");
561 safestrncpy(message
, "", sizeof message
);
562 username
= bstr("username");
564 if (!havebstr("ok_button")) {
565 safestrncpy(message
, _("Changes were not saved."), sizeof message
);
569 flags
= ibstr("flags");
570 if (yesbstr("inetmail")) {
571 flags
|= US_INTERNET
;
574 flags
&= ~US_INTERNET
;
577 if ((havebstr("newname")) && (strcasecmp(bstr("username"), bstr("newname")))) {
578 serv_printf("RENU %s|%s", bstr("username"), bstr("newname"));
579 serv_getln(buf
, sizeof buf
);
581 sprintf(&message
[strlen(message
)],
582 "<img src=\"static/error.gif\" align=center>"
583 "%s<br /><br />\n", &buf
[4]);
586 username
= bstr("newname");
590 serv_printf("ASUP %s|%s|%d|%s|%s|%s|%s|%s|%s|",
601 serv_getln(buf
, sizeof buf
);
603 sprintf(&message
[strlen(message
)],
604 "<img src=\"static/error.gif\" align=center>"
605 "%s<br /><br />\n", &buf
[4]);
610 * If we are in the middle of creating a new user, move on to
611 * the vCard edit screen.
614 display_edit_address_book_entry(username
, lbstr("usernum") );
617 select_user_to_edit(message
, username
);
623 * username the name of the user to remove
625 void delete_user(char *username
) {
629 serv_printf("ASUP %s|0|0|0|0|0|", username
);
630 serv_getln(buf
, sizeof buf
);
633 "<img src=\"static/error.gif\" align=center>"
634 "%s<br /><br />\n", &buf
[4]);
637 safestrncpy(message
, "", sizeof message
);
639 select_user_to_edit(message
, bstr("username"));
646 * take the web environment username and create it on the citadel server
648 void create_user(void) {
650 char error_message
[SIZ
];
653 safestrncpy(username
, bstr("username"), sizeof username
);
655 serv_printf("CREU %s", username
);
656 serv_getln(buf
, sizeof buf
);
659 sprintf(WC
->ImportantMessage
, _("A new user has been created."));
660 display_edituser(username
, 1);
662 else if (!strncmp(buf
, "570", 3)) {
663 sprintf(error_message
,
664 "<img src=\"static/error.gif\" align=center>"
666 _("You are attempting to create a new user from within Citadel "
667 "while running in host based authentication mode. In this mode, "
668 "you must create new users on the host system, not within Citadel.")
670 select_user_to_edit(error_message
, NULL
);
673 sprintf(error_message
,
674 "<img src=\"static/error.gif\" align=center>"
675 "%s<br /><br />\n", &buf
[4]);
676 select_user_to_edit(error_message
, NULL
);
682 void _select_user_to_edit(void){select_user_to_edit(NULL
, NULL
);}
683 void _display_edituser(void) {display_edituser(NULL
, 0);}
689 WebcitAddUrlHandler(HKEY("select_user_to_edit"), _select_user_to_edit
, 0);
690 WebcitAddUrlHandler(HKEY("display_edituser"), _display_edituser
, 0);
691 WebcitAddUrlHandler(HKEY("edituser"), edituser
, 0);
692 WebcitAddUrlHandler(HKEY("create_user"), create_user
, 0);
694 RegisterNamespace("USERLIST:USERNAME", 0, 1, tmplput_USERLIST_UserName
, CTX_USERLIST
);
695 RegisterNamespace("USERLIST:PASSWD", 0, 1, tmplput_USERLIST_Password
, CTX_USERLIST
);
696 RegisterNamespace("USERLIST:ACCLVLNO", 0, 0, tmplput_USERLIST_AccessLevelNo
, CTX_USERLIST
);
697 RegisterNamespace("USERLIST:ACCLVLSTR", 0, 0, tmplput_USERLIST_AccessLevelStr
, CTX_USERLIST
);
698 RegisterNamespace("USERLIST:UID", 0, 0, tmplput_USERLIST_UID
, CTX_USERLIST
);
699 RegisterNamespace("USERLIST:LASTLOGON:STR", 0, 0, tmplput_USERLIST_LastLogonStr
, CTX_USERLIST
);
700 RegisterNamespace("USERLIST:LASTLOGON:NO", 0, 0, tmplput_USERLIST_LastLogonNo
, CTX_USERLIST
);
701 RegisterNamespace("USERLIST:NLOGONS", 0, 0, tmplput_USERLIST_nLogons
, CTX_USERLIST
);
702 RegisterNamespace("USERLIST:NPOSTS", 0, 0, tmplput_USERLIST_nPosts
, CTX_USERLIST
);
704 RegisterNamespace("USERLIST:FLAGS", 0, 0, tmplput_USERLIST_Flags
, CTX_USERLIST
);
705 RegisterNamespace("USERLIST:DAYSTILLPURGE", 0, 0, tmplput_USERLIST_DaysTillPurge
, CTX_USERLIST
);
707 RegisterConditional(HKEY("COND:USERNAME"), 0, ConditionalUser
, CTX_USERLIST
);
708 RegisterConditional(HKEY("COND:USERACCESS"), 0, ConditionalUserAccess
, CTX_USERLIST
);
709 RegisterConditional(HKEY("COND:USERLIST:FLAG:USE_INTERNET"), 0, ConditionalFlagINetEmail
, CTX_USERLIST
);
711 RegisterIterator("USERLIST", 0, NULL
, iterate_load_userlist
, NULL
, DeleteHash
, CTX_USERLIST
, CTX_NONE
, IT_NOFLAG
);
714 RegisterSortFunc(HKEY("user:name"),
717 CompareUserListNameRev
,
718 GroupchangeUserListName
,
720 RegisterSortFunc(HKEY("user:accslvl"),
723 CompareAccessLevelRev
,
724 GroupchangeAccessLevel
,
727 RegisterSortFunc(HKEY("user:nlogons"),
734 RegisterSortFunc(HKEY("user:uid"),
741 RegisterSortFunc(HKEY("user:lastlogon"),
745 GroupchangeLastLogon
,
748 RegisterSortFunc(HKEY("user:nmsgposts"),