v1 api using api token

This commit is contained in:
Tyler Renelle 2013-01-30 15:57:36 -05:00
parent cd331dbca5
commit b896865865
3 changed files with 40 additions and 20 deletions

View file

@ -12,35 +12,37 @@ module.exports = (expressApp, root, derby) ->
expressApp.get '/terms', (req, res) ->
staticPages.render 'terms', res
# ---------- REST API ------------
# ---------- Deprecated Paths ------------
# Deprecated API (will remove soon)
deprecatedMessage = 'This REST resource is no longer supported, use /users/:uid/tasks/:taskId/:direction instead.'
expressApp.get '/:uid/up/:score?', (req, res) ->
res.send(200, deprecatedMessage)
expressApp.get '/:uid/down/:score?', (req, res) ->
res.send(200, deprecatedMessage)
deprecatedMessage = 'This API is no longer supported, see https://github.com/lefnire/habitrpg/wiki/API for new protocol'
expressApp.get '/:uid/up/:score?', (req, res) -> res.send(500, deprecatedMessage)
expressApp.get '/:uid/down/:score?', (req, res) -> res.send(500, deprecatedMessage)
expressApp.post '/v1/users/:uid/tasks/:taskId/:direction', (req, res) -> res.send(500, deprecatedMessage)
# New API
# test with `curl -X POST -H "Content-Type:application/json" localhost:3000/users/{uid}/tasks/productivity/up`
expressApp.post '/users/:uid/tasks/:taskId/:direction', (req, res) ->
# ---------- v1 API ------------
###
v1 API. Requires user-id and api_token, task-id, direction. Test with:
curl -X POST -H "Content-Type:application/json" -d '{"api_token":"{TOKEN}"}' localhost:3000/v1/users/{UID}/tasks/productivity/up
###
expressApp.post '/v1/users/:uid/tasks/:taskId/:direction', (req, res) ->
{uid, taskId, direction} = req.params
{title, service, icon} = req.body
{api_token, title, service, icon} = req.body
console.log {params:req.params, body:req.body} if process.env.NODE_ENV == 'development'
# Send error responses for improper API call
return res.send(500, 'request body "api_token" required') unless api_token
return res.send(500, ':uid required') unless uid
return res.send(500, ':taskId required') unless taskId
return res.send(500, ":direction must be 'up' or 'down'") unless direction in ['up','down']
model = req.getModel()
model.fetch "users.#{uid}", (err, user) ->
model.fetch model.query('users').withIdAndToken(uid, api_token), (err, result) ->
return res.send(500, err) if err
user = result.at(0)
userObj = user.get()
# Server crashes without this, I think some users are entering non-guid userIds and/or trying to use the API without having an account
unless userObj && !_.isEmpty(userObj.stats)
console.log {taskId:taskId, direction:direction, user:userObj, error: 'non-user attempted to score'} if process.env.NODE_ENV == 'development'
return res.send(500, "User #{uid} not found")
if _.isEmpty(userObj)
return res.send(500, "User with uid=#{uid}, token=#{api_token} not found. Make sure you're not using your username, but your User Id")
model.ref('_user', user)

View file

@ -14,4 +14,17 @@ module.exports = (store) ->
return unless @session and @session.userId # https://github.com/codeparty/racer/issues/37
next = arguments[arguments.length - 1]
isServer = not @req.socket
next(isServer)
next(isServer)
###
Get user with API token
###
store.query.expose "users", "withIdAndToken", (id, api_token) ->
@where("id").equals(id)
.where('preferences.api_token').equals(api_token)
.limit(1)
store.queryAccess "users", "withIdAndToken", (id, token, next) ->
return next(false) unless @session and @session.userId # https://github.com/codeparty/racer/issues/37
isServer = not @req.socket
next(isServer)

View file

@ -8,10 +8,15 @@
<modalDialogs:>
{#if _loggedIn}
<app:myModal modalId="settings-modal" header="Settings">
<strong>User ID</strong><br/>
<small>Copy this ID for use in third party applications.</small>
<pre class=prettyprint>{_user.id}</pre><br/>
<h4>API</h4>
<small>Copy these for use in third party applications.</small>
<h6>User ID</h6>
<pre class=prettyprint>{_user.id}</pre>
<h6>API Token</h6>
<pre class=prettyprint>{_user.preferences.api_token}</pre>
<hr/>
<h4>Gender</h4>
<label class="radio">
<input type="radio" name="genderRadios" value="m" x-bind="click:setMale" checked="{equal(_user.preferences.gender,'m')}">