Grammar change in the license declaration.
[citadel.git] / webcit-ng / server / admin_functions.c
1 // Admin functions
2 //
3 // Copyright (c) 1996-2023 by the citadel.org team
4 //
5 // This program is open source software.  Use, duplication, or
6 // disclosure is subject to the GNU General Public License v3.
7
8 #include "webcit.h"
9
10
11 // /ctdl/a/login is called when a user is trying to log in
12 void try_login(struct http_transaction *h, struct ctdlsession *c) {
13         char buf[1024];
14         char auth[AUTH_MAX];
15         char username[256];
16         char password[256];
17         int login_success = 0;
18
19         extract_token(username, h->request_body, 0, '|', sizeof username);
20         extract_token(password, h->request_body, 1, '|', sizeof password);
21
22         snprintf(buf, sizeof buf, "%s:%s", username, password);
23         CtdlEncodeBase64(auth, buf, strlen(buf), BASE64_NO_LINEBREAKS);
24
25         syslog(LOG_DEBUG, "try_login(username='%s',password=(%d bytes))", username, (int) strlen(password));
26
27         ctdl_printf(c, "LOUT");                                                 // log out, in case we were logged in
28         ctdl_readline(c, buf, sizeof(buf));                                     // ignore the result
29         memset(c->auth, 0, AUTH_MAX);                                           // if this connection had auth, it doesn't now.
30         memset(c->whoami, 0, 64);                                               // if this connection had auth, it doesn't now.
31         login_success = login_to_citadel(c, auth, buf);                         // Now try logging in to Citadel
32
33         JsonValue *j = NewJsonObject(HKEY("login"));                            // Compose a JSON object with the results
34         if (buf[0] == '2') {
35                 JsonObjectAppend(j, NewJsonBool(HKEY("result"), 1));
36                 JsonObjectAppend(j, NewJsonPlainString(HKEY("message"), "logged in", -1));
37                 extract_token(username, &buf[4], 0, '|', sizeof username);      // This will have the proper capitalization etc.
38                 JsonObjectAppend(j, NewJsonPlainString(HKEY("fullname"), username, -1));
39                 JsonObjectAppend(j, NewJsonNumber(HKEY("axlevel"), extract_int(&buf[4], 1) ));
40                 JsonObjectAppend(j, NewJsonNumber(HKEY("timescalled"), extract_long(&buf[4], 2) ));
41                 JsonObjectAppend(j, NewJsonNumber(HKEY("posted"), extract_long(&buf[4], 3) ));
42                 JsonObjectAppend(j, NewJsonNumber(HKEY("usernum"), extract_long(&buf[4], 5) ));
43                 JsonObjectAppend(j, NewJsonNumber(HKEY("previous_login"), extract_long(&buf[4], 6) ));
44         }
45         else {
46                 JsonObjectAppend(j, NewJsonBool(HKEY("result"), 0));
47                 JsonObjectAppend(j, NewJsonPlainString(HKEY("message"), &buf[4], -1));
48         }
49         StrBuf *sj = NewStrBuf();
50         SerializeJson(sj, j, 1);                                                // '1' == free the source object
51
52         add_response_header(h, strdup("Content-type"), strdup("application/json"));
53         h->response_code = 200;
54         h->response_string = strdup("OK");
55         h->response_body_length = StrLength(sj);
56         h->response_body = SmashStrBuf(&sj);
57 }
58
59
60 // /ctdl/a/logout is called when a user is trying to log out.   Don't use this as an ajax.
61 void logout(struct http_transaction *h, struct ctdlsession *c) {
62         char buf[1024];
63         char auth[AUTH_MAX];
64         char username[256];
65         char password[256];
66         int login_success = 0;
67
68         ctdl_printf(c, "LOUT"); // log out
69         ctdl_readline(c, buf, sizeof(buf));     // ignore the result
70         strcpy(c->auth, "x");
71         memset(c->whoami, 0, 64);               // if this connection had auth, it doesn't now.
72
73         http_redirect(h, "/ctdl/s/index.html"); // go back where we started :)
74 }
75
76
77 // /ctdl/a/whoami returns the name of the currently logged in user, or an empty string if not logged in
78 void whoami(struct http_transaction *h, struct ctdlsession *c) {
79         h->response_code = 200;
80         h->response_string = strdup("OK");
81         add_response_header(h, strdup("Content-type"), strdup("text/plain"));
82         h->response_body = strdup(c->whoami);
83         h->response_body_length = strlen(h->response_body);
84 }
85
86
87 // /ctdl/a/biff returns the number of new messages that have arrived in the inbox
88 // since the beginning of the session or since the last call to biff
89 void biff(struct http_transaction *h, struct ctdlsession *c) {
90         char biffbuff[1024];
91
92         ctdl_printf(c, "BIFF");                         // send the command
93         ctdl_readline(c, biffbuff, sizeof(biffbuff));   // read the result
94         h->response_code = 200;
95         h->response_string = strdup("OK");
96         add_response_header(h, strdup("Content-type"), strdup("text/plain"));
97         h->response_body = strdup(&biffbuff[4]);
98         h->response_body_length = strlen(h->response_body);
99 }
100
101
102 // Dispatcher for paths starting with /ctdl/a/
103 void ctdl_a(struct http_transaction *h, struct ctdlsession *c) {
104         if (!strcasecmp(h->url, "/ctdl/a/login")) {     // log in
105                 try_login(h, c);
106                 return;
107         }
108
109         if (!strcasecmp(h->url, "/ctdl/a/logout")) {    // log out
110                 logout(h, c);
111                 return;
112         }
113
114         if (!strcasecmp(h->url, "/ctdl/a/whoami")) {    // return display name of user
115                 whoami(h, c);
116                 return;
117         }
118
119         if (!strcasecmp(h->url, "/ctdl/a/biff")) {      // check for new messages in the inbox
120                 biff(h, c);
121                 return;
122         }
123
124         do_404(h);                                      // unknown
125 }