Differences From
Artifact [a9eb70a00e]:
4 4 local pstring = lib.mem.ptr(int8)
5 5 local rstring = lib.mem.ref(int8)
6 6 local hpath = lib.mem.ptr(rstring)
7 7 local http = {}
8 8
9 +terra meth_get(meth: method.t) return (meth == method.get) or (meth == method.head) end
9 10 terra http.actor_profile_xid(co: &lib.srv.convo, uri: lib.mem.ptr(int8), meth: method.t)
10 11 var handle = [lib.mem.ptr(int8)] { ptr = &uri.ptr[2], ct = 0 }
11 12 for i=2,uri.ct do
12 13 if uri.ptr[i] == @'/' or uri.ptr[i] == 0 then handle.ct = i - 2 break end
13 14 end
................................................................................
58 59
59 60 lib.render.user_page(co, actor.ptr)
60 61 end
61 62
62 63 terra http.login_form(co: &lib.srv.convo, meth: method.t)
63 - if meth == method.get then
64 + if meth_get(meth) then
64 65 -- request a username
65 66 lib.render.login(co, nil, nil, lib.str.plit(nil))
66 67 elseif meth == method.post then
67 68 var usn, usnl = co:postv('user')
68 69 var am, aml = co:postv('authmethod')
................................................................................
124 125 terra http.post_compose(co: &lib.srv.convo, meth: method.t)
125 126 if not co:assertpow('post') then return end
126 127 --if co.who.rights.powers.post() == false then
127 128 --co:complain(403,'insufficient privileges','you lack the <strong>post</strong> power and cannot perform this action')
128 129
129 - if meth == method.get then
130 + if meth_get(meth) then
130 131 lib.render.compose(co, nil, nil)
131 132 elseif meth == method.post then
132 133 var text, textlen = co:postv("post")
133 134 var acl, acllen = co:postv("acl")
134 135 var subj, subjlen = co:postv("subject")
................................................................................
140 141
141 142 var p = lib.store.post {
142 143 author = co.who.id, acl = acl;
143 144 body = text, subject = subj;
144 145 }
145 - var newid = co.srv:post_create(&p)
146 + var newid = p:publish(co.srv)
146 147
147 148 var idbuf: int8[lib.math.shorthand.maxlen]
148 149 var idlen = lib.math.shorthand.gen(newid, idbuf)
149 150 var redirto: lib.str.acc redirto:compose('/post/',{idbuf,idlen}) defer redirto:free()
150 151 co:reroute(redirto.buf)
................................................................................
183 184 var lnkp = lnk:finalize() defer lnkp:free()
184 185 if post(0).author ~= co.who.id then
185 186 co:complain(403, 'forbidden', 'you cannot alter other people\'s posts')
186 187 return
187 188 elseif path(2):cmp(lib.str.lit 'edit') then
188 - if meth == method.get then
189 + if meth_get(meth) then
189 190 lib.render.compose(co, post.ptr, nil)
190 191 return
191 192 elseif meth == method.post then
192 193 var newbody = co:postv('post')._0
193 194 var newacl = co:postv('acl')._0
................................................................................
198 199 post(0):save(true)
199 200 co:reroute(lnkp.ptr)
200 201 end
201 202 return
202 203 elseif path(2):cmp(lib.str.lit 'del') then
203 - if meth == method.get then
204 + if meth_get(meth) then
204 205 var conf = data.view.confirm {
205 206 title = lib.str.plit 'delete post';
206 207 query = lib.str.plit 'are you sure you want to delete this post?';
207 208 cancel = lnkp
208 209 }
................................................................................
222 223 else goto badop end
223 224 end
224 225 else goto badurl end
225 226 end
226 227
227 - if meth == method.post then goto badop end
228 + if meth == method.post then
229 + var replytext = co:ppostv('post')
230 + var acl = co:ppostv('acl')
231 + var subj = co:ppostv('subject')
232 + if not acl then acl = lib.str.plit 'all' end
233 + if not replytext then goto badop end
234 +
235 + var reply = lib.store.post {
236 + author = co.who.id, parent = pid;
237 + subject = subj.ptr, acl = acl.ptr, body = replytext.ptr;
238 + }
239 +
240 + reply:publish(co.srv)
241 + end
228 242
229 243 lib.render.tweet_page(co, path, post.ptr)
230 244 do return end
231 245
232 246 ::badurl:: do co:complain(404, 'invalid URL', 'this URL does not reference extant content or functionality') return end
................................................................................
242 256 co.who.bio = co:postv('bio')._0
243 257 co.who.nym = co:postv('nym')._0
244 258 if co.who.bio ~= nil and @co.who.bio == 0 then co.who.bio = nil end
245 259 if co.who.nym ~= nil and @co.who.nym == 0 then co.who.nym = nil end
246 260 co.who.source:actor_save(co.who)
261 +
262 + var act = co:ppostv('act')
263 + var resethue = false
264 + if act:ref() then
265 + resethue = act:cmp(lib.str.plit 'reset-hue')
266 + end
267 +
268 + if not resethue then
269 + var shue = co:ppostv('hue')
270 + var nhue, okhue = lib.math.decparse(shue)
271 + if okhue and nhue ~= co.ui_hue then
272 + if nhue == co.srv.cfg.ui_hue
273 + then resethue = true
274 + else co.srv:actor_conf_int_set(co.who.id, 'ui-accent', nhue)
275 + end
276 + co.ui_hue = nhue
277 + end
278 + end
279 + if resethue then
280 + co.srv:actor_conf_int_reset(co.who.id, 'ui-accent')
281 + co.ui_hue = co.srv.cfg.ui_hue
282 + end
283 +
247 284 msg = lib.str.plit 'profile changes saved'
248 285 --user_refresh = true -- not really necessary here, actually
249 286 elseif path(1):cmp(lib.str.lit 'srv') then
250 287 if not co.who.rights.powers.config() then goto nopriv end
251 288 elseif path(1):cmp(lib.str.lit 'brand') then
................................................................................
324 361 terra r.dispatch_http(co: &lib.srv.convo, uri: lib.mem.ptr(int8), meth: method.t)
325 362 lib.dbg('handling URI of form ', {uri.ptr,uri.ct})
326 363 co.navbar = lib.render.nav(co)
327 364 -- some routes are non-hierarchical, and can be resolved with a simple strcmp
328 365 -- we run through those first before giving up and parsing the URI
329 - if uri.ptr[0] ~= @'/' then
366 + if uri.ptr == nil or uri.ptr[0] ~= @'/' then
330 367 co:complain(404, 'what the hell', 'how did you do that')
331 - return
332 368 elseif uri.ct == 1 then -- root
333 369 if (co.srv.cfg.pol_sec == lib.srv.secmode.private or
334 370 co.srv.cfg.pol_sec == lib.srv.secmode.lockdown) and co.aid == 0 then
335 371 http.login_form(co, meth)
336 - else
337 - -- FIXME display home screen
338 - http.timeline(co, hpath {ptr=nil})
339 - goto notfound
340 - end
341 - return
372 + else http.timeline(co, hpath {ptr=nil}) end
342 373 elseif uri.ptr[1] == @'@' then
343 374 http.actor_profile_xid(co, uri, meth)
344 - return
345 375 elseif uri.ptr[1] == @'s' and uri.ptr[2] == @'/' and uri.ct > 3 then
346 - if meth ~= method.get then goto wrongmeth end
376 + if not meth_get(meth) then goto wrongmeth end
347 377 if not http.static_content(co, uri.ptr + 3, uri.ct - 3) then goto notfound end
348 - return
349 378 elseif lib.str.ncmp('/avi/', uri.ptr, 5) == 0 then
350 379 http.local_avatar(co, [lib.mem.ptr(int8)] {ptr = uri.ptr + 5, ct = uri.ct - 5})
351 - return
352 380 elseif lib.str.ncmp('/compose', uri.ptr, lib.math.biggest(uri.ct,8)) == 0 then
353 381 if co.aid == 0 then co:reroute('/login') return end
354 382 http.post_compose(co,meth)
355 - return
356 383 elseif lib.str.ncmp('/login', uri.ptr, lib.math.biggest(uri.ct,6)) == 0 then
357 384 if co.aid == 0
358 385 then http.login_form(co, meth)
359 386 else co:reroute('/')
360 387 end
361 - return
362 388 elseif lib.str.ncmp('/logout', uri.ptr, lib.math.biggest(uri.ct,7)) == 0 then
363 389 if co.aid == 0
364 390 then goto notfound
365 391 else co:reroute_cookie('/','auth=; Path=/')
366 392 end
367 - return
368 393 else -- hierarchical routes
369 394 var path = lib.http.hier(uri) defer path:free()
370 395 if path.ct > 1 and path(0):cmp(lib.str.lit('user')) then
371 396 http.actor_profile_uid(co, path, meth)
372 397 elseif path.ct > 1 and path(0):cmp(lib.str.lit('post')) then
373 398 http.tweet_page(co, path, meth)
374 399 elseif path(0):cmp(lib.str.lit('tl')) then
375 400 http.timeline(co, path)
376 401 elseif path(0):cmp(lib.str.lit('doc')) then
377 - if meth ~= method.get and meth ~= method.head then goto wrongmeth end
402 + if not meth_get(meth) then goto wrongmeth end
378 403 http.documentation(co, path)
379 404 elseif path(0):cmp(lib.str.lit('conf')) then
380 405 if co.aid == 0 then goto unauth end
381 406 http.configure(co,path,meth)
382 407 else goto notfound end
383 - return
384 408 end
409 + do return end
385 410
386 411 ::wrongmeth:: co:complain(405, 'method not allowed', 'that method is not meaningful for this endpoint') do return end
387 412 ::notfound:: co:complain(404, 'not found', 'no such resource available') do return end
388 413 ::unauth:: co:complain(401, 'unauthorized', 'this content is not available at your clearance level') do return end
389 414 end