new API features, better API structure, bug fixes w /get /do /undo
This commit is contained in:
parent
5985920dd4
commit
c041451360
@ -8,12 +8,15 @@ import api_request, abort, assert_model from locate "helpers.api"
|
|||||||
-- import escape_similar_to from locate "db"
|
-- import escape_similar_to from locate "db"
|
||||||
|
|
||||||
get_task = =>
|
get_task = =>
|
||||||
|
unless @params.content or tonumber @params.id
|
||||||
|
@params.content = @params.id
|
||||||
|
@params.id = nil
|
||||||
if @params.id
|
if @params.id
|
||||||
assert_valid @params, {
|
assert_valid @params, {
|
||||||
{"id", exists: true, min_length: 1, "Attempted to select by task id, but no id specified."}
|
{"id", exists: true, min_length: 1, "Attempted to select by task id, but no id specified."}
|
||||||
{"id", is_integer: true, "Task id specified is not an integer."}
|
{"id", is_integer: true, "Task id specified is not an integer."}
|
||||||
}
|
}
|
||||||
@task = assert_model Tasks\find id: @params.id, user_id: @user.id
|
@task = assert_model Tasks\find id: tonumber(@params.id), user_id: @user.id
|
||||||
elseif @params.content
|
elseif @params.content
|
||||||
assert_valid @params, {
|
assert_valid @params, {
|
||||||
{"content", exists: true, min_length: 1, "Attempted to select by task content, but no content specified."}
|
{"content", exists: true, min_length: 1, "Attempted to select by task content, but no content specified."}
|
||||||
@ -24,6 +27,17 @@ get_task = =>
|
|||||||
|
|
||||||
abort 404, "Invalid task specified." unless @task
|
abort 404, "Invalid task specified." unless @task
|
||||||
|
|
||||||
|
set_bool = (name) =>
|
||||||
|
if @params[name] == "true"
|
||||||
|
@params[name] = true
|
||||||
|
elseif @params[name] == "false"
|
||||||
|
@params[name] = false
|
||||||
|
if @params[name] != nil and "boolean" != type @params[name]
|
||||||
|
abort "#{name} must be true/false only."
|
||||||
|
|
||||||
|
send_task = =>
|
||||||
|
@write json: { success: true, task: @task }
|
||||||
|
|
||||||
class API extends Application
|
class API extends Application
|
||||||
@path: "/v1"
|
@path: "/v1"
|
||||||
@name: "api_"
|
@name: "api_"
|
||||||
@ -40,41 +54,40 @@ class API extends Application
|
|||||||
abort "Auth: Invalid api_key." unless @user -- NOTE this should also delete the api_key and error (this should never happen!)
|
abort "Auth: Invalid api_key." unless @user -- NOTE this should also delete the api_key and error (this should never happen!)
|
||||||
)
|
)
|
||||||
|
|
||||||
[new: "/new"]: api_request =>
|
[action: "/:action(/:id)"]: api_request =>
|
||||||
assert_valid @params, {
|
switch @params.action
|
||||||
{"content", exists: true, min_length: 1, "Task content not specified."}
|
when "new"
|
||||||
}
|
unless @params.content or tonumber @params.id
|
||||||
|
@params.content = @params.id
|
||||||
task = assert_model Tasks\create {
|
assert_valid @params, { {"content", exists: true, min_length: 1, "Task content not specified."} }
|
||||||
user_id: @user.id
|
@task = assert_model Tasks\create user_id: @user.id, content: @params.content
|
||||||
content: @params.content
|
send_task(@)
|
||||||
}
|
when "get", "do", "undo", "edit", "delete"
|
||||||
|
|
||||||
return json: { success: true, :task }
|
|
||||||
|
|
||||||
[get: "/get"]: api_request =>
|
|
||||||
get_task(@)
|
get_task(@)
|
||||||
return json: { success: true, :task }
|
else
|
||||||
|
abort "Invalid action: #{@params.action}"
|
||||||
|
|
||||||
[do: "/do"]: api_request =>
|
switch @params.action
|
||||||
get_task(@)
|
when "do"
|
||||||
@task = assert_model @task\update done: true
|
@task = assert_model @task\update done: true
|
||||||
|
when "undo"
|
||||||
return json: { success: true, :task }
|
|
||||||
|
|
||||||
[undo: "/undo"]: api_request =>
|
|
||||||
get_task(@)
|
|
||||||
@task = assert_model @task\update done: false
|
@task = assert_model @task\update done: false
|
||||||
|
when "edit"
|
||||||
return json: { success: true, :task }
|
assert_valid @params, {
|
||||||
|
{"new_content", exists: true, min_length: 1, optional: true, "Cannot set no content on a task."}
|
||||||
[delete: "/delete"]: api_request =>
|
}
|
||||||
get_task(@)
|
set_bool(@, "done")
|
||||||
|
@task = assert_model @task\update content: @params.new_content, done: @params.done
|
||||||
|
when "delete"
|
||||||
if @task\delete!
|
if @task\delete!
|
||||||
return json: { success: true }
|
return json: { success: true }
|
||||||
else
|
else
|
||||||
abort 500, "Error deleting task."
|
abort 500, "Error deleting task."
|
||||||
|
|
||||||
|
send_task(@)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[list: "/list"]: api_request =>
|
[list: "/list"]: api_request =>
|
||||||
assert_valid @params, {
|
assert_valid @params, {
|
||||||
{"count", exists: true, is_integer: true, optional: true, "Count is not an integer."}
|
{"count", exists: true, is_integer: true, optional: true, "Count is not an integer."}
|
||||||
@ -82,7 +95,9 @@ class API extends Application
|
|||||||
{"page", exists: true, is_integer: true, optional: true, "Page is not an integer."}
|
{"page", exists: true, is_integer: true, optional: true, "Page is not an integer."}
|
||||||
{"order", exists: true, one_of: {"asc", "desc"}, optional: true, "Invalid order. (Must be 'asc' or 'desc'.)"}
|
{"order", exists: true, one_of: {"asc", "desc"}, optional: true, "Invalid order. (Must be 'asc' or 'desc'.)"}
|
||||||
}
|
}
|
||||||
|
@params.count = tonumber @params.count
|
||||||
@params.count or= 50
|
@params.count or= 50
|
||||||
|
@params.page = tonumber @params.page
|
||||||
@params.page or= 1
|
@params.page or= 1
|
||||||
@params.order or= "asc"
|
@params.order or= "asc"
|
||||||
@params.page = 1 if @params.page < 1
|
@params.page = 1 if @params.page < 1
|
||||||
@ -91,6 +106,7 @@ class API extends Application
|
|||||||
if @params.done == nil
|
if @params.done == nil
|
||||||
Paginator = Tasks\paginated "WHERE user_id = ? ORDER BY created_at #{@params.order}", @user.id, per_page: @params.count
|
Paginator = Tasks\paginated "WHERE user_id = ? ORDER BY created_at #{@params.order}", @user.id, per_page: @params.count
|
||||||
else
|
else
|
||||||
|
set_bool(@, "done")
|
||||||
Paginator = Tasks\paginated "WHERE user_id = ? AND done = ? ORDER BY created_at #{@params.order}", @user.id, @params.done, per_page: @params.count
|
Paginator = Tasks\paginated "WHERE user_id = ? AND done = ? ORDER BY created_at #{@params.order}", @user.id, @params.done, per_page: @params.count
|
||||||
|
|
||||||
num_pages = Paginator\num_pages!
|
num_pages = Paginator\num_pages!
|
||||||
@ -98,9 +114,11 @@ class API extends Application
|
|||||||
@params.page = num_pages
|
@params.page = num_pages
|
||||||
tasks = Paginator\get_page(@params.page)
|
tasks = Paginator\get_page(@params.page)
|
||||||
|
|
||||||
-- returns page in case it returned a different page than you asked for! (in the case you ask for a page beyond the end)
|
-- returns page in case it returned a different page than you asked for! (in the case you ask for an out-of-range page)
|
||||||
return json: { success: true, page: @params.page, pages: num_pages, :tasks }
|
return json: { success: true, page: @params.page, pages: num_pages, :tasks }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
[random: "/random"]: api_request =>
|
[random: "/random"]: api_request =>
|
||||||
-- assert_valid @params, {
|
-- assert_valid @params, {
|
||||||
-- {"count", exists: true, is_integer: true, optional: true, "Count is not an integer."}
|
-- {"count", exists: true, is_integer: true, optional: true, "Count is not an integer."}
|
||||||
@ -131,20 +149,16 @@ class API extends Application
|
|||||||
api_key = assert_model APIKeys\create(@user)
|
api_key = assert_model APIKeys\create(@user)
|
||||||
return json: { success: true, :api_key }
|
return json: { success: true, :api_key }
|
||||||
|
|
||||||
[delete_key: "/key/delete"]: api_request =>
|
[delete_key: "/key/delete(/:key)"]: api_request =>
|
||||||
if @params.id
|
if @params.id
|
||||||
assert_valid @params, {
|
abort "api_key IDs do not exist anymore (sorry!)." -- no one should ever run into this
|
||||||
{"id", exists: true, min_length: 1, "Attempted to select by API key id, but no id specified."}
|
|
||||||
{"id", is_integer: true, "API key id is not an integer."}
|
|
||||||
}
|
|
||||||
@key_to_delete = assert_model APIKeys\find id: @params.id, user_id: @user.id
|
|
||||||
elseif @params.key
|
elseif @params.key
|
||||||
assert_valid @params, {
|
assert_valid @params, {
|
||||||
{"key", exists: true, min_length: 32, max_length: 32, "Invalid api_key specified."}
|
{"key", exists: true, min_length: 32, max_length: 32, "Invalid api_key specified."}
|
||||||
}
|
}
|
||||||
@key_to_delete = assert_model APIKeys\find key: @params.key, user_id: @user.id
|
@key_to_delete = assert_model APIKeys\find key: @params.key, user_id: @user.id
|
||||||
else
|
else
|
||||||
abort 400, "No api_key specified."
|
abort "No api_key specified."
|
||||||
|
|
||||||
abort 404, "Invalid api_key specified." unless @key_to_delete
|
abort 404, "Invalid api_key specified." unless @key_to_delete
|
||||||
if @key_to_delete\delete!
|
if @key_to_delete\delete!
|
||||||
|
@ -14,7 +14,7 @@ api_request = (fn) ->
|
|||||||
insert errors, err[2]
|
insert errors, err[2]
|
||||||
else
|
else
|
||||||
insert errors, err
|
insert errors, err
|
||||||
return(:status, json: { :errors })
|
return(:status, json: { success: false, :errors })
|
||||||
}
|
}
|
||||||
|
|
||||||
abort = (status, message) ->
|
abort = (status, message) ->
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import create_table, types, create_index, add_column from require "lapis.db.schema"
|
import create_table, types, create_index, add_column, drop_column from require "lapis.db.schema"
|
||||||
import make_migrations, autoload from require "locator"
|
import make_migrations, autoload from require "locator"
|
||||||
import settings from autoload "utility"
|
import settings from autoload "utility"
|
||||||
|
|
||||||
@ -37,9 +37,13 @@ make_migrations {
|
|||||||
[1524605427]: =>
|
[1524605427]: =>
|
||||||
add_column "api_keys", "id", types.serial primary_key: true
|
add_column "api_keys", "id", types.serial primary_key: true
|
||||||
|
|
||||||
|
-- technically there should be a migration here to wipe out the api_keys table
|
||||||
|
-- due to a strange bug with how adding an id to api_keys works (I think)
|
||||||
|
|
||||||
[1524607145]: =>
|
[1524607145]: =>
|
||||||
settings.set "simplex.key-increment", 100 -- I had been accidentally deleting this key over and over again
|
settings.set "simplex.key-increment", 100 -- I had been accidentally deleting this key over and over again
|
||||||
|
|
||||||
-- technically there should be a migration here to wipe out the api_keys table
|
[1525245815]: =>
|
||||||
-- due to a strange bug with how adding an id to api_keys works (I think)
|
drop_column "api_keys", "id"
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -15,8 +15,8 @@ class APIKeys extends Model
|
|||||||
error "API Keys need to be created using a user model."
|
error "API Keys need to be created using a user model."
|
||||||
|
|
||||||
values = {}
|
values = {}
|
||||||
while true
|
|
||||||
values.user_id = user.id
|
values.user_id = user.id
|
||||||
|
while true
|
||||||
values.key = encode_base64(bcrypt.digest "#{settings["simplex.key-increment"]}#{user.name}#{user.digest}", settings["users.bcrypt-digest-rounds"])\sub 1, 32
|
values.key = encode_base64(bcrypt.digest "#{settings["simplex.key-increment"]}#{user.name}#{user.digest}", settings["users.bcrypt-digest-rounds"])\sub 1, 32
|
||||||
settings["simplex.key-increment"] += 1
|
settings["simplex.key-increment"] += 1
|
||||||
unless APIKeys\find key: values.key
|
unless APIKeys\find key: values.key
|
||||||
|
Loading…
Reference in New Issue
Block a user