class GovernanceController(object): def __init__(self,container): log.debug('GovernanceController.__init__()') self.container = container self.enabled = False self.interceptor_by_name_dict = dict() self.interceptor_order = [] self.policy_decision_point_manager = None self.governance_dispatcher = None def start(self): log.debug("GovernanceController starting ...") config = CFG.interceptor.interceptors.governance.config if config is None: config['enabled'] = False if "enabled" in config: self.enabled = config["enabled"] log.debug("GovernanceInterceptor enabled: %s" % str(self.enabled)) self.resource_policy_event_subscriber = None if self.enabled: self.initialize_from_config(config) self.resource_policy_event_subscriber = EventSubscriber(event_type="ResourcePolicyEvent", callback=self.policy_event_callback) self.resource_policy_event_subscriber.activate() self.rr_client = ResourceRegistryServiceProcessClient(node=self.container.node, process=self.container) self.policy_client = PolicyManagementServiceProcessClient(node=self.container.node, process=self.container) self.org_client = OrgManagementServiceProcessClient(node=self.container.node, process=self.container) def initialize_from_config(self, config): self.governance_dispatcher = GovernanceDispatcher() self.policy_decision_point_manager = PolicyDecisionPointManager() if 'interceptor_order' in config: self.interceptor_order = config['interceptor_order'] if 'governance_interceptors' in config: gov_ints = config['governance_interceptors'] for name in gov_ints: interceptor_def = gov_ints[name] # Instantiate and put in by_name array parts = interceptor_def["class"].split('.') modpath = ".".join(parts[:-1]) classname = parts[-1] module = __import__(modpath, fromlist=[classname]) classobj = getattr(module, classname) classinst = classobj() # Put in by_name_dict for possible re-use self.interceptor_by_name_dict[name] = classinst def stop(self): log.debug("GovernanceController stopping ...") if self.resource_policy_event_subscriber is not None: self.resource_policy_event_subscriber.deactivate() def process_incoming_message(self,invocation): self.process_message(invocation, self.interceptor_order,'incoming' ) return self.governance_dispatcher.handle_incoming_message(invocation) def process_outgoing_message(self,invocation): self.process_message(invocation, reversed(self.interceptor_order),'outgoing') return self.governance_dispatcher.handle_outgoing_message(invocation) def process_message(self,invocation,interceptor_list, method): for int_name in interceptor_list: class_inst = self.interceptor_by_name_dict[int_name] getattr(class_inst, method)(invocation) return invocation def policy_event_callback(self, *args, **kwargs): resource_policy_event = args[0] policy_id = resource_policy_event.origin resource_id = resource_policy_event.resource_id resource_type = resource_policy_event.resource_type resource_name = resource_policy_event.resource_name log.info("Resource policy modified: %s %s %s" % ( policy_id, resource_id, resource_type)) if resource_type == 'ServiceDefinition': #TODO - REDO to have a configurable Org boundary by container ion_org = self.org_client.find_org() policy_rules = self.policy_client.get_active_service_policy_rules(ion_org._id, resource_name) self.update_resource_policy(resource_name, policy_rules) elif resource_type == 'Org': policy_rules = self.policy_client.get_active_resource_policy_rules(resource_id) if self.policy_decision_point_manager is not None: self.policy_decision_point_manager.load_org_policy_rules(policy_rules) self.update_all_resource_policies(resource_id) else: policy_rules = self.policy_client.get_active_resource_policy_rules(resource_id) self.update_resource_policy(resource_id, policy_rules) def update_resource_policy(self, resource_name, policy_rules): #Notify policy decision point of updated rules if self.policy_decision_point_manager is not None: log.debug("Loading policy for resource: %s" % resource_name) self.policy_decision_point_manager.load_policy_rules(resource_name, policy_rules) def update_all_resource_policies(self, org_id): #Notify policy decision point of updated rules for all existing service policies if self.policy_decision_point_manager is not None: for res_name in self.policy_decision_point_manager.policy_decision_point: try: policy_rules = self.policy_client.get_active_service_policy_rules(org_id, res_name) self.update_resource_policy(res_name, policy_rules) except Exception, e: log.error(e.message)
class GovernanceController(object): def __init__(self, container): log.debug('GovernanceController.__init__()') self.container = container self.enabled = False self.interceptor_by_name_dict = dict() self.interceptor_order = [] self.policy_decision_point_manager = None self.governance_dispatcher = None def start(self): log.debug("GovernanceController starting ...") config = CFG.interceptor.interceptors.governance.config if config is None: config['enabled'] = False if "enabled" in config: self.enabled = config["enabled"] log.debug("GovernanceInterceptor enabled: %s" % str(self.enabled)) self.resource_policy_event_subscriber = None if self.enabled: self.initialize_from_config(config) self.resource_policy_event_subscriber = EventSubscriber( event_type="ResourcePolicyEvent", callback=self.policy_event_callback) self.resource_policy_event_subscriber.activate() self.rr_client = ResourceRegistryServiceProcessClient( node=self.container.node, process=self.container) self.policy_client = PolicyManagementServiceProcessClient( node=self.container.node, process=self.container) self.org_client = OrgManagementServiceProcessClient( node=self.container.node, process=self.container) def initialize_from_config(self, config): self.governance_dispatcher = GovernanceDispatcher() self.policy_decision_point_manager = PolicyDecisionPointManager() if 'interceptor_order' in config: self.interceptor_order = config['interceptor_order'] if 'governance_interceptors' in config: gov_ints = config['governance_interceptors'] for name in gov_ints: interceptor_def = gov_ints[name] # Instantiate and put in by_name array parts = interceptor_def["class"].split('.') modpath = ".".join(parts[:-1]) classname = parts[-1] module = __import__(modpath, fromlist=[classname]) classobj = getattr(module, classname) classinst = classobj() # Put in by_name_dict for possible re-use self.interceptor_by_name_dict[name] = classinst def stop(self): log.debug("GovernanceController stopping ...") if self.resource_policy_event_subscriber is not None: self.resource_policy_event_subscriber.deactivate() def process_incoming_message(self, invocation): self.process_message(invocation, self.interceptor_order, 'incoming') return self.governance_dispatcher.handle_incoming_message(invocation) def process_outgoing_message(self, invocation): self.process_message(invocation, reversed(self.interceptor_order), 'outgoing') return self.governance_dispatcher.handle_outgoing_message(invocation) def process_message(self, invocation, interceptor_list, method): for int_name in interceptor_list: class_inst = self.interceptor_by_name_dict[int_name] getattr(class_inst, method)(invocation) return invocation def policy_event_callback(self, *args, **kwargs): resource_policy_event = args[0] policy_id = resource_policy_event.origin resource_id = resource_policy_event.resource_id resource_type = resource_policy_event.resource_type resource_name = resource_policy_event.resource_name log.info("Resource policy modified: %s %s %s" % (policy_id, resource_id, resource_type)) if resource_type == 'ServiceDefinition': #TODO - REDO to have a configurable Org boundary by container ion_org = self.org_client.find_org() policy_rules = self.policy_client.get_active_service_policy_rules( ion_org._id, resource_name) self.update_resource_policy(resource_name, policy_rules) elif resource_type == 'Org': policy_rules = self.policy_client.get_active_resource_policy_rules( resource_id) if self.policy_decision_point_manager is not None: self.policy_decision_point_manager.load_org_policy_rules( policy_rules) self.update_all_resource_policies(resource_id) else: policy_rules = self.policy_client.get_active_resource_policy_rules( resource_id) self.update_resource_policy(resource_id, policy_rules) def update_resource_policy(self, resource_name, policy_rules): #Notify policy decision point of updated rules if self.policy_decision_point_manager is not None: log.debug("Loading policy for resource: %s" % resource_name) self.policy_decision_point_manager.load_policy_rules( resource_name, policy_rules) def update_all_resource_policies(self, org_id): #Notify policy decision point of updated rules for all existing service policies if self.policy_decision_point_manager is not None: for res_name in self.policy_decision_point_manager.policy_decision_point: try: policy_rules = self.policy_client.get_active_service_policy_rules( org_id, res_name) self.update_resource_policy(res_name, policy_rules) except Exception, e: log.error(e.message)
def op_load_system_policies(cls, calling_process): org_client = OrgManagementServiceProcessClient(node=Container.instance.node, process=calling_process) ion_org = org_client.find_org() id_client = IdentityManagementServiceProcessClient(node=Container.instance.node, process=calling_process ) system_actor = id_client.find_actor_identity_by_name(name=CFG.system.system_actor) log.debug('system actor:' + system_actor._id) policy_client = PolicyManagementServiceProcessClient(node=Container.instance.node, process=calling_process) policy_text = ''' <Rule RuleId="urn:oasis:names:tc:xacml:2.0:example:ruleid:%s" Effect="Deny"> <Description> %s </Description> <Target> <Subjects> <Subject> <SubjectMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">anonymous</AttributeValue> <SubjectAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </SubjectMatch> </Subject> </Subjects> </Target> </Rule> ''' policy_obj = IonObject(RT.Policy, name='Anonymous_Deny_Everything', definition_type="global", rule=policy_text, description='A global policy rule that denies anonymous access to everything in the Org as the base') policy_id = policy_client.create_policy(policy_obj, headers={'ion-actor-id': system_actor._id}) policy_client.add_resource_policy(ion_org._id, policy_id, headers={'ion-actor-id': system_actor._id}) log.debug('Policy created: ' + policy_obj.name) ############## policy_text = ''' <Rule RuleId="urn:oasis:names:tc:xacml:2.0:example:ruleid:%s" Effect="Permit"> <Description> %s </Description> <Target> <Subjects> <Subject> <SubjectMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">anonymous</AttributeValue> <SubjectAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </SubjectMatch> </Subject> </Subjects> <Actions> <Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-regexp-match"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">read</AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ActionMatch> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-regexp-match"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">find</AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ActionMatch> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-regexp-match"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">get</AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ActionMatch> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">signon</AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ActionMatch> </Action> </Actions> </Target> <Condition> <Apply FunctionId="urn:oasis:names:tc:xacml:ooi:function:not"> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-at-least-one-member-of"> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-bag"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">find_requests</AttributeValue> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">find_user_requests</AttributeValue> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">find_enrolled_users</AttributeValue> </Apply> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </Apply> </Apply> </Condition> </Rule> ''' policy_obj = IonObject(RT.Policy, name='Anonymous_Allowed_Operations', definition_type="global", rule=policy_text, description='A global policy rule which specifies operations that are allowed with anonymous access') policy_id = policy_client.create_policy(policy_obj, headers={'ion-actor-id': system_actor._id}) policy_client.add_resource_policy(ion_org._id, policy_id, headers={'ion-actor-id': system_actor._id}) log.debug('Policy created: ' + policy_obj.name) ############## policy_client = PolicyManagementServiceProcessClient(node=Container.instance.node, process=calling_process) policy_text = ''' <Rule RuleId="urn:oasis:names:tc:xacml:2.0:example:ruleid:%s" Effect="Permit"> <Description> %s </Description> <Target> </Target> <Condition> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-at-least-one-member-of"> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-bag"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">ORG_MANAGER</AttributeValue> </Apply> <SubjectAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-role-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </Apply> </Condition> </Rule> ''' policy_obj = IonObject(RT.Policy, name='Org_Manager_Permit_Everything', definition_type="global", rule=policy_text, description='A global policy rule that permits access to everything in the Org for a user with Org Manager role') policy_id = policy_client.create_policy(policy_obj, headers={'ion-actor-id': system_actor._id}) policy_client.add_resource_policy(ion_org._id, policy_id, headers={'ion-actor-id': system_actor._id}) log.debug('Policy created: ' + policy_obj.name) ############## policy_client = PolicyManagementServiceProcessClient(node=Container.instance.node, process=calling_process) policy_text = ''' <Rule RuleId="urn:oasis:names:tc:xacml:2.0:example:ruleid:%s" Effect="Permit"> <Description> %s </Description> <Target> </Target> <Condition> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-at-least-one-member-of"> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-bag"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">ION_MANAGER</AttributeValue> </Apply> <SubjectAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-role-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </Apply> </Condition> </Rule> ''' policy_obj = IonObject(RT.Policy, name='ION_Manager_Permit_Everything', definition_type="global", rule=policy_text, description='A global policy rule that permits access to everything across Orgs for user with ION Manager role') policy_id = policy_client.create_policy(policy_obj, headers={'ion-actor-id': system_actor._id}) policy_client.add_resource_policy(ion_org._id, policy_id, headers={'ion-actor-id': system_actor._id}) log.debug('Policy created: ' + policy_obj.name) ############## policy_text = ''' <Rule RuleId="urn:oasis:names:tc:xacml:2.0:example:ruleid:%s" Effect="Permit"> <Description> %s </Description> <Target> <Subjects> <Subject> <SubjectMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">anonymous</AttributeValue> <SubjectAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </SubjectMatch> </Subject> </Subjects> <Resources> <Resource> <ResourceMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">datastore</AttributeValue> <ResourceAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ResourceMatch> </Resource> </Resources> <Actions> <Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">create_doc</AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ActionMatch> </Action> </Actions> </Target> <Condition> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> <SubjectAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-sender-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </Apply> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">bootstrap</AttributeValue> </Apply> </Condition> </Rule> ''' policy_obj = IonObject(RT.Policy, name='DataStore_Anonymous_Bootstrap', definition_type="service", rule=policy_text, description='Permit anonymous access to these operations in the Datastore Service if called from the Bootstrap Service') policy_id = policy_client.create_policy(policy_obj) policy_client.add_service_policy('datastore', policy_id) log.debug('Policy created: ' + policy_obj.name) ############## policy_text = ''' <Rule RuleId="urn:oasis:names:tc:xacml:2.0:example:ruleid:%s" Effect="Permit"> <Description> %s </Description> <Target> <Subjects> <Subject> <SubjectMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">anonymous</AttributeValue> <SubjectAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </SubjectMatch> </Subject> </Subjects> <Resources> <Resource> <ResourceMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">identity_management</AttributeValue> <ResourceAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ResourceMatch> </Resource> </Resources> <Actions> <Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">create_actor_identity</AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ActionMatch> </Action> </Actions> </Target> <Condition> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> <SubjectAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-sender-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </Apply> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">bootstrap</AttributeValue> </Apply> </Condition> </Rule> ''' policy_obj = IonObject(RT.Policy, name='Identity_Management_Anonymous_Bootstrap', definition_type="service", rule=policy_text, description='Permit anonymous access to these operations in the Identity Management Service if called from the Bootstrap Service') policy_id = policy_client.create_policy(policy_obj) policy_client.add_service_policy('identity_management', policy_id) log.debug('Policy created: ' + policy_obj.name) policy_text = ''' <Rule RuleId="urn:oasis:names:tc:xacml:2.0:example:ruleid:%s" Effect="Permit"> <Description> %s </Description> <Target> <Subjects> <Subject> <SubjectMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">anonymous</AttributeValue> <SubjectAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </SubjectMatch> </Subject> </Subjects> <Resources> <Resource> <ResourceMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">resource_registry</AttributeValue> <ResourceAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ResourceMatch> </Resource> </Resources> <Actions> <Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">create</AttributeValue> </ActionMatch> </Action> <Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">create_association</AttributeValue> </ActionMatch> </Action> </Actions> </Target> <Condition> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-one-and-only"> <SubjectAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-sender-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </Apply> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">identity_management</AttributeValue> </Apply> </Condition> </Rule> ''' policy_obj = IonObject(RT.Policy, name='Resource_Registry_Anonymous_Bootstrap', definition_type="service", rule=policy_text, description='Permit anonymous access to these operations in the Resource Registry Service if called from the Identity Management Service') policy_id = policy_client.create_policy(policy_obj) policy_client.add_service_policy('resource_registry', policy_id) log.debug('Policy created: ' + policy_obj.name) ############## policy_text = ''' <Rule RuleId="urn:oasis:names:tc:xacml:2.0:example:ruleid:%s" Effect="Deny"> <Description> %s </Description> <Target> <Resources> <Resource> <ResourceMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">org_management</AttributeValue> <ResourceAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ResourceMatch> </Resource> </Resources> <Actions> <Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">find_requests</AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ActionMatch> </Action> <Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">find_enrolled_users</AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ActionMatch> </Action> <Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">approve_request</AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ActionMatch> </Action> <Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">deny_request</AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ActionMatch> </Action> <Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">enroll_member</AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ActionMatch> </Action> <Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">cancel_member_enrollment</AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ActionMatch> </Action> <Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">grant_role</AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ActionMatch> </Action> <Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">revoke_role</AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ActionMatch> </Action> <Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">add_user_role</AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ActionMatch> </Action> <Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">remove_user_role</AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ActionMatch> </Action> <Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">acquire_resource</AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ActionMatch> </Action> <Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">release_resource</AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ActionMatch> </Action> </Actions> </Target> <Condition> <Apply FunctionId="urn:oasis:names:tc:xacml:ooi:function:not"> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-at-least-one-member-of"> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-bag"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">ORG_MANAGER</AttributeValue> </Apply> <SubjectAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-role-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </Apply> </Apply> </Condition> </Rule> ''' policy_obj = IonObject(RT.Policy, name='Org_Management_Org_Manager_Role_Permitted', definition_type="service", rule=policy_text, description='Deny these operations in the Org Management Service if not the role of Org Manager') policy_id = policy_client.create_policy(policy_obj) policy_client.add_service_policy('org_management', policy_id) log.debug('Policy created: ' + policy_obj.name) ############## policy_text = ''' <Rule RuleId="urn:oasis:names:tc:xacml:2.0:example:ruleid:%s" Effect="Deny"> <Description> %s </Description> <Target> <Resources> <Resource> <ResourceMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-equal"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">instrument_management</AttributeValue> <ResourceAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:resource:resource-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ResourceMatch> </Resource> </Resources> <Actions> <Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-regexp-match"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">create</AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ActionMatch> </Action> <Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-regexp-match"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">update</AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ActionMatch> </Action> <Action> <ActionMatch MatchId="urn:oasis:names:tc:xacml:1.0:function:string-regexp-match"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">delete</AttributeValue> <ActionAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:action:action-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </ActionMatch> </Action> </Actions> </Target> <Condition> <Apply FunctionId="urn:oasis:names:tc:xacml:ooi:function:not"> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-at-least-one-member-of"> <Apply FunctionId="urn:oasis:names:tc:xacml:1.0:function:string-bag"> <AttributeValue DataType="http://www.w3.org/2001/XMLSchema#string">INSTRUMENT_OPERATOR</AttributeValue> </Apply> <SubjectAttributeDesignator AttributeId="urn:oasis:names:tc:xacml:1.0:subject:subject-role-id" DataType="http://www.w3.org/2001/XMLSchema#string"/> </Apply> </Apply> </Condition> </Rule> ''' policy_obj = IonObject(RT.Policy, name='Instrument_Management_Instrument_Operator_Role_Permitted', definition_type="service", rule=policy_text, description='Deny these operations in the Instrument Management Service if not the role of Instrument Operator') policy_id = policy_client.create_policy(policy_obj) policy_client.add_service_policy('instrument_management', policy_id) log.debug('Policy created: ' + policy_obj.name) #TODO - replace with Event update framework from pyon.core.bootstrap import service_registry for service_name in service_registry.services: policy_rules = policy_client.get_active_service_policy_rules(ion_org._id, service_name) Container.instance.governance_controller.update_resource_policy(service_name, policy_rules)
class GovernanceController(object): def __init__(self, container): log.debug('GovernanceController.__init__()') self.container = container self.enabled = False self.interceptor_by_name_dict = dict() self.interceptor_order = [] self.policy_decision_point_manager = None self.governance_dispatcher = None def start(self): log.debug("GovernanceController starting ...") config = CFG.interceptor.interceptors.governance.config if config is None: config['enabled'] = False if "enabled" in config: self.enabled = config["enabled"] log.debug("GovernanceInterceptor enabled: %s" % str(self.enabled)) self.event_subscriber = None if self.enabled: self.initialize_from_config(config) self.event_subscriber = EventSubscriber( event_type="ResourceModifiedEvent", origin_type="Policy", callback=self.policy_event_callback) self.event_subscriber.activate() self.rr_client = ResourceRegistryServiceProcessClient( node=self.container.node, process=self.container) self.policy_client = PolicyManagementServiceProcessClient( node=self.container.node, process=self.container) def initialize_from_config(self, config): self.governance_dispatcher = GovernanceDispatcher() self.policy_decision_point_manager = PolicyDecisionPointManager() if 'interceptor_order' in config: self.interceptor_order = config['interceptor_order'] if 'governance_interceptors' in config: gov_ints = config['governance_interceptors'] for name in gov_ints: interceptor_def = gov_ints[name] # Instantiate and put in by_name array parts = interceptor_def["class"].split('.') modpath = ".".join(parts[:-1]) classname = parts[-1] module = __import__(modpath, fromlist=[classname]) classobj = getattr(module, classname) classinst = classobj() # Put in by_name_dict for possible re-use self.interceptor_by_name_dict[name] = classinst def stop(self): log.debug("GovernanceController stopping ...") if self.event_subscriber is not None: self.event_subscriber.deactivate() def process_incoming_message(self, invocation): self.process_message(invocation, self.interceptor_order, 'incoming') return self.governance_dispatcher.handle_incoming_message(invocation) def process_outgoing_message(self, invocation): self.process_message(invocation, reversed(self.interceptor_order), 'outgoing') return self.governance_dispatcher.handle_outgoing_message(invocation) def process_message(self, invocation, interceptor_list, method): for int_name in interceptor_list: class_inst = self.interceptor_by_name_dict[int_name] getattr(class_inst, method)(invocation) return invocation def policy_event_callback(self, *args, **kwargs): policy_event = args[0] log.debug("Policy modified: %s" % policy_event.origin) self.trigger_policy_update(policy_event.origin) #This is a function which allows for a manual update of the policies as well. def trigger_policy_update(self, policy_id): try: #TODO - Find a better way to work with org_id - use ION Org for now. ion_org, _ = self.rr_client.find_resources( restype=RT.Org, name=CFG.system.root_org) resource_list, _ = self.rr_client.find_subjects( "", PRED.hasPolicy, policy_id) for res in resource_list: #TODO - may figure out a better way to get the name of the Resource Type - or maybe this is ok resource_type = res.__class__.__name__ #log.debug("Resource Type: %s" % resource_type) if resource_type == 'ServiceDefinition': policy_rules = self.policy_client.get_active_service_policy_rules( ion_org[0]._id, res.name) self.update_resource_policy(res.name, policy_rules) elif resource_type == 'Org': self.update_all_resource_policy(res._id) else: policy_rules = self.policy_client.get_active_resource_policy_rules( res._id) self.update_resource_policy(res._id, policy_rules) except Exception, e: log.error(e.message)