parsav  Diff

Differences From Artifact [1740166796]:

To Artifact [36b1398523]:


    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