Differences From
Artifact [ae96c17fe6]:
10 10 var handle = [lib.mem.ptr(int8)] { ptr = &uri.ptr[2], ct = 0 }
11 11 for i=2,uri.ct do
12 12 if uri.ptr[i] == @'/' or uri.ptr[i] == 0 then handle.ct = i - 2 break end
13 13 end
14 14 if handle.ct == 0 then
15 15 handle.ct = uri.ct - 2
16 16 uri:advance(uri.ct)
17 - else
18 - if handle.ct + 2 < uri.ct then
19 - uri:advance(handle.ct + 2)
20 - --uri.ptr = uri.ptr + (handle.ct + 2)
21 - --uri.ct = uri.ct - (handle.ct + 2)
22 - end
23 - end
17 + elseif handle.ct + 2 < uri.ct then uri:advance(handle.ct + 2) end
24 18
25 19 lib.dbg('looking up user by xid "', {handle.ptr,handle.ct} ,'", path: ', {uri.ptr,uri.ct})
26 20
27 21 var path = lib.http.hier(uri) defer path:free()
28 22 for i=0,path.ct do
29 23 lib.dbg('got path component ', {path.ptr[i].ptr, path.ptr[i].ct})
30 24 end
................................................................................
32 26 var actor = co.srv:actor_fetch_xid(handle)
33 27 if actor.ptr == nil then
34 28 co:complain(404,'no such user','no such user known to this server')
35 29 return
36 30 end
37 31 defer actor:free()
38 32
39 - lib.render.userpage(co, actor.ptr)
33 + lib.render.user_page(co, actor.ptr)
40 34 end
41 35
42 -terra http.actor_profile_uid(co: &lib.srv.convo, path: lib.mem.ptr(lib.mem.ref(int8)), meth: method.t)
36 +terra http.actor_profile_uid (
37 + co: &lib.srv.convo,
38 + path: lib.mem.ptr(lib.mem.ref(int8)),
39 + meth: method.t
40 +)
43 41 if path.ct < 2 then
44 42 co:complain(404,'bad url','invalid user url')
45 43 return
46 44 end
47 45
48 46 var uid, ok = lib.math.shorthand.parse(path.ptr[1].ptr, path.ptr[1].ct)
49 47 if not ok then
................................................................................
54 52 var actor = co.srv:actor_fetch_uid(uid)
55 53 if actor.ptr == nil then
56 54 co:complain(404, 'no such user', 'no user by that ID is known to this instance')
57 55 return
58 56 end
59 57 defer actor:free()
60 58
61 - lib.render.userpage(co, actor.ptr)
59 + lib.render.user_page(co, actor.ptr)
62 60 end
63 61
64 62 terra http.login_form(co: &lib.srv.convo, meth: method.t)
65 63 if meth == method.get then
66 64 -- request a username
67 65 lib.render.login(co, nil, nil, lib.str.plit(nil))
68 66 elseif meth == method.post then
................................................................................
103 101 if lib.str.ncmp('pw', am, lib.math.biggest(2,aml)) == 0 and chrs ~= nil then
104 102 aid = co.srv:actor_auth_pw(co.peer,
105 103 [lib.mem.ptr(int8)]{ptr=usn,ct=usnl},
106 104 [lib.mem.ptr(int8)]{ptr=chrs,ct=chrsl})
107 105 elseif lib.str.ncmp('otp', am, lib.math.biggest(2,aml)) == 0 and chrs ~= nil then
108 106 lib.dbg('using otp auth')
109 107 -- ยทยทยท --
110 - else
111 - lib.dbg('invalid auth method')
112 - end
108 + else lib.dbg('invalid auth method') end
113 109
114 110 -- error out
115 111 if aid == 0 then
116 112 lib.render.login(co, nil, nil, lib.str.plit 'authentication failure')
117 113 else
118 - var sesskey: int8[lib.session.maxlen + #lib.session.cookiename + #"=; Path=/" + 1]
119 - do var p = &sesskey[0]
120 - p = lib.str.ncpy(p, [lib.session.cookiename .. '='], [#lib.session.cookiename + 1])
121 - p = p + lib.session.cookie_gen(co.srv.cfg.secret, aid, lib.osclock.time(nil), p)
122 - lib.dbg('sending cookie ',{&sesskey[0],15})
123 - p = lib.str.ncpy(p, '; Path=/', 9)
124 - end
125 - co:reroute_cookie('/', &sesskey[0])
114 + co:installkey('/',aid)
126 115 end
127 116 end
128 117 if act.ptr ~= nil and fakeact == false then act:free() end
129 118 else
130 119 ::wrongmeth:: co:complain(405, 'method not allowed', 'that method is not meaningful for this endpoint') do return end
131 120 end
132 121 return
................................................................................
134 123
135 124 terra http.post_compose(co: &lib.srv.convo, meth: method.t)
136 125 if not co:assertpow('post') then return end
137 126 --if co.who.rights.powers.post() == false then
138 127 --co:complain(403,'insufficient privileges','you lack the <strong>post</strong> power and cannot perform this action')
139 128
140 129 if meth == method.get then
141 - lib.render.compose(co, nil)
130 + lib.render.compose(co, nil, nil)
142 131 elseif meth == method.post then
143 132 var text, textlen = co:postv("post")
144 133 var acl, acllen = co:postv("acl")
145 134 var subj, subjlen = co:postv("subject")
146 135 if text == nil or acl == nil then
147 136 co:complain(405, 'invalid post', 'every post must have at least body text and an ACL')
148 137 return
................................................................................
171 160 lib.render.docpage(co,path(1))
172 161 elseif path.ct == 1 then
173 162 lib.render.docpage(co, rstring.null())
174 163 else
175 164 co:complain(404, 'no such documentation', 'invalid documentation URL')
176 165 end
177 166 end
167 +
168 +terra http.tweet_page(co: &lib.srv.convo, path: hpath, meth: method.t)
169 + var pid, ok = lib.math.shorthand.parse(path(1).ptr, path(1).ct)
170 + if not ok then
171 + co:complain(400, 'bad post ID', 'that post ID is not valid')
172 + return
173 + end
174 + var post = co.srv:post_fetch(pid)
175 + if not post then
176 + co:complain(404, 'post not found', 'no such post is known to this server')
177 + return
178 + end
179 + defer post:free()
180 +
181 + if path.ct == 3 then
182 + if path(2):cmp(lib.str.lit 'edit') then
183 + if post(0).author ~= co.who.id then
184 + co:complain(403, 'forbidden', 'you cannot edit other people\'s posts')
185 + return
186 + end
187 +
188 + if meth == method.get then
189 + lib.render.compose(co, post.ptr, nil)
190 + return
191 + elseif meth == method.post then
192 + var newbody = co:postv('post')._0
193 + var newacl = co:postv('acl')._0
194 + var newsubj = co:postv('subject')._0
195 + if newbody ~= nil then post(0).body = newbody end
196 + if newacl ~= nil then post(0).acl = newacl end
197 + if newsubj ~= nil then post(0).subject = newsubj end
198 + post(0):save(true)
199 +
200 + var lnk: lib.str.acc lnk:compose('/post/', path(1))
201 + co:reroute(lnk.buf)
202 + lnk:free()
203 + end
204 + return
205 + else goto badurl end
206 + end
207 +
208 + if meth == method.post then
209 + co:complain(405, 'invalid operation', 'the operation you have attempted on this post is not meaningful')
210 + return
211 + end
212 +
213 + lib.render.tweet_page(co, path, post.ptr)
214 + do return end
215 +
216 + ::badurl:: co:complain(404, 'invalid URL', 'this URL does not reference extant content or functionality')
217 +end
178 218
179 219 terra http.configure(co: &lib.srv.convo, path: hpath, meth: method.t)
180 220 var msg = pstring.null()
181 221 if meth == method.post and path.ct >= 1 then
182 222 var user_refresh = false var fail = false
183 223 if path(1):cmp(lib.str.lit 'profile') then
224 + lib.dbg('updating profile')
184 225 co.who.bio = co:postv('bio')._0
185 226 co.who.nym = co:postv('nym')._0
186 227 if co.who.bio ~= nil and @co.who.bio == 0 then co.who.bio = nil end
187 228 if co.who.nym ~= nil and @co.who.nym == 0 then co.who.nym = nil end
188 229 co.who.source:actor_save(co.who)
189 230 msg = lib.str.plit 'profile changes saved'
190 231 --user_refresh = true -- not really necessary here, actually
191 232 elseif path(1):cmp(lib.str.lit 'srv') then
192 233 elseif path(1):cmp(lib.str.lit 'users') then
193 -
234 + elseif path(1):cmp(lib.str.lit 'sec') then
235 + var act = co:ppostv('act')
236 + if act:cmp(lib.str.plit 'invalidate') then
237 + lib.dbg('setting user\'s cookie validation time to now')
238 + co.who.source:auth_sigtime_user_alter(co.who.id, lib.osclock.time(nil))
239 + -- the current session has been invalidated as well, so we need to immediately install a new authentication cookie with the same aid so the user doesn't need to log back in all over again
240 + co:installkey('/conf/sec',co.aid)
241 + return
242 + end
194 243 end
195 244
196 245 if user_refresh then -- refresh the user info for the renderer
197 246 var usr = co.srv:actor_fetch_uid(co.who.id)
198 247 lib.mem.heapf(co.who)
199 248 co.who = usr.ptr
200 249 end
................................................................................
222 271 ct = storage[([i-1])].ct;
223 272 }
224 273 goto [send]
225 274 end
226 275 end
227 276 end
228 277 terra http.static_content(co: &lib.srv.convo, [filename], [flen])
229 - var hdrs = array(lib.http.header{'Content-Type',nil})
278 + var hdrs = array(
279 + lib.http.header{'Content-Type',nil})
230 280 var [page] = lib.http.page {
231 281 respcode = 200;
232 282 headers = [lib.mem.ptr(lib.http.header)] {
233 283 ptr = &hdrs[0], ct = 1
234 284 }
235 285 }
236 286 [branches]
................................................................................
288 338 if co.aid == 0
289 339 then goto notfound
290 340 else co:reroute_cookie('/','auth=; Path=/')
291 341 end
292 342 return
293 343 else -- hierarchical routes
294 344 var path = lib.http.hier(uri) defer path:free()
295 - if path.ptr[0]:cmp(lib.str.lit('user')) then
345 + if path.ct > 1 and path(0):cmp(lib.str.lit('user')) then
296 346 http.actor_profile_uid(co, path, meth)
297 - elseif path.ptr[0]:cmp(lib.str.lit('tl')) then
347 + elseif path.ct > 1 and path(0):cmp(lib.str.lit('post')) then
348 + http.tweet_page(co, path, meth)
349 + elseif path(0):cmp(lib.str.lit('tl')) then
298 350 http.timeline(co, path)
299 - elseif path.ptr[0]:cmp(lib.str.lit('doc')) then
351 + elseif path(0):cmp(lib.str.lit('doc')) then
300 352 if meth ~= method.get and meth ~= method.head then goto wrongmeth end
301 353 http.documentation(co, path)
302 - elseif path.ptr[0]:cmp(lib.str.lit('conf')) then
354 + elseif path(0):cmp(lib.str.lit('conf')) then
303 355 if co.aid == 0 then goto unauth end
304 356 http.configure(co,path,meth)
305 357 else goto notfound end
306 358 return
307 359 end
308 360
309 361 ::wrongmeth:: co:complain(405, 'method not allowed', 'that method is not meaningful for this endpoint') do return end
310 362 ::notfound:: co:complain(404, 'not found', 'no such resource available') do return end
311 363 ::unauth:: co:complain(401, 'unauthorized', 'this content is not available at your clearance level') do return end
312 364 end