Differences From
Artifact [1740166796]:
58 58 where $1::text = (a.handle || '@' || domain) or
59 59 $1::text = ('@' || a.handle || '@' || domain) or
60 60 (a.origin is null and
61 61 $1::text = a.handle or
62 62 $1::text = ('@' || a.handle))
63 63 ]];
64 64 };
65 +
66 + actor_create = {
67 + params = {
68 + rawstring, rawstring, uint64, lib.store.timepoint,
69 + rawstring, rawstring, lib.mem.ptr(uint8),
70 + rawstring, uint16, uint32
71 + };
72 + sql = [[
73 + insert into parsav_actors (
74 + nym,handle,
75 + origin,knownsince,
76 + bio,avataruri,key,
77 + title,rank,quota
78 + ) values ($1::text, $2::text,
79 + case when $3::bigint = 0 then null
80 + else $3::bigint end,
81 + to_timestamp($4::bigint),
82 + $5::bigint, $6::bigint, $7::bytea,
83 + $8::text, $9::smallint, $10::integer
84 + ) returning id
85 + ]];
86 + };
87 +
65 88
66 89 actor_auth_pw = {
67 90 params = {pstring,rawstring,pstring,lib.store.inet}, sql = [[
68 - select a.aid from parsav_auth as a
91 + select a.aid, a.uid, a.name from parsav_auth as a
69 92 left join parsav_actors as u on u.id = a.uid
70 93 where (a.uid is null or u.handle = $1::text or (
71 94 a.uid = 0 and a.name = $1::text
72 95 )) and
73 96 (a.kind = 'trust' or (a.kind = $2::text and a.cred = $3::bytea)) and
74 97 (a.netmask is null or a.netmask >> $4::inet)
75 98 order by blacklist desc limit 1
................................................................................
161 184 left join parsav_actors a on au.uid = a.id
162 185 left join parsav_servers s on a.origin = s.id
163 186
164 187 where au.aid = $1::bigint and au.blacklist = false and
165 188 (au.netmask is null or au.netmask >> $2::inet)
166 189 ]];
167 190 };
191 +
192 + actor_powers_fetch = {
193 + params = {uint64}, sql = [[
194 + select key, allow from parsav_rights where actor = $1::bigint
195 + ]]
196 + };
168 197
169 198 post_create = {
170 199 params = {uint64, rawstring, rawstring, rawstring}, sql = [[
171 200 insert into parsav_posts (
172 201 author, subject, acl, body,
173 202 posted, discovered,
174 203 circles, mentions
................................................................................
213 242 terra pqr:len(row: intptr, col: intptr)
214 243 return lib.pq.PQgetlength(self.res, row, col)
215 244 end
216 245 terra pqr:cols() return lib.pq.PQnfields(self.res) end
217 246 terra pqr:string(row: intptr, col: intptr) -- not to be exported!!
218 247 if self:null(row,col) then return nil end
219 248 var v = lib.pq.PQgetvalue(self.res, row, col)
220 --- var r: lib.mem.ptr(int8)
221 --- r.ct = lib.str.sz(v)
222 --- r.ptr = v
223 249 return v
250 +end
251 +terra pqr:_string(row: intptr, col: intptr) -- not to be exported!!
252 + if self:null(row,col) then return pstring.null() end
253 + return pstring {
254 + ptr = lib.pq.PQgetvalue (self.res, row, col);
255 + ct = lib.pq.PQgetlength(self.res, row, col);
256 + }
224 257 end
225 258 terra pqr:bin(row: intptr, col: intptr) -- not to be exported!! DO NOT FREE
259 + if self:null(row,col) then return [lib.mem.ptr(uint8)].null() end
226 260 return [lib.mem.ptr(uint8)] {
227 261 ptr = [&uint8](lib.pq.PQgetvalue(self.res, row, col));
228 262 ct = lib.pq.PQgetlength(self.res, row, col);
229 263 }
230 264 end
231 265 terra pqr:String(row: intptr, col: intptr) -- suitable to be exported
232 - if self:null(row,col) then return [lib.mem.ptr(int8)] {ptr=nil,ct=0} end
233 - var s = [lib.mem.ptr(int8)] { ptr = lib.str.dup(self:string(row,col)) }
234 - s.ct = lib.pq.PQgetlength(self.res, row, col)
266 + if self:null(row,col) then return pstring.null() end
267 + var s = pstring {
268 + ptr = lib.str.dup(self:string(row,col));
269 + ct = lib.pq.PQgetlength(self.res, row, col);
270 + }
235 271 return s
236 272 end
237 273 terra pqr:bool(row: intptr, col: intptr)
238 274 var v = lib.pq.PQgetvalue(self.res, row, col)
239 275 if @v == 0x01 then return true else return false end
240 276 end
241 277 terra pqr:cidr(row: intptr, col: intptr)
................................................................................
421 457 else
422 458 a.ptr.key = r:bin(row,8)
423 459 end
424 460 if r:null(row,3) then a.ptr.origin = 0
425 461 else a.ptr.origin = r:int(uint64,row,3) end
426 462 return a
427 463 end
464 +
465 +local privmap = {}
466 +do local struct pt { name:pstring, priv:lib.store.powerset }
467 +for k,v in pairs(lib.store.powerset.members) do
468 + privmap[#privmap + 1] = quote
469 + var ps: lib.store.powerset ps:clear()
470 + (ps.[v] << true)
471 + in pt {name = lib.str.plit(v), priv = ps} end
472 +end end
428 473
429 474 local checksha = function(src, hash, origin, username, pw)
430 475 local validate = function(kind, cred, credlen)
431 476 return quote
432 477 var r = queries.actor_auth_pw.exec(
433 478 [&lib.store.source](src),
434 479 username,
435 480 kind,
436 481 [lib.mem.ptr(int8)] {ptr=[&int8](cred), ct=credlen},
437 482 origin)
438 483 if r.sz > 0 then -- found a record! stop here
439 484 var aid = r:int(uint64, 0,0)
485 + var uid = r:int(uint64, 0,1)
486 + var name = r:String(0,2)
440 487 r:free()
441 - return aid
488 + return aid, uid, name
442 489 end
443 490 end
444 491 end
445 492
446 493 local out = symbol(uint8[64])
447 494 local vdrs = {}
448 495
................................................................................
567 614 end];
568 615
569 616 actor_auth_pw = [terra(
570 617 src: &lib.store.source,
571 618 ip: lib.store.inet,
572 619 username: lib.mem.ptr(int8),
573 620 cred: lib.mem.ptr(int8)
574 - ): uint64
621 + ): {uint64, uint64, pstring}
575 622
576 623 [ checksha(`src, 256, ip, username, cred) ] -- most common
577 624 [ checksha(`src, 512, ip, username, cred) ] -- most secure
578 625 [ checksha(`src, 384, ip, username, cred) ] -- weird
579 626 [ checksha(`src, 224, ip, username, cred) ] -- weirdest
580 627
581 628 -- TODO: check pbkdf2-hmac
582 629 -- TODO: check OTP
583 - return 0
630 + return 0, 0, pstring.null()
584 631 end];
585 632
586 633 actor_stats = [terra(src: &lib.store.source, uid: uint64)
587 634 var r = queries.actor_stats.exec(src, uid)
588 635 if r.sz == 0 then lib.bail('error fetching actor stats!') end
589 636 var s: lib.store.actor_stats
590 637 s.posts = r:int(uint64, 0, 0)
................................................................................
652 699 end
653 700
654 701 var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz)
655 702 for i=0,r.sz do ret.ptr[i] = row_to_post(&r, i) end -- MUST FREE ALL
656 703
657 704 return ret
658 705 end];
706 +
707 + actor_powers_fetch = [terra(
708 + src: &lib.store.source,
709 + uid: uint64
710 + ): lib.store.powerset
711 + var powers = lib.store.rights_default().powers
712 + var map = array([privmap])
713 + var r = queries.actor_powers_fetch.exec(src, uid)
714 +
715 + for i=0, r.sz do
716 + for j=0, [map.type.N] do
717 + var pn = r:_string(i,0)
718 + if map[j].name:cmp(pn) then
719 + if r:bool(i,1)
720 + then powers = powers + map[j].priv
721 + else powers = powers - map[j].priv
722 + end
723 + end
724 + end
725 + end
726 +
727 + return powers
728 + end];
729 +
730 + actor_create = [terra(
731 + src: &lib.store.source,
732 + ac: &lib.store.actor
733 + ): uint64
734 + var r = queries.actor_create.exec(src,ac.nym, ac.handle, ac.origin, ac.knownsince, ac.bio, ac.avatar, ac.key, ac.title, ac.rights.rank, ac.rights.quota)
735 + if r.sz == 0 then lib.bail('failed to create actor!') end
736 + return r:int(uint64,0,0)
737 + end];
738 +
739 + actor_auth_register_uid = nil; -- not necessary for view-based auth
659 740 }
660 741
661 742 return b