parsav  Diff

Differences From Artifact [30375d8380]:

To Artifact [962a3e64e0]:


    26     26   
    27     27   	actor_fetch_uid = {
    28     28   		params = {uint64}, sql = [[
    29     29   			select a.id, a.nym, a.handle, a.origin, a.bio,
    30     30   			       a.avataruri, a.rank, a.quota, a.key, a.epithet,
    31     31   			       extract(epoch from a.knownsince)::bigint,
    32     32   				   coalesce(a.handle || '@' || s.domain,
    33         -				            '@' || a.handle) as xid
           33  +				            '@' || a.handle) as xid,
           34  +			       a.invites
    34     35   
    35     36   			from      parsav_actors  as a
    36     37   			left join parsav_servers as s
    37     38   				on a.origin = s.id
    38     39   			where a.id = $1::bigint
    39     40   		]];
    40     41   	};
................................................................................
    42     43   	actor_fetch_xid = {
    43     44   		params = {pstring}, sql = [[
    44     45   			select a.id, a.nym, a.handle, a.origin, a.bio,
    45     46   			       a.avataruri, a.rank, a.quota, a.key, a.epithet,
    46     47   			       extract(epoch from a.knownsince)::bigint,
    47     48   				   coalesce(a.handle || '@' || s.domain,
    48     49   				            '@' || a.handle) as xid,
           50  +			       a.invites,
    49     51   
    50     52   				coalesce(s.domain,
    51     53   				        (select value from parsav_config
    52     54   							where key='domain' limit 1)) as domain
    53     55   
    54     56   			from      parsav_actors  as a
    55     57   			left join parsav_servers as s
................................................................................
    58     60   			where $1::text = (a.handle || '@' || domain) or
    59     61   			      $1::text = ('@' || a.handle || '@' || domain) or
    60     62   				  (a.origin is null and
    61     63   					  $1::text = a.handle or
    62     64   					  $1::text = ('@' || a.handle))
    63     65   		]];
    64     66   	};
           67  +
           68  +	actor_purge_uid = {
           69  +		params = {uint64}, cmd = true, sql = [[
           70  +			with d as ( -- cheating
           71  +				delete from parsav_sanctions where victim = $1::bigint
           72  +			)
           73  +			delete from parsav_actors where id = $1::bigint
           74  +		]];
           75  +	};
    65     76   
    66     77   	actor_save = {
    67     78   		params = {
    68     79   			uint64, --id
    69     80   			rawstring, --nym
    70     81   			rawstring, --handle
    71     82   			rawstring, --bio 
    72     83   			rawstring, --epithet
    73     84   			rawstring, --avataruri
    74     85   			uint64, --avatarid
    75     86   			uint16, --rank
    76         -			uint32 --quota
           87  +			uint32, --quota
           88  +			uint32 --invites
    77     89   		}, cmd = true, sql = [[
    78     90   			update parsav_actors set
    79     91   				nym = $2::text,
    80     92   				handle = $3::text,
    81     93   				bio = $4::text,
    82     94   				epithet = $5::text,
    83     95   				avataruri = $6::text,
    84     96   				avatarid = $7::bigint,
    85     97   				rank = $8::smallint,
    86         -				quota = $9::integer
    87         -				--invites are controlled by their own specialized routines
           98  +				quota = $9::integer,
           99  +				invites = $10::integer
    88    100   			where id = $1::bigint
    89    101   		]];
    90    102   	};
    91    103   
    92    104   	actor_create = {
    93    105   		params = {
    94    106   			rawstring, rawstring, uint64, lib.store.timepoint,
    95    107   			rawstring, rawstring, lib.mem.ptr(uint8),
    96         -			rawstring, uint16, uint32
          108  +			rawstring, uint16, uint32, uint32
    97    109   		};
    98    110   		sql = [[
    99    111   			insert into parsav_actors (
   100    112   				nym,handle,
   101    113   				origin,knownsince,
   102    114   				bio,avataruri,key,
   103         -				epithet,rank,quota
          115  +				epithet,rank,quota,
          116  +				invites
   104    117   			) values ($1::text, $2::text,
   105    118   				case when $3::bigint = 0 then null
   106    119   				     else $3::bigint end,
   107    120   				to_timestamp($4::bigint),
   108    121   				$5::bigint, $6::bigint, $7::bytea,
   109         -				$8::text, $9::smallint, $10::integer
          122  +				$8::text, $9::smallint, $10::integer,
          123  +				$11::integer
   110    124   			) returning id
   111    125   		]];
   112    126   	};
   113    127   
   114    128   	actor_auth_pw = {
   115    129   		params = {pstring,rawstring,pstring,lib.store.inet}, sql = [[
   116    130   			select a.aid, a.uid, a.name from parsav_auth as a
................................................................................
   125    139   	};
   126    140   
   127    141   	actor_enum_local = {
   128    142   		params = {}, sql = [[
   129    143   			select id, nym, handle, origin, bio,
   130    144   			       null::text, rank, quota, key, epithet,
   131    145   			       extract(epoch from knownsince)::bigint,
   132         -				handle ||'@'||
   133         -				(select value from parsav_config
   134         -					where key='domain' limit 1) as xid
          146  +					'@' || handle,
          147  +				   invites
   135    148   			from parsav_actors where origin is null
          149  +			order by nullif(rank,0) nulls last, handle
   136    150   		]];
   137    151   	};
   138    152   
   139    153   	actor_enum = {
   140    154   		params = {}, sql = [[
   141    155   			select a.id, a.nym, a.handle, a.origin, a.bio,
   142    156   			       a.avataruri, a.rank, a.quota, a.key, a.epithet,
   143    157   			       extract(epoch from a.knownsince)::bigint,
   144    158   				   coalesce(a.handle || '@' || s.domain,
   145         -				            '@' || a.handle) as xid
          159  +				            '@' || a.handle) as xid,
          160  +				   invites
   146    161   			from parsav_actors a
   147    162   			left join parsav_servers s on s.id = a.origin
          163  +			order by nullif(a.rank,0) nulls last, a.handle, a.origin
   148    164   		]];
   149    165   	};
   150    166   
   151    167   	actor_stats = {
   152    168   		params = {uint64}, sql = ([[
   153    169   			with tweets as (
   154    170   				select from parsav_posts where author = $1::bigint
................................................................................
   786    802   end
   787    803   local terra row_to_actor(r: &pqr, row: intptr): lib.mem.ptr(lib.store.actor)
   788    804   	var a: lib.mem.ptr(lib.store.actor)
   789    805   	var av: rawstring, avlen: intptr
   790    806   	var nym: rawstring, nymlen: intptr
   791    807   	var bio: rawstring, biolen: intptr
   792    808   	var epi: rawstring, epilen: intptr
   793         -	if r:null(row,5) then avlen = 0 av = nil else
          809  +	var origin: uint64 = 0
          810  +	var handle = r:_string(row, 2)
          811  +	if not r:null(row,3) then origin = r:int(uint64,row,3) end
          812  +
          813  +	var avia = lib.str.acc {buf=nil}
          814  +	if origin == 0 then
          815  +		avia:compose('/avi/',handle)
          816  +		av = avia.buf
          817  +		avlen = avia.sz+1
          818  +	elseif r:null(row,5) then
   794    819   		av = r:string(row,5)
   795    820   		avlen = r:len(row,5)+1
          821  +	else
          822  +		av = '/s/default-avatar.webp'
          823  +		avlen = 22
   796    824   	end
          825  +
   797    826   	if r:null(row,1) then nymlen = 0 nym = nil else
   798    827   		nym = r:string(row,1)
   799    828   		nymlen = r:len(row,1)+1
   800    829   	end
   801    830   	if r:null(row,4) then biolen = 0 bio = nil else
   802    831   		bio = r:string(row,4)
   803    832   		biolen = r:len(row,4)+1
................................................................................
   807    836   		epilen = r:len(row,9)+1
   808    837   	end
   809    838   	a = [ lib.str.encapsulate(lib.store.actor, {
   810    839   		nym = {`nym, `nymlen};
   811    840   		bio = {`bio, `biolen};
   812    841   		epithet = {`epi, `epilen};
   813    842   		avatar = {`av,`avlen};
   814         -		handle = {`r:string(row, 2); `r:len(row,2) + 1};
          843  +		handle = {`handle.ptr, `handle.ct + 1};
   815    844   		xid = {`r:string(row, 11); `r:len(row,11) + 1};
   816    845   	}) ]
   817    846   	a.ptr.id = r:int(uint64, row, 0);
   818    847   	a.ptr.rights = lib.store.rights_default();
   819    848   	a.ptr.rights.rank = r:int(uint16, row, 6);
   820    849   	a.ptr.rights.quota = r:int(uint32, row, 7);
          850  +	a.ptr.rights.invites = r:int(uint32, row, 12);
   821    851   	a.ptr.knownsince = r:int(int64,row, 10);
   822    852   	if r:null(row,8) then
   823    853   		a.ptr.key.ct = 0 a.ptr.key.ptr = nil
   824    854   	else
   825    855   		a.ptr.key = r:bin(row,8)
   826    856   	end
   827         -	if r:null(row,3) then a.ptr.origin = 0
   828         -	else a.ptr.origin = r:int(uint64,row,3) end
          857  +	a.ptr.origin = origin
          858  +	if avia.buf ~= nil then avia:free() end
   829    859   	return a
   830    860   end
   831    861   
   832    862   local privmap = lib.store.privmap
   833    863   
   834    864   local checksha = function(src, hash, origin, username, pw)
   835    865   	local validate = function(kind, cred, credlen)
................................................................................
   873    903   local schema = sqlsquash(lib.util.ingest('backend/schema/pgsql.sql'))
   874    904   local obliterator = sqlsquash(lib.util.ingest('backend/schema/pgsql-drop.sql'))
   875    905   
   876    906   local privupdate = terra(
   877    907   	src: &lib.store.source,
   878    908   	ac: &lib.store.actor
   879    909   ): {}
   880         -	var pdef = lib.store.rights_default().powers
          910  +	var pdef: lib.store.powerset pdef:clear()
   881    911   	var map = array([privmap])
   882    912   	for i=0, [map.type.N] do
   883    913   		var d = pdef and map[i].priv
   884    914   		var u = ac.rights.powers and map[i].priv
   885    915   		queries.actor_power_delete.exec(src, ac.id, map[i].name)
   886    916   		if d:sz() > 0 and u:sz() == 0 then
   887    917   			lib.dbg('blocking power ', {map[i].name.ptr, map[i].name.ct})
................................................................................
  1042   1072   			return a
  1043   1073   		end
  1044   1074   	end];
  1045   1075   
  1046   1076   	actor_enum = [terra(src: &lib.store.source)
  1047   1077   		var r = queries.actor_enum.exec(src)
  1048   1078   		if r.sz == 0 then
  1049         -			return [lib.mem.ptr(&lib.store.actor)] { ct = 0, ptr = nil }
         1079  +			return [lib.mem.lstptr(lib.store.actor)].null()
  1050   1080   		else defer r:free()
  1051         -			var mem = lib.mem.heapa([&lib.store.actor], r.sz)
         1081  +			var mem = lib.mem.heapa([lib.mem.ptr(lib.store.actor)], r.sz)
  1052   1082   			for i=0,r.sz do
  1053         -				mem.ptr[i] = row_to_actor(&r, i).ptr
  1054         -				mem.ptr[i].source = src
         1083  +				mem.ptr[i] = row_to_actor(&r, i)
         1084  +				mem(i).ptr.source = src
  1055   1085   			end
  1056         -			return [lib.mem.ptr(&lib.store.actor)] { ct = r.sz, ptr = mem.ptr }
         1086  +			return [lib.mem.lstptr(lib.store.actor)] { ct = r.sz, ptr = mem.ptr }
  1057   1087   		end
  1058   1088   	end];
  1059   1089   
  1060   1090   	actor_enum_local = [terra(src: &lib.store.source)
  1061   1091   		var r = queries.actor_enum_local.exec(src)
  1062   1092   		if r.sz == 0 then
  1063         -			return [lib.mem.ptr(&lib.store.actor)] { ct = 0, ptr = nil }
         1093  +			return [lib.mem.lstptr(lib.store.actor)].null()
  1064   1094   		else defer r:free()
  1065         -			var mem = lib.mem.heapa([&lib.store.actor], r.sz)
         1095  +			var mem = lib.mem.heapa([lib.mem.ptr(lib.store.actor)], r.sz)
  1066   1096   			for i=0,r.sz do
  1067         -				mem.ptr[i] = row_to_actor(&r, i).ptr
  1068         -				mem.ptr[i].source = src
         1097  +				mem.ptr[i] = row_to_actor(&r, i)
         1098  +				mem(i).ptr.source = src
  1069   1099   			end
  1070         -			return [lib.mem.ptr(&lib.store.actor)] { ct = r.sz, ptr = mem.ptr }
         1100  +			return [lib.mem.lstptr(lib.store.actor)] { ct = r.sz, ptr = mem.ptr }
  1071   1101   		end
  1072   1102   	end];
  1073   1103   
  1074   1104   	actor_auth_how = [terra(
  1075   1105   			src: &lib.store.source,
  1076   1106   			ip: lib.store.inet,
  1077   1107   			username: rawstring
................................................................................
  1129   1159   
  1130   1160   			var a = row_to_actor(&r, 0)
  1131   1161   			a.ptr.source = src
  1132   1162   
  1133   1163   			var au = [lib.stat(lib.store.auth)] { ok = true }
  1134   1164   			au.val.aid = aid
  1135   1165   			au.val.uid = a.ptr.id
  1136         -			if not r:null(0,13) then -- restricted?
         1166  +			if not r:null(0,14) then -- restricted?
  1137   1167   				au.val.privs:clear()
  1138         -				(au.val.privs.post   << r:bool(0,14)) 
  1139         -				(au.val.privs.edit   << r:bool(0,15))
  1140         -				(au.val.privs.acct   << r:bool(0,16))
  1141         -				(au.val.privs.upload << r:bool(0,17))
  1142         -				(au.val.privs.censor << r:bool(0,18))
  1143         -				(au.val.privs.admin  << r:bool(0,19))
         1168  +				(au.val.privs.post   << r:bool(0,15)) 
         1169  +				(au.val.privs.edit   << r:bool(0,16))
         1170  +				(au.val.privs.acct   << r:bool(0,17))
         1171  +				(au.val.privs.upload << r:bool(0,18))
         1172  +				(au.val.privs.censor << r:bool(0,19))
         1173  +				(au.val.privs.admin  << r:bool(0,20))
  1144   1174   			else au.val.privs:fill() end
  1145   1175   
  1146   1176   			return au, a
  1147   1177   		end
  1148   1178   
  1149   1179   		::fail:: return [lib.stat   (lib.store.auth) ] { ok = false        },
  1150   1180   			            [lib.mem.ptr(lib.store.actor)] { ptr = nil, ct = 0 }
................................................................................
  1219   1249   	end];
  1220   1250   
  1221   1251   	actor_powers_fetch = getpow;
  1222   1252   	actor_save = [terra(
  1223   1253   		src: &lib.store.source,
  1224   1254   		ac: &lib.store.actor
  1225   1255   	): {}
         1256  +		var avatar = ac.avatar
         1257  +		if ac.origin == 0 then avatar = nil end
  1226   1258   		queries.actor_save.exec(src,
  1227   1259   			ac.id, ac.nym, ac.handle,
  1228         -			ac.bio, ac.epithet, ac.avatar,
  1229         -			ac.avatarid, ac.rights.rank, ac.rights.quota)
         1260  +			ac.bio, ac.epithet, avatar,
         1261  +			ac.avatarid, ac.rights.rank, ac.rights.quota, ac.rights.invites)
  1230   1262   	end];
  1231   1263   
  1232   1264   	actor_save_privs = privupdate;
  1233   1265   
  1234   1266   	actor_create = [terra(
  1235   1267   		src: &lib.store.source,
  1236   1268   		ac: &lib.store.actor
  1237   1269   	): uint64
  1238         -		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)
         1270  +		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,ac.rights.invites)
  1239   1271   		if r.sz == 0 then lib.bail('failed to create actor!') end
  1240   1272   		ac.id = r:int(uint64,0,0)
  1241   1273   
  1242   1274   		-- check against default rights, insert records for wherever powers differ
  1243   1275   		lib.dbg('created new actor, establishing powers')
  1244   1276   		privupdate(src,ac)
  1245   1277   
  1246   1278   		lib.dbg('powers established')
  1247   1279   		return ac.id
  1248   1280   	end];
  1249   1281   
         1282  +	actor_purge_uid = [terra(
         1283  +		src: &lib.store.source,
         1284  +		uid: uint64
         1285  +	) queries.actor_purge_uid.exec(src,uid) end];
         1286  +
  1250   1287   	auth_enum_uid = [terra(
  1251   1288   		src: &lib.store.source,
  1252   1289   		uid: uint64
  1253   1290   	): lib.mem.ptr(lib.mem.ptr(lib.store.auth))
  1254   1291   		var r = queries.auth_enum_uid.exec(src,uid)
  1255   1292   		if r.sz == 0 then return [lib.mem.ptr(lib.mem.ptr(lib.store.auth))].null() end
  1256   1293   		var ret = lib.mem.heapa([lib.mem.ptr(lib.store.auth)], r.sz)