Skeleton code for filters.
[citadel.git] / webcit-ng / server / user_functions.c
1 // User functions
2 //
3 // Copyright (c) 1996-2023 by the citadel.org team
4 //
5 // This program is open source software.  Use, duplication, or disclosure is subject to the GNU General Public License v3.
6
7 #include "webcit.h"
8
9
10 // Fetch a user photo (avatar)
11 void fetch_user_photo(struct http_transaction *h, struct ctdlsession *c, char *username) {
12         char buf[1024];
13         int content_length = 0;
14         char content_type[1024];
15         char *image = NULL;
16         int actual_length = 0;
17
18         ctdl_printf(c, "DLUI %s", username);
19         ctdl_readline(c, buf, sizeof(buf));
20         if (buf[0] == '6') {
21                 content_length = extract_int(&buf[4], 0);
22                 extract_token(content_type, &buf[4], 3, '|', sizeof content_type);
23
24                 image = malloc(content_length);
25                 if (image == NULL) {
26                         do_502(h);
27                         return;
28                 }
29                 actual_length = ctdl_read_binary(c, image, content_length);
30
31                 add_response_header(h, strdup("Content-type"), strdup(content_type));
32                 h->response_code = 200;
33                 h->response_string = strdup("OK");
34                 h->response_body_length = actual_length;
35                 h->response_body = image;
36                 return;
37         }
38
39         // The user has no avatar on file.  Redirect to a generic avatar.
40         http_redirect(h, "/ctdl/s/images/generic-user-icon-32px.png");
41
42         // Sending a 404 makes the browser request the same thing over and over again.
43         // do_404(h);
44 }
45
46
47 // Fetch a user bio (profile)
48 void fetch_user_bio(struct http_transaction *h, struct ctdlsession *c, char *username) {
49         do_404(h);      // FIXME finish this
50 }
51
52
53 // Client requested an object related to a user.
54 void object_in_user(struct http_transaction *h, struct ctdlsession *c, char *requested_username) {
55         char object_name[1024];
56
57         extract_token(object_name, h->url, 4, '/', sizeof object_name);
58
59         if (!strcasecmp(object_name, "userpic")) {              // user photo (avatar)
60                 fetch_user_photo(h, c, requested_username);
61                 return;
62         }
63
64         if (!strcasecmp(object_name, "bio")) {                  // user bio (profile)
65                 fetch_user_bio(h, c, requested_username);
66                 return;
67         }
68
69         do_404(h);                                              // unknown object
70         return;
71 }
72
73
74 // Handle REST/DAV requests for the user itself (such as /ctdl/u/username
75 // or /ctdl/i/username/ but *not* specific properties of the user)
76 void the_user_itself(struct http_transaction *h, struct ctdlsession *c, char *username) {
77         do_404(h);
78 }
79
80
81 // Dispatcher for "/ctdl/u" and "/ctdl/u/" for the user list
82 void user_list(struct http_transaction *h, struct ctdlsession *c) {
83         do_404(h);
84 }
85
86
87 // Dispatcher for paths starting with /ctdl/u/
88 void ctdl_u(struct http_transaction *h, struct ctdlsession *c) {
89         char requested_username[128];
90         char buf[1024];
91
92         // All user-related functions require accessing the user in question.
93         extract_token(requested_username, h->url, 3, '/', sizeof requested_username);
94         unescape_input(requested_username);
95
96         if (IsEmptyStr(requested_username)) {                           //      /ctdl/u/
97                 user_list(h, c);
98                 return;
99         }
100
101         // At this point we have extracted the name of the user we're interested in.
102         // FIXME should we validate it?
103
104         if (num_tokens(h->url, '/') == 4) {                             //      /ctdl/u/username
105                 the_user_itself(h, c, requested_username);
106                 return;
107         }
108
109         extract_token(buf, h->url, 4, '/', sizeof buf);
110         if (num_tokens(h->url, '/') == 5) {
111                 if (IsEmptyStr(buf)) {
112                         the_user_itself(h, c, requested_username);      //      /ctdl/u/username/ (same as /ctdl/u/username)
113                 }
114                 else {
115                         object_in_user(h, c, requested_username);       //      /ctdl/u/username/object
116                 }
117                 return;
118         }
119
120         if (num_tokens(h->url, '/') == 6) {
121                 object_in_user(h, c, requested_username);               //      /ctdl/u/username/object/ or possibly /ctdl/u/username/object/component
122                 return;
123         }
124
125         // If we get to this point, the client requested an action we don't know how to perform.
126         do_404(h);
127 }