Fossil SCM

Revamp the user list setup page. Show the last change time and expiration date for each login. Make the user list sortable using javascript.

drh 2015-11-17 19:52 trunk merge
Commit 01b1319931e282166dbd3e8b6defd91efee90b7e
1 file changed +89 -63
+89 -63
--- src/setup.c
+++ src/setup.c
@@ -153,71 +153,98 @@
153153
login_needed(0);
154154
return;
155155
}
156156
157157
style_submenu_element("Add", "Add User", "setup_uedit");
158
- style_header("User List");
159
- @ <table class="usetupLayoutTable">
160
- @ <tr><td class="usetupColumnLayout">
161
- @ <span class="note">Users:</span>
162
- @ <table class="usetupUserList">
163
- prevLevel = 0;
164
- db_prepare(&s,
165
- "SELECT uid, login, cap, info, 1 FROM user"
166
- " WHERE login IN ('anonymous','nobody','developer','reader') "
167
- " UNION ALL "
168
- "SELECT uid, login, cap, info, 2 FROM user"
169
- " WHERE login NOT IN ('anonymous','nobody','developer','reader') "
170
- "ORDER BY 5, 2 COLLATE nocase"
171
- );
172
- while( db_step(&s)==SQLITE_ROW ){
173
- int iLevel = db_column_int(&s, 4);
174
- const char *zCap = db_column_text(&s, 2);
175
- const char *zLogin = db_column_text(&s, 1);
176
- if( iLevel>prevLevel ){
177
- if( prevLevel>0 ){
178
- @ <tr><td colspan="3"><hr></td></tr>
179
- }
180
- if( iLevel==1 ){
181
- @ <tr>
182
- @ <th class="usetupListUser"
183
- @ style="text-align: right;padding-right: 20px;">Category</th>
184
- @ <th class="usetupListCap"
185
- @ style="text-align: center;padding-right: 15px;">Capabilities</th>
186
- @ <th class="usetupListCon"
187
- @ style="text-align: left;">Notes</th>
188
- @ </tr>
189
- }else{
190
- @ <tr>
191
- @ <th class="usetupListUser"
192
- @ style="text-align: right;padding-right: 20px;">User&nbsp;ID</th>
193
- @ <th class="usetupListCap"
194
- @ style="text-align: center;padding-right: 15px;">Capabilities</th>
195
- @ <th class="usetupListCon"
196
- @ style="text-align: left;">Contact&nbsp;Info</th>
197
- @ </tr>
198
- }
199
- prevLevel = iLevel;
200
- }
201
- @ <tr>
202
- @ <td class="usetupListUser"
203
- @ style="text-align: right;padding-right: 20px;white-space:nowrap;">
204
- if( g.perm.Admin && (zCap[0]!='s' || g.perm.Setup) ){
205
- @ <a href="setup_uedit?id=%d(db_column_int(&s,0))">
206
- }
207
- @ %h(zLogin)
208
- if( g.perm.Admin ){
209
- @ </a>
210
- }
211
- @ </td>
212
- @ <td class="usetupListCap" style="text-align: center;padding-right: 15px;">%s(zCap)</td>
213
- @ <td class="usetupListCon" style="text-align: left;">%h(db_column_text(&s,3))</td>
214
- @ </tr>
215
- }
216
- @ </table>
217
- @ </td><td class="usetupColumnLayout">
218
- @ <span class="note">Notes:</span>
158
+ style_submenu_element("Help", "Help", "setup_ulist_notes");
159
+ style_header("User List");
160
+ @ <table border=1 cellpadding=2 cellspacing=0 class='userTable'>
161
+ @ <thead><tr><th>UID <th>Category <th>Capabilities <th>Info <th>Last Change</tr></thead>
162
+ @ <tbody>
163
+ db_prepare(&s,
164
+ "SELECT uid, login, cap, date(mtime,'unixepoch')"
165
+ " FROM user"
166
+ " WHERE login IN ('anonymous','nobody','developer','reader')"
167
+ " ORDER BY login"
168
+ );
169
+ while( db_step(&s)==SQLITE_ROW ){
170
+ int uid = db_column_int(&s, 0);
171
+ const char *zLogin = db_column_text(&s, 1);
172
+ const char *zCap = db_column_text(&s, 2);
173
+ const char *zDate = db_column_text(&s, 4);
174
+ @ <tr>
175
+ @ <td><a href='setup_uedit?id=%d(uid)'>%d(uid)</a>
176
+ @ <td><a href='setup_uedit?id=%d(uid)'>%h(zLogin)</a>
177
+ @ <td>%h(zCap)
178
+
179
+ if( fossil_strcmp(zLogin,"anonymous")==0 ){
180
+ @ <td>All logged-in users
181
+ }else if( fossil_strcmp(zLogin,"developer")==0 ){
182
+ @ <td>Users with '<b>v</b>' capability
183
+ }else if( fossil_strcmp(zLogin,"nobody")==0 ){
184
+ @ <td>All users without login
185
+ }else if( fossil_strcmp(zLogin,"reader")==0 ){
186
+ @ <td>Users with '<b>u</b>' capability
187
+ }else{
188
+ @ <td>
189
+ }
190
+ if( zDate && zDate[0] ){
191
+ @ <td>%h(zDate)
192
+ }else{
193
+ @ <td>
194
+ }
195
+ @ </tr>
196
+ }
197
+ db_finalize(&s);
198
+ @ </tbody></table>
199
+ @ <div class='section'>Users</div>
200
+ @ <table border=1 cellpadding=2 cellspacing=0 class='userTable' id='userlist'>
201
+ @ <thead><tr>
202
+ @ <th>ID<th>Login<th>Caps<th>Info<th>Chng<th>Expire</tr></thead>
203
+ @ <tbody>
204
+ db_prepare(&s,
205
+ "SELECT uid, login, cap, info, date(mtime,'unixepoch'), lower(login) AS sortkey, "
206
+ " CASE WHEN info LIKE '%%expires 20%%'"
207
+ " THEN substr(info,instr(lower(info),'expires')+8,10)"
208
+ " END AS exp"
209
+ " FROM user"
210
+ " WHERE login NOT IN ('anonymous','nobody','developer','reader')"
211
+ " ORDER BY sortkey"
212
+ );
213
+ while( db_step(&s)==SQLITE_ROW ){
214
+ int uid = db_column_int(&s, 0);
215
+ const char *zLogin = db_column_text(&s, 1);
216
+ const char *zCap = db_column_text(&s, 2);
217
+ const char *zInfo = db_column_text(&s, 3);
218
+ const char *zDate = db_column_text(&s, 4);
219
+ const char *zSortKey = db_column_text(&s,5);
220
+ const char *zExp = db_column_text(&s,6);
221
+ @ <tr>
222
+ @ <td><a href='setup_uedit?id=%d(uid)'>%d(uid)</a>
223
+ @ <td data-sortkey='%h(zSortKey)'><a href='setup_uedit?id=%d(uid)'>%h(zLogin)</a>
224
+ @ <td>%h(zCap)
225
+ @ <td>%h(zInfo)
226
+ @ <td>%h(zDate?zDate:"")
227
+ @ <td>%h(zExp?zExp:"")
228
+ @ </tr>
229
+ }
230
+ @ </tbody></table>
231
+ db_finalize(&s);
232
+ output_table_sorting_javascript("userlist","nktxTT",2);
233
+ style_footer();
234
+}
235
+
236
+/*
237
+** WEBPAGE: setup_ulist_notes
238
+**
239
+** A documentation page showing notes about user configuration. This information
240
+** used to be a side-bar on the user list page, but has been factored out for
241
+** improved presentation.
242
+*/
243
+void setup_ulist_notes(void){
244
+ style_header("User Configuration Notes");
245
+ @ <h1>User Configuration Notes:</h1>
219246
@ <ol>
220247
@ <li><p>The permission flags are as follows:</p>
221248
@ <table>
222249
@ <tr><th valign="top">a</th>
223250
@ <td><i>Admin:</i> Create and delete users</td></tr>
@@ -295,14 +322,13 @@
295322
@ <span class="usertype">anonymous</span>, and
296323
@ <span class="usertype">nobody</span>.
297324
@ </p></li>
298325
@
299326
@ </ol>
300
- @ </td></tr></table>
301327
style_footer();
302
- db_finalize(&s);
303328
}
329
+
304330
305331
/*
306332
** Return true if zPw is a valid password string. A valid
307333
** password string is:
308334
**
309335
--- src/setup.c
+++ src/setup.c
@@ -153,71 +153,98 @@
153 login_needed(0);
154 return;
155 }
156
157 style_submenu_element("Add", "Add User", "setup_uedit");
158 style_header("User List");
159 @ <table class="usetupLayoutTable">
160 @ <tr><td class="usetupColumnLayout">
161 @ <span class="note">Users:</span>
162 @ <table class="usetupUserList">
163 prevLevel = 0;
164 db_prepare(&s,
165 "SELECT uid, login, cap, info, 1 FROM user"
166 " WHERE login IN ('anonymous','nobody','developer','reader') "
167 " UNION ALL "
168 "SELECT uid, login, cap, info, 2 FROM user"
169 " WHERE login NOT IN ('anonymous','nobody','developer','reader') "
170 "ORDER BY 5, 2 COLLATE nocase"
171 );
172 while( db_step(&s)==SQLITE_ROW ){
173 int iLevel = db_column_int(&s, 4);
174 const char *zCap = db_column_text(&s, 2);
175 const char *zLogin = db_column_text(&s, 1);
176 if( iLevel>prevLevel ){
177 if( prevLevel>0 ){
178 @ <tr><td colspan="3"><hr></td></tr>
179 }
180 if( iLevel==1 ){
181 @ <tr>
182 @ <th class="usetupListUser"
183 @ style="text-align: right;padding-right: 20px;">Category</th>
184 @ <th class="usetupListCap"
185 @ style="text-align: center;padding-right: 15px;">Capabilities</th>
186 @ <th class="usetupListCon"
187 @ style="text-align: left;">Notes</th>
188 @ </tr>
189 }else{
190 @ <tr>
191 @ <th class="usetupListUser"
192 @ style="text-align: right;padding-right: 20px;">User&nbsp;ID</th>
193 @ <th class="usetupListCap"
194 @ style="text-align: center;padding-right: 15px;">Capabilities</th>
195 @ <th class="usetupListCon"
196 @ style="text-align: left;">Contact&nbsp;Info</th>
197 @ </tr>
198 }
199 prevLevel = iLevel;
200 }
201 @ <tr>
202 @ <td class="usetupListUser"
203 @ style="text-align: right;padding-right: 20px;white-space:nowrap;">
204 if( g.perm.Admin && (zCap[0]!='s' || g.perm.Setup) ){
205 @ <a href="setup_uedit?id=%d(db_column_int(&s,0))">
206 }
207 @ %h(zLogin)
208 if( g.perm.Admin ){
209 @ </a>
210 }
211 @ </td>
212 @ <td class="usetupListCap" style="text-align: center;padding-right: 15px;">%s(zCap)</td>
213 @ <td class="usetupListCon" style="text-align: left;">%h(db_column_text(&s,3))</td>
214 @ </tr>
215 }
216 @ </table>
217 @ </td><td class="usetupColumnLayout">
218 @ <span class="note">Notes:</span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219 @ <ol>
220 @ <li><p>The permission flags are as follows:</p>
221 @ <table>
222 @ <tr><th valign="top">a</th>
223 @ <td><i>Admin:</i> Create and delete users</td></tr>
@@ -295,14 +322,13 @@
295 @ <span class="usertype">anonymous</span>, and
296 @ <span class="usertype">nobody</span>.
297 @ </p></li>
298 @
299 @ </ol>
300 @ </td></tr></table>
301 style_footer();
302 db_finalize(&s);
303 }
 
304
305 /*
306 ** Return true if zPw is a valid password string. A valid
307 ** password string is:
308 **
309
--- src/setup.c
+++ src/setup.c
@@ -153,71 +153,98 @@
153 login_needed(0);
154 return;
155 }
156
157 style_submenu_element("Add", "Add User", "setup_uedit");
158 style_submenu_element("Help", "Help", "setup_ulist_notes");
159 style_header("User List");
160 @ <table border=1 cellpadding=2 cellspacing=0 class='userTable'>
161 @ <thead><tr><th>UID <th>Category <th>Capabilities <th>Info <th>Last Change</tr></thead>
162 @ <tbody>
163 db_prepare(&s,
164 "SELECT uid, login, cap, date(mtime,'unixepoch')"
165 " FROM user"
166 " WHERE login IN ('anonymous','nobody','developer','reader')"
167 " ORDER BY login"
168 );
169 while( db_step(&s)==SQLITE_ROW ){
170 int uid = db_column_int(&s, 0);
171 const char *zLogin = db_column_text(&s, 1);
172 const char *zCap = db_column_text(&s, 2);
173 const char *zDate = db_column_text(&s, 4);
174 @ <tr>
175 @ <td><a href='setup_uedit?id=%d(uid)'>%d(uid)</a>
176 @ <td><a href='setup_uedit?id=%d(uid)'>%h(zLogin)</a>
177 @ <td>%h(zCap)
178
179 if( fossil_strcmp(zLogin,"anonymous")==0 ){
180 @ <td>All logged-in users
181 }else if( fossil_strcmp(zLogin,"developer")==0 ){
182 @ <td>Users with '<b>v</b>' capability
183 }else if( fossil_strcmp(zLogin,"nobody")==0 ){
184 @ <td>All users without login
185 }else if( fossil_strcmp(zLogin,"reader")==0 ){
186 @ <td>Users with '<b>u</b>' capability
187 }else{
188 @ <td>
189 }
190 if( zDate && zDate[0] ){
191 @ <td>%h(zDate)
192 }else{
193 @ <td>
194 }
195 @ </tr>
196 }
197 db_finalize(&s);
198 @ </tbody></table>
199 @ <div class='section'>Users</div>
200 @ <table border=1 cellpadding=2 cellspacing=0 class='userTable' id='userlist'>
201 @ <thead><tr>
202 @ <th>ID<th>Login<th>Caps<th>Info<th>Chng<th>Expire</tr></thead>
203 @ <tbody>
204 db_prepare(&s,
205 "SELECT uid, login, cap, info, date(mtime,'unixepoch'), lower(login) AS sortkey, "
206 " CASE WHEN info LIKE '%%expires 20%%'"
207 " THEN substr(info,instr(lower(info),'expires')+8,10)"
208 " END AS exp"
209 " FROM user"
210 " WHERE login NOT IN ('anonymous','nobody','developer','reader')"
211 " ORDER BY sortkey"
212 );
213 while( db_step(&s)==SQLITE_ROW ){
214 int uid = db_column_int(&s, 0);
215 const char *zLogin = db_column_text(&s, 1);
216 const char *zCap = db_column_text(&s, 2);
217 const char *zInfo = db_column_text(&s, 3);
218 const char *zDate = db_column_text(&s, 4);
219 const char *zSortKey = db_column_text(&s,5);
220 const char *zExp = db_column_text(&s,6);
221 @ <tr>
222 @ <td><a href='setup_uedit?id=%d(uid)'>%d(uid)</a>
223 @ <td data-sortkey='%h(zSortKey)'><a href='setup_uedit?id=%d(uid)'>%h(zLogin)</a>
224 @ <td>%h(zCap)
225 @ <td>%h(zInfo)
226 @ <td>%h(zDate?zDate:"")
227 @ <td>%h(zExp?zExp:"")
228 @ </tr>
229 }
230 @ </tbody></table>
231 db_finalize(&s);
232 output_table_sorting_javascript("userlist","nktxTT",2);
233 style_footer();
234 }
235
236 /*
237 ** WEBPAGE: setup_ulist_notes
238 **
239 ** A documentation page showing notes about user configuration. This information
240 ** used to be a side-bar on the user list page, but has been factored out for
241 ** improved presentation.
242 */
243 void setup_ulist_notes(void){
244 style_header("User Configuration Notes");
245 @ <h1>User Configuration Notes:</h1>
246 @ <ol>
247 @ <li><p>The permission flags are as follows:</p>
248 @ <table>
249 @ <tr><th valign="top">a</th>
250 @ <td><i>Admin:</i> Create and delete users</td></tr>
@@ -295,14 +322,13 @@
322 @ <span class="usertype">anonymous</span>, and
323 @ <span class="usertype">nobody</span>.
324 @ </p></li>
325 @
326 @ </ol>
 
327 style_footer();
 
328 }
329
330
331 /*
332 ** Return true if zPw is a valid password string. A valid
333 ** password string is:
334 **
335

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button