parsav  Diff

Differences From Artifact [9c53eed84d]:

To Artifact [175b022aff]:


   187    187   			select (pg_temp.parsavpg_translate_actor(a)).*,
   188    188   
   189    189   			       au.restrict,
   190    190   						array['post'    ] <@ au.restrict,
   191    191   						array['edit'    ] <@ au.restrict,
   192    192   						array['account' ] <@ au.restrict,
   193    193   						array['upload'  ] <@ au.restrict,
          194  +						array['artifact'] <@ au.restrict,
   194    195   						array['moderate'] <@ au.restrict,
   195         -						array['admin'   ] <@ au.restrict
          196  +						array['admin'   ] <@ au.restrict,
          197  +						array['invite'  ] <@ au.restrict
   196    198   
   197    199   			from      parsav_auth au
   198    200   			left join parsav_actors a     on au.uid = a.id
   199    201   
   200    202   			where au.aid = $1::bigint and au.blacklist = false and
   201    203   				(au.netmask is null or au.netmask >> $2::inet) and
   202    204   				($3::bigint = 0 or --slightly abusing the epoch time fmt here, but
................................................................................
   271    273   			update parsav_actors set
   272    274   				authtime = $2::bigint
   273    275   				where id = $1::bigint
   274    276   		]];
   275    277   	};
   276    278   
   277    279   	auth_create_pw = {
   278         -		params = {uint64, binblob, int64, pstring}, cmd = true, sql = [[
          280  +		params = {uint64, binblob, int64, pstring}, sql = [[
   279    281   			insert into parsav_auth (uid, name, kind, cred, valperiod, comment) values (
   280    282   				$1::bigint,
   281    283   				(select handle from parsav_actors where id = $1::bigint),
   282    284   				'pw-sha256', $2::bytea,
   283    285   				$3::bigint, $4::text
   284         -			)
          286  +			) on conflict (name,kind,cred) do update set comment = $4::text returning aid
   285    287   		]]
   286    288   	};
          289  +
          290  +	auth_privs_clear = {
          291  +		params = {uint64}, cmd = true, sql = [[
          292  +			update parsav_auth set restrict = array[]::text[] where aid = $1::bigint
          293  +		]];
          294  +	};
          295  +
          296  +	auth_priv_install = {
          297  +		params = {uint64,pstring}, cmd = true, sql = [[
          298  +			update parsav_auth set restrict = restrict || $2::text where aid = $1::bigint
          299  +		]];
          300  +	};
   287    301   
   288    302   	auth_purge_type = {
   289    303   		params = {rawstring, uint64, rawstring}, cmd = true, sql = [[
   290    304   			delete from parsav_auth where
   291    305   				((uid = 0 and name = $1::text) or uid = $2::bigint) and
   292    306   				kind like $3::text
   293    307   		]]
   294    308   	};
          309  +
          310  +	auth_purge_aid = {
          311  +		params = {uint64}, cmd = true, sql = [[
          312  +			delete from parsav_auth where aid = $1::bigint
          313  +		]]
          314  +	};
   295    315   
   296    316   	auth_enum_uid = {
   297    317   		params = {uint64}, sql = [[
   298    318   			select aid, kind, comment, netmask, blacklist from parsav_auth where uid = $1::bigint
   299    319   		]];
   300    320   	};
   301    321   
................................................................................
   401    421   		params = {uint64, uint64, pstring}, cmd = true, sql = [[
   402    422   			delete from parsav_acts where
   403    423   				actor = $1::bigint and
   404    424   				subject = $2::bigint and
   405    425   				kind = $3::text
   406    426   		]];
   407    427   	};
          428  +
          429  +	post_react_delete = {
          430  +		params = {uint64}, cmd = true, sql = [[
          431  +			delete from parsav_acts where id = $1::bigint
          432  +		]];
          433  +	};
   408    434   
   409    435   	post_reacts_fetch_uid = {
   410    436   		params = {uint64, uint64, pstring}, sql = [[
   411    437   			select id, actor, subject, kind, body, time from parsav_acts where
   412    438   				($1::bigint = 0 or actor   = $1::bigint) and
   413    439   				($2::bigint = 0 or subject = $2::bigint) and
   414    440   				($3::text is null or kind  = $3::text  )
   415         -		]]
          441  +		]];
          442  +	};
          443  +
          444  +	post_act_fetch_notice = {
          445  +		params = {uint64}, sql = [[
          446  +			select (pg_temp.parsavpg_translate_act(a)).*
          447  +			from parsav_acts as a
          448  +				where id = $1::bigint
          449  +		]];
   416    450   	};
   417    451   
   418    452   	post_enum_author_uid = {
   419    453   		params = {uint64,uint64,uint64,uint64, uint64}, sql = [[
   420    454   			select (c.post).*
   421    455   			from pg_temp.parsavpg_known_content as c
   422    456   
................................................................................
   964    998   		a.ptr.key = r:bin(row,8)
   965    999   	end
   966   1000   	a.ptr.origin = origin
   967   1001   	if avia.buf ~= nil then avia:free() end
   968   1002   	return a
   969   1003   end
   970   1004   
   971         -local privmap = lib.store.privmap
         1005  +local privmap = lib.store.powmap
   972   1006   
   973   1007   local checksha = function(src, hash, origin, username, pw)
   974   1008   	local validate = function(kind, cred, credlen)
   975   1009   		return quote 
   976   1010   			var r = queries.actor_auth_pw.exec(
   977   1011   				[&lib.store.source](src),
   978   1012   				username,
................................................................................
  1015   1049   local privupdate = terra(
  1016   1050   	src: &lib.store.source,
  1017   1051   	ac: &lib.store.actor
  1018   1052   ): {}
  1019   1053   	var pdef: lib.store.powerset pdef:clear()
  1020   1054   	var map = array([privmap])
  1021   1055   	for i=0, [map.type.N] do
  1022         -		var d = pdef and map[i].priv
  1023         -		var u = ac.rights.powers and map[i].priv
         1056  +		var d = pdef and map[i].val
         1057  +		var u = ac.rights.powers and map[i].val
  1024   1058   		queries.actor_power_delete.exec(src, ac.id, map[i].name)
  1025   1059   		if d:sz() > 0 and u:sz() == 0 then
  1026   1060   			lib.dbg('blocking power ', {map[i].name.ptr, map[i].name.ct})
  1027   1061   			queries.actor_power_insert.exec(src, ac.id, map[i].name, 0)
  1028   1062   		elseif d:sz() == 0 and u:sz() > 0 then
  1029   1063   			lib.dbg('granting power ', {map[i].name.ptr, map[i].name.ct})
  1030   1064   			queries.actor_power_insert.exec(src, ac.id, map[i].name, 1)
................................................................................
  1041   1075   	var r = queries.actor_powers_fetch.exec(src, uid)
  1042   1076   
  1043   1077   	for i=0, r.sz do
  1044   1078   		for j=0, [map.type.N] do
  1045   1079   			var pn = r:_string(i,0)
  1046   1080   			if map[j].name:cmp(pn) then
  1047   1081   				if r:bool(i,1)
  1048         -					then powers = powers + map[j].priv
  1049         -					else powers = powers - map[j].priv
         1082  +					then powers = powers + map[j].val
         1083  +					else powers = powers - map[j].val
  1050   1084   				end
  1051   1085   			end
  1052   1086   		end
  1053   1087   	end
  1054   1088   
  1055   1089   	return powers
  1056   1090   end
................................................................................
  1268   1302   
  1269   1303   			var a = row_to_actor(&r, 0)
  1270   1304   			a.ptr.source = src
  1271   1305   
  1272   1306   			var au = [lib.stat(lib.store.auth)] { ok = true }
  1273   1307   			au.val.aid = aid
  1274   1308   			au.val.uid = a.ptr.id
  1275         -			if not r:null(0,13) then -- restricted?
         1309  +			if not r:null(0,14) then -- restricted?
  1276   1310   				au.val.privs:clear()
  1277         -				(au.val.privs.post    << r:bool(0,14)) 
  1278         -				(au.val.privs.edit    << r:bool(0,15))
  1279         -				(au.val.privs.account << r:bool(0,16))
  1280         -				(au.val.privs.upload  << r:bool(0,17))
  1281         -				(au.val.privs.moderate<< r:bool(0,18))
  1282         -				(au.val.privs.admin   << r:bool(0,19))
         1311  +				(au.val.privs.post    << r:bool(0,15)) 
         1312  +				(au.val.privs.edit    << r:bool(0,16))
         1313  +				(au.val.privs.account << r:bool(0,17))
         1314  +				(au.val.privs.upload  << r:bool(0,18))
         1315  +				(au.val.privs.artifact<< r:bool(0,19))
         1316  +				(au.val.privs.moderate<< r:bool(0,20))
         1317  +				(au.val.privs.admin   << r:bool(0,21))
         1318  +				(au.val.privs.invite  << r:bool(0,22))
  1283   1319   			else au.val.privs:fill() end
  1284   1320   
  1285   1321   			return au, a
  1286   1322   		end
  1287   1323   
  1288   1324   		::fail:: return [lib.stat   (lib.store.auth) ] { ok = false        },
  1289   1325   			            [lib.mem.ptr(lib.store.actor)] { ptr = nil, ct = 0 }
................................................................................
  1321   1357   		var r = queries.post_fetch.exec(src, post)
  1322   1358   		if r.sz == 0 then return [lib.mem.ptr(lib.store.post)].null() end
  1323   1359   		var p = row_to_post(&r, 0)
  1324   1360   		p.ptr.source = src
  1325   1361   		return p
  1326   1362   	end];
  1327   1363   
         1364  +	post_act_cancel = [terra(
         1365  +		src: &lib.store.source,
         1366  +		act: uint64
         1367  +	): {} queries.post_react_delete.exec(src, act) end];
         1368  +
  1328   1369   	post_retweet = [terra(
  1329   1370   		src: &lib.store.source,
  1330   1371   		uid: uint64,
  1331   1372   		post: uint64,
  1332   1373   		undo: bool
  1333   1374   	): {}
  1334         -		var time = lib.osclock.time(nil)
  1335   1375   		if not undo then
         1376  +			var time = lib.osclock.time(nil)
  1336   1377   			queries.post_react_simple.exec(src,uid,post,"rt",time)
  1337   1378   		else
  1338   1379   			queries.post_react_cancel.exec(src,uid,post,"rt")
  1339   1380   		end
  1340   1381   	end];
  1341   1382   	post_like = [terra(
  1342   1383   		src: &lib.store.source,
................................................................................
  1528   1569   
  1529   1570   	auth_attach_pw = [terra(
  1530   1571   		src: &lib.store.source,
  1531   1572   		uid: uint64,
  1532   1573   		reset: bool,
  1533   1574   		pw: pstring,
  1534   1575   		comment: pstring
  1535         -	): {}
         1576  +	): uint64
  1536   1577   		var hash: uint8[lib.crypt.algsz.sha256]
  1537   1578   		if lib.md.mbedtls_md(lib.md.mbedtls_md_info_from_type(lib.crypt.alg.sha256.id),
  1538   1579   			[&uint8](pw.ptr), pw.ct, &hash[0]) ~= 0 then
  1539   1580   			lib.bail('cannot hash password')
  1540   1581   		end
  1541   1582   		if reset then queries.auth_purge_type.exec(src, nil, uid, 'pw-%') end
  1542         -		queries.auth_create_pw.exec(src, uid, binblob {ptr = &hash[0], ct = [hash.type.N]}, lib.osclock.time(nil), comment)
         1583  +		var r = queries.auth_create_pw.exec(src, uid, binblob {ptr = &hash[0], ct = [hash.type.N]}, lib.osclock.time(nil), comment)
         1584  +		if r.sz == 0 then return 0 end
         1585  +		var aid = r:int(uint64,0,0)
         1586  +		r:free()
         1587  +		return aid
         1588  +	end];
         1589  +
         1590  +	auth_privs_set = [terra(
         1591  +		src: &lib.store.source,
         1592  +		aid: uint64,
         1593  +		set: lib.store.privset
         1594  +	): {}
         1595  +		var map = array([lib.store.privmap])
         1596  +		queries.auth_privs_clear.exec(src,aid)
         1597  +		if set:sz() == 0 then return end
         1598  +		for i=0, [map.type.N] do
         1599  +			if (set and map[i].val):sz() > 0 then
         1600  +				queries.auth_priv_install.exec(src,aid,map[i].name)
         1601  +			end
         1602  +		end
  1543   1603   	end];
  1544   1604   
  1545   1605   	auth_purge_pw = [terra(src: &lib.store.source, uid: uint64, handle: rawstring): {}
  1546   1606   		queries.auth_purge_type.exec(src, handle, uid, 'pw-%')
  1547   1607   	end];
  1548   1608   
  1549   1609   	auth_purge_otp = [terra(src: &lib.store.source, uid: uint64, handle: rawstring): {}
................................................................................
  1699   1759   			post.id, post.chgcount, post.edited,
  1700   1760   			post.subject, post.acl, post.body)
  1701   1761   	end];
  1702   1762   
  1703   1763   	post_enum_parent = [terra(
  1704   1764   		src: &lib.store.source,
  1705   1765   		post: uint64
  1706         -	): lib.mem.ptr(lib.mem.ptr(lib.store.post))
         1766  +	): lib.mem.lstptr(lib.store.post)
  1707   1767   		var r = queries.post_enum_parent.exec(src,post)
  1708   1768   		if r.sz == 0 then
  1709   1769   			return [lib.mem.ptr(lib.mem.ptr(lib.store.post))].null()
  1710   1770   		end
  1711   1771   		defer r:free()
  1712   1772   		var lst = lib.mem.heapa([lib.mem.ptr(lib.store.post)], r.sz)
  1713   1773   
  1714   1774   		for i=0, r.sz do lst.ptr[i] = row_to_post(&r, i) end
  1715   1775   
  1716   1776   		return lst
  1717   1777   	end];
         1778  +
         1779  +	post_act_fetch_notice = [terra(
         1780  +		src: &lib.store.source,
         1781  +		act: uint64
         1782  +	): lib.store.notice
         1783  +		var r = queries.post_act_fetch_notice.exec(src,act)
         1784  +		if r.sz == 0 then return lib.store.notice { kind = lib.store.noticetype.none } end
         1785  +		defer r:free()
         1786  +		
         1787  +		var n: lib.store.notice
         1788  +		n.kind = r:int(uint16,0,0)
         1789  +		n.when = r:int(int64,0,1)
         1790  +		n.who = r:int(int64,0,2)
         1791  +		n.what = r:int(uint64,0,3)
         1792  +		if n.kind == lib.store.noticetype.react then
         1793  +			var react = r:_string(0,5)
         1794  +			lib.str.ncpy(n.reaction, react.ptr, lib.math.smallest(react.ct,[(`n.reaction).tree.type.N]))
         1795  +		end
         1796  +
         1797  +		return n
         1798  +	end];
  1718   1799   
  1719   1800   	thread_latest_arrival_calc = [terra(
  1720   1801   		src: &lib.store.source,
  1721   1802   		post: uint64
  1722   1803   	): lib.store.timepoint
  1723   1804   		var r = queries.thread_latest_arrival_calc.exec(src,post)
  1724   1805   		if r.sz == 0 or r:null(0,0) then return 0 end