Differences From
Artifact [d7d680b0a3]:
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