Metadata-Version: 2.1
Name: QMUtilities
Version: 1.0.2
Summary: ip whitelisting security module and okta token validator
Home-page: UNKNOWN
Author: Suman Kumar
Author-email: sumkumar@quotient.com
License: UNKNOWN
Description: QMUtilities
        =============
        
        Utility to validate incoming request to the backend python services
        pypi library link: https://pypi.org/project/QMUtilities/
        
        It validates IP and OKTA token of the incoming request
        =============
        
        1. IP Validate
        -------------
        
        It validates whether incoming request is from trusted or listed IP_LIST
        
        Before every endpoint is served, it will check for the remote IP if it exists in the list of white listed IPs  otherwise it throws abort error:
        
        ```
        HTTPErr: 403 Abort
        ```
        
        2. Validate Token
        ------------
        It also validates okta token in incoming header
        
        Authentication header format:
        
            Authentication: agency <id> user <id>:<assertid>
        
        Setup
        ----------
        
        ```
        1. Create VirtualENV
        2. source VirtualENV
        3. Install dependent libraries, please ignore if already installed. 
                        boto3, pymemcache (pip install)
        4. pip install QMUtilities
        5. create a stored secret at secret manager and store below keys and correspoding values of memcache server
            
            aws_elastic_cache_hostname : <hostname of memcache server>
            port : <port details>
        6. Add below blocks to the "view" file of the app
        
        ```
        
        ``` python
        from flask import Flask
        from security.validate import ValidateHeader
        
        @app.before_request
        def validate_header():
            ip_list = <list of IPs or import from config> 
            secret_name = <AWS secret name>
            memcache_host = CONFIG['memcache_host']
            memcache_port = CONFIG['memcache_port']
            
            ValidateHeader.check_whitelisting(IP_LIST=ip_list) #for ip validation
        
            #OKTA VALIDATOR
            #if host and port in config
            ValidateHeader.check_okta_token(MEMCACHE_HOST=memcache_host, MEMCACHE_PORT=memcache_port) #for okta token validation
            
            if host and port in AWS secret
            ValidateHeader.check_okta_token(SECRET_NAME=secret_name)
        ```
        
        
        Nginx Routing
        ====
        
        By default headers of the incoming request gets updated with localhost IP when it is passed to the backend Nginx server.
        In order to get the real IP of the client/LAN, we need to do following configurations in the nginx config:
        
        ```
        server {
            real_ip_recursive on;
        }
        
        location / {
            proxy_set_header  Host $host;
            proxy_set_header  X-Real-IP $remote_addr;
            proxy_set_header  X-Forwarded-For $remote_addr;
            proxy_set_header  X-Forwarded-Host $remote_addr;
           }
           
        ```
        
        **sample incoming request header dict after naking above changes in Nginx**
        ```
        {'wsgi.version': (1, 0), 'wsgi.url_scheme': 'http', 
        'wsgi.input': '<_io.BufferedReader name=5>', 'wsgi.errors': <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'>,
        'wsgi.multithread': True, 
        'wsgi.multiprocess': False, 'wsgi.run_once': False, 
        'werkzeug.server.shutdown': <function WSGIRequestHandler.make_environ.<locals>.shutdown_server at 0x7fba5d1bd598>, 
        'SERVER_SOFTWARE': 'Werkzeug/0.14.1', 'REQUEST_METHOD': 'GET', 'SCRIPT_NAME': '', 'PATH_INFO': '/', 'QUERY_STRING': '', 'REMOTE_ADDR': '127.0.0.1', 'REMOTE_PORT': 39534, 'SERVER_NAME': '127.0.0.1', 'SERVER_PORT': '8002', 'SERVER_PROTOCOL': 'HTTP/1.0', 
        'HTTP_HOST': '172.30.1.23', 
        'HTTP_X_REAL_IP': '10.21.120.11', 
        'HTTP_X_FORWARDED_FOR': '10.21.120.11', 
        'HTTP_X_FORWARDED_HOST': '10.21.120.11', 
        'HTTP_CONNECTION': 'close', 'HTTP_PRAGMA': 'no-cache', 
        'HTTP_CACHE_CONTROL': 'no-cache', 'HTTP_UPGRADE_INSECURE_REQUESTS': '1', 
        'HTTP_USER_AGENT': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.157 Safari/537.36', 
        HTTP_ACCEPT': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3', 
        'HTTP_ACCEPT_ENCODING': 'gzip, deflate', 'HTTP_ACCEPT_LANGUAGE': 'en-GB,en-US;q=0.9,en;q=0.8', 'werkzeug.request': <Request 'http://10.21.120.11/' [GET]>}
        
        ```
        
Platform: UNKNOWN
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Topic :: Software Development :: Build Tools
Classifier: Programming Language :: Python :: 2
Classifier: Programming Language :: Python :: 2.7
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.4
Classifier: Programming Language :: Python :: 3.5
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Requires-Python: >=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, <4
Description-Content-Type: text/markdown
