note description: "[ Global policy cache which is shared between all interfaces. Necessary because different interfaces should use the same cache for policies. ]" author: "Marco Zietzling " date: "$Date$" revision: "$Revision$" class POLICY_CACHE create make feature {NONE} -- Initialization make (a_db_handler: like db_handler) -- Create. require a_db_handler_ok: a_db_handler /= Void do db_handler := a_db_handler -- setup DB access create policy_access.make_policy_access (a_db_handler) -- setup cache create user_associations.make (100) create user_community_associations.make (100) create user_project_associations.make (100) create policies.make (150) -- retrieve existing policies and access groups retrieve_policies retrieve_access_groups ensure db_handler_set: db_handler = a_db_handler end feature -- Access retrieve_associations (a_user: INTEGER) -- Retrieve user, user_project and user_community associations for a_user. require a_user_set: a_user >= 0 local l_lst: LINKED_SET [INTEGER] l_up_assoc: LIST [USER_PROJECT_ASSOCIATION] l_uc_assoc: LIST [USER_COMMUNITY_ASSOCIATION] l_user_assoc: HASH_TABLE [LINKED_SET [INTEGER], INTEGER] l_upac: USER_PROJECT_ASSOCIATION l_ucac: USER_COMMUNITY_ASSOCIATION do -- retrieve user associations create l_lst.make user_associations.force (l_lst, a_user) policy_access.retrieve_user_association (a_user) policy_access.last_user_associations.do_all (agent (a_assoc: USER_ASSOCIATION; a_list: LINKED_SET [INTEGER]) do a_list.force (a_assoc.group_id) end (?, l_lst)) -- retrieve user project associations create l_user_assoc.make (5) user_project_associations.force (l_user_assoc, a_user) policy_access.retrieve_user_project_association (a_user) from l_up_assoc := policy_access.last_user_project_associations l_up_assoc.start until l_up_assoc.after loop l_upac := l_up_assoc.item l_lst := l_user_assoc.item (l_upac.project_id) if l_lst = Void then create l_lst.make l_user_assoc.force (l_lst, l_upac.project_id) end l_lst.force (l_upac.group_id) l_up_assoc.forth end -- retrieve user community associations create l_user_assoc.make (5) user_community_associations.force (l_user_assoc, a_user) policy_access.retrieve_user_community_association (a_user) from l_uc_assoc := policy_access.last_user_community_associations l_uc_assoc.start until l_uc_assoc.after loop l_ucac := l_uc_assoc.item l_lst := l_user_assoc.item (l_ucac.community_id) if l_lst = Void then create l_lst.make l_user_assoc.force (l_lst, l_ucac.community_id) end l_lst.force (l_ucac.group_id) l_uc_assoc.forth end end feature -- Cache user_associations: HASH_TABLE [LINKED_SET [INTEGER], INTEGER] -- access_groups mapped to each user_id (map[user_id]). user_community_associations: HASH_TABLE [HASH_TABLE [LINKED_SET [INTEGER], INTEGER], INTEGER] -- access_groups mapped to each community_id, mapped to each user_id (map[user_id][community_id]). user_project_associations: HASH_TABLE [HASH_TABLE [LINKED_SET [INTEGER], INTEGER], INTEGER] -- access_groups mapped to each project_id, mapped to each user_id (map[user_id][project_id]). policies: HASH_TABLE [LINKED_SET [INTEGER], STRING] -- Needed access_groups mapped to the instruction. global_access_groups: LIST [INTEGER] -- Valid global access groups. project_access_groups: LIST [INTEGER] -- Valid project specific access groups. community_access_groups: LIST [INTEGER] -- Valid community specific access groups. feature -- Utility is_origo_admin (a_user_id: INTEGER): BOOLEAN -- Is `a_user_id' an Origo administrator? do Result := user_associations.item (a_user_id) /= Void and then user_associations.item (a_user_id).has (1) end feature {NONE} -- Implementation db_handler: DATABASE_HANDLER -- Database handler. policy_access: POLICY_CACHE_ACCESS -- DB user access. retrieve_policies -- Retrieve all policies. local l_policies: LIST [POLICY] l_policy: POLICY l_gset: LINKED_SET [INTEGER] do policies.wipe_out policy_access.retrieve_policies from l_policies := policy_access.policies l_policies.start until l_policies.after loop l_policy := l_policies.item l_gset := policies.item (l_policy.instruction) if l_gset = Void then create l_gset.make policies.force (l_gset, l_policy.instruction) end l_gset.force (l_policy.group_id) l_policies.forth end end retrieve_access_groups --Retrieve all possible access groups do policy_access.retrieve_access_groups ("global") global_access_groups := policy_access.last_access_groups policy_access.retrieve_access_groups ("project") project_access_groups := policy_access.last_access_groups policy_access.retrieve_access_groups ("community") community_access_groups := policy_access.last_access_groups end invariant db_handler_not_void: db_handler /= Void policy_access_not_void: policy_access /= Void user_associations_not_void: user_associations /= Void user_community_associations_not_void: user_community_associations /= Void user_project_associations_not_void: user_project_associations /= Void policies_not_void: policies /= Void global_access_groups_not_void: global_access_groups /= Void project_access_groups_not_void: project_access_groups /= Void community_access_groups_not_void: community_access_groups /= Void end