summaryrefslogtreecommitdiff
path: root/app/models/api_token.rb
blob: 49b187050e00b73c27290e462d61aee87de1940b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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:
  #
  # {
  #    "<sha521 of token>" => "<username>"
  # }
  #
  # 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