pandorabox-io / pandorabox.io

Pandorabox infrastructure code
https://pandorabox.io
31 stars 4 forks source link

Add ability to POST from digistuff NIC #183

Open thomasrudin opened 5 years ago

thomasrudin commented 5 years ago

See: https://cheapiesystems.com/git/digistuff/tree/nic.lua

Message format

Simple GET (string type)

https://my.api.com/xy

POST (table type)

{
url="https://my.api.com/xy",
extra_headers = { "Accept-Language: en-us", "Accept-Charset: utf-8" },
data="{\"x\":1}"
}

Grand plan

TODO

S-S-X commented 4 years ago

Was there some specific reason why this was closed? Ability to POST would be very useful and all that would be needed is ability to set post_data for HTTPRequest:

`HTTPRequest` definition
------------------------

Used by `HTTPApiTable.fetch` and `HTTPApiTable.fetch_async`.

    {
        url = "http://example.org",

        timeout = 10,
        -- Timeout for connection in seconds. Default is 3 seconds.

        post_data = "Raw POST request data string" OR {field1 = "data1", field2 = "data2"},
        -- Optional, if specified a POST request with post_data is performed.
        -- Accepts both a string and a table. If a table is specified, encodes
        -- table as x-www-form-urlencoded key-value pairs.
        -- If post_data is not specified, a GET request is performed instead.

        user_agent = "ExampleUserAgent",
        -- Optional, if specified replaces the default minetest user agent with
        -- given string

        extra_headers = { "Accept-Language: en-us", "Accept-Charset: utf-8" },
        -- Optional, if specified adds additional headers to the HTTP request.
        -- You must make sure that the header strings follow HTTP specification
        -- ("Key: Value").

        multipart = boolean
        -- Optional, if true performs a multipart HTTP request.
        -- Default is false.
    }

extra_headers would also be useful.

BuckarooBanzay commented 4 years ago

Was there some specific reason why this was closed?

I had a fork of the digistuff mod that made POST requests if the data field was populated, but couldn't reach out to cheapie for a PR... After some updates from her side i threw my fork away and switched to hers again. (i don't have the code anymore but it was just a few lines anyway)

In hindsight i should have wrapped that up in a separated mod/node that just does POST requests (and optionally JSON encoding/decoding). Like the monitoring controller (https://github.com/minetest-monitoring/monitoring/blob/master/monitoring_digilines/metric_controller.lua) or the global_memory controller (https://github.com/BuckarooBanzay/digiline_global_memory/blob/master/controller.lua)

Security-wise i don't think POST'ing would be an issue but it opens some ways to spam websites or REST-Api's. But then again: there are some LuaC limits (length, CPU-Time) so spamming shouldn't be that effective.

S-S-X commented 4 years ago

there are some LuaC limits (length, CPU-Time) so spamming shouldn't be that effective.

It is also possible to add XP check or privilege check through customizations to limit use: can_post_nic(player) would be method to check if supplied player can or cannot use POST with NIC

local original_nic_action = nodedef.digiline.effector.action
local original_nic_after_place_node = nodedef.after_place_node
nodedef.after_place_node = function(pos, placer)
    minetest.get_meta(pos):set_string("owner", placer:get_player_name())
    return original_nic_after_place_node(pos, placer)
end
nodedef.digiline.effector.action = function(pos,node,channel,msg)
  if type(msg) == "table" and msg.post_data then
    local meta = minetest.get_meta(pos)
    if not can_post_nic(meta:get_string("owner")) then
      -- complain via chat maybe?
      return
    end
  end
  return original_nic_action(pos,node,channel,msg)
end