From c63791c7ffacb7c6cfc685e2654ffe66f0a6b185 Mon Sep 17 00:00:00 2001 From: elijah Date: Sun, 20 Mar 2016 01:13:24 -0700 Subject: api tokens: allow for special api tokens that work like session tokens but are configured in the static config, to be used for infrastructure monitoring. --- app/models/api_token.rb | 76 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 app/models/api_token.rb (limited to 'app/models/api_token.rb') diff --git a/app/models/api_token.rb b/app/models/api_token.rb new file mode 100644 index 0000000..49b1870 --- /dev/null +++ b/app/models/api_token.rb @@ -0,0 +1,76 @@ +# +# Works like a regular authentication Token, but is configured in the conf file for +# use by admins or testing. +# +# This is not actually a model, but it used in the place of the normal Token model +# when appropriate +# + +require 'digest/sha2' + +class ApiToken + + # + # Searches static config to see if there is a matching api token string. + # Return an ApiToken if successful, or nil otherwise. + # + def self.find_by_token(token) + if APP_CONFIG["api_tokens"].nil? || APP_CONFIG["api_tokens"].empty? + # no api auth tokens are configured + return nil + elsif !token.is_a?(String) || token.size < 24 + # don't allow obviously invalid token strings + return nil + else + token_digest = Digest::SHA512.hexdigest(token) + username = self.static_auth_tokens[token_digest] + if username + if username == "test" + return ApiTestToken.new + elsif username == "admin" + # not yet supported + return nil + end + else + return nil + end + end + end + + private + + # + # A static hash to represent the configured api auth tokens, in the form: + # + # { + # "" => "" + # } + # + # SHA512 is used here in order to prevent an attacker from discovering + # the value for an auth token by measuring the string comparison time. + # + def self.static_auth_tokens + @static_auth_tokens ||= APP_CONFIG["api_tokens"].inject({}) {|hsh, entry| + hsh[Digest::SHA512.hexdigest(entry[1])] = entry[0] + hsh + }.freeze + end + +end + +class ApiAdminToken < Token + # not yet supported + #def authenticate + # AdminUser.new + #end +end + +# +# These tokens used by the platform to run regular monitor tests +# of a production infrastructure. +# +class ApiTestToken < Token + def authenticate + ApiTestUser.new + end +end -- cgit v1.2.3 From e072ac2fa8bc93ed782df1ff95130f4794f9640f Mon Sep 17 00:00:00 2001 From: elijah Date: Mon, 28 Mar 2016 15:55:19 -0700 Subject: api: added allow ability to limit what IPs can access api using a static configured auth token. --- app/models/api_token.rb | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'app/models/api_token.rb') diff --git a/app/models/api_token.rb b/app/models/api_token.rb index 49b1870..5c7923d 100644 --- a/app/models/api_token.rb +++ b/app/models/api_token.rb @@ -14,10 +14,12 @@ class ApiToken # Searches static config to see if there is a matching api token string. # Return an ApiToken if successful, or nil otherwise. # - def self.find_by_token(token) + def self.find_by_token(token, ip_address=nil) if APP_CONFIG["api_tokens"].nil? || APP_CONFIG["api_tokens"].empty? # no api auth tokens are configured return nil + elsif ip_address && !ip_allowed?(ip_address) + return nil elsif !token.is_a?(String) || token.size < 24 # don't allow obviously invalid token strings return nil @@ -25,8 +27,8 @@ class ApiToken token_digest = Digest::SHA512.hexdigest(token) username = self.static_auth_tokens[token_digest] if username - if username == "test" - return ApiTestToken.new + if username == "monitor" + return ApiMonitorToken.new elsif username == "admin" # not yet supported return nil @@ -51,14 +53,25 @@ class ApiToken # def self.static_auth_tokens @static_auth_tokens ||= APP_CONFIG["api_tokens"].inject({}) {|hsh, entry| - hsh[Digest::SHA512.hexdigest(entry[1])] = entry[0] + if ["monitor", "admin"].include?(entry[0]) + hsh[Digest::SHA512.hexdigest(entry[1])] = entry[0] + end hsh }.freeze end + def self.ip_allowed?(ip) + ip == "0.0.0.0" || + ip == "127.0.0.1" || ( + APP_CONFIG["api_tokens"] && + APP_CONFIG["api_tokens"]["allowed_ips"].is_a?(Array) && + APP_CONFIG["api_tokens"]["allowed_ips"].include?(ip) + ) + end + end -class ApiAdminToken < Token +class ApiAdminToken < ApiToken # not yet supported #def authenticate # AdminUser.new @@ -69,8 +82,8 @@ end # These tokens used by the platform to run regular monitor tests # of a production infrastructure. # -class ApiTestToken < Token +class ApiMonitorToken < ApiToken def authenticate - ApiTestUser.new + ApiMonitorUser.new end end -- cgit v1.2.3