liberator

2016-12-07T03:44:12.000007Z

so, I have a RESTful endpoint POST /token that receives a body with username and password keys and return an auth token. I wanted the following rules to be true: 1. if there is an invalid json, return 400 (malformed) 2. if the json is valid, but there’s no username or no password, or they’re not strings (spec check), then return 422 (unprocessable entity); 3. if everything is valid, but username/password match are not found in database, return 401 (unauthorized). I have two doubts about this: from an HTTP/REST perspective, is this right? and if it is, how would I implement it in liberator? the authorized? decision comes before processable?, so the only way I can see this working is doing the whole logic inside post! or sth like that

2016-12-07T03:55:02.000008Z

I could throw 404 instead of 401 as well and it should work...

2016-12-07T04:03:32.000009Z

it kinda makes sense, as the resource token really does not exist for that username+password. but it feels hacky

ordnungswidrig 2016-12-07T13:43:10.000010Z

you’ve got two options to “flip” the order of authorized? and processable?

ordnungswidrig 2016-12-07T13:44:58.000012Z

@caio you can parse the body in authorized? and in case that fails, return true and store a flag in the context, e.g. {::parse-json-failes? true}. In processable? check for that flag.

ordnungswidrig 2016-12-07T13:47:37.000013Z

the other way is to defer the authorization check until processable? and return a response with a (forced) status code 401. Simply return (ring-response {:your-normal “response”} {:status 401}). This anything in the second map overrides what liberator would generate in the ring response

2016-12-07T14:07:36.000014Z

But that's hacking the state machine. The need to hack it to make it work seems like a bad sign

ordnungswidrig 2016-12-07T15:40:56.000015Z

the state mashine is opinionated. that’s ok 🙂

ordnungswidrig 2016-12-07T15:41:12.000016Z

I, personally, would return 422 if the json is unprocessable.

2016-12-07T15:46:42.000017Z

yeah my feeling’s always been that malformed was for the HTTP request itself, not the body… but all said and done it’s pretty arbitrary

2016-12-07T16:23:33.000018Z

Idk. If the content type is application/json and the body nontains invalid json, I'd say it's malformed (maybe the body is a valid XML and the content type header is the wrong one - there's no way for the backend to know)

2016-12-07T16:24:58.000019Z

If you can parse the json, you have an entity. If it's missing required fields, then it's unprocessable, even though it's a valid entity

2016-12-07T16:28:16.000020Z

But yeah, the standards are really broad. The unauthorized really seems like a stretch (there're no auth headers), but 422 also looks bad: the credentials were processed, it's just that there were no user to generate a token from

2016-12-07T16:29:18.000021Z

Meh. I think I'll return 418 - I'm a teapot

2016-12-07T16:29:46.000022Z

Does liberator have support for that? 😂

2016-12-07T16:30:34.000023Z

:teapot? decision handler

ordnungswidrig 2016-12-07T18:29:25.000025Z

Nope. But you can once again use ring-response to force a status code. Yada supports it imho.