├── src ├── Tests │ ├── __init__.py │ ├── TestMysql.py │ └── TestSqlite.py ├── main.py └── Classes │ ├── Mysql.py │ └── Sqlite.py ├── requirements.txt ├── .env_example ├── .github └── workflows │ ├── pylint.yml │ ├── 02_create_prod_pull_request.yml │ ├── 01_create_develop_pull_request.yml │ └── codeql-analysis.yml ├── README.md ├── SECURITY.md ├── .gitignore └── LICENSE /src/Tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/product/database-discovery/main/requirements.txt -------------------------------------------------------------------------------- /.env_example: -------------------------------------------------------------------------------- 1 | MYSQL_USER=root 2 | MYSQL_PASSWORD=root 3 | MYSQL_HOST=127.0.0.1 4 | MYSQL_DATABASE= 5 | SQLITE_DATABASE="base.db" 6 | SQLITE_PATH="sqlite:///" -------------------------------------------------------------------------------- /src/main.py: -------------------------------------------------------------------------------- 1 | from Classes.Sqlite import Sqlite 2 | from Classes.Mysql import MysqlDriver 3 | 4 | if __name__ == '__main__': 5 | # Create SQLITE tables 6 | Sqlite.create_tables() 7 | 8 | MysqlDriver.create_connection() 9 | Sqlite.create_connection() 10 | -------------------------------------------------------------------------------- /src/Tests/TestMysql.py: -------------------------------------------------------------------------------- 1 | from src.Classes.Mysql import MysqlDriver 2 | from unittest import TestCase, main 3 | 4 | 5 | class TestMysql(TestCase): 6 | def test_connection(self): 7 | mysql = MysqlDriver.create_connection() 8 | assert mysql == True 9 | 10 | if __name__ == '__main__': 11 | main() 12 | -------------------------------------------------------------------------------- /src/Tests/TestSqlite.py: -------------------------------------------------------------------------------- 1 | from src.Classes.Sqlite import Sqlite 2 | from unittest import TestCase, main 3 | 4 | 5 | class TestSqlite(TestCase): 6 | def test_create_connection(self): 7 | sqlite = Sqlite.create_connection() 8 | assert sqlite == True 9 | 10 | def test_check_connection(self): 11 | self.sqllite = Sqlite.check_connection() 12 | assert self.sqllite is not None 13 | 14 | 15 | if __name__ == '__main__': 16 | main() 17 | -------------------------------------------------------------------------------- /.github/workflows/pylint.yml: -------------------------------------------------------------------------------- 1 | name: Data Discovery 2 | 3 | on: [push] 4 | 5 | jobs: 6 | build: 7 | 8 | runs-on: [ubuntu-latest] 9 | 10 | steps: 11 | - uses: actions/checkout@v2 12 | - name: Set up Python 3.9 13 | uses: actions/setup-python@v2 14 | with: 15 | python-version: 3.9 16 | - name: Install dependencies 17 | run: | 18 | python -m pip install --upgrade pip 19 | pip install pylint 20 | pip install -r requirements.txt 21 | - name: Analysing the code with pylint 22 | run: | 23 | # pylint `ls -R|grep .py$|xargs` 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # database-discovery 2 | A simple project to discovery sensitive and personal data. 3 | 4 |

5 | 6 | [![Pylint](https://github.com/FelipeArruda/database-discovery/actions/workflows/pylint.yml/badge.svg)](https://github.com/FelipeArruda/database-discovery/actions/workflows/pylint.yml) 7 |

8 | 9 | ## ⚡️ Installation 10 | ```sh 11 | python -m pip install -r requirements.txt 12 | ``` 13 | * Rename `.env_example` to `.env` and set up your connection to mysql database. 14 | ## ⚡️ Used Packages 15 | ### Mysql connector 16 | ```sh 17 | pip install mysql-connector-python 18 | ``` 19 | ### SQLITE3 20 | ```sh 21 | pip install pysqlite3 22 | ``` -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | Use this section to tell people about which versions of your project are 6 | currently being supported with security updates. 7 | 8 | | Version | Supported | 9 | | ------- | ------------------ | 10 | | 5.1.x | :white_check_mark: | 11 | | 5.0.x | :x: | 12 | | 4.0.x | :white_check_mark: | 13 | | < 4.0 | :x: | 14 | 15 | ## Reporting a Vulnerability 16 | 17 | Use this section to tell people how to report a vulnerability. 18 | 19 | Tell them where to go, how often they can expect to get an update on a 20 | reported vulnerability, what to expect if the vulnerability is accepted or 21 | declined, etc. 22 | -------------------------------------------------------------------------------- /.github/workflows/02_create_prod_pull_request.yml: -------------------------------------------------------------------------------- 1 | name: create_prod_pull_request 2 | 3 | on: 4 | push: 5 | branches: 6 | - develop 7 | 8 | jobs: 9 | auto-pull-request: 10 | name: create_prod_pull_request 11 | runs-on: ubuntu-latest 12 | steps: 13 | - name: pull-request-action 14 | uses: vsoch/pull-request-action@1.0.18 15 | env: 16 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 17 | PULL_REQUEST_BRANCH: "main" 18 | PULL_REQUEST_TITLE: "Production Release" 19 | PULL_REQUEST_BODY: | 20 | # Production Release 21 | ## Changelog 22 | 23 | 24 | - < PR Number > @< username > -------------------------------------------------------------------------------- /src/Classes/Mysql.py: -------------------------------------------------------------------------------- 1 | import mysql.connector 2 | import os 3 | import dotenv 4 | from mysql.connector import errorcode 5 | 6 | # load .env file 7 | dotenv.load_dotenv(dotenv.find_dotenv()) 8 | 9 | 10 | class MysqlDriver: 11 | def __init__(self, val): 12 | self.val=val 13 | 14 | @staticmethod 15 | def create_connection(): 16 | global cnx 17 | try: 18 | cnx = mysql.connector.connect(user=os.getenv("MYSQL_USER"), password=os.getenv("MYSQL_PASSWORD"), 19 | host=os.getenv("MYSQL_HOST"), 20 | database=os.getenv("MYSQL_DATABASE")) 21 | print("Connected to Mysql.") 22 | except mysql.connector.Error as err: 23 | if err.errno == errorcode.ER_ACCESS_DENIED_ERROR: 24 | print("Something is wrong with your user name or password") 25 | exit() 26 | elif err.errno == errorcode.ER_BAD_DB_ERROR: 27 | print("Database does not exist") 28 | exit() 29 | else: 30 | print(err) 31 | exit() 32 | return True 33 | 34 | -------------------------------------------------------------------------------- /.github/workflows/01_create_develop_pull_request.yml: -------------------------------------------------------------------------------- 1 | name: create_develop_pull_request 2 | 3 | on: 4 | push: 5 | branches-ignore: 6 | - master 7 | - develop 8 | - main 9 | 10 | jobs: 11 | auto-pull-request: 12 | name: create_develop_pull_request 13 | runs-on: ubuntu-latest 14 | steps: 15 | # - uses: actions/checkout@v2 16 | - name: Extract Branch Name 17 | shell: bash 18 | run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})" 19 | id: extract_branch 20 | 21 | - name: pull-request-action 22 | uses: vsoch/pull-request-action@1.0.18 23 | env: 24 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 25 | PULL_REQUEST_BRANCH: "develop" 26 | PULL_REQUEST_TITLE: ${{ steps.extract_branch.outputs.branch }} 27 | PULL_REQUEST_DRAFT: true 28 | PULL_REQUEST_BODY: | 29 | # ISSUE INFORMATION 30 | 31 | Please check the following GitHub issues to find out more about this PR: 32 | - https://github.com/andresionek91/LIVE001-Criando-Lambda-Functions-para-Ingerir-Dados-de-APIs/issues/ 33 | # Checklist 34 | - [ ] Does the commit messages reference the GitHub issue? (i.e. ISSUE-1/commit message) 35 | - [ ] Does the commit message explain the change made? 36 | - [ ] Did you deploy to staging/UAT? 37 | - [ ] Were the changes approved by the stakeholders? 38 | ## What? 39 | 40 | 41 | 42 | ## Why? 43 | 44 | 45 | ## How? 46 | 47 | 48 | ## Testing? 49 | 50 | 51 | ## Documentation? 52 | 53 | 54 | ## Anything Else? 55 | 56 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | wheels/ 23 | pip-wheel-metadata/ 24 | share/python-wheels/ 25 | *.egg-info/ 26 | .installed.cfg 27 | *.egg 28 | MANIFEST 29 | 30 | # PyInstaller 31 | # Usually these files are written by a python script from a template 32 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 33 | *.manifest 34 | *.spec 35 | 36 | # Installer logs 37 | pip-log.txt 38 | pip-delete-this-directory.txt 39 | 40 | # Unit test / coverage reports 41 | htmlcov/ 42 | .tox/ 43 | .nox/ 44 | .coverage 45 | .coverage.* 46 | .cache 47 | nosetests.xml 48 | coverage.xml 49 | *.cover 50 | *.py,cover 51 | .hypothesis/ 52 | .pytest_cache/ 53 | 54 | # Translations 55 | *.mo 56 | *.pot 57 | 58 | # Django stuff: 59 | *.log 60 | local_settings.py 61 | db.sqlite3 62 | db.sqlite3-journal 63 | 64 | # Flask stuff: 65 | instance/ 66 | .webassets-cache 67 | 68 | # Scrapy stuff: 69 | .scrapy 70 | 71 | # Sphinx documentation 72 | docs/_build/ 73 | 74 | # PyBuilder 75 | target/ 76 | 77 | # Jupyter Notebook 78 | .ipynb_checkpoints 79 | 80 | # IPython 81 | profile_default/ 82 | ipython_config.py 83 | 84 | # pyenv 85 | .python-version 86 | 87 | # pipenv 88 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. 89 | # However, in case of collaboration, if having platform-specific dependencies or dependencies 90 | # having no cross-platform support, pipenv may install dependencies that don't work, or not 91 | # install all needed dependencies. 92 | #Pipfile.lock 93 | 94 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow 95 | __pypackages__/ 96 | 97 | # Celery stuff 98 | celerybeat-schedule 99 | celerybeat.pid 100 | 101 | # SageMath parsed files 102 | *.sage.py 103 | 104 | # Environments 105 | .env 106 | .venv 107 | env/ 108 | venv/ 109 | ENV/ 110 | env.bak/ 111 | venv.bak/ 112 | 113 | # Spyder project settings 114 | .spyderproject 115 | .spyproject 116 | 117 | # Rope project settings 118 | .ropeproject 119 | 120 | # mkdocs documentation 121 | /site 122 | 123 | # mypy 124 | .mypy_cache/ 125 | .dmypy.json 126 | dmypy.json 127 | 128 | # Pyre type checker 129 | .pyre/ 130 | 131 | # project 132 | base.db -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ main, develop ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ main ] 20 | schedule: 21 | - cron: '39 23 * * 2' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | permissions: 28 | actions: read 29 | contents: read 30 | security-events: write 31 | 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | language: [ 'python' ] 36 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ] 37 | # Learn more about CodeQL language support at https://git.io/codeql-language-support 38 | 39 | steps: 40 | - name: Checkout repository 41 | uses: actions/checkout@v2 42 | 43 | # Initializes the CodeQL tools for scanning. 44 | - name: Initialize CodeQL 45 | uses: github/codeql-action/init@v1 46 | with: 47 | languages: ${{ matrix.language }} 48 | # If you wish to specify custom queries, you can do so here or in a config file. 49 | # By default, queries listed here will override any specified in a config file. 50 | # Prefix the list here with "+" to use these queries and those in the config file. 51 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 52 | 53 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 54 | # If this step fails, then you should remove it and run the build manually (see below) 55 | - name: Autobuild 56 | uses: github/codeql-action/autobuild@v1 57 | 58 | # ℹ️ Command-line programs to run using the OS shell. 59 | # 📚 https://git.io/JvXDl 60 | 61 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 62 | # and modify them (or add more) to build your code if your project 63 | # uses a compiled language 64 | 65 | #- run: | 66 | # make bootstrap 67 | # make release 68 | 69 | - name: Perform CodeQL Analysis 70 | uses: github/codeql-action/analyze@v1 71 | -------------------------------------------------------------------------------- /src/Classes/Sqlite.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sqlite3 3 | import dotenv 4 | from sqlalchemy import create_engine 5 | 6 | # load .env file 7 | dotenv.load_dotenv(dotenv.find_dotenv()) 8 | 9 | 10 | class Sqlite: 11 | 12 | def __init__(self, val): 13 | self.val = val 14 | 15 | @staticmethod 16 | def create_connection(): 17 | sqlite3.connect("../base.db") 18 | print("Connect to SQLITE.") 19 | return True 20 | 21 | @staticmethod 22 | def check_connection(): 23 | global sqlite_connection 24 | try: 25 | sqlite_connection = sqlite3.connect(os.getenv("SQLITE_DATABASE")) 26 | cursor = sqlite_connection.cursor() 27 | print("Database Connected") 28 | 29 | sqlite_select_query = "select sqlite_version();" 30 | cursor.execute(sqlite_select_query) 31 | record = cursor.fetchall() 32 | print("SQLite Database Version is: ", record) 33 | cursor.close() 34 | return True 35 | except sqlite3.Error as error: 36 | print("Error while connecting to sqlite", error) 37 | return False 38 | finally: 39 | if sqlite_connection: 40 | sqlite_connection.close() 41 | print("The SQLite connection is closed") 42 | return False 43 | 44 | @staticmethod 45 | def create_tables(): 46 | 47 | engine = create_engine(os.getenv("SQLITE_PATH") + os.getenv("SQLITE_DATABASE")) 48 | 49 | # table: name 50 | engine.execute('CREATE TABLE IF NOT EXISTS "names" (' 51 | 'id integer PRIMARY KEY AUTOINCREMENT,' 52 | 'name VARCHAR (500) ' 53 | ');') 54 | 55 | # table: terms 56 | engine.execute('CREATE TABLE IF NOT EXISTS "terms" (' 57 | 'id integer PRIMARY KEY AUTOINCREMENT,' 58 | 'term VARCHAR (500) ' 59 | ');') 60 | 61 | # table: configs 62 | engine.execute('CREATE TABLE IF NOT EXISTS "configs" (' 63 | 'id integer PRIMARY KEY AUTOINCREMENT,' 64 | 'param VARCHAR (100), ' 65 | 'param_valor VARCHAR (500), ' 66 | 'param_system VARCHAR (500), ' 67 | 'start_date DATE, ' 68 | 'end_date DATE ' 69 | ');') 70 | 71 | # table: base 72 | engine.execute('CREATE TABLE IF NOT EXISTS "base" (' 73 | 'id integer PRIMARY KEY AUTOINCREMENT,' 74 | 'conceitual_data VARCHAR (500), ' 75 | 'data_classification VARCHAR (500), ' 76 | 'table_schema VARCHAR (500), ' 77 | 'table_name VARCHAR (500), ' 78 | 'column_name VARCHAR (500), ' 79 | 'date_type VARCHAR (500), ' 80 | 'column_type VARCHAR (500), ' 81 | 'sql VARCHAR (500), ' 82 | 'has_sensitive VARCHAR (500), ' 83 | 'is_empty_table VARCHAR (500), ' 84 | 'obs VARCHAR (500), ' 85 | 'classification_source VARCHAR (500), ' 86 | 'regex_ip char(1), ' 87 | 'regex_phone char(1), ' 88 | 'regex_email char(1), ' 89 | 'regex_address char(1), ' 90 | 'regex_links char(1), ' 91 | 'regex_social_media char(1), ' 92 | 'regex_cpf char(1), ' 93 | 'regex_credit_card char(1), ' 94 | 'regex_name char(1), ' 95 | 'date datetime, ' 96 | 'executed char(1) ' 97 | ');') 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Creative Commons Legal Code 2 | 3 | CC0 1.0 Universal 4 | 5 | CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE 6 | LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN 7 | ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS 8 | INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES 9 | REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS 10 | PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM 11 | THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED 12 | HEREUNDER. 13 | 14 | Statement of Purpose 15 | 16 | The laws of most jurisdictions throughout the world automatically confer 17 | exclusive Copyright and Related Rights (defined below) upon the creator 18 | and subsequent owner(s) (each and all, an "owner") of an original work of 19 | authorship and/or a database (each, a "Work"). 20 | 21 | Certain owners wish to permanently relinquish those rights to a Work for 22 | the purpose of contributing to a commons of creative, cultural and 23 | scientific works ("Commons") that the public can reliably and without fear 24 | of later claims of infringement build upon, modify, incorporate in other 25 | works, reuse and redistribute as freely as possible in any form whatsoever 26 | and for any purposes, including without limitation commercial purposes. 27 | These owners may contribute to the Commons to promote the ideal of a free 28 | culture and the further production of creative, cultural and scientific 29 | works, or to gain reputation or greater distribution for their Work in 30 | part through the use and efforts of others. 31 | 32 | For these and/or other purposes and motivations, and without any 33 | expectation of additional consideration or compensation, the person 34 | associating CC0 with a Work (the "Affirmer"), to the extent that he or she 35 | is an owner of Copyright and Related Rights in the Work, voluntarily 36 | elects to apply CC0 to the Work and publicly distribute the Work under its 37 | terms, with knowledge of his or her Copyright and Related Rights in the 38 | Work and the meaning and intended legal effect of CC0 on those rights. 39 | 40 | 1. Copyright and Related Rights. A Work made available under CC0 may be 41 | protected by copyright and related or neighboring rights ("Copyright and 42 | Related Rights"). Copyright and Related Rights include, but are not 43 | limited to, the following: 44 | 45 | i. the right to reproduce, adapt, distribute, perform, display, 46 | communicate, and translate a Work; 47 | ii. moral rights retained by the original author(s) and/or performer(s); 48 | iii. publicity and privacy rights pertaining to a person's image or 49 | likeness depicted in a Work; 50 | iv. rights protecting against unfair competition in regards to a Work, 51 | subject to the limitations in paragraph 4(a), below; 52 | v. rights protecting the extraction, dissemination, use and reuse of data 53 | in a Work; 54 | vi. database rights (such as those arising under Directive 96/9/EC of the 55 | European Parliament and of the Council of 11 March 1996 on the legal 56 | protection of databases, and under any national implementation 57 | thereof, including any amended or successor version of such 58 | directive); and 59 | vii. other similar, equivalent or corresponding rights throughout the 60 | world based on applicable law or treaty, and any national 61 | implementations thereof. 62 | 63 | 2. Waiver. To the greatest extent permitted by, but not in contravention 64 | of, applicable law, Affirmer hereby overtly, fully, permanently, 65 | irrevocably and unconditionally waives, abandons, and surrenders all of 66 | Affirmer's Copyright and Related Rights and associated claims and causes 67 | of action, whether now known or unknown (including existing as well as 68 | future claims and causes of action), in the Work (i) in all territories 69 | worldwide, (ii) for the maximum duration provided by applicable law or 70 | treaty (including future time extensions), (iii) in any current or future 71 | medium and for any number of copies, and (iv) for any purpose whatsoever, 72 | including without limitation commercial, advertising or promotional 73 | purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each 74 | member of the public at large and to the detriment of Affirmer's heirs and 75 | successors, fully intending that such Waiver shall not be subject to 76 | revocation, rescission, cancellation, termination, or any other legal or 77 | equitable action to disrupt the quiet enjoyment of the Work by the public 78 | as contemplated by Affirmer's express Statement of Purpose. 79 | 80 | 3. Public License Fallback. Should any part of the Waiver for any reason 81 | be judged legally invalid or ineffective under applicable law, then the 82 | Waiver shall be preserved to the maximum extent permitted taking into 83 | account Affirmer's express Statement of Purpose. In addition, to the 84 | extent the Waiver is so judged Affirmer hereby grants to each affected 85 | person a royalty-free, non transferable, non sublicensable, non exclusive, 86 | irrevocable and unconditional license to exercise Affirmer's Copyright and 87 | Related Rights in the Work (i) in all territories worldwide, (ii) for the 88 | maximum duration provided by applicable law or treaty (including future 89 | time extensions), (iii) in any current or future medium and for any number 90 | of copies, and (iv) for any purpose whatsoever, including without 91 | limitation commercial, advertising or promotional purposes (the 92 | "License"). The License shall be deemed effective as of the date CC0 was 93 | applied by Affirmer to the Work. Should any part of the License for any 94 | reason be judged legally invalid or ineffective under applicable law, such 95 | partial invalidity or ineffectiveness shall not invalidate the remainder 96 | of the License, and in such case Affirmer hereby affirms that he or she 97 | will not (i) exercise any of his or her remaining Copyright and Related 98 | Rights in the Work or (ii) assert any associated claims and causes of 99 | action with respect to the Work, in either case contrary to Affirmer's 100 | express Statement of Purpose. 101 | 102 | 4. Limitations and Disclaimers. 103 | 104 | a. No trademark or patent rights held by Affirmer are waived, abandoned, 105 | surrendered, licensed or otherwise affected by this document. 106 | b. Affirmer offers the Work as-is and makes no representations or 107 | warranties of any kind concerning the Work, express, implied, 108 | statutory or otherwise, including without limitation warranties of 109 | title, merchantability, fitness for a particular purpose, non 110 | infringement, or the absence of latent or other defects, accuracy, or 111 | the present or absence of errors, whether or not discoverable, all to 112 | the greatest extent permissible under applicable law. 113 | c. Affirmer disclaims responsibility for clearing rights of other persons 114 | that may apply to the Work or any use thereof, including without 115 | limitation any person's Copyright and Related Rights in the Work. 116 | Further, Affirmer disclaims responsibility for obtaining any necessary 117 | consents, permissions or other rights required for any use of the 118 | Work. 119 | d. Affirmer understands and acknowledges that Creative Commons is not a 120 | party to this document and has no duty or obligation with respect to 121 | this CC0 or use of the Work. 122 | --------------------------------------------------------------------------------