Differences From
Artifact [0fdc39456b]:
81 81 to_timestamp($4::bigint),
82 82 $5::bigint, $6::bigint, $7::bytea,
83 83 $8::text, $9::smallint, $10::integer
84 84 ) returning id
85 85 ]];
86 86 };
87 87
88 -
89 88 actor_auth_pw = {
90 89 params = {pstring,rawstring,pstring,lib.store.inet}, sql = [[
91 90 select a.aid, a.uid, a.name from parsav_auth as a
92 91 left join parsav_actors as u on u.id = a.uid
93 92 where (a.uid is null or u.handle = $1::text or (
94 93 a.uid = 0 and a.name = $1::text
95 94 )) and
................................................................................
198 197 actor_power_insert = {
199 198 params = {uint64,lib.mem.ptr(int8),uint16}, cmd = true, sql = [[
200 199 insert into parsav_rights (actor, key, allow) values (
201 200 $1::bigint, $2::text, ($3::smallint)::integer::bool
202 201 )
203 202 ]]
204 203 };
204 +
205 + actor_power_delete = {
206 + params = {uint64,lib.mem.ptr(int8)}, cmd = true, sql = [[
207 + delete from parsav_rights where
208 + actor = $1::bigint and
209 + key = $2::text
210 + ]]
211 + };
205 212
206 213 auth_create_pw = {
207 214 params = {uint64, lib.mem.ptr(uint8)}, cmd = true, sql = [[
208 215 insert into parsav_auth (uid, name, kind, cred) values (
209 216 $1::bigint,
210 217 (select handle from parsav_actors where id = $1::bigint),
211 218 'pw-sha256', $2::bytea
................................................................................
518 525 a.ptr.key = r:bin(row,8)
519 526 end
520 527 if r:null(row,3) then a.ptr.origin = 0
521 528 else a.ptr.origin = r:int(uint64,row,3) end
522 529 return a
523 530 end
524 531
525 -local privmap = {}
526 -do local struct pt { name:pstring, priv:lib.store.powerset }
527 -for k,v in pairs(lib.store.powerset.members) do
528 - privmap[#privmap + 1] = quote
529 - var ps: lib.store.powerset ps:clear()
530 - (ps.[v] << true)
531 - in pt {name = lib.str.plit(v), priv = ps} end
532 -end end
532 +local privmap = lib.store.privmap
533 533
534 534 local checksha = function(src, hash, origin, username, pw)
535 535 local validate = function(kind, cred, credlen)
536 536 return quote
537 537 var r = queries.actor_auth_pw.exec(
538 538 [&lib.store.source](src),
539 539 username,
................................................................................
568 568 [vdrs]
569 569 lib.dbg(['could not find password hash'])
570 570 end
571 571 end
572 572
573 573 local schema = sqlsquash(lib.util.ingest('backend/schema/pgsql.sql'))
574 574 local obliterator = sqlsquash(lib.util.ingest('backend/schema/pgsql-drop.sql'))
575 +
576 +local privupdate = terra(
577 + src: &lib.store.source,
578 + ac: &lib.store.actor
579 +): {}
580 + var pdef = lib.store.rights_default().powers
581 + var map = array([privmap])
582 + for i=0, [map.type.N] do
583 + var d = pdef and map[i].priv
584 + var u = ac.rights.powers and map[i].priv
585 + queries.actor_power_delete.exec(src, ac.id, map[i].name)
586 + if d:sz() > 0 and u:sz() == 0 then
587 + lib.dbg('blocking power ', {map[i].name.ptr, map[i].name.ct})
588 + queries.actor_power_insert.exec(src, ac.id, map[i].name, 0)
589 + elseif d:sz() == 0 and u:sz() > 0 then
590 + lib.dbg('granting power ', {map[i].name.ptr, map[i].name.ct})
591 + queries.actor_power_insert.exec(src, ac.id, map[i].name, 1)
592 + end
593 + end
594 +end
595 +
596 +local getpow = terra(
597 + src: &lib.store.source,
598 + uid: uint64
599 +): lib.store.powerset
600 + var powers = lib.store.rights_default().powers
601 + var map = array([privmap])
602 + var r = queries.actor_powers_fetch.exec(src, uid)
603 +
604 + for i=0, r.sz do
605 + for j=0, [map.type.N] do
606 + var pn = r:_string(i,0)
607 + if map[j].name:cmp(pn) then
608 + if r:bool(i,1)
609 + then powers = powers + map[j].priv
610 + else powers = powers - map[j].priv
611 + end
612 + end
613 + end
614 + end
615 +
616 + return powers
617 +end
575 618
576 619 local b = `lib.store.backend {
577 620 id = "pgsql";
578 621 open = [terra(src: &lib.store.source): &opaque
579 622 lib.report('connecting to postgres database: ', src.string.ptr)
580 623 var [con] = lib.pq.PQconnectdb(src.string.ptr)
581 624 if lib.pq.PQstatus(con) ~= lib.pq.CONNECTION_OK then
................................................................................
653 696
654 697 actor_fetch_uid = [terra(src: &lib.store.source, uid: uint64)
655 698 var r = queries.actor_fetch_uid.exec(src, uid)
656 699 if r.sz == 0 then
657 700 return [lib.mem.ptr(lib.store.actor)] { ct = 0, ptr = nil }
658 701 else defer r:free()
659 702 var a = row_to_actor(&r, 0)
703 + a.ptr.rights.powers = getpow(src, uid)
660 704 a.ptr.source = src
661 705 return a
662 706 end
663 707 end];
664 708
665 709 actor_fetch_xid = [terra(src: &lib.store.source, xid: lib.mem.ptr(int8))
666 710 var r = queries.actor_fetch_xid.exec(src, xid)
667 711 if r.sz == 0 then
668 712 return [lib.mem.ptr(lib.store.actor)] { ct = 0, ptr = nil }
669 713 else defer r:free()
670 714 var a = row_to_actor(&r, 0)
715 + a.ptr.rights.powers = getpow(src, a.ptr.id)
671 716 a.ptr.source = src
672 717 return a
673 718 end
674 719 end];
675 720
676 721 actor_enum = [terra(src: &lib.store.source)
677 722 var r = queries.actor_enum.exec(src)
................................................................................
806 851
807 852 var ret: lib.mem.ptr(lib.mem.ptr(lib.store.post)) ret:init(r.sz)
808 853 for i=0,r.sz do ret.ptr[i] = row_to_post(&r, i) end -- MUST FREE ALL
809 854
810 855 return ret
811 856 end];
812 857
813 - actor_powers_fetch = [terra(
814 - src: &lib.store.source,
815 - uid: uint64
816 - ): lib.store.powerset
817 - var powers = lib.store.rights_default().powers
818 - var map = array([privmap])
819 - var r = queries.actor_powers_fetch.exec(src, uid)
820 -
821 - for i=0, r.sz do
822 - for j=0, [map.type.N] do
823 - var pn = r:_string(i,0)
824 - if map[j].name:cmp(pn) then
825 - if r:bool(i,1)
826 - then powers = powers + map[j].priv
827 - else powers = powers - map[j].priv
828 - end
829 - end
830 - end
831 - end
832 -
833 - return powers
834 - end];
858 + actor_powers_fetch = getpow;
859 + actor_save_privs = privupdate;
835 860
836 861 actor_create = [terra(
837 862 src: &lib.store.source,
838 863 ac: &lib.store.actor
839 864 ): uint64
840 865 var r = queries.actor_create.exec(src,ac.nym, ac.handle, ac.origin, ac.knownsince, ac.bio, ac.avatar, ac.key, ac.epithet, ac.rights.rank, ac.rights.quota)
841 866 if r.sz == 0 then lib.bail('failed to create actor!') end
842 - var uid = r:int(uint64,0,0)
867 + ac.id = r:int(uint64,0,0)
843 868
844 869 -- check against default rights, insert records for wherever powers differ
845 870 lib.dbg('created new actor, establishing powers')
846 - var pdef = lib.store.rights_default().powers
847 - var map = array([privmap])
848 - for i=0, [map.type.N] do
849 - var d = pdef and map[i].priv
850 - var u = ac.rights.powers and map[i].priv
851 - if d:sz() > 0 and u:sz() == 0 then
852 - lib.dbg('blocking power ', {map[i].name.ptr, map[i].name.ct})
853 - queries.actor_power_insert.exec(src, uid, map[i].name, 0)
854 - elseif d:sz() == 0 and u:sz() > 0 then
855 - lib.dbg('granting power ', {map[i].name.ptr, map[i].name.ct})
856 - queries.actor_power_insert.exec(src, uid, map[i].name, 1)
857 - end
858 - end
871 + privupdate(src,ac)
859 872
860 873 lib.dbg('powers established')
861 - return uid
874 + return ac.id
862 875 end];
863 876
864 877 auth_create_pw = [terra(
865 878 src: &lib.store.source,
866 879 uid: uint64,
867 880 reset: bool,
868 881 pw: lib.mem.ptr(int8)