Overview
| Comment: | get some user admin shit working, general cleanups |
|---|---|
| Downloads: | Tarball | ZIP archive | SQL archive |
| Timelines: | family | ancestors | descendants | both | trunk |
| Files: | files | file ages | folders |
| SHA3-256: |
e1ff4f301edd5ee416d023d88a327090 |
| User & Date: | lexi on 2021-01-10 14:26:47 |
| Other Links: | manifest | tags |
Context
|
2021-01-10
| ||
| 16:44 | add avatar panel check-in: 8398fcda5a user: lexi tags: trunk | |
| 14:26 | get some user admin shit working, general cleanups check-in: e1ff4f301e user: lexi tags: trunk | |
| 11:17 | add follow notices check-in: 00a6815988 user: lexi tags: trunk | |
Changes
Modified mime.t from [2e40a434e4] to [b6a24abaaf].
2 2 ['text/csrc'] = { 3 3 ext = 'c', lang = 'c'; 4 4 }; 5 5 ['text/html'] = { 6 6 ext = 'html', lang = 'html'; 7 7 unsafe = true; 8 8 }; 9 + ['text/x-lua'] = { 10 + ext = 'lua', lang = 'lua'; 11 + }; 9 12 ['text/markdown'] = { 10 13 formatter = 'smackdown'; 11 14 ext = 'md', doc = true; 12 15 }; 13 16 }
Modified render/docpage.t from [8016afcf69] to [9f2f406de7].
85 85 if started then list:lpush('</ol>') end 86 86 end 87 87 88 88 local terra 89 89 render_docpage(co: &lib.srv.convo, pg: pref) 90 90 var nullprivs: lib.store.powerset nullprivs:clear() 91 91 if not pg then -- display index 92 - var list: lib.str.acc list:compose('<ul>') 92 + var list = co:stra(256) 93 + list:lpush('<ul>') 93 94 var [pages] = array([allpages]) 94 95 for i=0,[pages.type.N] do 95 96 if pages[i].parent == 0 and (pages[i].priv:sz() == 0 or 96 97 (co.aid ~= 0 and (co.who.rights.powers 97 98 and pages[i].priv):sz() > 0)) then 98 99 list:lpush('<li><a href="/doc/'):rpush(pages[i].name):lpush('">') 99 100 :rpush(pages[i].title):lpush('</a>') ................................................................................ 103 104 pushbranches(&list, i, nullprivs) 104 105 end 105 106 list:lpush('</li>') 106 107 end 107 108 end 108 109 list:lpush('</ul>') 109 110 110 - var bp = list:finalize() 111 111 co:stdpage(page { 112 112 title = 'documentation'; 113 - body = bp; 113 + body = list:finalize(); 114 114 class = P'doc listing'; 115 115 cache = false; 116 116 }) 117 - bp:free() 118 117 else showpage(co, pg) end 119 118 end 120 119 121 120 return render_docpage
Modified render/media-gallery.t from [5c4e9df122] to [18e4a71c1d].
73 73 lib.str.cmp(art(0).mime, 'application/sql') == 0 74 74 -- and so on (we need a mimelib at some point) -- 75 75 then 76 76 var view = data.view.media_text(viewerprops) 77 77 var text, mime = co.srv:artifact_load(id) mime:free() 78 78 var san = lib.html.sanitize(&co.srv.pool,pstr{[rawstring](text.ptr),text.ct}, false) 79 79 text:free() 80 - view.text = lib.str.acc{}:compose('<pre>',san,'</pre>'):finalize() 81 - san:free() 82 - var pg = view:tostr() 83 - view.text:free() 80 + view.text = co:qstr('<pre>',san,'</pre>') 81 + --san:free() 82 + var pg = view:poolstr(&co.srv.pool) 83 + --view.text:free() 84 84 co:stdpage([lib.srv.convo.page] { 85 85 title = lib.str.plit'media :: text'; 86 86 class = lib.str.plit'media viewer text'; 87 87 cache = false, body = pg; 88 88 }) 89 - pg:free() 89 + --pg:free() 90 90 else co:complain(500,'bad file type','this file type is not supported') end 91 91 elseif path.ct == 4 then 92 92 var act = path(3) 93 - var curl = lib.str.acc{}:compose(pfx, '/media/a/', path(2)):finalize() 94 - defer curl:free() 93 + var curl = co:qstr('/media/a/', path(2)) 94 + -- defer curl:free() 95 95 if act:cmp(lib.str.lit'avi') and lib.str.ncmp(art(0).mime, 'image/', 6) == 0 then 96 96 co:confirm('set avatar', 'are you sure you want this image to be your new avatar?',curl) 97 97 elseif act:cmp(lib.str.lit'del') then 98 98 co:confirm('delete', 'are you sure you want to permanently delete this artifact?',curl) 99 99 else goto e404 end 100 100 end 101 101 else ................................................................................ 123 123 folders = pstr{'',0}; 124 124 directory = pstr{'',0}; 125 125 images = pstr{'',0}; 126 126 pfx = pfx; 127 127 } 128 128 129 129 if folders.ct > 0 then 130 - var fa: lib.str.acc fa:pool(&co.srv.pool,128) 130 + var fa = co:stra(128) 131 131 var fldr = co:pgetv('folder') 132 132 for i=0,folders.ct do 133 133 var ule = lib.html.urlenc(&co.srv.pool,folders(i), true) -- defer ule:free() 134 134 var san = lib.html.sanitize(&co.srv.pool,folders(i), true) -- defer san:free() 135 135 fa:lpush('<a href="'):ppush(pfx):lpush('/media?folder='):ppush(ule) 136 136 :lpush('">'):ppush(san):lpush('</a>') 137 137 lib.dbg('checking folder ',{fldr.ptr,fldr.ct},' against ',{folders(i).ptr,folders(i).ct})
Modified render/profile.t from [cdb26ba3d8] to [849244d87f].
37 37 var sn_followers = cs(lib.math.decstr_friendly(stats.followers, sn_follows.ptr - 1)) 38 38 var sn_mutuals = cs(lib.math.decstr_friendly(stats.mutuals, sn_followers.ptr - 1)) 39 39 var bio = lib.str.plit '<em style="opacity:0.6">tall, dark, and mysterious</em>' 40 40 if actor.bio ~= nil then 41 41 bio = lib.smackdown.html(&co.srv.pool,cs(actor.bio),false) 42 42 end 43 43 var fullname = lib.render.nym(actor,0,nil,false) defer fullname:free() 44 - var comments: lib.str.acc comments:pool(&co.srv.pool,64) 44 + var comments = co:stra(64) 45 45 46 46 if co.srv.cfg.master == actor.id then 47 47 var foundertxt = lib.str.plit 'founder' 48 48 if co.srv.cfg.ui_cue_founder:ref() then 49 49 if co.srv.cfg.ui_cue_founder.ct == 0 -- empty string, suppress field 50 50 then foundertxt = pstr.null() 51 51 else foundertxt = co.srv.cfg.ui_cue_founder ................................................................................ 99 99 auxbtn = auxp; 100 100 } 101 101 if comments.sz > 0 then profile.remarks = comments:finalize() end 102 102 103 103 var ret = profile:poolstr(&co.srv.pool) 104 104 -- auxp:free() 105 105 --if actor.bio ~= nil then bio:free() end 106 - if comments.sz > 0 then profile.remarks:free() end 106 + --if comments.sz > 0 then profile.remarks:free() end 107 107 return ret 108 108 end 109 109 110 110 return render_profile
Modified route.t from [47b3eeec8d] to [efbc5e4a8e].
12 12 terra http.actor_profile(co: &lib.srv.convo, actor: &lib.store.actor, meth: method.t) 13 13 var rel: lib.store.relationship 14 14 if co.aid ~= 0 then 15 15 rel = co.srv:actor_rel_calc(co.who.id, actor.id) 16 16 if meth == method.post then 17 17 var act = co:ppostv('act') 18 18 if rel.recip.block() then 19 - if act:cmp(lib.str.plit 'follow') or act:cmp(lib.str.plit 'subscribe') then 19 + if act:cmp( 'follow') or act:cmp( 'subscribe') then 20 20 co:complain(403,'blocked','you cannot follow a user you are blocked by') return 21 21 end 22 22 end 23 - if act:cmp(lib.str.plit 'block') and not rel.rel.block() then 23 + if act:cmp( 'block') and not rel.rel.block() then 24 24 (rel.rel.block << true) ; (rel.recip.follow << false) 25 25 co.srv:actor_rel_create([lib.store.relation.idvmap.block], co.who.id, actor.id) 26 26 co.srv:actor_rel_destroy([lib.store.relation.idvmap.follow], actor.id, co.who.id) 27 27 else 28 28 [(function() 29 29 local tests = quote co:complain(400,'bad request','the action you have attempted on this user is not meaningful') return end 30 30 for i,v in ipairs(lib.store.relation.members) do 31 31 tests = quote 32 - if [v ~= 'block'] and act:cmp(lib.str.plit([v])) and not rel.rel.[v]() then -- rely on dead code elimination :/ 32 + if [v ~= 'block'] and act:cmp(([v])) and not rel.rel.[v]() then -- rely on dead code elimination :/ 33 33 (rel.rel.[v] << true) 34 34 co.srv:actor_rel_create([lib.store.relation.idvmap[v]], co.who.id, actor.id) 35 - elseif act:cmp(lib.str.plit(['un'..v])) and rel.rel.[v]() then 35 + elseif act:cmp((['un'..v])) and rel.rel.[v]() then 36 36 (rel.rel.[v] << false) 37 37 co.srv:actor_rel_destroy([lib.store.relation.idvmap[v]], co.who.id, actor.id) 38 38 else [tests] end 39 39 end 40 40 end 41 41 return tests 42 42 end)()] ................................................................................ 102 102 103 103 http.actor_profile(co,actor.ptr,meth) 104 104 end 105 105 106 106 terra http.login_form(co: &lib.srv.convo, meth: method.t) 107 107 if meth_get(meth) then 108 108 -- request a username 109 - lib.render.login(co, nil, nil, lib.str.plit(nil)) 109 + lib.render.login(co, nil, nil, pstring.null()) 110 110 elseif meth == method.post then 111 111 var usn, usnl = co:postv('user') 112 112 var am, aml = co:postv('authmethod') 113 113 var chrs, chrsl = co:postv('response') 114 114 var cs, authok = co.srv:actor_auth_how(co.peer, usn) 115 115 var act = co.srv:actor_fetch_xid([lib.mem.ptr(int8)] { 116 116 ptr = usn, ct = usnl 117 117 }) 118 118 if authok == false then 119 - lib.render.login(co, nil, nil, lib.str.plit'access denied') 119 + lib.render.login(co, nil, nil, 'access denied') 120 120 return 121 121 end 122 122 var fakeact = false 123 123 var fakeactor: lib.store.actor 124 124 if act.ptr == nil then 125 125 -- the user is known to us but has not yet claimed an 126 126 -- account on the server. create a template for the ................................................................................ 134 134 } 135 135 act.ct = 1 136 136 act.ptr = &fakeactor 137 137 act.ptr.rights = lib.store.rights_default() 138 138 end 139 139 if am == nil then 140 140 -- pick an auth method 141 - lib.render.login(co, act.ptr, &cs, lib.str.plit(nil)) 141 + lib.render.login(co, act.ptr, &cs, pstring.null()) 142 142 else var aid: uint64 = 0 143 143 lib.dbg('authentication attempt beginning') 144 144 -- attempt login with provided method 145 145 if lib.str.ncmp('pw', am, lib.math.biggest(2,aml)) == 0 and chrs ~= nil then 146 146 aid = co.srv:actor_auth_pw(co.peer, 147 147 [lib.mem.ptr(int8)]{ptr=usn,ct=usnl}, 148 148 [lib.mem.ptr(int8)]{ptr=chrs,ct=chrsl}) ................................................................................ 149 149 elseif lib.str.ncmp('otp', am, lib.math.biggest(2,aml)) == 0 and chrs ~= nil then 150 150 lib.dbg('using otp auth') 151 151 -- ยทยทยท -- 152 152 else lib.dbg('invalid auth method') end 153 153 154 154 -- error out 155 155 if aid == 0 then 156 - lib.render.login(co, nil, nil, lib.str.plit 'authentication failure') 156 + lib.render.login(co, nil, nil, 'authentication failure') 157 157 else 158 158 co:installkey('/',aid) 159 159 end 160 160 end 161 161 if act.ptr ~= nil and fakeact == false then act:free() end 162 162 else 163 163 ::wrongmeth:: co:complain(405, 'method not allowed', 'that method is not meaningful for this endpoint') do return end ................................................................................ 253 253 end 254 254 return 255 255 elseif path(2):cmp(lib.str.lit 'del') then 256 256 if meth_get(meth) then 257 257 var conf: data.view.confirm 258 258 if post:ref() then 259 259 conf = data.view.confirm { 260 - title = lib.str.plit 'delete post'; 261 - query = lib.str.plit 'are you sure you want to delete this post?'; 260 + title = 'delete post'; 261 + query = 'are you sure you want to delete this post?'; 262 262 cancel = lnkp 263 263 } 264 264 else 265 265 conf = data.view.confirm { 266 - title = lib.str.plit 'cancel retweet'; 267 - query = lib.str.plit 'are you sure you want to undo this retweet?'; 268 - cancel = lib.str.plit'/'; 266 + title = 'cancel retweet'; 267 + query = 'are you sure you want to undo this retweet?'; 268 + cancel = '/'; 269 269 } 270 270 end 271 271 var fr = co.srv.pool:frame() 272 272 var body = conf:poolstr(&co.srv.pool) --defer body:free() 273 273 co:stdpage([lib.srv.convo.page] { 274 - title = lib.str.plit 'post :: delete'; 275 - class = lib.str.plit 'query'; 274 + title = 'post :: delete'; 275 + class = 'query'; 276 276 body = body; cache = false; 277 277 }) 278 278 co.srv.pool:reset(fr) 279 279 return 280 280 elseif meth == method.post then 281 281 var act = co:ppostv('act') 282 - if act:cmp(lib.str.plit 'confirm') then 282 + if act:cmp( 'confirm') then 283 283 if post:ref() then 284 284 post(0).source:post_destroy(post(0).id) 285 285 elseif rt.kind ~= 0 then 286 286 co.srv:post_act_cancel(pid) 287 287 end 288 288 co:reroute('/') -- TODO maybe return to parent or conversation if possible 289 289 return ................................................................................ 291 291 end 292 292 else goto badurl end 293 293 end 294 294 295 295 if post:ref() and meth == method.post then 296 296 if co.aid == 0 then goto noauth end 297 297 var act = co:ppostv('act') 298 - if act:cmp(lib.str.plit 'like') and not co.srv:post_liked_uid(co.who.id,pid) then 298 + if act:cmp( 'like') and not co.srv:post_liked_uid(co.who.id,pid) then 299 299 co.srv:post_like(co.who.id, pid, false) 300 300 post.ptr.likes = post.ptr.likes + 1 301 - elseif act:cmp(lib.str.plit 'dislike') and co.srv:post_liked_uid(co.who.id,pid) then 301 + elseif act:cmp( 'dislike') and co.srv:post_liked_uid(co.who.id,pid) then 302 302 co.srv:post_like(co.who.id, pid, true) 303 303 post.ptr.likes = post.ptr.likes - 1 304 - elseif act:cmp(lib.str.plit 'rt') then 304 + elseif act:cmp( 'rt') then 305 305 co.srv:post_retweet(co.who.id, pid, false) 306 306 post.ptr.rts = post.ptr.rts + 1 307 - elseif act:cmp(lib.str.plit 'post') then 307 + elseif act:cmp( 'post') then 308 308 var replytext = co:ppostv('post') 309 309 var acl = co:ppostv('acl') 310 310 var subj = co:ppostv('subject') 311 - if not acl then acl = lib.str.plit 'all' end 311 + if not acl then acl = 'all' end 312 312 if not replytext then goto badop end 313 313 314 314 var reply = lib.store.post { 315 315 author = co.who.id, parent = pid; 316 316 subject = subj.ptr, acl = acl.ptr, body = replytext.ptr; 317 317 } 318 318 ................................................................................ 330 330 ::noauth:: do co:complain(401, 'unauthorized', 'you have not supplied the necessary credentials to perform this operation') return end 331 331 end 332 332 333 333 local terra 334 334 credsec_for_uid(co: &lib.srv.convo, uid: uint64) 335 335 var act = co:ppostv('act') 336 336 lib.dbg('showing credentials') 337 - if act:cmp(lib.str.plit 'invalidate') then 337 + if act:cmp( 'invalidate') then 338 338 lib.dbg('setting user\'s cookie validation time to now') 339 339 co.who.source:auth_sigtime_user_alter(uid, lib.osclock.time(nil)) 340 340 -- the current session has been invalidated as well, so we need to immediately install a new authentication cookie with the same aid so the user doesn't need to log back in all over again 341 341 co:installkey('?',co.aid) 342 342 return 343 - elseif act:cmp(lib.str.plit 'newcred') then 343 + elseif act:cmp( 'newcred') then 344 344 var cmt = co:ppostv('comment') 345 345 var pw = co:ppostv('newpw') 346 346 var aid: uint64 = 0 347 347 if pw:ref() then 348 348 var cpw = co:ppostv('rptpw') 349 349 if not pw:cmp(cpw) then 350 350 co:complain(400,'enrollment failure','the passwords you supplied do not match') ................................................................................ 361 361 lib.dbg('setting credential restrictions') 362 362 var privs = [(function() 363 363 local check = quote end 364 364 local me = symbol(lib.store.privset) 365 365 for i,v in ipairs(lib.store.privset.members) do 366 366 check = quote [check] 367 367 var val = co:pgetv(['allow-' .. v]) 368 - if val:ref() and val:cmp(lib.str.plit'on') 368 + if val:ref() and val:cmp('on') 369 369 then ([me].[v] << true) 370 370 else ([me].[v] << false) 371 371 end 372 372 end 373 373 end 374 374 return quote 375 375 var [me] ................................................................................ 393 393 end 394 394 395 395 terra http.configure(co: &lib.srv.convo, path: hpath, meth: method.t) 396 396 var msg = pstring.null() 397 397 -- first things first, do priv checks 398 398 if path.ct >= 2 then 399 399 if not co.who.rights.powers.config() and ( 400 - path(1):cmp(lib.str.lit 'srv') or 401 - path(1):cmp(lib.str.lit 'badge') or 402 - path(1):cmp(lib.str.lit 'emoji') 400 + path(1):cmp('srv') or 401 + path(1):cmp('badge') or 402 + path(1):cmp('emoji') 403 403 ) then goto nopriv 404 404 405 405 elseif not co.who.rights.powers.rebrand() and ( 406 - path(1):cmp(lib.str.lit 'brand') 406 + path(1):cmp('brand') 407 407 ) then goto nopriv 408 408 409 409 elseif not co.who.rights.powers.account() and ( 410 - path(1):cmp(lib.str.lit 'profile') or 411 - path(1):cmp(lib.str.lit 'sec') or 412 - path(1):cmp(lib.str.lit 'avi') or 413 - path(1):cmp(lib.str.lit 'ui') 410 + path(1):cmp('profile') or 411 + path(1):cmp('sec') or 412 + path(1):cmp('avi') or 413 + path(1):cmp('ui') 414 414 ) then goto nopriv 415 415 416 416 elseif not co.who.rights.powers:affect_users() and ( 417 417 path(1):cmp(lib.str.lit 'users') 418 418 ) then goto nopriv end 419 419 end 420 420 ................................................................................ 427 427 if co.who.bio ~= nil and @co.who.bio == 0 then co.who.bio = nil end 428 428 if co.who.nym ~= nil and @co.who.nym == 0 then co.who.nym = nil end 429 429 co.who.source:actor_save(co.who) 430 430 431 431 var act = co:ppostv('act') 432 432 var resethue = false 433 433 if act:ref() then 434 - resethue = act:cmp(lib.str.plit 'reset-hue') 434 + resethue = act:cmp( 'reset-hue') 435 435 end 436 436 437 437 if not resethue then 438 438 var shue = co:ppostv('hue') 439 439 var nhue, okhue = lib.math.decparse(shue) 440 440 if okhue and nhue ~= co.ui_hue then 441 441 if nhue == co.srv.cfg.ui_hue ................................................................................ 446 446 end 447 447 end 448 448 if resethue then 449 449 co.srv:actor_conf_int_reset(co.who.id, 'ui-accent') 450 450 co.ui_hue = co.srv.cfg.ui_hue 451 451 end 452 452 453 - msg = lib.str.plit 'profile changes saved' 453 + msg = 'profile changes saved' 454 454 --user_refresh = true -- not really necessary here, actually 455 455 456 - elseif path(1):cmp(lib.str.lit 'sec') then 456 + elseif path(1):cmp('sec') then 457 457 credsec_for_uid(co, co.who.id) 458 - elseif path(1):cmp(lib.str.lit 'users') then 458 + elseif path(1):cmp('users') then 459 459 if path.ct >= 3 then 460 460 var userid, ok = lib.math.shorthand.parse(path(2).ptr, path(2).ct) 461 461 if ok then 462 462 var usr = co.srv:actor_fetch_uid(userid) 463 - if usr:ref() then defer usr:free() 464 - if not co.who:overpowers(usr.ptr) then goto nopriv end 465 - end 463 + if usr:ref() then --defer usr:free() 464 + if not co.who:overpowers(usr.ptr) then 465 + usr:free() 466 + goto nopriv 467 + end 468 + else goto badop end 469 + defer usr:free() 470 + 466 471 if path.ct == 4 then 467 472 if path(3):cmp(lib.str.lit 'cred') then 468 473 credsec_for_uid(co, userid) 469 474 end 475 + elseif path.ct == 3 then 476 + var purgestr = co:ppostv("purgestr") 477 + var purgekey = co:ppostv("purgekey") 478 + if purgestr:ref() and purgekey:ref() and purgestr(0) ~= 0 then 479 + if purgestr:cmp(purgekey) then -- destroying account! :O 480 + co.srv:actor_purge_uid(userid) 481 + co:reroute('/conf/users') 482 + return 483 + else msg = 'purge confirmation failed' end 484 + end 485 + 486 + var epithet = co:ppostv("epithet") 487 + var s_rank = co:ppostv("rank") 488 + var s_invites = co:ppostv("invites") 489 + var s_quota = co:ppostv("quota") 490 + var ch_staff = co:ppostv("staff") 491 + var torank: uint16 = usr(0).rights.rank 492 + if ch_staff:ref() and ch_staff:cmp('on') then 493 + if s_rank:ref() then 494 + var rank, rok = lib.math.decparse(s_rank) 495 + if rok and rank <= co.srv.cfg.nranks then 496 + torank = rank 497 + end 498 + elseif usr(0).rights.rank == 0 then 499 + torank = co.who.rights.rank + 1 500 + end 501 + else torank = 0 end 502 + 503 + if co.who.id ~= userid and co.who.rights.rank > 0 then 504 + if (co.who.rights.powers.elevate() and 505 + (torank < usr(0).rights.rank or usr(0).rights.rank == 0) and 506 + (torank > co.who.rights.rank or co.who.rights.rank == 1)) 507 + or (co.who.rights.powers.demote() and 508 + (torank > usr(0).rights.rank or torank == 0)) 509 + then usr(0).rights.rank = torank end 510 + end 511 + 512 + if s_invites:ref() then 513 + var n_invites, n_invites_ok = lib.math.decparse(s_invites) 514 + if n_invites_ok and n_invites ~= usr(0).rights.invites then 515 + if (n_invites > usr(0).rights.invites and 516 + co.who.rights.powers.elevate() and 517 + co.who.rights.powers.invite()) 518 + or (n_invites < usr(0).rights.invites and 519 + co.who.rights.powers.demote()) 520 + then usr(0).rights.invites = n_invites end 521 + end 522 + end 523 + 524 + if (co.who.id ~= userid or co.who.rights.rank == 1) and s_quota:ref() then 525 + var n_quota, n_quota_ok = lib.math.decparse(s_quota) 526 + if n_quota_ok and n_quota ~= usr(0).rights.quota then 527 + if (co.who.rights.powers.elevate() and 528 + ((n_quota == 0 and co.who.rights.quota == 0 or co.who.rights.rank == 1) or 529 + (n_quota ~= 0 and (n_quota > usr(0).rights.quota and 530 + (co.who.rights.quota == 0 or 531 + co.who.rights.quota >= n_quota or 532 + co.who.rights.rank == 1))))) 533 + or (co.who.rights.powers.demote() and n_quota ~= 0 and 534 + (n_quota < usr(0).rights.quota or 535 + co.who.rights.rank == 1)) 536 + then usr(0).rights.quota = n_quota end 537 + end 538 + end 539 + 540 + if co.who.rights.powers.herald() and 541 + (co.who.id ~= userid or 542 + co.srv.cfg.pol_autoherald or 543 + co.who.rights.rank == 1) then 544 + if epithet:ref() and epithet(0) ~= 0 then 545 + usr(0).epithet = epithet.ptr 546 + else 547 + usr(0).epithet = nil 548 + end 549 + end 550 + 551 + if co.who.id ~= userid then 552 + -- update powers 553 + end 554 + co.srv:actor_save(usr.ptr) 555 + if not msg then msg = 'user record updated' end 470 556 end 471 557 end 472 558 elseif path.ct == 2 and meth == method.post then 473 559 var act = co:ppostv('act') 474 - if act:cmp(lib.str.plit'create') then 560 + if act:cmp('create') then 475 561 var newname = co:ppostv('handle') 476 562 if not newname or not lib.store.actor.handle_validate(newname.ptr) then 477 563 co:complain(400,'invalid handle','the handle you have requested is not valid') 478 564 end 479 565 var tu = co.srv:actor_fetch_xid(newname) 480 566 if tu:ref() then tu:free() 481 567 co:complain(409,'handle clash','that handle conflicts with one that already exists') ................................................................................ 486 572 na.handle = newname.ptr 487 573 var newuid = co.srv:actor_create(&na) 488 574 var shid: int8[lib.math.shorthand.maxlen] 489 575 var shidlen = lib.math.shorthand.gen(newuid, &shid[0]) 490 576 var url = lib.str.acc{}:compose('/conf/users/',pstring{&shid[0],shidlen}):finalize() defer url:free() 491 577 co:reroute(url.ptr) 492 578 return 493 - elseif act:cmp(lib.str.plit'inst') then 579 + elseif act:cmp('inst') then 494 580 else goto badop end 495 581 end 496 582 end 497 583 498 584 if user_refresh then -- refresh the user info for the renderer 499 585 var usr = co.srv:actor_fetch_uid(co.who.id) 500 586 lib.mem.heapf(co.who) ................................................................................ 512 598 ::nopriv:: do co:complain(403,'insufficient privileges','you do not have the necessary powers to perform this action') return end 513 599 ::badop:: do co:complain(400,'bad request','the operation you have requested is not meaningful in this context') return end 514 600 end 515 601 516 602 terra http.user_notices(co: &lib.srv.convo, meth: method.t) 517 603 if meth == method.post then 518 604 var act = co:ppostv('act') 519 - if act:cmp(lib.str.plit'clear') then 605 + if act:cmp('clear') then 520 606 co.srv:actor_conf_int_set(co.who.id, 'notice-clear-time', lib.osclock.time(nil)) 521 607 co:reroute('/') 522 608 return 523 609 else goto badop end 524 610 end 525 611 526 612 lib.render.notices(co) ................................................................................ 533 619 if co.aid ~= 0 and co.who.id == uid and path.ct == 2 and path(1):cmp(lib.str.lit'upload') and co.who.rights.powers.artifact() then 534 620 if meth == method.get then 535 621 var view = data.view.media_upload { 536 622 folders = '' 537 623 } 538 624 var pg = view:poolstr(&co.srv.pool) -- defer pg:free() 539 625 co:stdpage([lib.srv.convo.page] { 540 - title = lib.str.plit'media :: upload'; 541 - class = lib.str.plit'media upload'; 626 + title = 'media :: upload'; 627 + class = 'media upload'; 542 628 cache = false; body = pg; 543 629 }) 544 630 elseif meth == method.post_file then 545 631 var desc = pstring.null() 546 632 var folder = pstring.null() 547 633 var mime = pstring.null() 548 634 var name = pstring.null() 549 635 var body = binblob.null() 550 636 for i=0, co.uploads.sz do var up = co.uploads.storage.ptr + i 551 637 if up.body.ct > 0 then 552 - if up.field:cmp(lib.str.plit'desc') then 638 + if up.field:cmp('desc') then 553 639 desc = up.body 554 - elseif up.field:cmp(lib.str.plit'folder') then 640 + elseif up.field:cmp('folder') then 555 641 folder = up.body 556 - elseif up.field:cmp(lib.str.plit'file') then 642 + elseif up.field:cmp('file') then 557 643 mime = up.ctype 558 644 body = binblob {ptr = [&uint8](up.body.ptr), ct = up.body.ct} 559 645 name = up.filename 560 646 end 561 647 end 562 648 end 563 649 if not body then goto badop end ................................................................................ 577 663 578 664 var url = lib.str.acc{}:compose('/media/a/',pstring{&idbuf[0],idlen}):finalize() 579 665 co:reroute(url.ptr) 580 666 url:free() 581 667 else goto badop end 582 668 elseif co.aid ~= 0 and path.ct == 4 and path(1):cmp(lib.str.lit'a') and meth==method.post then 583 669 var act = co:ppostv('act') 584 - if not act or not act:cmp(lib.str.plit'confirm') then goto badop end 670 + if not act or not act:cmp('confirm') then goto badop end 585 671 var artid, aok = lib.math.shorthand.parse(path(2).ptr,path(2).ct) 586 672 if not aok then goto e404 end 587 673 var art = co.srv:artifact_fetch(uid,artid) 588 674 if not art then goto e404 end 589 675 defer art:free() 590 676 591 677 if path(3):cmp(lib.str.lit'avi') then ................................................................................ 691 777 elseif uri.ptr[1] == @'s' and uri.ptr[2] == @'/' and uri.ct > 3 then 692 778 if not meth_get(meth) then goto wrongmeth end 693 779 if not http.static_content(co, uri.ptr + 3, uri.ct - 3) then goto notfound end 694 780 elseif lib.str.ncmp('/avi/', uri.ptr, 5) == 0 then 695 781 http.local_avatar(co, [lib.mem.ptr(int8)] {ptr = uri.ptr + 5, ct = uri.ct - 5}) 696 782 elseif lib.str.ncmp('/file/', uri.ptr, 6) == 0 then 697 783 http.file_serve_raw(co, [lib.mem.ptr(int8)] {ptr = uri.ptr + 6, ct = uri.ct - 6}) 698 - elseif uri:cmp(lib.str.plit '/notices') then 784 + elseif uri:cmp( '/notices') then 699 785 if co.aid == 0 then co:reroute('/login') return end 700 786 http.user_notices(co,meth) 701 - elseif uri:cmp(lib.str.plit '/compose') then 787 + elseif uri:cmp( '/compose') then 702 788 if co.aid == 0 then co:reroute('/login') return end 703 789 http.post_compose(co,meth) 704 - elseif uri:cmp(lib.str.plit '/login') then 790 + elseif uri:cmp( '/login') then 705 791 if co.aid == 0 706 792 then http.login_form(co, meth) 707 793 else co:reroute('/') 708 794 end 709 - elseif uri:cmp(lib.str.plit '/logout') then 795 + elseif uri:cmp( '/logout') then 710 796 if co.aid == 0 711 797 then goto notfound 712 798 else co:reroute_cookie('/','auth=; Path=/') 713 799 end 714 800 else -- hierarchical routes 715 801 var path = lib.http.hier(&co.srv.pool, uri) --defer path:free() 716 802 if path.ct > 1 and path(0):cmp(lib.str.lit('user')) then
Modified srv.t from [854410a8ca] to [baac561cfe].
3 3 local secmode = lib.enum { 'public', 'private', 'lockdown', 'isolate' } 4 4 local pstring = lib.mem.ptr(int8) 5 5 local struct srv 6 6 local struct cfgcache { 7 7 secret: pstring 8 8 pol_sec: secmode.t 9 9 pol_reg: bool 10 + pol_autoherald: bool 10 11 credmgd: bool 11 12 maxupsz: intptr 12 13 poolinitsz: intptr 13 14 instance: pstring 14 15 overlord: &srv 15 16 ui_cue_staff: pstring 16 17 ui_cue_founder: pstring ................................................................................ 324 325 end 325 326 326 327 terra convo:stra(sz: intptr) -- convenience function 327 328 var s: lib.str.acc 328 329 s:pool(&self.srv.pool,sz) 329 330 return s 330 331 end 332 + 333 +convo.methods.qstr = macro(function(self, ...) -- convenience string builder 334 + local exp = {...} 335 + return `lib.str.acc{}:pcompose(&self.srv.pool, [exp]):finalize() 336 +end) 331 337 332 338 convo.methods.assertpow = macro(function(self, pow) 333 339 return quote 334 340 var ok = true 335 341 if self.aid == 0 or self.who.rights.powers.[pow:asvalue()]() == false then 336 342 ok = false 337 343 self:complain(403,'insufficient privileges',['you lack the <strong>'..pow:asvalue()..'</strong> power and cannot perform this action']) ................................................................................ 950 956 end 951 957 952 958 terra cfgcache:load() 953 959 self.instance = self.overlord:conf_get('instance-name') 954 960 self.secret = self.overlord:conf_get('server-secret') 955 961 956 962 self.pol_reg = self:cfbool('policy-self-register', false) 963 + self.pol_autoherald = self:cfbool('policy-self-herald', true) 957 964 958 965 do self.credmgd = false 959 966 var sreg = self.overlord:conf_get('credential-store') 960 967 if sreg:ref() then 961 968 if lib.str.cmp(sreg.ptr, 'managed') == 0 962 969 then self.credmgd = true 963 970 else self.credmgd = false
Modified str.t from [89921fa130] to [c8b5d8bfdc].
32 32 return str 33 33 end 34 34 35 35 36 36 do local strptr = (lib.mem.ptr(int8)) 37 37 local strref = (lib.mem.ref(int8)) 38 38 local byteptr = (lib.mem.ptr(uint8)) 39 - strptr.metamethods.__cast = function(from,to,e) 40 - if from == &int8 then 41 - return `strptr {ptr = e, ct = m.sz(e)} 42 - elseif to == &int8 then 43 - return e.ptr 44 - end 45 - end 46 - 47 - terra strptr:cmp(other: strptr) 48 - if self.ptr == nil and other.ptr == nil then return true end 49 - if self.ptr == nil or other.ptr == nil then return false end 50 - 51 - var sz = lib.math.biggest(self.ct, other.ct) 52 - for i = 0, sz do 53 - if self.ptr[i] == 0 and other.ptr[i] == 0 then return true end 54 - if self.ptr[i] ~= other.ptr[i] then return false end 55 - end 56 - return true 57 - end 58 - terra strref:cmp(other: strref) 59 - if self.ptr == nil and other.ptr == nil then return true end 60 - if self.ptr == nil or other.ptr == nil then return false end 61 - 62 - var sz = lib.math.biggest(self.ct, other.ct) 63 - for i = 0, sz do 64 - if self.ptr[i] == 0 and other.ptr[i] == 0 then return true end 65 - if self.ptr[i] ~= other.ptr[i] then return false end 66 - end 67 - return true 68 - end 69 - terra strptr:ffw() 70 - var newp = m.ffw(self.ptr,self.ct) 71 - var newct = self.ct - (newp - self.ptr) 72 - return strptr { ptr = newp, ct = newct } 73 - end 74 - strptr.methods.cmpl = macro(function(self,other) 75 - return `self:cmp(strptr { ptr = [other:asvalue()], ct = [#(other:asvalue())] }) 76 - end) 77 - strref.methods.cmpl = macro(function(self,other) 78 - return `self:cmp(strref { ptr = [other:asvalue()], ct = [#(other:asvalue())] }) 79 - end) 39 + local function install_funcs(ty) 40 + ty.metamethods.__cast = function(from,to,e) 41 + local v = e:asvalue() 42 + if type(v) == 'string' then 43 + print('hard-coding pstr',v,#v) 44 + return `ty {ptr = v, ct = [#v]} 45 + elseif from == &int8 then 46 + return `ty {ptr = e, ct = m.sz(e)} 47 + elseif to == &int8 then 48 + return e.ptr 49 + end 50 + end 51 + terra ty:cmp(other: ty) 52 + if self.ptr == nil and other.ptr == nil then return true end 53 + if self.ptr == nil or other.ptr == nil then return false end 54 + 55 + var sz = lib.math.biggest(self.ct, other.ct) 56 + for i = 0, sz do 57 + if self.ptr[i] == 0 and other.ptr[i] == 0 then return true end 58 + if self.ptr[i] ~= other.ptr[i] then return false end 59 + end 60 + return true 61 + end 62 + terra ty:ffw() 63 + var newp = m.ffw(self.ptr,self.ct) 64 + var newct = self.ct - (newp - self.ptr) 65 + return ty { ptr = newp, ct = newct } 66 + end 67 + end 68 + install_funcs(strptr) 69 + install_funcs(strref) 70 + 71 + --strptr.methods.cmpl = macro(function(self,other) 72 + -- return `self:cmp(strptr { ptr = [other:asvalue()], ct = [#(other:asvalue())] }) 73 + --end) 74 + --strref.methods.cmpl = macro(function(self,other) 75 + -- return `self:cmp(strref { ptr = [other:asvalue()], ct = [#(other:asvalue())] }) 76 + --end) 80 77 81 78 terra byteptr:cmp(other: byteptr) 82 79 var sz = lib.math.biggest(self.ct, other.ct) 83 80 for i = 0, sz do 84 81 if self.ptr[i] == 0 and other.ptr[i] == 0 then return true end 85 82 if self.ptr[i] ~= other.ptr[i] then return false end 86 83 end