├── 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 | [](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 |
--------------------------------------------------------------------------------