Closed iamranger closed 9 years ago
Changed
GET /threads?id={max_thread_id}&{count=50}
Added
GET /threads/[id]
(returns all answers)
Added
GET /messages/[id]/answers
Are you working on this? can I help?
This task is next on my to-do list. All read-only methods that did not require user context are done, now we need ones that do require it to work.
The first step is to add authentication. Should not be hard - I already added a stub that gets executed before every resolved REST method (see index.php, near the top). The question is how exactly to do the authentication, as there are several alternatives. I do not mind a second opinion on this, or something completely different. So, in no particular order, with my comments:
1) Basic HTTP Auth, username/password passed every call and checked against confa_users .
Simple to implement, but I do not like this solution much, because it makes it hard to test using the browser, there is no audit trail, no "session" context and password is passed around in plain text way too much for my liking.
I could be wrong and this may be the best solution based on KISS principle.
2) Piggy-backing the existing code (auth.php) - authentication is done once on the first request (any request), a record in confa_session is created, and the session context is kept in cookies.
Username/password for the initial authentication can be passed in headers (basic http auth?) and/or as parameters (to simplify testing), then the caller is responsible for storing the auth cookie and passing it with the other requests.
Pros: can reuse the existing code including session context, audit trail (some), can test the code simply by using the browser (can't post with it anyway, though, but GET mymessages, answered and "since last time I checked"-variation of bydate mode will work.
Cons: harder to implement.
In the end, this new authentication should replace auth.php for index.php that is currently included as part of head_inc.php - we definitely need to decouple them.
The implementation of the rest of REST methods (pun intended) should be fairly straightforward - just pulling the relevant code from PHP pages, and may be making them into functions at the same time, so we don't duplicate the code.
Also, index.php is starting to get uncomfortably big, so may be it makes sense to separate the logic leaving object rendering in index.php, or split it some other way that makes sense. I have no clear plan here.
I am on vacation next week, so if you have ideas or can contribute something - feel free.
Ability to register and authenticate via Google+/Facebook/Twitter etc could be an interesting project - not for API, for web UI.
RE: authentication - they say: "At its heart REST is a stateless client-server relationship; this means that unlike many other approaches there is no client context being stored server side (no Sessions). To counteract that, each request contains all the information necessary for the server to authenticate the user, and any session state data that must be sent as well."
How do you test API btw? I tried using browser to no luck.
Sent from myMail app for Android Tuesday, 21 July 2015, 10:22AM -07:00 from EYurchenko < notifications@github.com> :
RE: authentication - they say: "At its heart REST is a stateless client-server relationship; this means that unlike many other approaches there is no client context being stored server side (no Sessions). To counteract that, each request contains all the information necessary for the server to authenticate the user, and any session state data that must be sent as well." How do you test API btw? I tried using browser to no luck. — Reply to this email directly or view it on GitHub .
Ok. Rewrite will properly work for API calls only if I rename/remove php/api.php file. Can you please check on kirdyk forum if it is there?
Nice catch! No luck, though - it is there. It is also there in my dev setup (EasyPHP/Windows), and I also have no issues. The .htaccess is written to redirect all requests for missing resources to index.php that implements the REST API. Looks like something else interferes and resolves /api as api.php for you.
api.php is only used by user profile editor, so if you don't need it for development, you can just rename api.php on your machine (or rename it for good... call it profileapi.php or something. it's not a perfect fix, but it'll work).
Thanks. Found that MultiViews option was doing that for me. After applying following change there is no problem with api.php ---Options Indexes FollowSymLinks MultiViews +++Options Indexes FollowSymLinks
Nice!
I think we need to explicitly define Content-Type in responses to all API calls: $response->setContentType('application/json'); It's just easier to read output when you do testing using command line (I've done some, will post code later when have something more concrete) and generally it is more correct than 'plain/html'. i.e. in case of using Httpful library to test like
<?php
include('./httpful.phar');
$response = \Httpful\Request::get("http://<host>/api/threads/4")->send();
print $response->body->id ."\n";
print $response->body->message->subject ."\n";
?>
instead of
PHP Notice: Trying to get property of non-object in ...
we'd have
4
Тест редактирования сообщения
Sure. It makes perfect sense.
Added three things:
1) authentication support (basic http or cookies). 2) new method GET /profile, returns 403. 3) explicit content type.
Check it out!
Implemented like and dislike:
PUT /messages/$id/like DELETE /messages/$id/like
Both methods require authentication
Implemented
POST /threads POST /messages/id/answers PUT /messages/id
Body must be JSON, with fields: subject, body and, optionally, ticket (a unique string, to prevent duplicates) and nsfw flag (boolean)
PUT /messages/id/bookmark DELETE /messages/id/bookmark
Sorry but I still don't get it how you do PUT/POST testing with HTTP authentication. PHP_AUTH_USER and PHP_AUTH_PW are set up only in response to user's input into pop-up Username/Password window which in turn pops up by a browser in response to "WWW-Authenticate:" header. In other words I do not see where you send this header and in what way a native app (let's forget about browsers) should response to it / or provide PHP_AUTH_USER and PHP_AUTH_PW in initial PUT/POST request. Can you share your testing strategy please?
just set the header for basic http authentication, that's all.
see http://kirdyk.radier.ca/restsample.html (the example doesn't actually set the header, as SendRequest is called with null, null as username/password - but the code is there)
PHP_* are server-side things, you need not worry about them.
The easiest way to test is probably with Chrome App called Postman. You can easily compose requests right in its UI and it supports all kinds of HTTP methods, headers, formats and other things including, naturally, Basic HTTP Authentication.
I am a Linux guy -((( prefer testing from command line. Following seems to work: <?php include('./httpful.phar');
$request = \Httpful\Request::post("http://kitchen.bgmot.com/api/threads") ->sendsJson() ->authenticateWith('test','xxx') ->body('{"subject":"subject goes here"}'); $response = $request->send(); if ($response->hasErrors() ){ print_r( $response->_parseHeaders($response->raw_headers)); exit -1; } print($response->raw_body);
oh... by the way body is marked on Wiki as mandatory parameter but validate() actionally does not check that on "" and passes requests with only 'subject' specified. We need either to modify Wiki or add a fix to validate().
Nice work, thanks!
Got the auth test working in mobile app. Getting ready to implement PostReply(). Fingers crossed.
Actually, Ranger, if you could update app.js and index.html on Kyrdyk/mobile it would be greatly appreciated. :-) I was unable to configure my own instance and I gave up on this idea for now
Feel free to use my test-bed at http://kitchen.bgmot.com It's has the latest code from github at the moment.
The latest code was promoted to "production" :)
@BGmot : Thanks! I tried to check http://kitchen.bgmot.com/Mobile/index.html and it's not there. I guess you only managed to configure the desktop portion.
Try now. I did not realize you were going to work with Mobile/ section of this site... sorry.
No problem. And for now you gotta change the root URL in the app.js in order for it to work. We'll keep it as is here for convenience, but eventually it should query a setting or simply detect the forum root URL
Here, in the 1st line: https://github.com/wolfpet/kitchen/blob/master/mobile/www/js/app.js
Now changed to correct URL and the interface looks nice on my BlackBerry -) Unfortunately I don't know javascript and don't know how to get this variable from settings.php or detect on the fly.
We'll figure this out, no worries.
both "mymessages" and "answered" modes should be working now.
Outstanding is PM access. I am thinking:
GET /api/inbox{?id=<max_id>&count=<how_many>}
GET /api/inbox/{id}
GET /api/sent (same parameters)
GET /api/sent{id}
POST /api/sent
A number of new messages in Inbox can be read from /api/profile
What do you think?
How do I specify who is the message for in POST /api/sent ? In the body?
A property in the payload called 'recipient'. Messages returned by /inbox method will have 'author' property in addition to usual subject and body.
sounds good!
Implemented POST /api/sent
'recipient' property is a string (name of the recipient)
I think that's it, folks! I make a motion to close this issue, possible additions can be handled as enhancements
I'm thinking of implementing Pmail to look like a typical email mobile app. Any suggestions on the UI? I personally love Outlook on my phone,
Seems reasonable.
Rationale: mobile client support, dynamic HTML clients etc.
Authentication:
Basic HTTP (username/password in every request or by a token, retrieved by GET /api/profile)
API:
Returns user profile, can be used for authentication. Authentication:
Basic HTTP Auth - username, password
If credentials are valid, the response returns the cookies user2 and auth_cookie2. If the request has no Basic HTTP Auth info, but has the cookies, they will be used to determine user context.
Example of the data returned:
"Collapsed threads" view, also a default view for mobile client. optional arguments - $id (max ID, inclusive), $count (how many threads to return)
Data:
{count: -1, threads: [ {msg_id:-1, subject:"", created:"ts",author : {id:-1, name:""}, answers: {count : -1}, likes:-1, dislikes:-1, flags:[], permissions:[], thread_id:-1} .... ]}
Return message data by ID, including content
Create new topic
Return answers (1 level)
Respond to a message
Like a message
Dislike a message
Optional
Message search (covers modes "By date", "Answered", "My messages")
Update user profile
"Collapsed threads"'s thread view. Returns all responses (subjects + metadata) to thread with id={id}
Enhancements
Update a message