php8
[web.mtrack] / MTrackWeb / User.php
1 <?php # vim:ts=2:sw=2:et:
2 /* For licensing and copyright terms, see the file named LICENSE */
3 die("FIXME");
4 include '../inc/common.php';
5
6 $user = mtrack_get_pathinfo();
7 if ($user === null && isset($_GET['user'])) {
8   $user = $_GET['user'];
9 }
10 if (!strlen(trim($user))) {
11   throw new Exception("No user name provided");
12 }
13 $user = mtrack_canon_username($user);
14
15 $me = mtrack_canon_username(MTrackAuth::whoami());
16
17
18
19 if (!empty($_REQUEST['edit'])) {
20   if (MTrackACL::hasAllRights('User', 'modify')) {
21     // can edit all
22   } else if ($me != 'anonymous' && $me === $user) {
23     // Can edit my own bits
24     MTrackACL::requireAllRights('User', 'read');
25   } else {
26     // already checked this above, but we want it to trigger the privilege
27     // error here
28     MTrackACL::requireAllRights('User', 'modify');
29   }
30
31   if ($_SERVER['REQUEST_METHOD'] == 'POST') {
32     $http_auth = MTrackAuth::getMech('MTrackAuth_HTTP');
33     if ($http_auth && !isset($_SERVER['REMOTE_USER'])) {
34       if ($_POST['passwd1'] != $_POST['passwd2']) {
35         throw new Exception("passwords don't match!");
36       }
37     }
38
39     $data = MTrackDB::q('select * from userinfo where userid = ?', $user)
40               ->fetchAll(PDO::FETCH_ASSOC);
41     if (isset($data[0])) {
42       // Updating
43       if (MTrackACL::hasAllRights('User', 'modify')) {
44         if (isset($_POST['active'])) {
45           $active = $_POST['active'] == 'on' ? '1' : '0';
46         } else {
47           $active = '0';
48         }
49         MTrackDB::q('update userinfo set fullname = ?, email = ?, timezone = ?, active = ?, sshkeys = ? where userid = ?', $_POST['fullname'], $_POST['email'], $_POST['timezone'], $active, $_POST['keys'], $user);
50       } else {
51         MTrackDB::q('update userinfo set fullname = ?, email = ?, timezone = ?, sshkeys = ? where userid = ?', $_POST['fullname'], $_POST['email'], $_POST['timezone'], $_POST['keys'], $user);
52       }
53     } else {
54       MTrackDB::q('insert into userinfo (active, fullname, email, timezone, sshkeys, userid) values (1, ?, ?, ?, ?, ?)', $_POST['fullname'], $_POST['email'], $_POST['timezone'], $_POST['keys'], $user);
55     }
56
57     if (MTrackACL::hasAllRights('User', 'modify')) {
58       MTrackDB::q('delete from useraliases where userid = ?', $user);
59       foreach (preg_split("/\r?\n/", $_POST['aliases']) as $alias) {
60         if (!strlen(trim($alias))) {
61           continue;
62         }
63         MTrackDB::q('insert into useraliases (userid, alias) values (?, ?)',
64           $user, $alias);
65       }
66
67       $user_class = MTrackAuth::getUserClass($user);
68       if (isset($_POST['user_role']) && $_POST['user_role'] != $user_class) {
69         MTrackConfig::set('user_classes', $user, $_POST['user_role']);
70         MTrackConfig::save();
71       }
72     }
73     $http_auth = MTrackAuth::getMech('MTrackAuth_HTTP');
74     if ($http_auth && !isset($_SERVER['REMOTE_USER']) && !empty($_POST['passwd1'])) {
75       // Allow changing their password
76       $http_auth->setUserPassword($user, $_POST['passwd1']);
77     }
78     header("Location: {$ABSWEB}user.php?user=" . urlencode($user));
79     exit;
80   }
81
82 } else {
83   MTrackACL::requireAllRights('User', 'read');
84 }
85
86 mtrack_head("User $user");
87
88 $data = MTrackDB::q('select * from userinfo where userid = ?', $user)->fetchAll(PDO::FETCH_ASSOC);
89 if (isset($data[0])) {
90   $data = $data[0];
91 } else {
92   $data = null;
93 }
94
95 $display = $user;
96
97 if (strlen($data['fullname'])) {
98   $display .= " - " . $data['fullname'];
99 }
100
101 echo "<h1>", htmlentities($display, ENT_QUOTES, 'utf-8'), "</h1>";
102 echo "<div class='userinfo'>";
103 echo mtrack_username($user, array(
104   'no_name' => true,
105   'size' => 128
106 ));
107 echo "<a href='mailto:$data[email]'>$data[email]</a><br>\n";
108
109 if (empty($_GET['edit'])) {
110   $aliases = MTrackDB::q('select alias from useraliases where userid = ? order by alias', $user)->fetchAll(PDO::FETCH_COLUMN, 0);
111   if (count($aliases)) {
112     echo "<h2>Aliases</h2><ul>\n";
113     foreach ($aliases as $alias) {
114       echo "<li>", htmlentities($alias, ENT_QUOTES, 'utf-8'), "</li>\n";
115     }
116     echo "</ul>\n";
117   }
118 }
119
120 echo "</div>";
121
122 if (empty($_GET['edit'])) {
123   $me = mtrack_canon_username(MTrackAuth::whoami());
124   if ($me != 'anonymous' && $me === $user) {
125     $label = 'Edit my details';
126   } else if (MTrackACL::hasAnyRights('User', 'modify')) {
127     $label = 'Edit user details';
128   } else {
129     $label = null;
130   }
131   if ($label !== null) {
132     echo "<form method='get' action='{$ABSWEB}user.php'>" .
133       "<input type='hidden' name='user' value='" . $user . "'>" .
134       "<input type='hidden' name='edit' value='1'>" .
135       "<button type='submit'>$label</button></form>";
136   }
137
138   if (MTrackACL::hasAnyRights('Timeline', 'read')) {
139     echo "<h2>Recent Activity</h2>\n";
140     mtrack_render_timeline($user);
141   }
142 } else {
143
144   echo "<form method='post' action='{$ABSWEB}user.php?user=" .
145     urlencode($user) . "'>\n";
146
147   $fullname = htmlentities(
148     isset($data['fullname']) ? $data['fullname'] : '',
149     ENT_QUOTES, 'utf-8');
150   $email = htmlentities(
151     isset($data['email']) ? $data['email'] : '',
152     ENT_QUOTES, 'utf-8');
153   $timezone = htmlentities(
154     isset($data['timezone']) ? $data['timezone'] : '',
155     ENT_QUOTES, 'utf-8');
156
157   echo <<<HTML
158 <input type='hidden' name='edit' value='1'>
159
160 <fieldset id='userinfo-container'>
161   <legend>User Information</legend>
162   <table>
163     <tr valign='top'>
164       <td>
165         <label for='fullname'>Full name</label>
166       </td>
167       <td>
168         <input type='text' name='fullname' size='64' value='$fullname'>
169       </td>
170     </tr>
171     <tr valign='top'>
172       <td>
173         <label for='email'>Email</label>
174       </td>
175       <td>
176         <input type='text' name='email' size='64' value='$email'><br>
177         <em>We use this with <a href='http://gravatar.com'>Gravatar</a>
178           to obtain your avatar image throughout mtrack</em>
179       </td>
180     </tr>
181     <tr valign='top'>
182       <td>
183         <label for='timezone'>Timezone</label>
184       </td>
185       <td>
186         <input type='text' name='timezone' size='24' value='$timezone'><br>
187         <em>We use this to show times in your preferred timezone</em>
188       </td>
189     </tr>
190 HTML;
191   if (MTrackACL::hasAllRights('User', 'modify')) {
192     if (isset($data['active'])) {
193       $active = (int)$data['active'];
194     } else {
195       $active = 0;
196     }
197     if ($active) {
198       $active = " checked='checked'";
199     }
200     echo <<<HTML
201     <tr valign='top'>
202       <td>
203         <label for='active'>Active?</label>
204       </td>
205       <td>
206         <input type='checkbox' name='active' $active><br>
207         <em>Active users are shown in the Responsible users list when editing tickets</em>
208       </td>
209     </tr>
210 HTML;
211
212     $user_class = MTrackAuth::getUserClass($user);
213     $user_class_roles = array();
214     foreach (MTrackConfig::getSection('user_class_roles') as $role => $rights) {
215       $user_class_roles[$role] = $role;
216     }
217     $role_select = mtrack_select_box('user_role', $user_class_roles,
218                     $user_class);
219     echo <<<HTML
220     <tr valign='top'>
221       <td>
222         <label for='active'>Role</label>
223       </td>
224       <td>
225         $role_select<br>
226         <em>The role defines which actions this user can carry out in mtrack</em>
227       </td>
228     </tr>
229 HTML;
230
231   }
232
233   $http_auth = MTrackAuth::getMech('MTrackAuth_HTTP');
234   if ($http_auth && !isset($_SERVER['REMOTE_USER'])) {
235
236     if ($me == $user) {
237       $your = "your";
238     } else {
239       $your = "this users";
240     }
241
242     echo <<<HTML
243     <tr>
244       <td>
245         <label for='passwd1'>New Password</label>
246       </td>
247       <td>
248         <input type="password" name="passwd1"><br>
249         <em>Enter $your new password</em>
250       </td>
251     </tr>
252     <tr>
253       <td>
254         <label for='passwd2'>Confirm Password</label>
255       </td>
256       <td>
257         <input type="password" name="passwd2"><br>
258         <em>Confirm $your new password</em>
259       </td>
260     </tr>
261 HTML;
262
263   }
264
265   echo <<<HTML
266   </table>
267 </fieldset>
268 HTML;
269
270   $groups = MTrackAuth::getGroups($user);
271   echo <<<HTML
272 <fieldset id='userinfo-groups'>
273   <legend>Groups</legend>
274   <em>This user is a member of the following groups</em>
275   <ul>
276 HTML;
277   foreach ($groups as $group) {
278     echo "<li>" . htmlentities($group, ENT_QUOTES, 'utf-8') . "</li>\n";
279   }
280   echo <<<HTML
281   </ul>
282 </fieldset>
283 HTML;
284
285   if (MTrackACL::hasAllRights('User', 'modify')) {
286
287     $aliases = MTrackDB::q('select alias from useraliases where userid = ? order by alias', $user)->fetchAll(PDO::FETCH_COLUMN, 0);
288     $atext = '';
289     foreach ($aliases as $alias) {
290       $atext .= htmlentities($alias, ENT_QUOTES, 'utf-8') . "\n";
291     }
292
293     echo <<<HTML
294 <fieldset id='userinfo-container'>
295   <legend>Aliases</legend>
296   <em>This user is also known by the following identities (one per line) when
297   assessing changes in the various repositories</em><br>
298   <textarea name='aliases' cols='64' rows='10'>$atext</textarea>
299 </fieldset>
300
301 HTML;
302
303   }
304
305   echo <<<HTML
306   </table>
307 </fieldset>
308 HTML;
309
310   $keytext = htmlentities($data['sshkeys'], ENT_QUOTES, 'utf-8');
311   echo <<<HTML
312 <fieldset id='sshkey-container'>
313   <legend>SSH Keys</legend>
314   <em>The repositories created and managed by mtrack are served over SSH.
315     Access is enabled only based on public SSH keys, not passwords.
316     In order to check code in or out, you must provide one or more
317     keys.  Paste in the public key(s) you want to use below, one per line.
318   </em><br>
319   <textarea name='keys' cols='64' rows='10'>$keytext</textarea>
320 </fieldset>
321
322 HTML;
323
324   echo <<<HTML
325
326   <button>Save Changes</button>
327 </form>
328 HTML;
329 }
330
331 mtrack_foot();