Class: HasGlobalSession::Directory

Inherits:
Object
  • Object
show all
Defined in:
lib/has_global_session/directory.rb

Overview

The global session directory, which provides some lookup and decision services to instances of GlobalSession.

The default implementation is simplistic, but should be suitable for most applications. Directory is designed to be specialized via subclassing. To override the behavior to suit your needs, simply create a subclass of Directory and add a configuration file setting to specify the class name of your implementation:

common:
  directory: MyCoolDirectory

The Authority Keystore

Directory uses a filesystem directory as a backing store for RSA public keys of global session authorities. The directory should contain one or more *.pub files containing OpenSSH-format public RSA keys. The name of the pub file determines the name of the authority it represents.

The Local Authority

Directory will infer the name of the local authority (if any) by looking for a private-key file in the keystore. If a *.key file is found, then its name is taken to be the name of the local authority and all GlobalSessions created will be signed by that authority’s private key.

If more than one key file is found, Directory will raise an error at initialization time.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(configuration, keystore_directory) ⇒ Directory

Create a new Directory.

Parameters

keystore_directory(String)

Absolute path to authority keystore

Raise

ConfigurationError

if too many or too few keys are found, or if .key/.pub files are malformatted

Raises:



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/has_global_session/directory.rb', line 41

def initialize(configuration, keystore_directory)
  @configuration = configuration
  certs = Dir[File.join(keystore_directory, '*.pub')]
  keys  = Dir[File.join(keystore_directory, '*.key')]
  raise ConfigurationError, "Excepted 0 or 1 key files, found #{keys.size}" unless [0, 1].include?(keys.size)

  @authorities = {}
  certs.each do |cert_file|
    basename = File.basename(cert_file)
    authority = basename[0...(basename.rindex('.'))] #chop trailing .ext
    @authorities[authority] = OpenSSL::PKey::RSA.new(File.read(cert_file))
    raise ConfigurationError, "Expected #{basename} to contain an RSA public key" unless @authorities[authority].public?
  end

  if (authority_name = @configuration['authority'])
    key_file = keys.detect { |kf| kf =~ /#{authority_name}.key$/ }
    raise ConfigurationError, "Key file #{authority_name}.key not found" unless key_file        
    @private_key  = OpenSSL::PKey::RSA.new(File.read(key_file))
    raise ConfigurationError, "Expected #{key_file} to contain an RSA private key" unless @private_key.private?
    @local_authority_name = authority_name
  end
end

Instance Attribute Details

#authoritiesObject (readonly)

Returns the value of attribute authorities.



32
33
34
# File 'lib/has_global_session/directory.rb', line 32

def authorities
  @authorities
end

#configurationObject (readonly)

Returns the value of attribute configuration.



32
33
34
# File 'lib/has_global_session/directory.rb', line 32

def configuration
  @configuration
end

#local_authority_nameObject (readonly)

Returns the value of attribute local_authority_name.



32
33
34
# File 'lib/has_global_session/directory.rb', line 32

def local_authority_name
  @local_authority_name
end

#private_keyObject (readonly)

Returns the value of attribute private_key.



32
33
34
# File 'lib/has_global_session/directory.rb', line 32

def private_key
  @private_key
end

Instance Method Details

#report_invalid_session(uuid, expired_at) ⇒ Object

Callback used by GlobalSession objects to report when the application code calls #invalidate! on them. The default implementation of this method does nothing.

uuid(String)

Global session UUID

expired_at(Time)

When the session expired

Return

true

Always returns true



99
100
101
# File 'lib/has_global_session/directory.rb', line 99

def report_invalid_session(uuid, expired_at)
  true
end

#trusted_authority?(authority) ⇒ Boolean

Determine whether this system trusts a particular authority based on the trust settings specified in Configuration.

Parameters

authority(String)

The name of the authority

Return

trusted(true|false)

whether the local system trusts sessions signed by the specified authority

Returns:

  • (Boolean)


72
73
74
# File 'lib/has_global_session/directory.rb', line 72

def trusted_authority?(authority)
  @configuration['trust'].include?(authority)
end

#valid_session?(uuid, expired_at) ⇒ Boolean

Determine whether the given session UUID is valid. The default implementation only considers a session to be invalid if its expired_at timestamp is in the past. Custom implementations might want to consider other factors, such as whether the user has signed out of this node or another node (perhaps using some sort of centralized lookup or single sign-out mechanism).

Parameters

uuid(String)

Global session UUID

expired_at(Time)

When the session expired (or will expire)

Return

valid(true|false)

whether the specified session is valid

Returns:

  • (Boolean)


87
88
89
# File 'lib/has_global_session/directory.rb', line 87

def valid_session?(uuid, expired_at)
  expired_at > Time.now
end