Metadata-Version: 2.1
Name: QMUtilities
Version: 0.0.4
Summary: ip whitelisting security module and okta token validator
Home-page: UNKNOWN
Author: Suman Kumar
Author-email: sumkumar@quotient.com
License: UNKNOWN
Description: QMUtilities
        =============
        
        Its a generic Utils library from where you can import various modules. Below are the modules and their installation steps with usage description
        
        pypi library link: https://pypi.org/project/QMUtilities/
        
        IP Validate and OKTA token Validate
        =============
        
        1. IP Validate
        -------------
        
        This is a simple security module to check whether client IP is allowed to access the flask`s backend APIs.
        
        Before every endpoint is served, it will check for the remote IP if it exists in the list of white listed IPs and it also checks if it has valid okta token, if it meets both the conditions, it passes through firewall to access API otherwise it throws abort error:
        
        ```
        HTTPErr: 403 Abort
        ```
        
        2. Validate Token
        ------------
        It also validates okta token in incoming header, when request type is POST.
        
        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
        
        @centrifuge.before_request
        def validate_header():
            ip_list = <list of IPs or import from config> 
            secret_name = <secret name or import from config>
            validate_object = ValidateHeader(ip_list, secret_name)
            validate_object.check_whitelisting() #for ip validation
            validate_object.check_okta_token() #for okta token validation
        
        ```
        
        
        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
