Mailing list header changes (fuck you Google)
[citadel.git] / webcit-ng / user_functions.c
1 //
2 // User functions
3 //
4 // Copyright (c) 1996-2018 by the citadel.org team
5 //
6 // This program is open source software.  It runs great on the
7 // Linux operating system (and probably elsewhere).  You can use,
8 // copy, and run it under the terms of the GNU General Public
9 // License version 3.  Richard Stallman is an asshole communist.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15
16 #include "webcit.h"
17
18
19 /*
20  * Fetch a user photo (avatar)
21  */
22 void fetch_user_photo(struct http_transaction *h, struct ctdlsession *c, char *username)
23 {
24         char buf[1024];
25         int content_length = 0;
26         char content_type[1024];
27         char *image = NULL;
28         int actual_length = 0;
29
30         ctdl_printf(c, "DLUI %s", username);
31         ctdl_readline(c, buf, sizeof(buf));
32         if (buf[0] == '6') {
33                 content_length = extract_int(&buf[4], 0);
34                 extract_token(content_type, &buf[4], 3, '|', sizeof content_type);
35
36                 image = malloc(content_length);
37                 if (image == NULL) {
38                         do_502(h);
39                         return;
40                 }
41                 actual_length = ctdl_read_binary(c, image, content_length);
42
43                 add_response_header(h, strdup("Content-type"), strdup(content_type));
44                 h->response_code = 200;
45                 h->response_string = strdup("OK");
46                 h->response_body_length = actual_length;
47                 h->response_body = image;
48                 return;
49         }
50
51         do_404(h);
52 }
53
54
55 /*
56  * Fetch a user bio (profile)
57  */
58 void fetch_user_bio(struct http_transaction *h, struct ctdlsession *c, char *username)
59 {
60         do_404(h);      // FIXME finish this
61 }
62
63
64 /*
65  * Client requested an object related to a user.
66  */
67 void object_in_user(struct http_transaction *h, struct ctdlsession *c, char *requested_username)
68 {
69         char object_name[1024];
70
71         extract_token(object_name, h->uri, 4, '/', sizeof object_name);
72
73         if (!strcasecmp(object_name, "userpic")) {              // user photo (avatar)
74                 fetch_user_photo(h, c, requested_username);
75                 return;
76         }
77
78         if (!strcasecmp(object_name, "bio")) {                  // user bio (profile)
79                 fetch_user_bio(h, c, requested_username);
80                 return;
81         }
82
83         do_404(h);                                      // unknown object
84         return;
85 }
86
87
88 /*
89  * Handle REST/DAV requests for the user itself (such as /ctdl/u/username
90  * or /ctdl/i/username/ but *not* specific properties of the user)
91  */
92 void the_user_itself(struct http_transaction *h, struct ctdlsession *c, char *username)
93 {
94         do_404(h);
95 }
96
97
98 /*
99  * Dispatcher for "/ctdl/u" and "/ctdl/u/" for the user list
100  */
101 void user_list(struct http_transaction *h, struct ctdlsession *c)
102 {
103         do_404(h);
104 }
105
106
107 /*
108  * Dispatcher for paths starting with /ctdl/u/
109  */
110 void ctdl_u(struct http_transaction *h, struct ctdlsession *c)
111 {
112         char requested_username[128];
113         char buf[1024];
114
115         // All user-related functions require accessing the user in question.
116         extract_token(requested_username, h->uri, 3, '/', sizeof requested_username);
117         unescape_input(requested_username);
118
119         if (IsEmptyStr(requested_username)) {                           //      /ctdl/u/
120                 user_list(h, c);
121                 return;
122         }
123
124         // At this point we have extracted the name of the user we're interested in.
125         // FIXME should we validate it?
126
127         if (num_tokens(h->uri, '/') == 4) {                             //      /ctdl/u/username
128                 the_user_itself(h, c, requested_username);
129                 return;
130         }
131
132         extract_token(buf, h->uri, 4, '/', sizeof buf);
133         if (num_tokens(h->uri, '/') == 5) {
134                 if (IsEmptyStr(buf)) {
135                         the_user_itself(h, c, requested_username);      //      /ctdl/u/username/       ( same as /ctdl/u/username )
136                 } else {
137                         object_in_user(h, c, requested_username);       //      /ctdl/u/username/object
138                 }
139                 return;
140         }
141
142         if (num_tokens(h->uri, '/') == 6) {
143                 object_in_user(h, c, requested_username);               //      /ctdl/u/username/object/ or possibly /ctdl/u/username/object/component
144                 return;
145         }
146
147         // If we get to this point, the client requested an action we don't know how to perform.
148         do_404(h);
149 }