entitlements-app 1.2.3 → 1.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1d78c3e43bb1a892e7d45aa8c1a9c608c26db75f36a8adda13646b5ae9a756dc
4
- data.tar.gz: afd0505ea8106dbaaa3486e1c2dfab168c6209b97d99322cc6f560a6526f8aab
3
+ metadata.gz: bdd6741cf78fb17f3d3cc0e21b27543be1b02810317b906bd7344fc4652f11dd
4
+ data.tar.gz: a4a0ccd8e4ff59d73ec26eb494c16c68ce88d8c4c5df4c6fd969e53d91d92dc6
5
5
  SHA512:
6
- metadata.gz: 0b1279f7726543ffcaf95228c7b0f831f462bcb05431db9acd195afa01f6f40c00561dd0cb81c3c097c9d75291d87db1c2eb16a237e2ced1b22ac3d00b8967b4
7
- data.tar.gz: b0f8f91d63df0e79a77bf8e00d39a2403a2281a71dc533f7d45bb0ba476c30f45953f828011006a9533ec2f3f77796859a16d5bd832a2e1d4272f8a598894bb8
6
+ metadata.gz: 801efc4677593d00afd2c52e60c56d1fdb5b5fb87c9957c2bc71f7a9adc7766cfd4e49f95b2621935be7d5fa8001815029b2fe196290312affe4eff93e142092
7
+ data.tar.gz: a179762674b835b741edfdef40ec65f7a57738509c2d31a11aa702ee57aea5c67aaff03761d3f9a89fe1f92258b6d0e5511d9715617df0a5cb5d3f123d0846d9
@@ -217,7 +217,7 @@ module Entitlements
217
217
  return false if expiration.nil? || expiration.strip.empty?
218
218
  if expiration =~ /\A(\d{4})-(\d{2})-(\d{2})\z/
219
219
  year, month, day = Regexp.last_match(1).to_i, Regexp.last_match(2).to_i, Regexp.last_match(3).to_i
220
- return Time.utc(year, month, day, 0, 0, 0) <= Time.now.utc
220
+ return Time.utc(year, month, day, 0, 0, 0) <= Entitlements.evaluation_time.utc
221
221
  end
222
222
  message = "Invalid expiration date #{expiration.inspect} in #{context} (expected format: YYYY-MM-DD)"
223
223
  raise ArgumentError, message
@@ -340,7 +340,7 @@ module Entitlements
340
340
  # Returns C::SetOf[Entitlements::Models::Person] from a recursive call.
341
341
  def handle_and(rule)
342
342
  ensure_type!("and", rule, Array)
343
- return result unless rule.any?
343
+ return Set.new unless rule.any?
344
344
 
345
345
  first_rule = rule.shift
346
346
  ensure_type!("and", first_rule, Hash)
@@ -30,7 +30,7 @@ module Entitlements
30
30
  end
31
31
 
32
32
  # If the date is in the future, leave the entitlement unchanged.
33
- return false if parse_date > Time.now.utc.to_date
33
+ return false if parse_date > Entitlements.evaluation_time.utc.to_date
34
34
 
35
35
  # Empty the group. Set metadata allowing no members. Return true to indicate modification.
36
36
  rs.metadata["no_members_ok"] = true
@@ -21,10 +21,12 @@ module Entitlements
21
21
  # Returns a Set[String] with DN's of the people in the group.
22
22
  Contract C::None => C::Or[:calculating, C::SetOf[Entitlements::Models::Person]]
23
23
  def members
24
- @members ||= begin
25
- Entitlements.logger.debug "Calculating members from #{filename}"
26
- members_from_rules(rules)
27
- end
24
+ return @members if @members
25
+
26
+ Entitlements.logger.debug "Calculating members from #{filename}"
27
+ result = members_from_rules(rules)
28
+ @members = result unless result == :calculating
29
+ result
28
30
  end
29
31
 
30
32
  # Standard interface: Get the description of this group.
@@ -182,7 +184,7 @@ module Entitlements
182
184
  if parsed_data.key?("modifier_expiration") && affirmative.empty?
183
185
  exp_date = parsed_data.fetch("modifier_expiration").fetch("=").first.fetch(:key)
184
186
  date = Entitlements::Util::Util.parse_date(exp_date)
185
- return {"always" => false} if date <= Time.now.utc.to_date
187
+ return {"always" => false} if date <= Entitlements.evaluation_time.utc.to_date
186
188
  end
187
189
 
188
190
  # There has to be at least one affirmative condition, not just all negative ones.
@@ -18,10 +18,12 @@ module Entitlements
18
18
  # Returns a Set[String] with DN's of the people in the group.
19
19
  Contract C::None => C::Or[:calculating, C::SetOf[Entitlements::Models::Person]]
20
20
  def members
21
- @members ||= begin
22
- Entitlements.logger.debug "Calculating members from #{filename}"
23
- members_from_rules(rules)
24
- end
21
+ return @members if @members
22
+
23
+ Entitlements.logger.debug "Calculating members from #{filename}"
24
+ result = members_from_rules(rules)
25
+ @members = result unless result == :calculating
26
+ result
25
27
  end
26
28
 
27
29
  # Standard interface: Get the description of this group.
data/lib/entitlements.rb CHANGED
@@ -22,6 +22,7 @@ require "logger"
22
22
  require "ostruct"
23
23
  require "resolv"
24
24
  require "stringio"
25
+ require "thread"
25
26
  require "uri"
26
27
  require "yaml"
27
28
 
@@ -90,6 +91,7 @@ module Entitlements
90
91
  @config = nil
91
92
  @config_file = nil
92
93
  @config_path_override = nil
94
+ @evaluation_time = nil
93
95
  @person_extra_methods = {}
94
96
  @statsd = nil
95
97
 
@@ -97,6 +99,24 @@ module Entitlements
97
99
  Entitlements::Data::Groups::Calculated.reset!
98
100
  end
99
101
 
102
+ # Return the fixed time used for the current date-sensitive entitlement evaluation.
103
+ #
104
+ # Returns a Time.
105
+ Contract C::None => Time
106
+ def self.evaluation_time
107
+ @evaluation_time ||= Time.now
108
+ end
109
+
110
+ # Set the time used for date-sensitive entitlement evaluation.
111
+ #
112
+ # value - A Time.
113
+ #
114
+ # Returns the supplied Time.
115
+ Contract Time => Time
116
+ def self.evaluation_time=(value)
117
+ @evaluation_time = value
118
+ end
119
+
100
120
  def self.reset_extras!
101
121
  extras_loaded = @extras_loaded
102
122
  if extras_loaded
@@ -438,19 +458,33 @@ module Entitlements
438
458
  # Calculate old and new membership in each group.
439
459
  thread_pool = Concurrent::FixedThreadPool.new(max_parallelism)
440
460
  logger.debug("Begin prefetch and validate for all groups")
461
+
441
462
  prep_start = Time.now
442
- futures = Entitlements.child_classes.map do |group_name, obj|
443
- Concurrent::Future.execute({ executor: thread_pool }) do
444
- group_start = Time.now
445
- logger.debug("Begin prefetch and validate for #{group_name}")
446
- provider = Entitlements.config["groups"].fetch(group_name).fetch("type")
447
- timed_operation(phase: "prefetch", provider: provider, target: group_name, concurrent: true) { obj.prefetch }
448
- timed_operation(phase: "validate", provider: provider, target: group_name, concurrent: true) { obj.validate }
449
- logger.debug("Finished prefetch and validate for #{group_name} in #{Time.now - group_start}")
463
+ jobs = Entitlements.child_classes
464
+ completions = Queue.new
465
+
466
+ begin
467
+ jobs.each do |group_name, obj|
468
+ thread_pool.post do
469
+ group_start = Time.now
470
+ logger.debug("Begin prefetch and validate for #{group_name}")
471
+ provider = Entitlements.config["groups"].fetch(group_name).fetch("type")
472
+ timed_operation(phase: "prefetch", provider: provider, target: group_name, concurrent: true) { obj.prefetch }
473
+ timed_operation(phase: "validate", provider: provider, target: group_name, concurrent: true) { obj.validate }
474
+ logger.debug("Finished prefetch and validate for #{group_name} in #{Time.now - group_start}")
475
+ completions << nil
476
+ rescue => e
477
+ completions << e
478
+ end
450
479
  end
451
- end
452
480
 
453
- futures.each(&:value!)
481
+ jobs.size.times do
482
+ exception = completions.pop
483
+ raise exception if exception
484
+ end
485
+ ensure
486
+ thread_pool.kill
487
+ end
454
488
  logger.debug("Finished all prefetch and validate in #{Time.now - prep_start}")
455
489
 
456
490
  logger.debug("Begin all calculations")
data/lib/version.rb CHANGED
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Entitlements
4
4
  module Version
5
- VERSION = "1.2.3"
5
+ VERSION = "1.2.5"
6
6
  end
7
7
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: entitlements-app
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.3
4
+ version: 1.2.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - GitHub, Inc. Security Ops
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-09-14 00:00:00.000000000 Z
11
+ date: 2026-09-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby