170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
...
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
|
-- FIXME allow xids as well, for manual queries
if not user then goto e404 end
defer user:free()
if not co.who:overpowers(user.ptr) then goto e403 end
if path.ct == 4 then
if path(3):cmp(lib.str.lit'cred') then
var pg: lib.str.acc pg:init(1024)
pg:lpush('<div class="context">editing credentials for user <a href="/conf/users/'):rpush(path(2)):lpush('">'):push(user(0).xid,0):lpush('</a></div>')
var credmgr = lib.render.conf.sec(co, uid)
pg:ppush(credmgr)
credmgr:free()
return pg:finalize()
else goto e404 end
elseif path.ct == 3 then
var cinp: lib.str.acc cinp:init(256)
cinp:lpush('<div class="elem-group">')
if user.ptr.rights.rank > 0 and (co.who.rights.powers.elevate() or co.who.rights.powers.demote()) then
var max = co.who.rights.rank
if not co.who.rights.powers.elevate() then max = user.ptr.rights.rank end
var min = co.srv.cfg.nranks
if not co.who.rights.powers.demote() then min = user.ptr.rights.rank end
push_num_field(cinp, 'rank', 'rank', max, min, user.ptr.rights.rank, user.ptr.id == co.who.id)
end
if co.who.rights.powers.herald() then
var sanitized: pstr
if user.ptr.epithet == nil
then sanitized = pstr {ptr='', ct=0}
else sanitized = lib.html.sanitize(cs(user.ptr.epithet),true)
end
cinp:lpush('<div class="elem"><label for="epithet">epithet</label><input type="text" id="epithet" name="epithet" value="'):ppush(sanitized):lpush('"></div>')
if user.ptr.epithet ~= nil then sanitized:free() end
end
if co.who.rights.powers.invite() or co.who.rights.powers.discipline() then
var min: uint32 = 0
if not (co.who.rights.powers.discipline() or
co.who.rights.powers.demote() and co.who.rights.powers.invite())
then min = user.ptr.rights.invites end
var max: uint32 = co.srv.cfg.maxinvites
................................................................................
var map = array([lib.store.powmap])
cinp:lpush('<details><summary>powers</summary><div class="pick-list">')
for i=0, [map.type.N] do
if (co.who.rights.powers and map[i].val):sz() > 0 then
var on = (user.ptr.rights.powers and map[i].val):sz() > 0
var enabled = ( on and co.who.rights.powers.demote() ) or
((not on) and co.who.rights.powers.elevate())
var namea: lib.str.acc namea:compose('power-', map[i].name)
var name = namea:finalize()
push_pickbox(&cinp, name, pstr.null(), map[i].name, on, enabled, pstr.null())
name:free()
end
end
cinp:lpush('</div></details>')
end
if co.who.id ~= uid and co.who.rights.powers.purge() then
var purgeconf: lib.str.acc purgeconf:init(48)
var purgestrs = array(
'alpha', 'beta', 'gamma', 'delta', 'epsilon', 'eta', 'nu', 'kappa',
'emerald', 'carnelian', 'sapphire', 'ruby', 'amethyst', 'glory',
'hope', 'grace', 'pearl', 'carnation', 'rose', 'peony', 'poppy'
)
for i=0,3 do
purgeconf:push(purgestrs[lib.crypt.random(intptr,0,[purgestrs.type.N])],0)
if i ~= 2 then purgeconf:lpush('-') end
end
cinp:lpush('<details><summary>purge account</summary><p>you have the authority to destroy this account and all its associated content irreversibly and irretrievably. if you really wish to apply such an extreme sanction, enter the confirmation string <strong style="user-select:none">'):push(purgeconf.buf,purgeconf.sz):lpush('</strong> below and press the “alter” button to begin the process.</p><div class="elem"><label for="purge">purge confirmation string</label><input type="text" id="purge" name="purgekey"></div><input type="hidden" name="purgestr" value="'):push(purgeconf.buf,purgeconf.sz):lpush('"></details>')
purgeconf:free()
end
-- TODO black mark system? e.g. resolution option for badthink reports
-- adds a black mark to the offending user; they can be automatically banned
-- or brought up for review after a certain number of offenses; possibly lower
-- set of default privs for marked users
var cinpp = cinp:finalize() defer cinpp:free()
var unym: lib.str.acc unym:init(64)
unym:lpush('<a href="/')
if user(0).origin ~= 0 then unym:lpush('@') end
do var sanxid = lib.html.sanitize(user(0).xid, true)
unym:ppush(sanxid)
sanxid:free() end
unym:lpush('" class="id">')
lib.render.nym(user.ptr,0,&unym,false)
unym:lpush('</a>')
var ctlbox = data.view.conf_user_ctl {
name = unym:finalize();
inputcontent = cinpp;
btns = pstr{'',0};
}
if co.who.id ~= uid and co.who.rights.powers.cred() then
ctlbox.btns = lib.str.acc{}:compose('<a class="button" href="/conf/users/',path(2),'/cred">security & credentials</a>'):finalize()
end
var pg: lib.str.acc pg:init(512)
ctlbox:append(&pg)
ctlbox.name:free()
if ctlbox.btns.ct > 0 then ctlbox.btns:free() end
return pg:finalize()
end
else
var modes = array(P'local', P'remote', P'staff', P'titled', P'peons', P'all')
var idbuf: int8[lib.math.shorthand.maxlen]
var ulst: lib.str.acc ulst:init(256)
var mode: uint8 = mode_local
var modestr = co:pgetv('show')
ulst:lpush('<div style="text-align: right"><em>showing ')
for i=0,[modes.type.N] do
if modestr:ref() and modes[i]:cmp(modestr) then mode = i end
end
for i=0,[modes.type.N] do
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
...
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
|
-- FIXME allow xids as well, for manual queries
if not user then goto e404 end
defer user:free()
if not co.who:overpowers(user.ptr) then goto e403 end
if path.ct == 4 then
if path(3):cmp(lib.str.lit'cred') then
var pg = co:stra(1024)
pg:lpush('<div class="context">editing credentials for user <a href="/conf/users/'):rpush(path(2)):lpush('">'):push(user(0).xid,0):lpush('</a></div>')
var credmgr = lib.render.conf.sec(co, uid)
pg:ppush(credmgr)
--credmgr:free()
return pg:finalize()
else goto e404 end
elseif path.ct == 3 then
var cinp = co:stra(256)
cinp:lpush('<div class="elem-group">')
if user.ptr.rights.rank > 0 and (co.who.rights.powers.elevate() or co.who.rights.powers.demote()) then
var max = co.who.rights.rank
if not co.who.rights.powers.elevate() then max = user.ptr.rights.rank end
var min = co.srv.cfg.nranks
if not co.who.rights.powers.demote() then min = user.ptr.rights.rank end
push_num_field(cinp, 'rank', 'rank', max, min, user.ptr.rights.rank, user.ptr.id == co.who.id)
end
if co.who.rights.powers.herald() then
var sanitized: pstr
if user.ptr.epithet == nil
then sanitized = pstr {ptr='', ct=0}
else sanitized = lib.html.sanitize(&co.srv.pool,cs(user.ptr.epithet),true)
end
cinp:lpush('<div class="elem"><label for="epithet">epithet</label><input type="text" id="epithet" name="epithet" value="'):ppush(sanitized):lpush('"></div>')
--if user.ptr.epithet ~= nil then sanitized:free() end
end
if co.who.rights.powers.invite() or co.who.rights.powers.discipline() then
var min: uint32 = 0
if not (co.who.rights.powers.discipline() or
co.who.rights.powers.demote() and co.who.rights.powers.invite())
then min = user.ptr.rights.invites end
var max: uint32 = co.srv.cfg.maxinvites
................................................................................
var map = array([lib.store.powmap])
cinp:lpush('<details><summary>powers</summary><div class="pick-list">')
for i=0, [map.type.N] do
if (co.who.rights.powers and map[i].val):sz() > 0 then
var on = (user.ptr.rights.powers and map[i].val):sz() > 0
var enabled = ( on and co.who.rights.powers.demote() ) or
((not on) and co.who.rights.powers.elevate())
var namea: lib.str.acc namea:pcompose(&co.srv.pool,'power-', map[i].name)
var name = namea:finalize()
push_pickbox(&cinp, name, pstr.null(), map[i].name, on, enabled, pstr.null())
--name:free()
end
end
cinp:lpush('</div></details>')
end
if co.who.id ~= uid and co.who.rights.powers.purge() then
var purgeconf = co:stra(48)
var purgestrs = array(
'alpha', 'beta', 'gamma', 'delta', 'epsilon', 'eta', 'nu', 'kappa',
'emerald', 'carnelian', 'sapphire', 'ruby', 'amethyst', 'glory',
'hope', 'grace', 'pearl', 'carnation', 'rose', 'peony', 'poppy'
)
for i=0,3 do
purgeconf:push(purgestrs[lib.crypt.random(intptr,0,[purgestrs.type.N])],0)
if i ~= 2 then purgeconf:lpush('-') end
end
cinp:lpush('<details><summary>purge account</summary><p>you have the authority to destroy this account and all its associated content irreversibly and irretrievably. if you really wish to apply such an extreme sanction, enter the confirmation string <strong style="user-select:none">'):push(purgeconf.buf,purgeconf.sz):lpush('</strong> below and press the “alter” button to begin the process.</p><div class="elem"><label for="purge">purge confirmation string</label><input type="text" id="purge" name="purgekey"></div><input type="hidden" name="purgestr" value="'):push(purgeconf.buf,purgeconf.sz):lpush('"></details>')
--purgeconf:free()
end
-- TODO black mark system? e.g. resolution option for badthink reports
-- adds a black mark to the offending user; they can be automatically banned
-- or brought up for review after a certain number of offenses; possibly lower
-- set of default privs for marked users
var cinpp = cinp:finalize() --defer cinpp:free()
var unym = co:stra(64)
unym:lpush('<a href="/')
if user(0).origin ~= 0 then unym:lpush('@') end
do var sanxid = lib.html.sanitize(&co.srv.pool,user(0).xid, true)
unym:ppush(sanxid)
--sanxid:free()
end
unym:lpush('" class="id">')
lib.render.nym(user.ptr,0,&unym,false)
unym:lpush('</a>')
var ctlbox = data.view.conf_user_ctl {
name = unym:finalize();
inputcontent = cinpp;
btns = pstr{'',0};
}
if co.who.id ~= uid and co.who.rights.powers.cred() then
ctlbox.btns = lib.str.acc{}:pcompose(&co.srv.pool,'<a class="button" href="/conf/users/',path(2),'/cred">security & credentials</a>'):finalize()
end
var pg = co:stra(512)
ctlbox:append(&pg)
--ctlbox.name:free()
--if ctlbox.btns.ct > 0 then ctlbox.btns:free() end
return pg:finalize()
end
else
var modes = array(P'local', P'remote', P'staff', P'titled', P'peons', P'all')
var idbuf: int8[lib.math.shorthand.maxlen]
var ulst = co:stra(256)
var mode: uint8 = mode_local
var modestr = co:pgetv('show')
ulst:lpush('<div style="text-align: right"><em>showing ')
for i=0,[modes.type.N] do
if modestr:ref() and modes[i]:cmp(modestr) then mode = i end
end
for i=0,[modes.type.N] do
|