Commit 90818df7 authored by Jorge Moratinos's avatar Jorge Moratinos
Browse files

Adding accCtrlPolList

parent 1624c79b
Loading
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -37,8 +37,8 @@ class accessControlPolicyApi(Resource):

            current_app.logger.debug(policies)

            api_invoker_policies = policies[0]['apiInvokerPolicies']
            current_app.logger.debug(f"apiinvokerPolicies: {api_invoker_policies}")
            api_invoker_policies = policies[0]['api_invoker_policies']
            current_app.logger.debug(f"api_invoker_policies: {api_invoker_policies}")
            if not api_invoker_policies:
                current_app.logger.info(f"ACLs list is present but empty, then no ACLs found for the requested service: {service_api_id}, aef_id: {aef_id}, invoker: {api_invoker_id} and supportedFeatures: {supported_features}")
                #Not found error
+68 −45
Original line number Diff line number Diff line
@@ -4,9 +4,10 @@ from .resources import Resource
from ..models.api_invoker_policy import ApiInvokerPolicy
from ..models.time_range_list import TimeRangeList
from datetime import datetime, timedelta
from ..core.publisher import Publisher
from .redis_event import RedisEvent
from ..util import dict_to_camel_case, clean_empty


publisher_ops = Publisher()
class InternalServiceOps(Resource):

    def create_acl(self, invoker_id, service_id, aef_id):
@@ -18,31 +19,49 @@ class InternalServiceOps(Resource):

        mycol = self.db.get_col_by_name(self.db.acls)

        res = mycol.find_one({"service_id": service_id, "aef_id":aef_id}, {"_id":0})
        res = mycol.find_one(
            {"service_id": service_id, "aef_id": aef_id}, {"_id": 0})

        if res:
            current_app.logger.info(f"Adding invoker ACL for invoker {invoker_id}")
            range_list = [TimeRangeList(datetime.utcnow(), datetime.utcnow()+timedelta(days=365))]
            invoker_acl = ApiInvokerPolicy(invoker_id, current_app.config["invocations"]["total"], current_app.config["invocations"]["perSecond"], range_list)
            r = mycol.find_one({"service_id": service_id, "aef_id":aef_id, "apiInvokerPolicies.api_invoker_id": invoker_id}, {"_id":0})
            current_app.logger.info(
                f"Adding invoker ACL for invoker {invoker_id}")
            range_list = [TimeRangeList(
                datetime.utcnow(), datetime.utcnow()+timedelta(days=365))]
            invoker_acl = ApiInvokerPolicy(
                invoker_id, current_app.config["invocations"]["total"], current_app.config["invocations"]["perSecond"], range_list)
            r = mycol.find_one({"service_id": service_id, "aef_id": aef_id,
                               "apiInvokerPolicies.api_invoker_id": invoker_id}, {"_id": 0})
            if r is None:
                mycol.update_one({"service_id": service_id, "aef_id":aef_id }, {"$push":{"apiInvokerPolicies":invoker_acl.to_dict()}})
                mycol.update_one({"service_id": service_id, "aef_id": aef_id}, {
                                 "$push": {"apiInvokerPolicies": invoker_acl.to_dict()}})
        else:
            current_app.logger.info(f"Creating service ACLs for service: {service_id}")
            range_list = [TimeRangeList(datetime.utcnow(), datetime.utcnow()+timedelta(days=365))]
            invoker_acl = ApiInvokerPolicy(invoker_id, current_app.config["invocations"]["total"], current_app.config["invocations"]["perSecond"], range_list)
            
            
            current_app.logger.info(
                f"Creating service ACLs for service: {service_id}")
            range_list = [TimeRangeList(
                datetime.utcnow(), datetime.utcnow()+timedelta(days=365))]
            invoker_acl = ApiInvokerPolicy(
                invoker_id, current_app.config["invocations"]["total"], current_app.config["invocations"]["perSecond"], range_list)

            service_acls = {
                "service_id": service_id,
                "aef_id": aef_id,
                "apiInvokerPolicies": [invoker_acl.to_dict()]
                "api_invoker_policies": [invoker_acl.to_dict()]
            }
            mycol.insert_one(service_acls)
            publisher_ops.publish_message("events", "ACCESS_CONTROL_POLICY_UPDATE")
            result = mycol.insert_one(service_acls)

            inserted_service_acls=mycol.find_one({"_id": result.inserted_id}, {"_id": 0})
            current_app.logger.info(inserted_service_acls)
            inserted_service_acls_camel=dict_to_camel_case(inserted_service_acls)
            current_app.logger.info(inserted_service_acls_camel)
            accCtrlPolListExt = {
                "apiId": service_id,
                "apiInvokerPolicies": inserted_service_acls_camel['apiInvokerPolicies']
            }
            RedisEvent("ACCESS_CONTROL_POLICY_UPDATE",
                       "accCtrlPolList", accCtrlPolListExt).send_event()

        current_app.logger.info(f"Invoker ACL added for invoker: {invoker_id} for service: {service_id}")
        current_app.logger.info(
            f"Invoker ACL added for invoker: {invoker_id} for service: {service_id}")

    def remove_acl(self, invoker_id, service_id, aef_id):

@@ -50,28 +69,33 @@ class InternalServiceOps(Resource):

        mycol = self.db.get_col_by_name(self.db.acls)

        res = mycol.find_one({"service_id": service_id, "aef_id":aef_id}, {"_id":0})
        res = mycol.find_one(
            {"service_id": service_id, "aef_id": aef_id}, {"_id": 0})

        if res:
            mycol.update_many({"service_id": service_id, "aef_id": aef_id},
                           {"$pull":{ "apiInvokerPolicies": { "api_invoker_id": invoker_id }}}
                              {"$pull": {"api_invoker_policies": {
                                  "api_invoker_id": invoker_id}}}
                              )
        else:
            current_app.logger.info(f"Not found: {service_id} for api : {service_id}")
            current_app.logger.info(
                f"Not found: {service_id} for api : {service_id}")

        publisher_ops.publish_message("events", "ACCESS_CONTROL_POLICY_UNAVAILABLE")
        RedisEvent("ACCESS_CONTROL_POLICY_UNAVAILABLE").send_event()

        current_app.logger.info(f"Invoker ACL removed for invoker: {invoker_id} for service: {service_id}")
        current_app.logger.info(
            f"Invoker ACL removed for invoker: {invoker_id} for service: {service_id}")

    def remove_invoker_acl(self, invoker_id):

        current_app.logger.info(f"Removing ACLs for invoker: {invoker_id}")
        mycol = self.db.get_col_by_name(self.db.acls)

        mycol.update_many({"apiInvokerPolicies.api_invoker_id": invoker_id},
                           {"$pull":{ "apiInvokerPolicies": { "api_invoker_id": invoker_id }}}
        mycol.update_many({"api_invoker_policies.api_invoker_id": invoker_id},
                          {"$pull": {"api_invoker_policies": {
                              "api_invoker_id": invoker_id}}}
                          )
        publisher_ops.publish_message("events", "ACCESS_CONTROL_POLICY_UNAVAILABLE")
        RedisEvent("ACCESS_CONTROL_POLICY_UNAVAILABLE").send_event()
        current_app.logger.info(f"ACLs for invoker: {invoker_id} removed")

    def remove_provider_acls(self, id):
@@ -79,7 +103,6 @@ class InternalServiceOps(Resource):
        current_app.logger.info(f"Removing ACLs for provider/service: {id}")
        mycol = self.db.get_col_by_name(self.db.acls)

        mycol.delete_many({"$or":[{"service_id":id}, {"aef_id":id}]}
                           )
        publisher_ops.publish_message("events", "ACCESS_CONTROL_POLICY_UNAVAILABLE")
        mycol.delete_many({"$or": [{"service_id": id}, {"aef_id": id}]})
        RedisEvent("ACCESS_CONTROL_POLICY_UNAVAILABLE").send_event()
        current_app.logger.info(f"ACLs for provider/service: {id} removed")
+41 −0
Original line number Diff line number Diff line
from ..encoder import JSONEncoder
from .publisher import Publisher
import json

publisher_ops = Publisher()


class RedisEvent():
    def __init__(self, event, event_detail_key=None, information=None) -> None:
        self.EVENTS_ENUM = [
            'SERVICE_API_AVAILABLE',
            'SERVICE_API_UNAVAILABLE',
            'SERVICE_API_UPDATE',
            'API_INVOKER_ONBOARDED',
            'API_INVOKER_OFFBOARDED',
            'SERVICE_API_INVOCATION_SUCCESS',
            'SERVICE_API_INVOCATION_FAILURE',
            'ACCESS_CONTROL_POLICY_UPDATE',
            'ACCESS_CONTROL_POLICY_UNAVAILABLE',
            'API_INVOKER_AUTHORIZATION_REVOKED',
            'API_INVOKER_UPDATED',
            'API_TOPOLOGY_HIDING_CREATED',
            'API_TOPOLOGY_HIDING_REVOKED']
        if event not in self.EVENTS_ENUM:
            raise Exception(
                "Event (" + event + ") is not on event enum (" + ','.join(self.EVENTS_ENUM) + ")")
        self.redis_event = {
            "event": event
        }
        if event_detail_key != None and information != None:
            self.redis_event['key'] = event_detail_key
            self.redis_event['information'] = information

    def to_string(self):
        return json.dumps(self.redis_event, cls=JSONEncoder)

    def send_event(self):
        publisher_ops.publish_message("events-log", self.to_string())

    def __call__(self):
        return self.redis_event
+1 −1
Original line number Diff line number Diff line
@@ -45,7 +45,7 @@ class Notifications():
                event_detail=None
                if redis_event.get('key', None) != None and redis_event.get('information', None) != None:
                    event_detail={redis_event.get('key'):redis_event.get('information')}
                
                current_app.logger.debug(event_detail)
                data = EventNotification(sub["subscription_id"], events=redis_event.get('event'), event_detail=event_detail)
                current_app.logger.debug(json.dumps(data,cls=JSONEncoder))

+106 −1
Original line number Diff line number Diff line
@@ -485,7 +485,112 @@ Provider subscribe to API Invoker events
    Check Variable    ${events_expected}    EventNotification

    # Check results
    ${events_expected_length}=   Get Length    ${event_expected}
    ${events_expected_length}=   Get Length    ${events_expected}
    Length Should Be    ${notification_events_on_mock_server}   ${events_expected_length}
    FOR    ${event_expected}    IN    @{events_expected}
        Log    ${event_expected}
        List Should Contain Value    ${notification_events_on_mock_server}    ${event_expected}
    END

Invoker subscribed to ACL update event
    [Tags]    capif_api_events-10    mockserver

    # Start Mock server
    Check Mock Server
    Clean Mock Server

    # Register APF
    ${register_user_info_provider}=    Provider Default Registration

    # Publish one api
    ${service_api_description_published}    ${resource_url}    ${request_body}=    Publish Service Api
    ...    ${register_user_info_provider}

    # Store apiId1
    ${serviceApiId}=    Set Variable    ${service_api_description_published['apiId']}

    # Register INVOKER
    ${register_user_info_invoker}    ${url}    ${request_body}=    Invoker Default Onboarding

    # Subscribe to events
    ${events_list}=    Create List    ACCESS_CONTROL_POLICY_UPDATE
    ${request_body}=    Create Events Subscription
    ...    events=@{events_list}
    ...    notificationDestination=${MOCK_SERVER_URL}/testing
    ${resp}=    Post Request Capif
    ...    /capif-events/v1/${register_user_info_provider['amf_id']}/subscriptions
    ...    json=${request_body}
    ...    server=${CAPIF_HTTPS_URL}
    ...    verify=ca.crt
    ...    username=${AMF_PROVIDER_USERNAME}

    # Check Results
    Check Response Variable Type And Values    ${resp}    201    EventSubscription
    ${subscriber_id}    ${subscription_id}=    Check Event Location Header    ${resp}


    # Test
    ${discover_response}=    Get Request Capif
    ...    ${DISCOVER_URL}${register_user_info_invoker['api_invoker_id']}&aef-id=${register_user_info_provider['aef_id']}
    ...    server=${CAPIF_HTTPS_URL}
    ...    verify=ca.crt
    ...    username=${INVOKER_USERNAME}

    Check Response Variable Type And Values    ${discover_response}    200    DiscoveredAPIs

    # create Security Context
    ${request_service_security_body}=    Create Service Security From Discover Response
    ...    http://${CAPIF_HOSTNAME}:${CAPIF_HTTP_PORT}/test
    ...    ${discover_response}
    ${resp}=    Put Request Capif
    ...    /capif-security/v1/trustedInvokers/${register_user_info_invoker['api_invoker_id']}
    ...    json=${request_service_security_body}
    ...    server=${CAPIF_HTTPS_URL}
    ...    verify=ca.crt
    ...    username=${INVOKER_USERNAME}

    # Check Service Security
    Check Response Variable Type And Values    ${resp}    201    ServiceSecurity
    ${resource_url}=    Check Location Header    ${resp}    ${LOCATION_SECURITY_RESOURCE_REGEX}

    ${resp}=    Get Request Capif
    ...    /access-control-policy/v1/accessControlPolicyList/${serviceApiId}?aef-id=${register_user_info_provider['aef_id']}
    ...    server=${CAPIF_HTTPS_URL}
    ...    verify=ca.crt
    ...    username=${AEF_PROVIDER_USERNAME}

    Check Response Variable Type And Values    ${resp}    200    AccessControlPolicyList
    # Check returned values
    Should Not Be Empty    ${resp.json()['apiInvokerPolicies']}
    Length Should Be    ${resp.json()['apiInvokerPolicies']}    1
    Should Be Equal As Strings
    ...    ${resp.json()['apiInvokerPolicies'][0]['apiInvokerId']}
    ...    ${register_user_info_invoker['api_invoker_id']}

    ${api_invoker_policies}=  Set Variable  ${resp.json()['apiInvokerPolicies']}

    # Check Results
    Sleep    3s
    # Get from Mock server the EventNotification Messages sent to callback setup on event subscription.
    ${resp}=    Get Mock Server Messages
    ${notification_events_on_mock_server}=    Set Variable    ${resp.json()}

    ## Create events expected
    ${acc_ctrl_pol_list}=  Create Dictionary   apiId=${serviceApiId}  apiInvokerPolicies=${api_invoker_policies}
    Check Variable    ${acc_ctrl_pol_list}    AccessControlPolicyListExt

    ${events_expected}=    Create List
    ${event_expected}=    Create Notification Event
    ...    ${subscription_id}
    ...    ACCESS_CONTROL_POLICY_UPDATE
    ...    accCtrlPolList=${acc_ctrl_pol_list}

    Append To List    ${events_expected}     ${event_expected}

    Check Variable    ${events_expected}    EventNotification

    # Check results
    ${events_expected_length}=   Get Length    ${events_expected}
    Length Should Be    ${notification_events_on_mock_server}   ${events_expected_length}
    FOR    ${event_expected}    IN    @{events_expected}
        Log    ${event_expected}
Loading