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