예제 #1
0
    def is_valid_token(self):

        credentials = self.__parse_token();
        username = credentials[1]
        pwd = credentials[2]

        keycloak = KeyCloak(server_url="https://auth.s2s-omxware.us-south.containers.appdomain.cloud/auth/",
                                client_id="omx-zeppelin",
                                realm_name="omxware",
                                client_secret_key="c05b7553-cf21-4f0c-ab81-a38aca3ba172",
                                verify=False)

        if self.__env != 'public':
            keycloak = KeyCloak(server_url="https://omx-auth.sl.cloud9.ibm.com/auth/",
                                client_id="omx-zeppelin",
                                realm_name="omxware",
                                client_secret_key="1320e78d-025d-48eb-ad3e-451281786932",
                                verify=False)

        try:
            # Get Token
            token = keycloak.token(username, pwd)
            self.__userinfo = keycloak.userinfo(token['access_token'])

            self.__keycloak_token = token['access_token']

            return True

        except KeycloakAuthenticationError as auth_error:
            # Exception object looks like this
            # keycloak.exceptions.KeycloakAuthenticationError:
            # 401: b'{"error":"invalid_grant","error_description":"Invalid user credentials"}'

            error_msg = ''

            if auth_error['error_description'] != None:
                error_msg = auth_error['error_description']

            if error_msg.strip() != None:
                print(error_msg)
            else:
                print(auth_error['error_description'])

            return False
예제 #2
0
    realm_name="wienernetze",
    client_secret_key=uuid.uuid1())

try:
    token = keycloak_openid.token(USERNAME, PASSWORD)
except:
    try:
        print('[' + str(sys.exc_info()[1]).split(":")[0] + '] ' +
              requests.status_codes._codes[int(
                  str(sys.exc_info()[1]).split(":")[0])][0])
    except:
        print("Network ERROR")
    print(" ")
    sys.exit()

userinfo = keycloak_openid.userinfo(token['access_token'])
print('[200] ' + str(userinfo))

print(" ")
print("===============")
print("=== OPTIONS ===")
print("===============")
print(" ")

URL = "https://service.wienernetze.at/rest/smp/1.0/m/messdaten/zaehlpunkt/" + ZNR + "/verbrauch"
URL += "?dateFrom=" + from_date_utc.isoformat() + ".000Z"
URL += "&period=DAY&accumulate=false&offset=0&dayViewResolution=QUARTER-HOUR"

headers = {
    'User-Agent':
    'Mozilla/5.0 (X11; Linux ppc64le; rv:66.0) Gecko/20100101 Firefox/66.0',
예제 #3
0
class Keycloak:
    """Keycloak authentication class."""
    def get_keycloak_user_token(self, tenant: AnyStr,
                                password: AnyStr) -> Dict:
        """
        Get the token of the user authentication in Keycloak.

        :tenant (AnyStr) the user username
        :password (AnyStr) the user password

        Return the keycloak user token if valid credentials.
        """
        keycloak_openid = self.client
        token = None
        try:
            token = keycloak_openid.token(tenant, password)
            if envvar('GRAFANA') == 'true':
                user_grafana = grafana.get_grafana_user(tenant)
                if not user_grafana:
                    grafana.create_grafana_user(tenant, password)
                if self.verify_group_admin():
                    grafana.update_grafana_role(user_grafana, 'Editor')
        except exceptions.KeycloakAuthenticationError or exceptions.KeycloakGetError:
            logging.error(f'Authentication error for user {tenant}')
        finally:
            return token

    def client(self, **kwargs: Dict) -> KeycloakOpenID:
        """
        Create an authenticated keycloak client.

        :kwargs (Dict) A directory contaning
        the keycloak client authentication credentials

        Return the KeycloakOpenID object.
        """
        config = {}
        if kwargs:
            config.update(kwargs)
        else:
            config.update({
                'server_url': envvar('KEYCLOAK_URL'),
                'client_id': envvar('KEYCLOAK_CLIENT_ID'),
                'realm_name': envvar('KEYCLOAK_REALM'),
                'client_secret_key': envvar('KEYCLOAK_SECRET_KEY')
            })
        self.client = KeycloakOpenID(**config)
        return self.client

    def verify(self, tenant: AnyStr, password: AnyStr) -> bool:
        """
        Verify if a user token is not empty.

        :tenant (AnyStr) the user username
        :password (AnyStr) the user password

        Return a boolean describing the success of the user verification in keycloak.
        """
        if tenant == envvar('ADMIN_ACCOUNT'):
            if password == envvar('GRAFANA_ADMIN_PASSWORD'):
                return True
            else:
                return False
        else:
            return self.get_token(tenant, password)

    def verify_group_admin(self, **kwargs: Dict) -> bool:
        """
        Check if a user is admin.

        Return a boolean to express if a user is admin or no.
        """
        tenant_info = self.get_infos()
        group = tenant_info.get('group', '')
        if group == 'admin':
            return True
        else:
            return False

    def get_infos(self) -> Any:
        """Verify users information."""
        return self.client.userinfo(self.token['access_token'])

    def get_token(self, tenant: AnyStr, password: AnyStr) -> Dict:
        """
        Get the token of the user authentication in Keycloak.

        :tenant (AnyStr) the user username
        :password (AnyStr) the user password
        """
        self.token = self.get_keycloak_user_token(tenant, password)
        return self.token

    def get_namespace(self, **kwargs: Dict) -> AnyStr:
        """
        Get the user namespaces attribute from the token.

        Return the user namespaces.
        """
        tenant_info = self.get_infos()
        return tenant_info.get('namespaces', '')
예제 #4
0
#!/usr/bin/env python3
from keycloak import KeycloakOpenID

keycloak_openid = KeycloakOpenID(
    server_url='http://localhost:8080/auth/',
    client_id='romi-dashboard',
    realm_name='master'
)

token = keycloak_openid.token('admin', 'admin')
user_id = keycloak_openid.userinfo(token['access_token'])['sub']
user_name = keycloak_openid.userinfo(token['access_token'])['preferred_username']
print(f'user ID: {user_id}')
print(f'user name: {user_name}')

#import requests
# todo: stuff the token into the request headers
#headers = {'foo': 'bar'}
#r = requests.get('http://localhost:5000', headers=headers)
#print(r.text)
예제 #5
0
class KeycloakMiddleware(MiddlewareMixin):

    def __init__(self, get_response):
        """

        :param get_response:
        """

        self.config = settings.APPLICATION_CONFIG

        # Read configurations
        try:
            self.server_url = get_application_config_for_key('KEYCLOAK_SERVER_URL')
            self.client_id = get_application_config_for_key('KEYCLOAK_CLIENT_ID')
            self.realm = get_application_config_for_key('KEYCLOAK_REALM')
        except KeyError as e:
            raise Exception("KEYCLOAK_SERVER_URL, KEYCLOAK_CLIENT_ID or KEYCLOAK_REALM not found.")

        self.client_secret_key = get_application_config_for_key('KEYCLOAK_CLIENT_SECRET_KEY')
        self.default_access = get_application_config_for_key('KEYCLOAK_DEFAULT_ACCESS')
        self.method_validate_token = get_application_config_for_key('KEYCLOAK_METHOD_VALIDATE_TOKEN')
        self.keycloak_authorization_config = get_application_config_for_key('KEYCLOAK_AUTHORIZATION_CONFIG')

        # Create Keycloak instance
        self.keycloak = KeycloakOpenID(server_url=self.server_url,
                                       client_id=self.client_id,
                                       realm_name=self.realm,
                                       client_secret_key=self.client_secret_key,
                                       )

        # Read policies
        if self.keycloak_authorization_config:
            self.keycloak.load_authorization_config(self.keycloak_authorization_config)

        # Django
        self.get_response = get_response

        print("KEYCLOAK_SERVER URL", get_application_config_for_key('KEYCLOAK_SERVER_URL'))
        print("KEYCLOAK_CLIENT_ID URL", get_application_config_for_key('KEYCLOAK_CLIENT_ID'))
        print("KEYCLOAK_REALM URL", get_application_config_for_key('KEYCLOAK_REALM'))


    @property
    def keycloak(self):
        return self._keycloak

    @keycloak.setter
    def keycloak(self, value):
        self._keycloak = value

    @property
    def config(self):
        return self._config

    @config.setter
    def config(self, value):
        self._config = value

    @property
    def server_url(self):
        return self._server_url

    @server_url.setter
    def server_url(self, value):
        self._server_url = value

    @property
    def client_id(self):
        return self._client_id

    @client_id.setter
    def client_id(self, value):
        self._client_id = value

    @property
    def client_secret_key(self):
        return self._client_secret_key

    @client_secret_key.setter
    def client_secret_key(self, value):
        self._client_secret_key = value

    @property
    def client_public_key(self):
        return self._client_public_key

    @client_public_key.setter
    def client_public_key(self, value):
        self._client_public_key = value

    @property
    def realm(self):
        return self._realm

    @realm.setter
    def realm(self, value):
        self._realm = value

    @property
    def keycloak_authorization_config(self):
        return self._keycloak_authorization_config

    @keycloak_authorization_config.setter
    def keycloak_authorization_config(self, value):
        self._keycloak_authorization_config = value

    @property
    def method_validate_token(self):
        return self._method_validate_token

    @method_validate_token.setter
    def method_validate_token(self, value):
        self._method_validate_token = value

    def __call__(self, request):
        """
        :param request:
        :return:
        """
        return self.get_response(request)

    def process_view(self, request, view_func, view_args, view_kwargs):
        """
        Validate only the token introspect.
        :param request: django request
        :param view_func:
        :param view_args: view args
        :param view_kwargs: view kwargs
        :return:
        """

        print ('DEBUG:', request)

        # do not block the access to root!
        if request.path_info == '/':
            logger.debug('** exclude path found, skipping')
            return None
        
        # CONTINGENCY SOLUTION!!! review API to avoid this
        # if request.path_info[-7:] == '/series':
        #     return None

        whitelist = [
             '/api/v1/api',
             '/api/v1/alive',
             '/api/v1/ready',
             '/oformat/WORD/documentation',
             '/oformat/EXCEL/documentation', 
             '/export_download'
        ]
        for iwhite in whitelist:
            if request.path_info.endswith(iwhite):
                print ('skipped:', request.path_info)
                return None

        if hasattr(settings, 'KEYCLOAK_BEARER_AUTHENTICATION_EXEMPT_PATHS'):
            path = request.path_info.lstrip('/')

            if any(re.match(m, path) for m in
                   settings.KEYCLOAK_BEARER_AUTHENTICATION_EXEMPT_PATHS):
                logger.debug('** exclude path found, skipping')
                return None

        try:
            roles = view_func.cls.roles
        except AttributeError as e:
            return JsonResponse({"detail": NotAuthenticated.default_detail}, status=NotAuthenticated.status_code)

        if 'HTTP_AUTHORIZATION' not in request.META:
            return JsonResponse({"detail": NotAuthenticated.default_detail}, status=NotAuthenticated.status_code)

        auth_header = request.META.get('HTTP_AUTHORIZATION').split()
        token = auth_header[1] if len(auth_header) == 2 else auth_header[0]

        try:
            userinfo = self.keycloak.userinfo(token)
        except KeycloakError as e:
            return JsonResponse({"detail": AuthenticationFailed.default_detail}, status=AuthenticationFailed.status_code)

        has_role = True
        for role in roles:
            if role not in userinfo['groups']:
                has_role = False

        # In case we need to verify token. But since we verify it by using userinfo call, it is not necessary atm.
        # KEYCLOAK_PUBLIC_KEY = self.client_public_key
        # options = {"verify_signature": True, "verify_aud": True, "verify_exp": True}
        # token_info = self.keycloak.decode_token(token, key=KEYCLOAK_PUBLIC_KEY, options=options)

        # if token_info['realm_access'] and token_info['realm_access']['roles']:
        #     print(token_info['realm_access']['roles'])

        if has_role:
            return None

        # User Permission Denied
        return JsonResponse({"detail": PermissionDenied.default_detail}, status=PermissionDenied.status_code)
예제 #6
0
class KeycloakUserManagement(UserManagement):
    def __init__(self, ex, parameters=None):
        from keycloak import KeycloakOpenID

        if parameters is None:
            parameters = {}
        self.ex = ex
        self.server_url = parameters["server_url"]
        self.client_id = parameters["client_id"]
        self.realm_name = parameters["realm_name"]
        self.client_secret_key = parameters["client_secret_key"]

        self.keycloak_manager = KeycloakOpenID(
            server_url=self.server_url,
            client_id=self.client_id,
            realm_name=self.realm_name,
            client_secret_key=self.client_secret_key)

        UserManagement.__init__(self, ex)

    def do_login(self, user, password):
        """
        Logs in a user and returns a session id

        Parameters
        ------------
        user
            Username
        password
            Password

        Returns
        ------------
        session_id
            Session ID
        """
        try:
            token = self.keycloak_manager.token(user, password)
            return token['access_token']
        except:
            # traceback.print_exc()
            pass
        return None

    def check_session_validity(self, session_id):
        """
        Checks the validity of a session

        Parameters
        ------------
        session_id
            Session ID

        Returns
        ------------
        boolean
            Boolean value
        """
        validity = False
        try:
            if not (str(session_id) == "null"):
                userinfo = self.keycloak_manager.userinfo(session_id)
                if type(userinfo["preferred_username"]) is str:
                    if userinfo["preferred_username"]:
                        validity = True
        except:
            # traceback.print_exc()
            pass
        return validity

    def get_user_from_session(self, session_id):
        """
        Gets the user from the session

        Parameters
        ------------
        session_id
            Session ID

        Returns
        ------------
        user
            User ID
        """
        user = None
        try:
            if not (str(session_id) == "null"):
                userinfo = self.keycloak_manager.userinfo(session_id)
                if type(userinfo["preferred_username"]) is str:
                    if userinfo["preferred_username"]:
                        user = userinfo["preferred_username"]
        except:
            # traceback.print_exc()
            pass
        return user

    def clean_expired_sessions(self):
        """
        Cleans the expired sessions in IAM
        """
        pass

    def get_all_sessions(self):
        """
        Gets all sessions from the users database

        Returns
        -----------
        sessions
            List of sessions
        """

        return None

    def get_all_users(self):
        """
        Possibly get all the users from the users database

        Returns
        -------------
        users
            List of users
        """

        return []
예제 #7
0
class NDMWS:
    ''' Main class to talk to NDM Web Services.

        NDM public web services are at endpoints:
        - /api/mprc: MAVProxy Remote Console services (add, remove, list and update data)
        - /api/rmp: Reactive Mission Planner services (send or retrieve subplan, get GPS pos)

        In order to use these service, an authentication bearer is required that should be
        sent along with the request to any service. The NDMWS library helps with this
        authentication and provides several shortcuts to common sequences of service
        requests.

        A tipical use of the library could be:
        1. Connect to Keycloak (retrieve the authentication bearer)
        2. Create a custom subplan
        3. Send the subplan to the RMP

        Other tipical (shorter) use could be:
        1. Connect to Keycloak (retrieve the authentication bearer)
        2. Trigger a predefined alarm (with its mapped subplan)

        In this last case, the alarm is only a label identifying a predefined mapping
        that we want to call use. This requires an association between the alarm and a
        subplan that should be defined in the configuration file in advance. The alarm
        is then sent to the vMPA and the mapped subplan is sent to the vDFC for execution.
    '''
    def __init__(self,
                 dfcaddr=None,
                 droneid=None,
                 mpaaddr=None,
                 inifile='ndmws.ini',
                 debug=False):
        ''' Creates an instance of the helper to call NDM Web Services.

            This is the first object to instantiate and the one to start WS interaction.
            You can specify `dfcaddr`, `mpaaddr` and a `droneid` or you can leave it blank.
            In this case, you an alternativelly inform the `inifile` name or leave the
            defaults. Debug is `False` by default, so you'll have to set `debug=True` to
            see config variables, i.e.
        '''
        global DEBUG
        DEBUG = debug
        config.read(inifile)
        if dfcaddr == None:
            _('Using config: %s' % inifile)
            self.dfcaddr = config.get('dfc', 'hostport')
        else:
            self.dfcaddr = dfcaddr
        if mpaaddr == None:
            self.mpaaddr = config.get('mpa', 'hostport')
            _('Using mpaaddr: %s' % self.mpaaddr)
        else:
            self.mpaaddr = mpaaddr
        if droneid == None:
            self.droneid = config.get('dfc', 'droneid')
            _('Using droneid: %s' % self.droneid)
        else:
            self.droneid = droneid
        self.logger = logging.getLogger(__name__)
        # create console handler with a higher log level
        ch = logging.StreamHandler()
        ch.setLevel(logging.INFO)
        # create formatter and add it to the handlers
        formatter = logging.Formatter(
            "%(asctime)s.%(msecs)03d[%(levelname)-8s]:%(created).3f %(message)s",
            datefmt="%Y-%m-%d %H:%M:%S")
        ch.setFormatter(formatter)
        # add the handlers to logger
        if (self.logger.hasHandlers()):
            self.logger.handlers.clear()
        self.logger.addHandler(ch)
        self.logger.propagate = False

        self.authenticate()

        self.last_t_subplan = 0

        # self.relay_bcp_client = RelayClient(
        #     password=PASSWORD,
        #     keyfile=KEYFILE,
        #     identity=IDENTITY,  # can be set afterwards by calling `client.set_identity(identity)`
        #     tx_relay_address=TX_RELAY_ADDRESS,
        #     meta_identity_manager_address=META_IDENTITY_MANAGER_ADDRESS,
        #     entity_data_manager_address=ENTITY_DATA_MANAGER_ADDRESS,
        #     relay_server_address=RELAY_ENDPOINT,)

        # self.vmme_producer = None
        # self.initialized_vmme = False

    def authenticate(self, hostport=None, username=None, password=None):
        ''' Authentication with Keycloak is required before any API interaction.

            Realm is hardcoded to 'ndmws' and client 'ndmws-client', so no other
            configuration is required. Note that the communication is always
            encrypted so no plain text is on the wire, but you should protect your
            configuration file from unathorized access (i.e. don't ever commit your
            ndmws.ini file in your repo).
        '''
        if hostport == None or username == None or password == None:
            hostport = config.get('auth', 'hostport')
            _('Using auth hostport: %s' % hostport)
            username = config.get('auth', 'username')
            _('Using auth username: %s' % username)
            password = config.get('auth', 'password')
            _('Using auth password: %s' % password)
            _('Using auth url: %s' % (AUTHURL % hostport))
        self.kc = KeycloakOpenID(server_url=AUTHURL % hostport,
                                 client_id='ndmws-client',
                                 realm_name='ndmws')
        self.token = self.kc.token(username, password)
        self.logger.info(self.token)

    def userinfo(self):
        ''' Get keycloak user info from the identity server.

            This is only required if you want to be sure that the user you are
            authenticating with is the one allowed to interact with the
            web services, also no estrictly neccessary.
        '''
        return self.kc.userinfo(self.token['access_token'])

    def getpos(self, ts, th):
        ''' Get the GPS position of the flying drone when time = `ts`.

            While the drone (in config) is flying, every instant can be resolved
            to a known GPS position. This method retrieves the GPS position from
            the done `traces` before the drone lands. The opposite is not true,
            since the drone might (and usually does) pass twice or more to the
            same GPS position.
        '''
        auth = self.token['access_token']
        trace_url = TRACEURL % (self.dfcaddr, self.droneid, ts, th)
        r = get(trace_url, headers={'Authorization': 'Bearer %s' % auth})
        self.logger.info("RESPONSE GETPOS: {}".format(r.text))
        if r.status_code == 200:
            j = loads(r.text)
            return {'time': j['time'], 'pos': j['pos']}
        else:
            return {'code': r.status_code, 'msg': r.json()['msg']}

    def sendplan(self, data):
        ''' Send a subplan to the vDFC for a subplan change.

            With this method you can arbitrarily send a hand-made subplan (JSON)
            or a plan constructed using the `Subplan` fluent language builder.
            The plan will be executed only if the drone is not currently executing
            a subplan. If the drone is yet executing a subplan, an 409 error will be
            issued, but you can catch and ignore it as you wish, since no exception
            is raised at this moment.
        '''
        auth = self.token['access_token']
        r = put(SUBPLANURL % (self.dfcaddr, self.droneid),
                json=loads(data) if type(data) == str else data,
                headers={'Authorization': 'Bearer %s' % auth})
        self.logger.info('SUBPLAN RESPONSE: {}'.format(r.text))
        if r.status_code == 200:
            return r.text
        else:
            return {'code': r.status_code, 'msg': r.json()['msg']}

    def sendalarm(self, src, obj, ts):
        ''' Send an alarm to the vMPA for notification.

            Use this method to send a notification to the vMPA party.
            This notification could be sent in parallel to a subplan change (i.e.
            senplan) in the vDFC, so that both parties are notified of
            the alarm at the same time or sent by itself when an uploaded video
            is being processed. The 'src' param should be self.droneid if the
            video source comes from a drone live video or the label id (user
            supplied when a video is uploaded. 'object' identification and actual
            time 'ts' should also be passed as a way to enrich the alert message.
        '''
        auth = self.token['access_token']
        r = put(ALARMURL % (self.mpaaddr, src, obj, ts),
                headers={'Authorization': 'Bearer %s' % auth})
        self.logger.info("Response ALARM:{}".format(r.text))
        if r.status_code == 200:
            return r.text
        else:
            return {'code': r.status_code, 'msg': r.json()['msg']}

    def triggeralarm(self,
                     alarm,
                     t,
                     subplan_time_space=60,
                     send_subplan=False,
                     threshold=GPS_POS_THRESHOLD):
        ''' Trigger an alarm and send a predefined subplan to the RMP (Reactive Mission Planner).

            Predefined subplans could be configured in the configuration file easily
            following this structure:

            [alarmmap]
            ALARM = SP_SUBPLAN_NAME

            By adding a mapping between an alarm name and a suplan name, the library knows
            which subplan should be loaded when an alarm is triggered.

            [ALARM]
            reason = reason_text
            object = object_text

            A new section should be added for every new alarm, specifying two keys, `reason`
            and `object` that will be substituted into every subplan mapped to this alarm.

            [subplans]
            SP_SUBPLAN_NAME = { subplan: [ ... ] }

            A new key should be added to the `subplans` section to write the JSON corresponding
            to the subplan. Of course, the subplan object can (and should) include substitution
            variables that need to be escaped (use a double `%`) to avoid early template subtitution.

            Allowed template variables are as follows:
            - clientid
            - reason
            - obj
            - lat
            - lon
            - alt
        '''
        try:
            resp = self.getpos(t, threshold)
            if 'code' in resp:
                # self.logger.info('Exception of drone not flying')
                raise Exception('%d: %s' % (resp['code'], resp['msg']))
            else:
                _('Event: %s' % alarm)
                sp = config.get('alarmmap', alarm)
                _('Subplan name: %s' % sp)
                if sp == None:
                    raise Exception('ERROR: alarm `%s` has no mapped subplan' %
                                    alarm)
                subplan = config.get('subplans', sp)
                _('Subplan: %s' % subplan)
                reason = config.get(alarm, 'reason')
                obj = config.get(alarm, 'object')
                _('Sending alert of object %s at time %d' % (obj, t))
                self.sendalarm(self.droneid, obj, t)
                if t > (self.last_t_subplan +
                        subplan_time_space * 1000) and send_subplan:
                    clientid = config.get('client', 'clientid')
                    params = resp['pos']
                    params.update({
                        'clientid': clientid,
                        'reason': reason,
                        'obj': obj
                    })
                    _('Subplan params: %s' % params.__str__())
                    self.logger.info(('Subplan params: %s' % params.__str__()))
                    subplan = subplan % params
                    _('Sending subplan: %s' % subplan)
                    # vBCP client
                    # params["ts"] = t
                    # self.send_bcp_data(params)
                    # vMME client
                    # self.send_mme_data(params)
                    # self.last_t_subplan = t
                    self.logger.info("sending subplan")
                    return self.sendplan(subplan)
                else:
                    # if (int((t-self.last_t_subplan)*0.001)) % 10 == 0:
                    # self.logger.info('No subplans allowed. Last one sent {}(s) ago'.format(int((t-self.last_t_subplan)*0.001)))
                    return {'code': 200, 'msg': 'No subplans allowed'}
        except Exception:
            pass

    def send_bcp_data(self, data):
        payload = dumps(data)
        # Relay the payload as a signed message to the  Relay Server. The message will be forwarded to the vMCM.
        self.logger.info(
            'Relaying signed payload to the server: {}'.format(payload))
        # status = self.relay_bcp_client.relay_signed_message(payload)
        # self.logger.info('Got status code : {}'.format(status))
        tx_hash = self.relay_bcp_client.register_mpa_data(payload)
        self.logger.info('Got transaction hash : {}'.format(tx_hash))
        self.logger.info("data has been sent to vBCP")

    # def init_mme(self, data):
    #     device_data = self.generate_mme_data(data)
    #     send_init_msg_influx(device_data)

    def generate_mme_data(self, data):
        topic = generate_mqtt_topics()
        device_data = {
            "device_id": "DEVICE_ID_VMPA",
            "device_name": "DEVICE_NAME_VMPA",
            "device_ip": self.droneid,
            "lat": data['lat'],
            "lon": data['lon'],
            "prev_mme": "none",
            "sender": "device",
            "device_topic": topic,
            # data["topic"] if "topic" in data.keys() else data["reason"],
            "entity_type": "drone"
        }
        return device_data

    def send_mme_data(self, data):
        db_path = "vmme_client/device.db"
        device_data = self.generate_mme_data(data)
        self.write_mme_data(db_path, device_data)
        self.logger.info("Data has been sent to vMME")

    def write_mme_data(self, db_path, device_data):
        self.logger.info("On write_mme_data")
        self.logger.info(self.initialized_vmme)
        if self.initialized_vmme == False:
            self.logger.info("TO INITIALIZE VMME")
            initialize_vmme(db_path, device_data)
            #             send_init_msg_influx(device_data)
            #             FIRST_BROKER = select(db_path, device_data["device_id"])
            # #             if DEMO:
            # #                 try:
            # #                     base = BaseClient(password=password,
            # #                                       keyfile="vmme_client/keyfile.json")
            # #                     base.create_keyfile()
            # #                     vmme_wallet_addr = base._fetch_signer_address()
            # #                     identity_hash_response = create_identity(vmme_wallet_addr)
            # #                     identity_hash = identity_hash_response.json()
            # #                     valid_identity(identity_hash["tx_hash"].strip(), vmme_wallet_addr, device_data["entity_type"])
            # #                     self.logger.info("The device registration to the vAAA was successful: \n")
            # #                 except Exception as e:
            # #                     self.logger.info(e)
            #             insert_ip(db_path, FIRST_BROKER)
            #             insert_device_data(db_path, device_data)
            self.vmme_producer = Producer()
            self.initialized_vmme = True
            self.logger.info("Initialized vMME")
        if self.vmme_producer:
            self.vmme_producer.operate(device_data["device_id"])
        self.logger.info("Out of write mme data")
예제 #8
0
class AuthentificationMiddleware:
    def __init__(self, get_response):
        self.get_response = get_response
        # One-time configuration and initialization.
        self.config = settings.KEYCLOAK_IAM_CLIENT_CONFIG
        try:
            self.server_url = self.config['KEYCLOAK_SERVER_URL']
            self.client_id = self.config['KEYCLOAK_CLIENT_ID']
            self.realm = self.config['KEYCLOAK_REALM']
        except KeyError:
            raise Exception(
                "KEYCLOAK_SERVER_URL, KEYCLOAK_CLIENT_ID or KEYCLOAK_REALM not found.")

        self.client_secret_key = self.config.get(
            'KEYCLOAK_CLIENT_SECRET_KEY', None)
        self.client_public_key = self.config.get(
            'KEYCLOAK_CLIENT_PUBLIC_KEY', None)
        self.default_access = self.config.get(
            'KEYCLOAK_DEFAULT_ACCESS', "DENY")
        self.method_validate_token = self.config.get(
            'KEYCLOAK_METHOD_VALIDATE_TOKEN', "INTROSPECT")
        self.keycloak_authorization_config = self.config.get(
            'KEYCLOAK_AUTHORIZATION_CONFIG', None)

        self.keycloak = KeycloakOpenID(server_url=self.server_url,
                                       client_id=self.client_id,
                                       realm_name=self.realm,
                                       client_secret_key=self.client_secret_key)

    @property
    def keycloak(self):
        return self._keycloak

    @keycloak.setter
    def keycloak(self, value):
        self._keycloak = value

    @property
    def config(self):
        return self._config

    @config.setter
    def config(self, value):
        self._config = value

    @property
    def server_url(self):
        return self._server_url

    @server_url.setter
    def server_url(self, value):
        self._server_url = value

    @property
    def client_id(self):
        return self._client_id

    @client_id.setter
    def client_id(self, value):
        self._client_id = value

    @property
    def client_secret_key(self):
        return self._client_secret_key

    @client_secret_key.setter
    def client_secret_key(self, value):
        self._client_secret_key = value

    @property
    def client_public_key(self):
        return self._client_public_key

    @client_public_key.setter
    def client_public_key(self, value):
        self._client_public_key = value

    @property
    def realm(self):
        return self._realm

    @realm.setter
    def realm(self, value):
        self._realm = value

    @property
    def keycloak_authorization_config(self):
        return self._keycloak_authorization_config

    @keycloak_authorization_config.setter
    def keycloak_authorization_config(self, value):
        self._keycloak_authorization_config = value

    @property
    def method_validate_token(self):
        return self._method_validate_token

    @method_validate_token.setter
    def method_validate_token(self, value):
        self._method_validate_token = value

    def __call__(self, request):
        print("queryString",  request.META.get('QUERY_STRING', ''))
        # Code to be executed for each request before
        # the view (and later middleware) are called.

        response = self.get_response(request)

        # Code to be executed for each request/response after
        # the view is called.

        return response

    def process_view(self, request, view_func, view_args, view_kwargs):
        if hasattr(settings, 'KEYCLOAK_BEARER_AUTHENTICATION_EXEMPT_PATHS'):
            path = request.path_info.lstrip('/')

            if any(re.match(m, path) for m in
                   settings.KEYCLOAK_BEARER_AUTHENTICATION_EXEMPT_PATHS):
                logger.debug('** exclude path found, skipping')
                return None
        if 'HTTP_AUTHORIZATION' not in request.META:
            token_request = request.META.get('QUERY_STRING' , "")
            print('token_request' , token_request)
            print("init =====" ,  request.GET , request.META)
            initToken = token_request.split('init=')[-1].split("&")[0]
            request_type = request.META.get('CONTENT_TYPE' , '')
            print('text/html' == request_type , 'text/plain' == request_type)
            if not initToken and not 'text/html' == request_type and not 'text/plain' == request_type:
                return JsonResponse({"detail": NotAuthenticated.default_detail},
                                    status=NotAuthenticated.status_code)
            else:
                token = initToken
        else:
            auth_header = request.META.get('HTTP_AUTHORIZATION').split()
            token = auth_header[1] if len(auth_header) == 2 else auth_header[0]

        try:
            user = self.keycloak.userinfo(token)
            request.authUser = user

        except KeycloakInvalidTokenError:
            return JsonResponse({"detail": AuthenticationFailed.default_detail,
                                 "code": settings.CUSTOM_ERRORS_TEXT['AUTHENTIFICATION_FAILLED']},
                                status=AuthenticationFailed.status_code)
        except KeycloakAuthenticationError as e:
            return JsonResponse({"detail": "Token Expiré veuillez refresh",
                                 "code": settings.CUSTOM_ERRORS_TEXT['REFRESH_TOKEN']},
                                status=AuthenticationFailed.status_code)

        return None