Class: Keycard::Request::Attributes

Inherits:
Object
  • Object
show all
Defined in:
lib/keycard/request/attributes.rb

Overview

Base class for extracting attributes from a Rack request.

This provides the interface for attribute extraction, independent of how the application is served and accessed. It is not intended to be used directly; you should use AttributesFactory to create an appropriate subclass based on configuration.

The overall design is that a subclass will extract various attributes from the request headers and environment, and a set of attribute finders may be supplied to examine the base set and add additional attributes.

Constant Summary collapse

IDENTITY_ATTRS =
%i[user_pid user_eid].freeze

Instance Method Summary collapse

Constructor Details

#initialize(request, finders: []) ⇒ Attributes

Returns a new instance of Attributes.



17
18
19
20
# File 'lib/keycard/request/attributes.rb', line 17

def initialize(request, finders: [])
  @request = request
  @finders = finders
end

Instance Method Details

#[](attr) ⇒ Object



74
75
76
# File 'lib/keycard/request/attributes.rb', line 74

def [](attr)
  all[attr]
end

#allObject



78
79
80
# File 'lib/keycard/request/attributes.rb', line 78

def all
  base.merge!(external).delete_if { |_k, v| v.nil? || v == '' }
end

#auth_tokenObject

The token supplied by the user via auth_param according to RFC 7235. Typically, this is the API token.



57
58
59
# File 'lib/keycard/request/attributes.rb', line 57

def auth_token
  Keycard::Token.rfc7235(safe('HTTP_AUTHORIZATION'))
end

#baseObject

The set of base attributes for this request.

Subclasses should implement user_pid, user_eid, and client_ip and include them in the hash under those keys.



65
66
67
68
69
70
71
72
# File 'lib/keycard/request/attributes.rb', line 65

def base
  {
    user_pid: user_pid,
    user_eid: user_eid,
    client_ip: client_ip,
    auth_token: auth_token
  }
end

#client_ipObject

The user’s IP address.

This will be a string version of the IP address of the client, whether or not they have been proxied.



51
52
53
# File 'lib/keycard/request/attributes.rb', line 51

def client_ip
  nil
end

#externalObject



82
83
84
85
86
# File 'lib/keycard/request/attributes.rb', line 82

def external
  finders
    .map        { |finder| finder.attributes_for(self) }
    .reduce({}) { |hash, attrs| hash.merge!(attrs) }
end

#identityObject



88
89
90
# File 'lib/keycard/request/attributes.rb', line 88

def identity
  all.select { |k, _v| identity_keys.include?(k.to_sym) }
end

#identity_keysObject



96
97
98
# File 'lib/keycard/request/attributes.rb', line 96

def identity_keys
  @identity_keys ||= IDENTITY_ATTRS + finders.map(&:identity_keys).flatten
end

#supplementalObject



92
93
94
# File 'lib/keycard/request/attributes.rb', line 92

def supplemental
  all.reject { |k, _v| identity_keys.include?(k.to_sym) }
end

#user_eidObject

The user’s enterprise identifier.

If the client has authenticated as a user and the identity provider has releases one, this will be the “enterprise” identifier, some string that is useful for display and resolving to a person. It will tend to be something recognizable to that person, such as a network ID or email address. It may be helpful for displaying who is logged in or looking up directory information, for example. It should not be assumed to be permanent; that is, the EID may change for a person (and PID), so this should not used as a database key, for example.



43
44
45
# File 'lib/keycard/request/attributes.rb', line 43

def user_eid
  nil
end

#user_pidObject

The user’s persistent identifier.

If the client has authenticated as a user, this will be a peristent identifier suitable as a key for an application account. It is expressly opaque, meaning that it cannot be assumed to be resolvable to a person or be useful for display purposes. It can be relied on to be stable for the same person as the identity provider determines that.



29
30
31
# File 'lib/keycard/request/attributes.rb', line 29

def user_pid
  nil
end