diff --git a/spec/unit/validations_spec.lua b/spec/unit/validations_spec.lua index 3bd16f9b9a0..614c0d92cb3 100644 --- a/spec/unit/validations_spec.lua +++ b/spec/unit/validations_spec.lua @@ -1,8 +1,18 @@ local schemas = require "kong.dao.schemas" +local constants = require "kong.constants" local validate = schemas.validate describe("Validation #schema", function() + it("should return the right alias", function() + assert.are.same("number", schemas.get_type("number")) + assert.are.same("string", schemas.get_type("string")) + assert.are.same("boolean", schemas.get_type("boolean")) + assert.are.same("table", schemas.get_type("table")) + assert.are.same("string", schemas.get_type(constants.DATABASE_TYPES.ID)) + assert.are.same("number", schemas.get_type(constants.DATABASE_TYPES.TIMESTAMP)) + end) + describe("#validate()", function() -- Ok kids, today we're gonna test a custom validation schema, -- grab a pair of glasses, this stuff can literally explode. diff --git a/src/constants.lua b/src/constants.lua index fece0411f95..a3dfefe8bb8 100644 --- a/src/constants.lua +++ b/src/constants.lua @@ -8,6 +8,10 @@ return { UNIQUE = "unique", FOREIGN = "foreign" }, + DATABASE_TYPES = { + ID = "id", + TIMESTAMP = "timestamp" + }, HEADERS = { SERVER = "Server", PROXY_TIME = "X-Kong-Proxy-Time", diff --git a/src/dao/cassandra/accounts.lua b/src/dao/cassandra/accounts.lua index ecae9ca3bfb..c4e3de678cf 100644 --- a/src/dao/cassandra/accounts.lua +++ b/src/dao/cassandra/accounts.lua @@ -1,9 +1,10 @@ local BaseDao = require "kong.dao.cassandra.base_dao" +local constants = require "kong.constants" local SCHEMA = { - id = { type = "id" }, - provider_id = { unique = true, queryable = true }, - created_at = { type = "timestamp" } + id = { type = constants.DATABASE_TYPES.ID }, + provider_id = { type = "string", unique = true, queryable = true }, + created_at = { type = constants.DATABASE_TYPES.TIMESTAMP } } local Accounts = BaseDao:extend() diff --git a/src/dao/cassandra/apis.lua b/src/dao/cassandra/apis.lua index 4be2c9999d6..573cfa46198 100644 --- a/src/dao/cassandra/apis.lua +++ b/src/dao/cassandra/apis.lua @@ -1,12 +1,13 @@ local BaseDao = require "kong.dao.cassandra.base_dao" +local constants = require "kong.constants" local SCHEMA = { - id = { type = "id" }, - name = { required = true, unique = true, queryable = true }, - public_dns = { required = true, unique = true, queryable = true, + id = { type = constants.DATABASE_TYPES.ID }, + name = { type = "string", required = true, unique = true, queryable = true }, + public_dns = { type = "string", required = true, unique = true, queryable = true, regex = "(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])" }, - target_url = { required = true }, - created_at = { type = "timestamp" } + target_url = { type = "string", required = true }, + created_at = { type = constants.DATABASE_TYPES.TIMESTAMP } } local Apis = BaseDao:extend() diff --git a/src/dao/cassandra/applications.lua b/src/dao/cassandra/applications.lua index 85abfb26a15..fc439e53174 100644 --- a/src/dao/cassandra/applications.lua +++ b/src/dao/cassandra/applications.lua @@ -1,11 +1,12 @@ local BaseDao = require "kong.dao.cassandra.base_dao" +local constants = require "kong.constants" local SCHEMA = { - id = { type = "id" }, - account_id = { type = "id", required = true, foreign = true, queryable = true }, - public_key = { required = true, unique = true, queryable = true }, - secret_key = {}, - created_at = { type = "timestamp" } + id = { type = constants.DATABASE_TYPES.ID }, + account_id = { type = constants.DATABASE_TYPES.ID, required = true, foreign = true, queryable = true }, + public_key = { type = "string", required = true, unique = true, queryable = true }, + secret_key = { type = "string" }, + created_at = { type = constants.DATABASE_TYPES.TIMESTAMP } } local Applications = BaseDao:extend() diff --git a/src/dao/cassandra/base_dao.lua b/src/dao/cassandra/base_dao.lua index dcb2a346f28..0f4e9a217a9 100644 --- a/src/dao/cassandra/base_dao.lua +++ b/src/dao/cassandra/base_dao.lua @@ -47,13 +47,13 @@ local function encode_cassandra_values(schema, t, parameters) local schema_field = schema[column] local value = t[column] - if schema_field.type == "id" and value then + if schema_field.type == constants.DATABASE_TYPES.ID and value then if is_valid_uuid(value) then value = cassandra.uuid(value) else errors = utils.add_error(errors, column, value.." is an invalid uuid") end - elseif schema_field.type == "timestamp" and value then + elseif schema_field.type == constants.DATABASE_TYPES.TIMESTAMP and value then value = cassandra.timestamp(value) elseif value == nil then value = cassandra.null diff --git a/src/dao/cassandra/plugins.lua b/src/dao/cassandra/plugins.lua index 0a7597fd499..e490cdb6395 100644 --- a/src/dao/cassandra/plugins.lua +++ b/src/dao/cassandra/plugins.lua @@ -12,13 +12,13 @@ local function load_value_schema(plugin_t) end local SCHEMA = { - id = { type = "id" }, - api_id = { type = "id", required = true, foreign = true, queryable = true }, - application_id = { type = "id", foreign = true, queryable = true, default = constants.DATABASE_NULL_ID }, - name = { required = true, queryable = true, immutable = true }, + id = { type = constants.DATABASE_TYPES.ID }, + api_id = { type = constants.DATABASE_TYPES.ID, required = true, foreign = true, queryable = true }, + application_id = { type = constants.DATABASE_TYPES.ID, foreign = true, queryable = true, default = constants.DATABASE_NULL_ID }, + name = { type = "string", required = true, queryable = true, immutable = true }, value = { type = "table", required = true, schema = load_value_schema }, enabled = { type = "boolean", default = true }, - created_at = { type = "timestamp" } + created_at = { type = constants.DATABASE_TYPES.TIMESTAMP } } local Plugins = BaseDao:extend() diff --git a/src/dao/schemas.lua b/src/dao/schemas.lua index 7e324e0c0eb..9bd9f0cb8ef 100644 --- a/src/dao/schemas.lua +++ b/src/dao/schemas.lua @@ -1,5 +1,6 @@ local rex = require "rex_pcre" -- Why? Lua has built in pattern which should do the job too local utils = require "kong.tools.utils" +local constants = require "kong.constants" local LUA_TYPES = { boolean = true, @@ -8,11 +9,26 @@ local LUA_TYPES = { table = true } +local LUA_TYPE_ALIASES = { + [constants.DATABASE_TYPES.ID] = "string", + [constants.DATABASE_TYPES.TIMESTAMP] = "number" +} + -- -- Schemas -- local _M = {} + +-- Returns the proper Lua type from a schema type, handling aliases +-- @param {string} type_val The type of the schema property +-- @return {string} A valid Lua type +function _M.get_type(type_val) + local alias = LUA_TYPE_ALIASES[type_val] + return alias and alias or type_val +end + + -- Validate a table against a given schema -- @param {table} t Table to validate -- @param {table} schema Schema against which to validate the table @@ -38,7 +54,7 @@ function _M.validate(t, schema, is_update) errors = utils.add_error(errors, column, column.." is required") -- Check type if valid - elseif v.type ~= nil and t[column] ~= nil and type(t[column]) ~= v.type and LUA_TYPES[v.type] then + elseif v.type ~= nil and t[column] ~= nil and type(t[column]) ~= _M.get_type(v.type) and LUA_TYPES[v.type] then errors = utils.add_error(errors, column, column.." is not a "..v.type) -- Check type if value is allowed in the enum diff --git a/src/plugins/ratelimiting/schema.lua b/src/plugins/ratelimiting/schema.lua index bf2db7ae84d..337d60619f1 100644 --- a/src/plugins/ratelimiting/schema.lua +++ b/src/plugins/ratelimiting/schema.lua @@ -2,5 +2,5 @@ local constants = require "kong.constants" return { limit = { required = true, type = "number" }, - period = { required = true, enum = constants.RATELIMIT.PERIODS } + period = { required = true, type = "string", enum = constants.RATELIMIT.PERIODS } } diff --git a/src/plugins/tcplog/schema.lua b/src/plugins/tcplog/schema.lua index 4482b913701..5875720a41f 100644 --- a/src/plugins/tcplog/schema.lua +++ b/src/plugins/tcplog/schema.lua @@ -1,6 +1,6 @@ return { - host = { required = true }, - port = { required = true }, - timeout = { required = false, default = 10000 }, - keepalive = { required = false, default = 60000 } + host = { required = true, type = "string" }, + port = { required = true, type = "number" }, + timeout = { required = false, default = 10000, type = "number" }, + keepalive = { required = false, default = 60000, type = "number" } } diff --git a/src/plugins/udplog/schema.lua b/src/plugins/udplog/schema.lua index fa8c204afa5..9e8c4a9ed3c 100644 --- a/src/plugins/udplog/schema.lua +++ b/src/plugins/udplog/schema.lua @@ -1,5 +1,5 @@ return { - host = { required = true }, - port = { required = true }, - timeout = { required = false, default = 10000 } + host = { required = true, type = "string" }, + port = { required = true, type = "number" }, + timeout = { required = false, default = 10000, type = "number" } }