Class: ForestLiana::ScopeManager

Inherits:
Object
  • Object
show all
Defined in:
app/services/forest_liana/scope_manager.rb

Constant Summary collapse

@@scopes_cache =
Hash.new
@@scope_cache_expiration_delta =

5 minutes exipration cache

300

Class Method Summary collapse

Class Method Details

.append_scope_for_user(existing_filter, user, collection_name) ⇒ Object


15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'app/services/forest_liana/scope_manager.rb', line 15

def self.append_scope_for_user(existing_filter, user, collection_name)
  scope_filter = get_scope_for_user(user, collection_name, as_string: true)
  filters = [existing_filter, scope_filter].compact

  case filters.length
  when 0
    nil
  when 1
    filters[0]
  else
    "{\"aggregator\":\"and\",\"conditions\":[#{existing_filter},#{scope_filter}]}"
  end
end

.apply_scopes_on_records(records, forest_user, collection_name, timezone) ⇒ Object


7
8
9
10
11
12
13
# File 'app/services/forest_liana/scope_manager.rb', line 7

def self.apply_scopes_on_records(records, forest_user, collection_name, timezone)
  scope_filters = get_scope_for_user(forest_user, collection_name, as_string: true)

  return records if scope_filters.blank?

  FiltersParser.new(scope_filters, records, timezone).apply_filters
end

.fetch_scopes(rendering_id) ⇒ Object


70
71
72
73
74
75
76
77
78
79
# File 'app/services/forest_liana/scope_manager.rb', line 70

def self.fetch_scopes(rendering_id)
  query_parameters = { 'renderingId' => rendering_id }
  response = ForestLiana::ForestApiRequester.get('/liana/scopes', query: query_parameters)

  if response.is_a?(Net::HTTPOK)
    JSON.parse(response.body)
  else
    raise 'Unable to fetch scopes'
  end
end

.format_dynamic_values(user_id, collection_scope) ⇒ Object


81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'app/services/forest_liana/scope_manager.rb', line 81

def self.format_dynamic_values(user_id, collection_scope)
  filter = collection_scope.dig('scope', 'filter')
  return nil unless filter

  dynamic_scopes_values = collection_scope.dig('scope', 'dynamicScopesValues')

  # Only goes one level deep as required for now
  filter['conditions'].map do |condition|
    value = condition['value']
    if value.is_a?(String) && value.start_with?('$currentUser')
      condition['value'] = dynamic_scopes_values.dig('users', user_id, value)
    end
  end

  filter
end

.get_collection_scope(rendering_id, collection_name) ⇒ Object


42
43
44
45
46
47
48
49
50
51
52
# File 'app/services/forest_liana/scope_manager.rb', line 42

def self.get_collection_scope(rendering_id, collection_name)
  if !@@scopes_cache[rendering_id]
    # when scope cache is unset wait for the refresh
    refresh_scopes_cache(rendering_id)
  elsif has_cache_expired?(rendering_id)
    # when cache expired refresh the scopes without waiting for it
    Thread.new { refresh_scopes_cache(rendering_id) }
  end

  @@scopes_cache[rendering_id][:scopes][collection_name]
end

.get_scope_for_user(user, collection_name, as_string: false) ⇒ Object


29
30
31
32
33
34
35
36
37
38
39
40
# File 'app/services/forest_liana/scope_manager.rb', line 29

def self.get_scope_for_user(user, collection_name, as_string: false)
  raise 'Missing required rendering_id' unless user['rendering_id']
  raise 'Missing required collection_name' unless collection_name

  collection_scope = get_collection_scope(user['rendering_id'], collection_name)

  return nil unless collection_scope

  filters = format_dynamic_values(user['id'], collection_scope)

  as_string && filters ? JSON.generate(filters) : filters
end

.has_cache_expired?(rendering_id) ⇒ Boolean

Returns:

  • (Boolean)

54
55
56
57
58
59
60
# File 'app/services/forest_liana/scope_manager.rb', line 54

def self.has_cache_expired?(rendering_id)
  rendering_scopes = @@scopes_cache[rendering_id]
  return true unless rendering_scopes

  second_since_last_fetch = Time.now - rendering_scopes[:fetched_at]
  second_since_last_fetch >= @@scope_cache_expiration_delta
end

.invalidate_scope_cache(rendering_id) ⇒ Object


98
99
100
# File 'app/services/forest_liana/scope_manager.rb', line 98

def self.invalidate_scope_cache(rendering_id)
  @@scopes_cache.delete(rendering_id)
end

.refresh_scopes_cache(rendering_id) ⇒ Object


62
63
64
65
66
67
68
# File 'app/services/forest_liana/scope_manager.rb', line 62

def self.refresh_scopes_cache(rendering_id)
  scopes = fetch_scopes(rendering_id)
  @@scopes_cache[rendering_id] = {
    :fetched_at => Time.now,
    :scopes => scopes
  }
end