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