Skip to content

Commit

Permalink
Merge pull request #741 from 3scale/default-credentials-policy
Browse files Browse the repository at this point in the history
[THREESCALE-586] Default credentials policy
  • Loading branch information
davidor authored Jun 4, 2018
2 parents 6a48e85 + 407e7de commit bc19191
Show file tree
Hide file tree
Showing 7 changed files with 622 additions and 1 deletion.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Ability to modify query parameters in the URL rewriting policy [PR #724](https://github.com/3scale/apicast/pull/724)
- 3scale referrer policy [PR #728](https://github.com/3scale/apicast/pull/728)
- Liquid templating support in the rate-limit policy [PR #719](https://github.com/3scale/apicast/pull/719)
- Default credentials policy [PR #741](https://github.com/3scale/apicast/pull/741), [THREESCALE-586](https://issues.jboss.org/browse/THREESCALE-586)

### Changed

Expand Down
69 changes: 69 additions & 0 deletions gateway/src/apicast/policy/default_credentials/apicast-policy.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{
"$schema": "http://apicast.io/policy-v1/schema#manifest#",
"name": "Default credentials",
"summary": "Provides default credentials for unauthenticated requests",
"description":
["This policy allows to expose a service without authentication. ",
"It can be useful, for example, for legacy apps that cannot be adapted to ",
"send the auth params. ",
"When the credentials are not provided in the request, this policy ",
"provides the default ones configured. ",
"An app_id + app_key or a user_key should be configured."],
"version": "builtin",
"configuration": {
"type":"object",
"properties":{
"auth_type":{
"type":"string",
"enum":[
"user_key",
"app_id_and_app_key"
],
"default":"user_key"
}
},
"required":[
"auth_type"
],
"dependencies":{
"auth_type":{
"oneOf":[
{
"properties":{
"auth_type":{
"enum":[
"user_key"
]
},
"user_key":{
"type":"string"
}
},
"required":[
"user_key"
]
},
{
"properties":{
"auth_type":{
"enum":[
"app_id_and_app_key"
]
},
"app_id":{
"type":"string"
},
"app_key":{
"type":"string"
}
},
"required":[
"app_id",
"app_key"
]
}
]
}
}
}
}
102 changes: 102 additions & 0 deletions gateway/src/apicast/policy/default_credentials/default_credentials.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
--- Default credentials policy

local tostring = tostring

local policy = require('apicast.policy')
local _M = policy.new('Default credentials policy')

local new = _M.new

function _M.new(config)
local self = new(config)

if config then
self.default_credentials = {
user_key = config.user_key,
app_id = config.app_id,
app_key = config.app_key
}
else
self.default_credentials = {}
end

return self
end

local function creds_missing(service)
local service_creds = service:extract_credentials()
if not service_creds then return true end

local backend_version = tostring(service.backend_version)

if backend_version == '1' then
return service_creds.user_key == nil
elseif backend_version == '2' then
return service_creds.app_id == nil and service_creds.app_key == nil
end
end

local function provide_creds_for_version_1(service, default_creds)
if default_creds.user_key then
-- follows same format as Service.extract_credentials()
service.extracted_credentials = {
default_creds.user_key,
user_key = default_creds.user_key
}

ngx.log(ngx.DEBUG, 'Provided default creds for request')
else
ngx.log(ngx.WARN, 'No default user key configured')
end
end

local function provide_creds_for_version_2(service, default_creds)
if default_creds.app_id and default_creds.app_key then
-- follows same format as Service.extract_credentials()
service.extracted_credentials = {
default_creds.app_id,
default_creds.app_key,
app_id = default_creds.app_id,
app_key = default_creds.app_key
}

ngx.log(ngx.DEBUG, 'Provided default creds for request')
else
ngx.log(ngx.WARN, 'No default app_id + app_key configured')
end
end

local creds_provider = {
["1"] = provide_creds_for_version_1,
["2"] = provide_creds_for_version_2
}

local function backend_version_is_supported(backend_version)
return creds_provider[backend_version] ~= nil
end

local function provide_creds(service, default_creds)
local backend_version = tostring(service.backend_version)
creds_provider[backend_version](service, default_creds)
end

function _M:rewrite(context)
local service = context.service

if not service then
ngx.log(ngx.ERR, 'No service in the context')
return
end

local backend_version = tostring(service.backend_version)
if not backend_version_is_supported(backend_version) then
ngx.log(ngx.ERR, 'Incompatible backend version: ', backend_version)
return
end

if creds_missing(service) then
provide_creds(service, self.default_credentials)
end
end

return _M
1 change: 1 addition & 0 deletions gateway/src/apicast/policy/default_credentials/init.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
return require('default_credentials')
8 changes: 7 additions & 1 deletion gateway/src/apicast/proxy.lua
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,13 @@ function _M:rewrite(service, context)

ngx.var.secret_token = service.secret_token

local credentials, err = service:extract_credentials()
-- Another policy might have already extracted the creds.
local credentials = service.extracted_credentials

local err
if not credentials then
credentials, err = service:extract_credentials()
end

if not credentials then
ngx.log(ngx.WARN, "cannot get credentials: ", err or 'unknown error')
Expand Down
Loading

0 comments on commit bc19191

Please sign in to comment.