parsav  Diff

Differences From Artifact [d7d680b0a3]:

To Artifact [4d69f275c0]:


     1      1   -- vim: ft=terra
     2      2   local r = lib.srv.route
     3      3   local method = lib.http.method
            4  +local pstring = lib.mem.ptr(int8)
            5  +local rstring = lib.mem.ref(int8)
            6  +local hpath = lib.mem.ptr(rstring)
     4      7   local http = {}
     5      8   
     6      9   terra http.actor_profile_xid(co: &lib.srv.convo, uri: lib.mem.ptr(int8), meth: method.t)
     7     10   	var handle = [lib.mem.ptr(int8)] { ptr = &uri.ptr[2], ct = 0 }
     8     11   	for i=2,uri.ct do
     9     12   		if uri.ptr[i] == @'/' or uri.ptr[i] == 0 then handle.ct = i - 2 break end
    10     13   	end
................................................................................
    57     60   
    58     61   	lib.render.userpage(co, actor.ptr)
    59     62   end
    60     63   
    61     64   terra http.login_form(co: &lib.srv.convo, meth: method.t)
    62     65   	if meth == method.get then
    63     66   		-- request a username
    64         -		lib.render.login(co, nil, nil, nil)
           67  +		lib.render.login(co, nil, nil, lib.str.plit(nil))
    65     68   	elseif meth == method.post then
    66     69   		var usn, usnl = co:postv('user')
    67         -		lib.dbg('got name ',{usn,usnl})
    68         -		lib.io.fmt('name len %llu\n',usnl)
    69     70   		var am, aml = co:postv('authmethod')
    70     71   		var chrs, chrsl = co:postv('response')
    71     72   		var cs, authok = co.srv:actor_auth_how(co.peer, usn)
    72     73   		var act = co.srv:actor_fetch_xid([lib.mem.ptr(int8)] {
    73     74   			ptr = usn, ct = usnl
    74     75   		})
    75     76   		if authok == false then
    76         -			lib.render.login(co, nil, nil, 'access denied')
           77  +			lib.render.login(co, nil, nil, lib.str.plit'access denied')
    77     78   			return
    78     79   		end
    79     80   		var fakeact = false
    80     81   		var fakeactor: lib.store.actor
    81     82   		if act.ptr == nil then
    82     83   			-- the user is known to us but has not yet claimed an
    83     84   			-- account on the server. create a template for the
................................................................................
    90     91   			}
    91     92   			act.ct = 1
    92     93   			act.ptr = &fakeactor
    93     94   			act.ptr.rights = lib.store.rights_default()
    94     95   		end
    95     96   		if am == nil then
    96     97   			-- pick an auth method
    97         -			lib.render.login(co, act.ptr, &cs, nil)
           98  +			lib.render.login(co, act.ptr, &cs, lib.str.plit(nil))
    98     99   		else var aid: uint64 = 0
    99    100   			lib.dbg('authentication attempt beginning')
   100    101   			-- attempt login with provided method
   101    102   			if lib.str.ncmp('pw', am, lib.math.biggest(2,aml)) == 0 and chrs ~= nil then
   102    103   				aid = co.srv:actor_auth_pw(co.peer,
   103    104   					[lib.mem.ptr(int8)]{ptr=usn,ct=usnl},
   104    105   					[lib.mem.ptr(int8)]{ptr=chrs,ct=chrsl})
................................................................................
   105    106   			elseif lib.str.ncmp('otp', am, lib.math.biggest(2,aml)) == 0 and chrs ~= nil then
   106    107   				lib.dbg('using otp auth')
   107    108   				-- ยทยทยท --
   108    109   			else
   109    110   				lib.dbg('invalid auth method')
   110    111   			end
   111    112   
   112         -			lib.io.fmt('login got aid = %llu\n', aid)
   113    113   			-- error out
   114    114   			if aid == 0 then
   115         -				lib.render.login(co, nil, nil, 'authentication failure')
          115  +				lib.render.login(co, nil, nil, lib.str.plit 'authentication failure')
   116    116   			else
   117    117   				var sesskey: int8[lib.session.maxlen + #lib.session.cookiename + #"=; Path=/" + 1]
   118    118   				do var p = &sesskey[0]
   119    119   					p = lib.str.ncpy(p, [lib.session.cookiename .. '='], [#lib.session.cookiename + 1])
   120    120   					p = p + lib.session.cookie_gen(co.srv.cfg.secret, aid, lib.osclock.time(nil), p)
   121    121   					lib.dbg('sending cookie',&sesskey[0])
   122    122   					p = lib.str.ncpy(p, '; Path=/', 9)
................................................................................
   134    134   terra http.post_compose(co: &lib.srv.convo, meth: method.t)
   135    135   	if meth == method.get then
   136    136   		lib.render.compose(co, nil)
   137    137   	elseif meth == method.post then
   138    138   		if co.who.rights.powers.post() == false then
   139    139   			co:complain(401,'insufficient privileges','you lack the <strong>post</strong> power and cannot perform this action') return
   140    140   		end
          141  +		var text, textlen = co:postv("post")
          142  +		var acl, acllen = co:postv("acl")
          143  +		var subj, subjlen = co:postv("subject")
          144  +		if text == nil or acl == nil then
          145  +			co:complain(405, 'invalid post', 'every post must have at least body text and an ACL')
          146  +			return
          147  +		end
          148  +		if subj == nil then subj = '' end
          149  +
          150  +		var p = lib.store.post {
          151  +			author = co.who.id, acl = acl;
          152  +			body = text, subject = subj;
          153  +		}
          154  +		var newid = co.srv:post_create(&p)
   141    155   
          156  +		var idbuf: int8[lib.math.shorthand.maxlen]
          157  +		var idlen = lib.math.shorthand.gen(newid, idbuf)
          158  +		var redirto: lib.str.acc redirto:compose('/post/',{idbuf,idlen}) defer redirto:free()
          159  +		co:reroute(redirto.buf)
   142    160   	end
   143    161   end
          162  +
          163  +terra http.timeline(co: &lib.srv.convo, mode: hpath)
          164  +	lib.render.timeline(co,lib.trn(mode.ptr == nil, rstring{ptr=nil}, mode.ptr[1]))
          165  +	return
          166  +end
   144    167   
   145    168   do local branches = quote end
   146    169   	local filename, flen = symbol(&int8), symbol(intptr)
   147    170   	local page = symbol(lib.http.page)
   148    171   	local send = label()
   149    172   	local storage = data.stmap
   150    173   	for i,e in ipairs(config.embeds) do local id,mime = e[1],e[2]
................................................................................
   180    203   	co:reroute('/s/default-avatar.webp')
   181    204   end
   182    205   
   183    206   -- entry points
   184    207   terra r.dispatch_http(co: &lib.srv.convo, uri: lib.mem.ptr(int8), meth: method.t)
   185    208   	lib.dbg('handling URI of form ', {uri.ptr,uri.ct})
   186    209   	co.navbar = lib.render.nav(co)
          210  +	lib.dbg('got nav ', {co.navbar.ptr,co.navbar.ct}, "||", co.navbar.ptr)
   187    211   	-- some routes are non-hierarchical, and can be resolved with a simple strcmp
   188    212   	-- we run through those first before giving up and parsing the URI
   189    213   	if uri.ptr[0] ~= @'/' then
   190    214   		co:complain(404, 'what the hell', 'how did you do that')
   191    215   		return
   192    216   	elseif uri.ct == 1 then -- root
   193         -		lib.io.fmt('root directory, aid is %llu\n', co.aid)
   194    217   		if (co.srv.cfg.pol_sec == lib.srv.secmode.private or
   195    218   		   co.srv.cfg.pol_sec == lib.srv.secmode.lockdown) and co.aid == 0 then
   196    219   		   http.login_form(co, meth)
   197    220   		else
   198    221   			-- FIXME display home screen
          222  +			http.timeline(co, hpath {ptr=nil})
   199    223   			goto notfound
   200    224   		end
   201    225   		return
   202    226   	elseif uri.ptr[1] == @'@' then
   203    227   		http.actor_profile_xid(co, uri, meth)
   204    228   		return
   205    229   	elseif uri.ptr[1] == @'s' and uri.ptr[2] == @'/' and uri.ct > 3 then
................................................................................
   225    249   			else co:reroute_cookie('/','auth=; Path=/')
   226    250   		end
   227    251   		return
   228    252   	else -- hierarchical routes
   229    253   		var path = lib.http.hier(uri) defer path:free()
   230    254   		if path.ptr[0]:cmp(lib.str.lit('user')) then
   231    255   			http.actor_profile_uid(co, path, meth)
          256  +		elseif path.ptr[0]:cmp(lib.str.lit('tl')) then
          257  +			http.timeline(co, path)
   232    258   		else goto notfound end
   233    259   		return
   234    260   	end
   235    261   
   236    262   	::wrongmeth:: co:complain(405, 'method not allowed', 'that method is not meaningful for this endpoint') do return end
   237    263   	::notfound:: co:complain(404, 'not found', 'no such resource available') do return end
   238    264   end