11module ForestLiana
22 class ScopeManager
3- @@scopes_cache = Hash . new
4- # 5 minutes exipration cache
3+ # 5 minutes expiration cache
54 @@scope_cache_expiration_delta = 300
65
7- def self . apply_scopes_on_records ( records , forest_user , collection_name , timezone )
8- scope_filters = get_scope_for_user ( forest_user , collection_name , as_string : true )
6+ def self . apply_scopes_on_records ( records , user , collection_name , timezone )
7+ scope_filters = get_scope ( collection_name , user )
98
109 return records if scope_filters . blank?
1110
1211 FiltersParser . new ( scope_filters , records , timezone ) . apply_filters
1312 end
1413
15- def self . append_scope_for_user ( existing_filter , user , collection_name )
16- existing_filter = existing_filter . to_json if existing_filter . is_a? ( ActionController :: Parameters )
17- scope_filter = get_scope_for_user ( user , collection_name , as_string : true )
14+ def self . append_scope_for_user ( existing_filter , user , collection_name , request_context_variables = nil )
15+ existing_filter = inject_context_variables ( existing_filter , user , request_context_variables ) if existing_filter
16+ scope_filter = get_scope ( collection_name , user , request_context_variables )
1817 filters = [ existing_filter , scope_filter ] . compact
1918
2019 case filters . length
@@ -23,80 +22,57 @@ def self.append_scope_for_user(existing_filter, user, collection_name)
2322 when 1
2423 filters [ 0 ]
2524 else
26- "{ \" aggregator\" : \" and\" , \" conditions\" :[ #{ existing_filter } , #{ scope_filter } ]}"
25+ { ' aggregator' => ' and' , ' conditions' => [ existing_filter , scope_filter ] }
2726 end
2827 end
2928
30- def self . get_scope_for_user ( user , collection_name , as_string : false )
31- raise 'Missing required rendering_id' unless user [ 'rendering_id' ]
32- raise 'Missing required collection_name' unless collection_name
29+ def self . get_scope ( collection_name , user , request_context_variables = nil )
30+ retrieve = fetch_scopes ( user [ 'rendering_id' ] )
31+ scope = retrieve [ 'scopes' ] [ collection_name ]
3332
34- collection_scope = get_collection_scope ( user [ 'rendering_id' ] , collection_name )
33+ return nil if scope . nil?
3534
36- return nil unless collection_scope
37-
38- filters = format_dynamic_values ( user [ 'id' ] , collection_scope )
39-
40- as_string && filters ? JSON . generate ( filters ) : filters
35+ inject_context_variables ( scope , user , request_context_variables )
4136 end
4237
43- def self . get_collection_scope ( rendering_id , collection_name )
44- if !@@scopes_cache [ rendering_id ]
45- # when scope cache is unset wait for the refresh
46- refresh_scopes_cache ( rendering_id )
47- elsif has_cache_expired? ( rendering_id )
48- # when cache expired refresh the scopes without waiting for it
49- Thread . new { refresh_scopes_cache ( rendering_id ) }
50- end
38+ def self . inject_context_variables ( filter , user , request_context_variables = nil )
39+ filter = JSON . parse ( filter ) if filter . is_a? String
5140
52- @@scopes_cache [ rendering_id ] [ :scopes ] [ collection_name ] . deep_dup
53- end
41+ retrieve = fetch_scopes ( user [ ' rendering_id' ] )
42+ context_variables = Utils :: ContextVariables . new ( retrieve [ 'team' ] , user , request_context_variables )
5443
55- def self . has_cache_expired? ( rendering_id )
56- rendering_scopes = @@scopes_cache [ rendering_id ]
57- return true unless rendering_scopes
58-
59- second_since_last_fetch = Time . now - rendering_scopes [ :fetched_at ]
60- second_since_last_fetch >= @@scope_cache_expiration_delta
44+ Utils ::ContextVariablesInjector . inject_context_in_filter ( filter , context_variables )
6145 end
6246
63- def self . refresh_scopes_cache ( rendering_id )
64- scopes = fetch_scopes ( rendering_id )
65- @@scopes_cache [ rendering_id ] = {
66- :fetched_at => Time . now ,
67- :scopes => scopes
68- }
47+ def self . invalidate_scope_cache ( rendering_id )
48+ Rails . cache . delete ( 'forest.scopes.' + rendering_id . to_s )
6949 end
7050
7151 def self . fetch_scopes ( rendering_id )
72- query_parameters = { 'renderingId' => rendering_id }
73- response = ForestLiana ::ForestApiRequester . get ( '/liana/scopes' , query : query_parameters )
52+ response = ForestLiana ::ForestApiRequester . get ( "/liana/v4/permissions/renderings/#{ rendering_id } " )
7453
7554 if response . is_a? ( Net ::HTTPOK )
76- JSON . parse ( response . body )
55+ Rails . cache . fetch ( 'forest.scopes.' + rendering_id . to_s , expires_in : @@scope_cache_expiration_delta ) do
56+ data = { }
57+ parse_response = JSON . parse ( response . body )
58+
59+ data [ 'scopes' ] = decode_scope ( parse_response [ 'collections' ] )
60+ data [ 'team' ] = parse_response [ 'team' ]
61+
62+ data
63+ end
7764 else
7865 raise 'Unable to fetch scopes'
7966 end
8067 end
8168
82- def self . format_dynamic_values ( user_id , collection_scope )
83- filter = collection_scope . dig ( 'scope' , 'filter' )
84- return nil unless filter
85-
86- dynamic_scopes_values = collection_scope . dig ( 'scope' , 'dynamicScopesValues' )
87-
88- # Only goes one level deep as required for now
89- filter [ 'conditions' ] . map do |condition |
90- value = condition [ 'value' ]
91- if value . is_a? ( String ) && value . start_with? ( '$currentUser' )
92- condition [ 'value' ] = dynamic_scopes_values . dig ( 'users' , user_id , value )
93- end
69+ def self . decode_scope ( raw_scopes )
70+ scopes = { }
71+ raw_scopes . each do |collection_name , value |
72+ scopes [ collection_name ] = value [ 'scope' ] unless value [ 'scope' ] . nil?
9473 end
95- filter
96- end
9774
98- def self . invalidate_scope_cache ( rendering_id )
99- @@scopes_cache . delete ( rendering_id )
75+ scopes
10076 end
10177 end
10278end
0 commit comments