Class: FlossFunding::Namespace

Inherits:
Object
  • Object
show all
Defined in:
lib/floss_funding/namespace.rb

Overview

Represents a logical namespace that groups activation events across one or more libraries
sharing the same namespace string. It mainly serves as a container for ActivationEvent
instances recorded for that namespace.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, base = nil, activation_events = []) ⇒ Namespace

Initialize a Namespace container.

Parameters:

  • name (String)

    the namespace string this object represents

  • base (Module) (defaults to: nil)

    the including module that provides check_activation

  • activation_events (Array<FlossFunding::ActivationEvent>) (defaults to: [])

    initial events (defaults to empty)

Raises:

  • (ArgumentError)


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
# File 'lib/floss_funding/namespace.rb', line 24

def initialize(name, base = nil, activation_events = [])
  raise ArgumentError, "name must be a String" unless name.is_a?(String)

  @name = name
  @env_var_name = ::FlossFunding::UnderBar.env_variable_name(name)
  @activation_key = ENV.fetch(@env_var_name, "")

  # Determine the initial state for this namespace based on its activation key
  @state = begin
    if @activation_key.empty?
      ::FlossFunding::STATES[:unactivated]
    elsif check_unpaid_silence(@activation_key)
      ::FlossFunding::STATES[:activated]
    elsif !(@activation_key =~ ::FlossFunding::HEX_LICENSE_RULE)
      ::FlossFunding::STATES[:invalid]
    else
      plain_text = floss_funding_decrypt(@activation_key)
      if ::FlossFunding.check_activation(plain_text)
        ::FlossFunding::STATES[:activated]
      else
        ::FlossFunding::DEFAULT_STATE
      end
    end
  end

  self.activation_events = activation_events
end

Instance Attribute Details

#activation_eventsArray<FlossFunding::ActivationEvent>

Returns:



17
18
19
# File 'lib/floss_funding/namespace.rb', line 17

def activation_events
  @activation_events
end

#activation_keyString (readonly)

Returns:

  • (String)


13
14
15
# File 'lib/floss_funding/namespace.rb', line 13

def activation_key
  @activation_key
end

#env_var_nameString (readonly)

Returns:

  • (String)


11
12
13
# File 'lib/floss_funding/namespace.rb', line 11

def env_var_name
  @env_var_name
end

#nameString? (readonly)

Returns:

  • (String, nil)


9
10
11
# File 'lib/floss_funding/namespace.rb', line 9

def name
  @name
end

#stateString (readonly)

Returns:

  • (String)


15
16
17
# File 'lib/floss_funding/namespace.rb', line 15

def state
  @state
end

Instance Method Details

#check_unpaid_silence(activation_key) ⇒ Boolean

Returns true for unpaid or opted-out activation_key that
should not emit any console output (silent success).
Otherwise false.

Parameters:

  • activation_key (String)

Returns:

  • (Boolean)


87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/floss_funding/namespace.rb', line 87

def check_unpaid_silence(activation_key)
  return false if activation_key.empty?

  case activation_key
  when ::FlossFunding::FREE_AS_IN_BEER, ::FlossFunding::BUSINESS_IS_NOT_GOOD_YET, "#{::FlossFunding::NOT_FINANCIALLY_SUPPORTING}-#{name}"
    # Configured as unpaid
    true
  else
    # Might be configured as paid
    false
  end
end

#configsArray<FlossFunding::Configuration>

Returns:



65
66
67
# File 'lib/floss_funding/namespace.rb', line 65

def configs
  @activation_events.map(&:library).map(&:config)
end

#floss_funding_decrypt(activation_key) ⇒ String, false

Decrypts a hex-encoded activation key using a namespace-derived key.

Parameters:

  • activation_key (String)

    64-character hex string for paid activation

Returns:

  • (String, false)

    plaintext activation key (base word) on success; false if empty



104
105
106
107
108
109
110
111
112
113
114
# File 'lib/floss_funding/namespace.rb', line 104

def floss_funding_decrypt(activation_key)
  return false if activation_key.nil? || activation_key.empty?

  cipher = OpenSSL::Cipher.new("aes-256-cbc").decrypt
  # Memoize the MD5 hexdigest for this namespace instance
  @ff_key_digest ||= Digest::MD5.hexdigest(name)
  cipher.key = @ff_key_digest
  s = [activation_key].pack("H*")

  cipher.update(s) + cipher.final
end

#has_state?(state) ⇒ Boolean

Returns:

  • (Boolean)


56
57
58
# File 'lib/floss_funding/namespace.rb', line 56

def has_state?(state)
  !activation_events.detect { |ae| ae.state == state }.nil?
end

#merged_config::FlossFunding::Configuration

Merge all configurations for this namespace into a single Configuration.
Concatenates array values for identical keys across configs.



119
120
121
# File 'lib/floss_funding/namespace.rb', line 119

def merged_config
  ::FlossFunding::Configuration.merged_config(configs)
end

#to_sObject



52
53
54
# File 'lib/floss_funding/namespace.rb', line 52

def to_s
  name
end

#with_state(state) ⇒ Object



60
61
62
# File 'lib/floss_funding/namespace.rb', line 60

def with_state(state)
  activation_events.select { |ae| ae.state == state }
end