--
-- Licensed to the Apache Software Foundation (ASF) under one or more
-- contributor license agreements.  See the NOTICE file distributed with
-- this work for additional information regarding copyright ownership.
-- The ASF licenses this file to You under the Apache License, Version 2.0
-- (the "License"); you may not use this file except in compliance with
-- the License.  You may obtain a copy of the License at
--
--     http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software
-- distributed under the License is distributed on an "AS IS" BASIS,
-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-- See the License for the specific language governing permissions and
-- limitations under the License.
--

--- @module clientSecret
-- Check a subscription with a client id and a hashed secret
local _M = {}

local utils = require "lib/utils"
local request = require "lib/request"

--- Validate that the subscription exists in the dataStore
-- @param dataStore the datastore object
-- @param tenant the tenantId we are checking for
-- @param gatewayPath the possible resource we are checking for
-- @param apiId if we are checking for an api
-- @param scope which values should we be using to find the location of the secret
-- @param clientId the subscribed client id
-- @param clientSecret the hashed client secret
local function validate(dataStore, tenant, gatewayPath, apiId, scope, clientId, clientSecret)
  -- Open connection to redis or use one from connection pool
  local k
  if scope == "tenant" then
    k = utils.concatStrings({"subscriptions:tenant:", tenant})
  elseif scope == "resource" then
    k = utils.concatStrings({"subscriptions:tenant:", tenant, ":resource:", gatewayPath})
  elseif scope == "api" then
    k = utils.concatStrings({"subscriptions:tenant:", tenant, ":api:", apiId})
  end
  -- using the same key location in redis, just using :clientsecret: instead of :key:
  k = utils.concatStrings({k, ":clientsecret:", clientId, ":", clientSecret})
  if dataStore:exists(k) == 1 then
    return k
  else
    return nil
  end
end

--- In order to properly test this functionallity, I use this function to do all of the business logic with injected dependencies
-- Takes 2 headers and decides if the request should be allowed based on a hashed secret key
-- @param dataStore the datastore object
-- @param securityObj the security configuration for the tenant/resource/api we are verifying
-- @param hashFunction the function used to perform the hash of the api secret
local function processWithHashFunction(dataStore, securityObj, hashFunction)
  -- pull the configuration from nginx
  local tenant = ngx.var.tenant
  local gatewayPath = ngx.var.gatewayPath
  local apiId = ngx.var.apiId
  local scope = securityObj.scope
  local queryString = ngx.req.get_uri_args()
  local location = (securityObj.location == nil) and "header" or securityObj.location
  local clientId = nil
  local clientSecret = nil

  ngx.log(ngx.DEBUG, "Processing CLIENT_SECRET security policy")

  -- allow support for custom names in query or header
  local clientIdName = (securityObj.idFieldName == nil) and "X-Client-ID" or securityObj.idFieldName
  if location == "header" then
    clientId = ngx.var[utils.concatStrings({"http_", clientIdName}):gsub("-", "_")]
  end
  if location == "query" then
    clientId = queryString[clientIdName]
  end
  -- if they didn't supply whatever name this is configured to require, error out
  if clientId == nil or clientId == "" then
    request.err(401, clientIdName .. " required")
    return false
  end

  -- allow support for custom names in query or header
  local clientSecretName = (securityObj.secretFieldName == nil) and "X-Client-Secret" or securityObj.secretFieldName
  ngx.ctx.clientSecretName = clientSecretName:lower()
  if location == "header" then
    clientSecret = ngx.var[utils.concatStrings({"http_", clientSecretName}):gsub("-", "_")]
  end
  if location == "query" then
    clientSecret = queryString[clientSecretName]
  end
  -- if they didn't supply whatever name this is configured to require, error out
  if clientSecret == nil or clientSecret == "" then
    request.err(401, clientSecretName .. " required")
    return false
  end

  -- hash the secret
  local result = validate(dataStore, tenant, gatewayPath, apiId, scope, clientId, hashFunction(clientSecret))
  if result == nil then
    request.err(401, "Secret mismatch or not subscribed to this api.")
  end
  ngx.var.apiKey = clientId
  return result
end

--- Process function main entry point for the security block.
--  Takes 2 headers and decides if the request should be allowed based on a hashed secret key
--@param dataStore the datastore object
--@param securityObj the security object loaded from nginx.conf
--@return a string representation of what this looks like in redis :clientsecret:clientid:hashed secret
local function process(dataStore, securityObj)
  return processWithHashFunction(dataStore, securityObj, utils.hash)
end

_M.processWithHashFunction = processWithHashFunction
_M.process = process
return _M
