├── .github
└── ISSUE_TEMPLATE
│ ├── bug_report.md
│ ├── custom.md
│ └── feature_request.md
├── .gitignore
├── .travis.yml
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── SECURITY.md
├── codecov.ynl
├── hash.txt
├── nbactions.xml
├── pom.xml
├── sample_projects
├── anonymizer
│ ├── DataDefender-jar-file-here
│ ├── anonymize.config
│ ├── database.config
│ ├── datadefender
│ ├── datadefender.bat
│ ├── extensions
│ │ ├── EmployeeNumber.class
│ │ └── EmployeeNumber.java
│ └── requirement.xml
├── database-logging
│ ├── DataDefender-jar-file-here
│ ├── column-discovery.config
│ ├── common-discovery.config
│ ├── create-logging-table.sql
│ ├── data-discovery.config
│ ├── database.config
│ ├── datadefender
│ ├── datadefender.bat
│ └── log4j2.properties
├── database_discovery
│ ├── mysql
│ │ ├── DataDefender-jar-file-here
│ │ ├── column-discovery.config
│ │ ├── common-discovery.config
│ │ ├── data-discovery.config
│ │ ├── database.config
│ │ ├── datadefender
│ │ └── datadefender.bat
│ └── postgresql
│ │ ├── DataDefender-jar-file-here
│ │ ├── column-discovery.config
│ │ ├── common-discovery.config
│ │ ├── data-discovery.config
│ │ ├── database.config
│ │ ├── datadefender
│ │ └── datadefender.bat
└── file_discovery
│ ├── DataDefender-jar-file-here
│ ├── datadefender
│ ├── datadefender.bat
│ └── file-discovery.config
└── src
├── main
├── java
│ └── com
│ │ └── strider
│ │ └── datadefender
│ │ ├── Anonymize.java
│ │ ├── DataDefender.java
│ │ ├── DataDefenderException.java
│ │ ├── DbConfig.java
│ │ ├── Discover.java
│ │ ├── DiscoverColumns.java
│ │ ├── DiscoverData.java
│ │ ├── DiscoverFiles.java
│ │ ├── Extract.java
│ │ ├── IRequirementCommand.java
│ │ ├── ModelDiscoveryConfig.java
│ │ ├── TestRequirement.java
│ │ ├── anonymizer
│ │ ├── DatabaseAnonymizer.java
│ │ ├── DatabaseAnonymizerException.java
│ │ ├── IAnonymizer.java
│ │ └── functions
│ │ │ ├── Address.java
│ │ │ ├── Bio.java
│ │ │ ├── Core.java
│ │ │ ├── Lipsum.java
│ │ │ └── Table.java
│ │ ├── database
│ │ ├── DatabaseException.java
│ │ ├── DbConnection.java
│ │ ├── IDbConnection.java
│ │ ├── IDbFactory.java
│ │ ├── MsSqlDbConnection.java
│ │ ├── metadata
│ │ │ ├── IMetaData.java
│ │ │ ├── MetaData.java
│ │ │ ├── MySqlMetaData.java
│ │ │ ├── SqlTypeToClass.java
│ │ │ └── TableMetaData.java
│ │ └── sqlbuilder
│ │ │ ├── ISqlBuilder.java
│ │ │ ├── MsSqlBuilder.java
│ │ │ ├── OracleSqlBuilder.java
│ │ │ └── SqlBuilder.java
│ │ ├── discoverer
│ │ ├── ColumnDiscoverer.java
│ │ ├── DatabaseDiscoverer.java
│ │ ├── Discoverer.java
│ │ ├── FileDiscoverer.java
│ │ ├── FileDiscoveryException.java
│ │ ├── IDiscoverer.java
│ │ ├── Model.java
│ │ └── Probability.java
│ │ ├── extensions
│ │ ├── BiographicFunctions.java
│ │ └── ExtensionExample.java
│ │ ├── extractor
│ │ ├── DataExtractor.java
│ │ └── IExtractor.java
│ │ ├── file
│ │ └── metadata
│ │ │ └── FileMatchMetaData.java
│ │ ├── functions
│ │ ├── NamedParameter.java
│ │ └── Utils.java
│ │ ├── report
│ │ └── ReportUtil.java
│ │ ├── requirement
│ │ ├── ClassAdapter.java
│ │ ├── Column.java
│ │ ├── Exclude.java
│ │ ├── Requirement.java
│ │ ├── RequirementException.java
│ │ ├── Table.java
│ │ ├── TypeConverter.java
│ │ ├── file
│ │ │ ├── Generator.java
│ │ │ ├── JaxbValidationEventHandler.java
│ │ │ └── Loader.java
│ │ ├── package-info.java
│ │ ├── plan
│ │ │ ├── Argument.java
│ │ │ ├── ArrayElement.java
│ │ │ ├── Function.java
│ │ │ ├── FunctionAttributeAdapter.java
│ │ │ ├── GlobalPlan.java
│ │ │ ├── Invokable.java
│ │ │ ├── Plan.java
│ │ │ ├── PlanRef.java
│ │ │ └── package-info.java
│ │ └── registry
│ │ │ ├── ClassAndFunctionRegistry.java
│ │ │ ├── DatabaseAwareRequirementFunction.java
│ │ │ └── RequirementFunction.java
│ │ ├── specialcase
│ │ ├── EmailDetector.java
│ │ ├── PhiDetector.java
│ │ ├── SinDetector.java
│ │ └── SpecialCase.java
│ │ └── utils
│ │ ├── ApplicationLock.java
│ │ ├── Encoder.java
│ │ ├── ICloseableNoException.java
│ │ ├── IConsumerWithException.java
│ │ ├── ISupplierWithException.java
│ │ ├── LikeMatcher.java
│ │ ├── Score.java
│ │ ├── Xeger.java
│ │ └── XegerUtils.java
└── resources
│ ├── com
│ └── strider
│ │ └── datadefender
│ │ ├── anonymizer
│ │ └── functions
│ │ │ ├── cities.txt
│ │ │ ├── countries.txt
│ │ │ ├── dictionary.txt
│ │ │ ├── first_names.txt
│ │ │ ├── last_names.txt
│ │ │ ├── lipsum.txt
│ │ │ ├── provinces_states.txt
│ │ │ ├── provinces_states_codes.txt
│ │ │ └── streets.txt
│ │ ├── discoverer
│ │ ├── en-ner-date.bin
│ │ ├── en-ner-location.bin
│ │ ├── en-ner-money.bin
│ │ ├── en-ner-organization.bin
│ │ ├── en-ner-person.bin
│ │ ├── en-ner-time.bin
│ │ ├── en-sent.bin
│ │ └── en-token.bin
│ │ └── requirement
│ │ └── file
│ │ └── requirement.xsd
│ ├── filediscovery.properties
│ ├── log4j2.properties
│ ├── names.dict
│ └── phi.txt
├── run-scripts
├── datadefender
└── datadefender.bat
└── test
├── java
└── com
│ └── strider
│ └── datadefender
│ ├── anonymizer
│ └── functions
│ │ ├── BioTest.java
│ │ ├── CoreTest.java
│ │ └── LipsumTest.java
│ ├── database
│ ├── DbConnectionTest.java
│ ├── IDbFactoryTest.java
│ ├── metadata
│ │ └── MetaDataTest.java
│ └── sqlbuilder
│ │ └── SqlBuilderTest.java
│ ├── functions
│ └── UtilsTest.java
│ └── utils
│ ├── EncoderTest.java
│ ├── LikeMatcherTest.java
│ ├── RequirementUtilsTest.java
│ └── XegerTest.java
└── resources
├── AppPropertiesTest.properties
├── Requirement-H2DB-DG.xml
├── Requirement-H2DB.xml
├── Requirement.xml
├── core-test.txt
├── log4j2.properties
└── names.txt
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/custom.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Custom issue template
3 | about: Describe this issue template's purpose here.
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 |
11 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 | nbactions.xml
3 | *.log
4 | nb-configuration.xml
5 | sample_projects/database_discovery/logs/anonymizer.log.2
6 | sample_projects/database_discovery/logs/anonymizer.log.3
7 | /nbproject/
8 | sample_projects/file_discovery/files/000b2798-b3a2-4231-aab1-6a5da3999a11.xls
9 | sample_projects/file_discovery/files/0074014f-b378-4e51-a1ea-56499560f1e3.pdf
10 | sample_projects/file_discovery/files/026fafb2-364e-4e04-b006-3b4ab5808e87.pdf
11 | sample_projects/file_discovery/files/0379be65-9ead-420e-93d5-8f3d4ef69287.pdf
12 | sample_projects/file_discovery/files/0a87d04c-8f4d-404f-85ab-bc9da56a7c04.docx
13 | sample_projects/file_discovery/files/0a965acb-e8e7-43f7-9aec-dde7b15eeca6.docx
14 | sample_projects/file_discovery/files/0aa0a91c-a325-4101-a8db-17ef92510da0.docx
15 | sample_projects/file_discovery/files/0aa28454-3280-4cd6-9f9c-d1331efe895d.pdf
16 | sample_projects/file_discovery/files/0b8da254-9dd1-48c6-9224-af656dbec616.docx
17 | sample_projects/file_discovery/files/0be3924f-c04b-4cf9-9258-f75fe2f91b9c.pdf
18 | sample_projects/file_discovery/files/0bebf028-07b2-4489-a08e-d9a6b1f4fbb8.docx
19 | sample_projects/file_discovery/files/0c309926-72e4-49c3-9f00-92617e8cf648.pdf
20 | sample_projects/file_discovery/files/1c0ee6a2-a86b-4fd7-9942-e20cb64de58c.xls
21 | sample_projects/file_discovery/files/1fba4e10-f1a5-4c42-b1cc-f6bf22136f39.xls
22 | sample_projects/file_discovery/files/2e7a4ced-dd04-4977-9b3c-1581d091d311.xls
23 | sample_projects/file_discovery/files/8d6b912d-a5ee-467e-ba82-4440f3fe816f.xls
24 |
25 | # Ignore IntelliJ files.
26 | .idea/
27 | *.iml
28 | *.ipr
29 | *.iws
30 |
31 | # Ignore Eclipse files.
32 | .classpath
33 | .project
34 | .factorypath
35 | .checkstyle
36 | .fbExcludeFilterFile
37 | .apt_generated/
38 | .settings/
39 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: java
2 | dist: bionic
3 |
--------------------------------------------------------------------------------
/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation.
6 |
7 | ## Our Standards
8 |
9 | Examples of behavior that contributes to creating a positive environment include:
10 |
11 | * Using welcoming and inclusive language
12 | * Being respectful of differing viewpoints and experiences
13 | * Gracefully accepting constructive criticism
14 | * Focusing on what is best for the community
15 | * Showing empathy towards other community members
16 |
17 | Examples of unacceptable behavior by participants include:
18 |
19 | * The use of sexualized language or imagery and unwelcome sexual attention or advances
20 | * Trolling, insulting/derogatory comments, and personal or political attacks
21 | * Public or private harassment
22 | * Publishing others' private information, such as a physical or electronic address, without explicit permission
23 | * Other conduct which could reasonably be considered inappropriate in a professional setting
24 |
25 | ## Our Responsibilities
26 |
27 | Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
28 |
29 | Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
30 |
31 | ## Scope
32 |
33 | This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
34 |
35 | ## Enforcement
36 |
37 | Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at agstrider@gmail.com. The project team will review and investigate all complaints, and will respond in a way that it deems appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
38 |
39 | Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
40 |
41 | ## Attribution
42 |
43 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [http://contributor-covenant.org/version/1/4][version]
44 |
45 | [homepage]: http://contributor-covenant.org
46 | [version]: http://contributor-covenant.org/version/1/4/
47 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing
2 |
3 | You can contribute by clicking the star button and using this software!
4 |
5 | Contributors are encouraged to fork this repository and issue pull requests. If you would like to contribute, please
6 |
7 | * Fork it
8 | * Create your feature branch (git checkout -b new-feature)
9 | * Commit your changes (git commit -am 'Add new feature')
10 | * Push to the branch (git push origin new-feature)
11 | * Create new Pull Request
12 |
--------------------------------------------------------------------------------
/SECURITY.md:
--------------------------------------------------------------------------------
1 | # Security Policy
2 |
3 | ## Supported Versions
4 |
5 | Versions 1.0.x and above are currently being supported with security updates.
6 |
7 | | Version | Supported |
8 | | ------- | ------------------ |
9 | | 1.0.x | :white_check_mark: |
10 | | < 1.0.x | :x: |
11 |
12 | ## Reporting a Vulnerability
13 |
14 | Please report a vulnerability by creating a new issue. The issue will be fixed in one business day.
15 |
--------------------------------------------------------------------------------
/codecov.ynl:
--------------------------------------------------------------------------------
1 | ignore:
2 | - "pom.xml"
3 | - "sample_projects/.*"
4 | - "DADependencyInjection/Libraries/.*"
5 | - "DADependencyInjectionTests/.*"
6 | - "**/*ViewController.swift"
7 |
--------------------------------------------------------------------------------
/hash.txt:
--------------------------------------------------------------------------------
1 | qDZagyGH3z8fBDzAGhSPNgGV
2 |
--------------------------------------------------------------------------------
/nbactions.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | run
5 |
6 | jar
7 |
8 |
9 | process-classes
10 | org.codehaus.mojo:exec-maven-plugin:1.2.1:exec
11 |
12 |
13 | -classpath %classpath com.strider.datadefender.DataDefender anonymize
14 | java
15 | /Users/strider/work/strider/DataDefender
16 |
17 |
18 |
19 | debug
20 |
21 | jar
22 |
23 |
24 | process-classes
25 | org.codehaus.mojo:exec-maven-plugin:1.2.1:exec
26 |
27 |
28 | -agentlib:jdwp=transport=dt_socket,server=n,address=${jpda.address} -classpath %classpath com.strider.datadefender.DataDefender anonymize
29 | java
30 | true
31 | /Users/strider/work/strider/DataDefender
32 |
33 |
34 |
35 | profile
36 |
37 | jar
38 |
39 |
40 | process-classes
41 | org.codehaus.mojo:exec-maven-plugin:1.2.1:exec
42 |
43 |
44 | -classpath %classpath com.strider.datadefender.DataDefender anonymize
45 | java
46 | /Users/strider/work/strider/DataDefender
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/sample_projects/anonymizer/DataDefender-jar-file-here:
--------------------------------------------------------------------------------
1 | DataDefender.jar would need to be copied to this folder.
2 |
--------------------------------------------------------------------------------
/sample_projects/anonymizer/anonymize.config:
--------------------------------------------------------------------------------
1 | -r=requirement.xml
2 |
--------------------------------------------------------------------------------
/sample_projects/anonymizer/database.config:
--------------------------------------------------------------------------------
1 | --url=jdbc:mysql://localhost:3306/mydb?zeroDateTimeBehavior=convertToNull
2 | --password
3 | --user=root
4 |
--------------------------------------------------------------------------------
/sample_projects/anonymizer/datadefender:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | java -cp ".:extensions/*:extensions:lib:DataDefender.jar" com.strider.datadefender.DataDefender "$@"
3 |
--------------------------------------------------------------------------------
/sample_projects/anonymizer/datadefender.bat:
--------------------------------------------------------------------------------
1 | java -cp ".;extensions/*;extensions;lib;DataDefender.jar" com.strider.datadefender.DataDefender %*
2 |
--------------------------------------------------------------------------------
/sample_projects/anonymizer/extensions/EmployeeNumber.class:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/armenak/DataDefender/40a43c621d88b326fee206e45fd1b7e8760a6a0b/sample_projects/anonymizer/extensions/EmployeeNumber.class
--------------------------------------------------------------------------------
/sample_projects/anonymizer/extensions/EmployeeNumber.java:
--------------------------------------------------------------------------------
1 | import org.apache.commons.lang3.RandomUtils;
2 | public class EmployeeNumber {
3 | public static String randomNumber() {
4 | return String.format("%086d", RandomUtils.nextInt(0, 1000000) * 18);
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/sample_projects/database-logging/DataDefender-jar-file-here:
--------------------------------------------------------------------------------
1 | DataDefender.jar would need to be copied to this folder.
2 |
--------------------------------------------------------------------------------
/sample_projects/database-logging/column-discovery.config:
--------------------------------------------------------------------------------
1 | --column-pattern=(?i).*first.*
2 | --column-pattern=(?i).*last.*
3 | --column-pattern=(?i).*middle.*
4 | --column-pattern=(?i).*name.*
5 | --column-pattern=(?i).*birth.*
6 | --column-pattern=(?i)date*
7 | --column-pattern=(?i).*phone.*
8 | --column-pattern=(?i).*email.*
9 | --column-pattern=(?i).*sin.*
10 |
--------------------------------------------------------------------------------
/sample_projects/database-logging/common-discovery.config:
--------------------------------------------------------------------------------
1 | -o=generated-requirement.xml
2 |
--------------------------------------------------------------------------------
/sample_projects/database-logging/create-logging-table.sql:
--------------------------------------------------------------------------------
1 | create table log_table_name (
2 | id int(11) AUTO_INCREMENT PRIMARY KEY,
3 | eventDate TIMESTAMP,
4 | level VARCHAR(20),
5 | logger VARCHAR(100),
6 | message TEXT,
7 | exception TEXT
8 | );
9 |
--------------------------------------------------------------------------------
/sample_projects/database-logging/data-discovery.config:
--------------------------------------------------------------------------------
1 | -m date
2 | -m location
3 | -m money
4 | -m organization
5 | -m person
6 | --score-calculation
7 | -e com.strider.datadefender.specialcase.SinDetector.detectSin
8 |
--------------------------------------------------------------------------------
/sample_projects/database-logging/database.config:
--------------------------------------------------------------------------------
1 | --url=jdbc:mysql://localhost:3306/mydb?zeroDateTimeBehavior=convertToNull
2 | --password
3 | --user=root
4 |
--------------------------------------------------------------------------------
/sample_projects/database-logging/datadefender:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | java -cp ".:extensions/*:extensions:lib:DataDefender.jar" com.strider.datadefender.DataDefender "$@"
3 |
--------------------------------------------------------------------------------
/sample_projects/database-logging/datadefender.bat:
--------------------------------------------------------------------------------
1 | java -cp ".;extensions/*;extensions;lib;DataDefender.jar" com.strider.datadefender.DataDefender %*
2 |
--------------------------------------------------------------------------------
/sample_projects/database-logging/log4j2.properties:
--------------------------------------------------------------------------------
1 |
2 | appender.console.type=Console
3 | appender.console.name=STDOUT
4 | appender.console.layout.type=PatternLayout
5 | appender.console.layout.pattern=[%highlight{%p}{FATAL=red, ERROR=red, WARN=yellow bright, INFO=blue bright, DEBUG=green bright}] %m%n
6 |
7 | # using a DynamicThresholdFilter keeps the --debug and --verbose console options
8 | # working. Otherwise setting the rootLogger level appropriately causes those
9 | # flags to not work.
10 | appender.console.filter.threshold.type=DynamicThresholdFilter
11 | appender.console.filter.threshold.defaultThreshold=warn
12 | appender.console.filter.threshold.key=console-level
13 | appender.console.filter.threshold.keyValuePair.type=KeyValuePair
14 | appender.console.filter.threshold.keyValuePair.key=info
15 | appender.console.filter.threshold.keyValuePair.value=info
16 | appender.console.filter.threshold.keyValuePair2.type=KeyValuePair
17 | appender.console.filter.threshold.keyValuePair2.key=debug
18 | appender.console.filter.threshold.keyValuePair2.value=debug
19 | appender.console.filter.threshold.onMatch=ACCEPT
20 | appender.console.filter.threshold.onMismatch=DENY
21 |
22 | appender.jdbc.type=JDBC
23 | appender.jdbc.name=DatabaseAppender
24 | appender.jdbc.tableName=log_table_name
25 | appender.jdbc.connectionSource.type=DriverManager
26 | appender.jdbc.connectionSource.connectionString=jdbc:mariadb://localhost:3306/database_name
27 | appender.jdbc.connectionSource.username=user
28 | appender.jdbc.connectionSource.password=password
29 | appender.jdbc.connectionSource.driverClassName=org.mariadb.jdbc.Driver
30 |
31 | # using a DynamicThresholdFilter keeps the --debug and --verbose console options
32 | # working. Otherwise setting the rootLogger level appropriately causes those
33 | # flags to not work. Note how this is configured with the "file-level"
34 | # threshold. Note also that this is completely optional... if the command-line
35 | # options are not needed, this can be skipped and set on rootLevel for example
36 | appender.jdbc.filter.threshold.type=DynamicThresholdFilter
37 | appender.jdbc.filter.threshold.defaultThreshold=info
38 | appender.jdbc.filter.threshold.key=file-level
39 | appender.jdbc.filter.threshold.keyValuePair.type=KeyValuePair
40 | appender.jdbc.filter.threshold.keyValuePair.key=debug
41 | appender.jdbc.filter.threshold.keyValuePair.value=debug
42 | appender.jdbc.filter.threshold.onMatch=ACCEPT
43 | appender.jdbc.filter.threshold.onMismatch=DENY
44 |
45 | appender.jdbc.columnConfigs[0].type=Column
46 | appender.jdbc.columnConfigs[0].name=eventDate
47 | appender.jdbc.columnConfigs[0].isEventTimestamp=true
48 |
49 | appender.jdbc.columnConfigs[1].type=Column
50 | appender.jdbc.columnConfigs[1].name=level
51 | appender.jdbc.columnConfigs[1].pattern=%level
52 |
53 | appender.jdbc.columnConfigs[2].type=Column
54 | appender.jdbc.columnConfigs[2].name=logger
55 | appender.jdbc.columnConfigs[2].pattern=%logger
56 |
57 | appender.jdbc.columnConfigs[3].type=Column
58 | appender.jdbc.columnConfigs[3].name=message
59 | appender.jdbc.columnConfigs[3].pattern=%m
60 |
61 | appender.jdbc.columnConfigs[4].type=Column
62 | appender.jdbc.columnConfigs[4].name=exception
63 | appender.jdbc.columnConfigs[4].pattern=%ex{full}
64 |
65 | rootLogger.level=all
66 | rootLogger.appenderRef.database.ref=DatabaseAppender
67 | rootLogger.appenderRef.console.ref=STDOUT
68 |
--------------------------------------------------------------------------------
/sample_projects/database_discovery/mysql/DataDefender-jar-file-here:
--------------------------------------------------------------------------------
1 | DataDefender.jar would need to be copied to this folder.
2 |
--------------------------------------------------------------------------------
/sample_projects/database_discovery/mysql/column-discovery.config:
--------------------------------------------------------------------------------
1 | --column-pattern=(?i).*first.*
2 | --column-pattern=(?i).*last.*
3 | --column-pattern=(?i).*middle.*
4 | --column-pattern=(?i).*name.*
5 | --column-pattern=(?i).*birth.*
6 | --column-pattern=(?i)date*
7 | --column-pattern=(?i).*phone.*
8 | --column-pattern=(?i).*email.*
9 | --column-pattern=(?i).*sin.*
10 |
--------------------------------------------------------------------------------
/sample_projects/database_discovery/mysql/common-discovery.config:
--------------------------------------------------------------------------------
1 | -o=generated-requirement.xml
2 |
--------------------------------------------------------------------------------
/sample_projects/database_discovery/mysql/data-discovery.config:
--------------------------------------------------------------------------------
1 | -m date
2 | -m location
3 | -m money
4 | -m organization
5 | -m person
6 | --score-calculation
7 | -e com.strider.datadefender.specialcase.SinDetector.detectSin
8 |
--------------------------------------------------------------------------------
/sample_projects/database_discovery/mysql/database.config:
--------------------------------------------------------------------------------
1 | --url=jdbc:mysql://localhost:3306/mydb?zeroDateTimeBehavior=convertToNull
2 | --password
3 | --user=root
4 |
--------------------------------------------------------------------------------
/sample_projects/database_discovery/mysql/datadefender:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | java -cp ".:extensions/*:extensions:lib:DataDefender.jar" com.strider.datadefender.DataDefender "$@"
3 |
--------------------------------------------------------------------------------
/sample_projects/database_discovery/mysql/datadefender.bat:
--------------------------------------------------------------------------------
1 | java -cp ".;extensions/*;extensions;lib;DataDefender.jar" com.strider.datadefender.DataDefender %*
2 |
--------------------------------------------------------------------------------
/sample_projects/database_discovery/postgresql/DataDefender-jar-file-here:
--------------------------------------------------------------------------------
1 | DataDefender.jar would need to be copied to this folder.
2 |
--------------------------------------------------------------------------------
/sample_projects/database_discovery/postgresql/column-discovery.config:
--------------------------------------------------------------------------------
1 | --column-pattern=.*f.*rst.*
2 | --column-pattern=.*l.*st.*
3 | --column-pattern=.*name.*
4 | --column-pattern=.*birth.*
5 | --column-pattern=.*address.*
6 | --column-pattern=.*phone.*
7 | --column-pattern=.*number.*
8 | --column-pattern=.*email.*
9 | --column-pattern=.*st.*d.*nt.*
10 | --column-pattern=.*sin.*
11 | --column-pattern=.*stud.*
12 |
--------------------------------------------------------------------------------
/sample_projects/database_discovery/postgresql/common-discovery.config:
--------------------------------------------------------------------------------
1 | -o=generated-requirement.xml
2 |
--------------------------------------------------------------------------------
/sample_projects/database_discovery/postgresql/data-discovery.config:
--------------------------------------------------------------------------------
1 | -m person
2 | --probability-threshold=0.55
3 | --limit=0
4 | --threshold-count=6
5 | --threshold-high=3
6 | --score-calculation
7 |
--------------------------------------------------------------------------------
/sample_projects/database_discovery/postgresql/database.config:
--------------------------------------------------------------------------------
1 | --url=jdbc:postgresql://localhost/example
2 | --schema=public
3 | --password
4 | --user=root
5 | --no-skip-empty-tables-metadata
6 | --exclude-table-pattern-metadata=".*db_meta_info.*"
7 |
--------------------------------------------------------------------------------
/sample_projects/database_discovery/postgresql/datadefender:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | java -cp ".:extensions/*:extensions:lib:DataDefender.jar" com.strider.datadefender.DataDefender "$@"
3 |
--------------------------------------------------------------------------------
/sample_projects/database_discovery/postgresql/datadefender.bat:
--------------------------------------------------------------------------------
1 | java -cp ".;extensions/*;extensions;lib;DataDefender.jar" com.strider.datadefender.DataDefender %*
2 |
--------------------------------------------------------------------------------
/sample_projects/file_discovery/DataDefender-jar-file-here:
--------------------------------------------------------------------------------
1 | DataDefender.jar would need to be copied to this folder.
2 |
--------------------------------------------------------------------------------
/sample_projects/file_discovery/datadefender:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | java -cp ".:extensions/*:extensions:lib:DataDefender.jar" com.strider.datadefender.DataDefender "$@"
3 |
--------------------------------------------------------------------------------
/sample_projects/file_discovery/datadefender.bat:
--------------------------------------------------------------------------------
1 | java -cp ".;extensions/*;extensions;lib;DataDefender.jar" com.strider.datadefender.DataDefender %*
2 |
--------------------------------------------------------------------------------
/sample_projects/file_discovery/file-discovery.config:
--------------------------------------------------------------------------------
1 | -m date
2 | -m location
3 | -m money
4 | -m organization
5 | -m person
6 | --score-calculation
7 | --directory=/path/to/directory/to/scan
8 | --directory=/another/path/to/scan
9 | --exclude-extension=jar
10 | --exclude-extension=exe
11 | --exclude-extension=dll
12 | --exclude-extension=so
13 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/Anonymize.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender;
17 |
18 | import com.strider.datadefender.anonymizer.DatabaseAnonymizer;
19 | import com.strider.datadefender.anonymizer.IAnonymizer;
20 | import com.strider.datadefender.database.IDbFactory;
21 | import com.strider.datadefender.requirement.Requirement;
22 | import com.strider.datadefender.requirement.registry.ClassAndFunctionRegistry;
23 |
24 | import java.util.concurrent.Callable;
25 | import java.util.List;
26 |
27 | import org.apache.commons.collections4.CollectionUtils;
28 | import org.apache.commons.lang3.StringUtils;
29 |
30 | import picocli.CommandLine.ArgGroup;
31 | import picocli.CommandLine.Option;
32 | import picocli.CommandLine.Command;
33 | import picocli.CommandLine.Parameters;
34 |
35 | import lombok.extern.log4j.Log4j2;
36 |
37 | /**
38 | * Anonymize picocli subcommand, configures and executes the database
39 | * anonymizer.
40 | *
41 | * @author Zaahid Bateson
42 | */
43 | @Command(
44 | name = "anonymize",
45 | version = "1.0",
46 | mixinStandardHelpOptions = true,
47 | description = "Run anonymization utility"
48 | )
49 | @Log4j2
50 | public class Anonymize implements Callable {
51 |
52 | @Option(names = { "-r", "--requirement-file" }, paramLabel = "", description = "Requirement XML file", required = true)
53 | private Requirement requirement;
54 |
55 | @Option(names = { "-b", "--batch-size" }, description = "Number of update queries to batch together", defaultValue = "1000")
56 | private Integer batchSize;
57 |
58 | @ArgGroup(exclusive = false, multiplicity = "1", heading = "Database connection settings%n")
59 | private DbConfig dbConfig;
60 |
61 | @Parameters(paramLabel = "tables", description = "Limit anonymization to specified tables")
62 | private List tables;
63 |
64 | @Override
65 | public Integer call() throws Exception {
66 | System.out.println("");
67 | System.out.println("Starting anonymizer");
68 | log.info("Datasource URL: {}, vendor: {}, schema: {}", dbConfig.getUrl(), dbConfig.getVendor(), dbConfig.getSchema());
69 | log.info("Username: {}, Password provided: {}", dbConfig.getUsername(), (StringUtils.isNotBlank(dbConfig.getPassword()) ? "yes" : "no"));
70 | log.info("Batch size: {}", batchSize);
71 | log.info("Limiting to tables: {}", CollectionUtils.isEmpty(tables) ? "" : StringUtils.join(tables, ", "));
72 |
73 | IDbFactory factory = IDbFactory.get(dbConfig);
74 | ClassAndFunctionRegistry.singleton().initialize(factory);
75 |
76 | final IAnonymizer anonymizer = new DatabaseAnonymizer(
77 | factory,
78 | dbConfig,
79 | batchSize,
80 | requirement,
81 | tables
82 | );
83 | try {
84 | anonymizer.anonymize();
85 | } catch (DataDefenderException e) {
86 | log.error(e.getMessage());
87 | log.debug("Exception occurred during anonymization", e);
88 | return 1;
89 | } catch (Throwable e) {
90 | log.error(e.getMessage(), e);
91 | return 1;
92 | }
93 | return 0;
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/DataDefenderException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender;
17 |
18 | /**
19 | * Application-level exception.
20 | *
21 | * @author Armenak Grigoryan
22 | */
23 | public class DataDefenderException extends Exception {
24 |
25 | private static final long serialVersionUID = 1L;
26 |
27 | public DataDefenderException(final String msg) {
28 | super(msg);
29 | }
30 |
31 | public DataDefenderException(final String msg, final Throwable t) {
32 | super(msg, t);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/DbConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender;
17 |
18 | import java.util.List;
19 | import java.util.Map;
20 | import java.util.regex.Matcher;
21 | import java.util.regex.Pattern;
22 | import picocli.CommandLine.Option;
23 |
24 | import lombok.Getter;
25 |
26 | /**
27 | * Database configuration options for picocli.
28 | *
29 | * @author Zaahid Bateson
30 | */
31 | @Getter
32 | public class DbConfig {
33 |
34 | public enum Vendor {
35 | H2, MYSQL, POSTGRESQL, SQLSERVER, ORACLE, MARIADB;
36 | }
37 |
38 | private static final Map VENDOR_MAP = Map.of(
39 | "h2", Vendor.H2,
40 | "mysql", Vendor.MYSQL,
41 | "mariadb", Vendor.MARIADB,
42 | "postgresql", Vendor.POSTGRESQL,
43 | "sqlserver", Vendor.SQLSERVER,
44 | "mssql", Vendor.SQLSERVER,
45 | "oracle", Vendor.ORACLE
46 | );
47 |
48 | private Vendor vendor;
49 |
50 | @Option(names = { "-u", "--user" }, description = "The username to connect with")
51 | private String username;
52 |
53 | @Option(names = { "-p", "--password" }, description = "The password to connect with", arity = "0..1", interactive = true)
54 | private String password;
55 |
56 | @Option(names = { "--schema" }, description = "The schema to connect to")
57 | private String schema;
58 |
59 | @Option(names = { "--no-skip-empty-tables-metadata" }, description = "Include generating metadata for empty tables (defaults to skipping)", defaultValue = "true", negatable = true)
60 | private boolean skipEmptyTables = true;
61 |
62 | @Option(names = { "--include-table-pattern-metadata" }, description = "Pattern(s) matching table names to include for metadata analysis")
63 | private List includeTablePatterns;
64 | @Option(names = { "--exclude-table-pattern-metadata" }, description = "Pattern(s) matching table names to exclude for metadata analysis")
65 | private List excludeTablePatterns;
66 |
67 | private String url;
68 |
69 | @Option(
70 | names = { "--vendor" },
71 | description = "Database vendor, available options are: h2, mysql, mariadb, postgresql, sqlserver, oracle. "
72 | + "If not specified, vendor will attempt to be extracted from the datasource url for a jdbc scheme."
73 | )
74 | public void setVendor(String vendor) {
75 | String c = vendor.trim().toLowerCase();
76 | if (!VENDOR_MAP.containsKey(c)) {
77 | throw new IllegalArgumentException(
78 | "Invalid value for option '--vendor': Valid options are: "
79 | + "h2, mysql, mariadb, postgresql, sqlserver and oracle."
80 | );
81 | }
82 | this.vendor = VENDOR_MAP.get(c);
83 | }
84 |
85 | @Option(names = { "--url" }, description = "The datasource URL")
86 | public void setUrl(String url) {
87 | Pattern p = Pattern.compile("\\s*jdbc:([^:]+):.*");
88 | if (vendor == null) {
89 | Matcher m = p.matcher(url);
90 | if (m.find()) {
91 | setVendor(m.group(1));
92 | }
93 | }
94 | this.url = url;
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/Discover.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender;
17 |
18 | import com.strider.datadefender.database.metadata.TableMetaData.ColumnMetaData;
19 | import com.strider.datadefender.requirement.file.Generator;
20 | import java.io.File;
21 | import java.util.List;
22 |
23 | import java.util.Set;
24 | import java.util.concurrent.Callable;
25 | import java.util.stream.Collectors;
26 |
27 | import picocli.CommandLine;
28 | import picocli.CommandLine.ArgGroup;
29 | import picocli.CommandLine.Command;
30 | import picocli.CommandLine.Model.CommandSpec;
31 | import picocli.CommandLine.Option;
32 | import picocli.CommandLine.Spec;
33 |
34 | import lombok.extern.log4j.Log4j2;
35 | import lombok.Getter;
36 | import lombok.Setter;
37 |
38 | /**
39 | * "discover" picocli subcommand, configures and executes the data discoverer.
40 | *
41 | * TODO(ZB): Look into setting up command mixins sp dbconfig options don't have
42 | * to appear before subcommands [https://picocli.info/#_mixins]
43 | *
44 | * @author Zaahid Bateson
45 | */
46 | @Command(
47 | name = "discover",
48 | version = "1.0",
49 | description = "Run data discovery utility",
50 | mixinStandardHelpOptions = true,
51 | subcommands = {
52 | DiscoverColumns.class,
53 | DiscoverData.class,
54 | DiscoverFiles.class
55 | },
56 | subcommandsRepeatable = true
57 | )
58 | @Log4j2
59 | public class Discover implements Callable {
60 |
61 | @Getter
62 | @Setter
63 | @ArgGroup(exclusive = false, multiplicity = "0..1", heading = "Database connection settings%n")
64 | private DbConfig dbConfig;
65 |
66 | @Option(names = { "-o", "--output" }, description = "Generate a requirements xml file and write it out to the specified file")
67 | @Setter
68 | private File outputFile;
69 |
70 | @Spec
71 | private CommandSpec spec;
72 |
73 | public void afterSubcommand() {
74 | List subcommands = spec
75 | .commandLine()
76 | .getParseResult()
77 | .subcommands()
78 | .stream()
79 | .map((p) -> p.commandSpec().userObject())
80 | .filter((u) -> (u instanceof IRequirementCommand))
81 | .map((r) -> (IRequirementCommand) r)
82 | .collect(Collectors.toList());
83 | if (subcommands.stream().allMatch((r) -> r.getColumnMetaData() != null)) {
84 | Set combined = subcommands.stream().flatMap((r) -> r.getColumnMetaData().stream()).collect(Collectors.toSet());
85 | try {
86 | Generator.write(Generator.create(combined), outputFile);
87 | } catch (Exception e) {
88 | log.error("Error creating or writing to an output xml file", e);
89 | }
90 | }
91 | }
92 |
93 | @Override
94 | public Integer call() throws Exception {
95 | CommandLine.usage(this, System.out);
96 | return 0;
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/DiscoverColumns.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender;
17 |
18 | import com.strider.datadefender.database.IDbFactory;
19 | import com.strider.datadefender.database.metadata.TableMetaData.ColumnMetaData;
20 | import com.strider.datadefender.discoverer.ColumnDiscoverer;
21 | import java.io.File;
22 |
23 | import java.util.List;
24 | import java.util.concurrent.Callable;
25 | import java.util.regex.Pattern;
26 |
27 | import picocli.CommandLine.ArgGroup;
28 | import picocli.CommandLine.Command;
29 | import picocli.CommandLine.Model.CommandSpec;
30 | import picocli.CommandLine.Option;
31 | import picocli.CommandLine.ParentCommand;
32 | import picocli.CommandLine.Spec;
33 |
34 | import lombok.extern.log4j.Log4j2;
35 | import org.apache.commons.lang3.StringUtils;
36 |
37 |
38 | /**
39 | * "discover" picocli subcommand, configures and executes the data discoverer.
40 | *
41 | * @author Zaahid Bateson
42 | */
43 | @Command(
44 | name = "columns",
45 | version = "1.0",
46 | mixinStandardHelpOptions = true,
47 | description = "Run column discovery utility"
48 | )
49 | @Log4j2
50 | public class DiscoverColumns implements Callable, IRequirementCommand {
51 |
52 | private File outputFile;
53 |
54 | @Option(names = { "--column-pattern" }, description = "Regex pattern(s) to match column names", required = true)
55 | private List patterns;
56 |
57 | @ArgGroup(exclusive = false, multiplicity = "0..1", heading = "Database connection settings%n")
58 | private DbConfig dbConfig;
59 |
60 | @ParentCommand
61 | private Discover discover;
62 |
63 | @Spec
64 | private CommandSpec spec;
65 |
66 | private List results;
67 |
68 | @Option(names = { "-o", "--output" }, description = "Generate a requirements xml file and write it out to the specified file")
69 | public void setOutputFile(File f) {
70 | discover.setOutputFile(f);
71 | }
72 |
73 | @Override
74 | public Integer call() throws Exception {
75 |
76 | if (dbConfig == null) {
77 | dbConfig = discover.getDbConfig();
78 | } else {
79 | discover.setDbConfig(dbConfig);
80 | }
81 |
82 | System.out.println("Starting column discovery");
83 | log.warn("Discovery writes personal data to log files.");
84 | log.info("Datasource URL: {}, vendor: {}, schema: {}", dbConfig.getUrl(), dbConfig.getVendor(), dbConfig.getSchema());
85 | log.info("Username: {}, Password provided: {}", dbConfig.getUsername(), (StringUtils.isNotBlank(dbConfig.getPassword()) ? "yes" : "no"));
86 |
87 | IDbFactory factory = IDbFactory.get(dbConfig);
88 | ColumnDiscoverer discoverer = new ColumnDiscoverer(factory, patterns);
89 |
90 | try {
91 | results = discoverer.discover();
92 | } catch (Exception e) {
93 | log.error(e.getMessage());
94 | log.debug("Exception occurred during anonymization", e);
95 | return 1;
96 | }
97 |
98 | discover.afterSubcommand();
99 |
100 | return 0;
101 | }
102 |
103 | @Override
104 | public List getColumnMetaData() {
105 | return results;
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/DiscoverData.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender;
17 |
18 | import com.strider.datadefender.database.IDbFactory;
19 | import com.strider.datadefender.database.metadata.TableMetaData.ColumnMetaData;
20 | import com.strider.datadefender.discoverer.DatabaseDiscoverer;
21 |
22 | import java.io.File;
23 | import java.util.List;
24 | import java.util.concurrent.Callable;
25 |
26 | import picocli.CommandLine.ArgGroup;
27 | import picocli.CommandLine.Command;
28 | import picocli.CommandLine.Model.CommandSpec;
29 | import picocli.CommandLine.Option;
30 | import picocli.CommandLine.ParentCommand;
31 | import picocli.CommandLine.Spec;
32 |
33 | import org.apache.commons.lang3.StringUtils;
34 |
35 | import lombok.extern.log4j.Log4j2;
36 |
37 | /**
38 | * "discover" picocli subcommand, configures and executes the data discoverer.
39 | *
40 | * @author Zaahid Bateson
41 | */
42 | @Command(
43 | name = "data",
44 | version = "1.0",
45 | mixinStandardHelpOptions = true,
46 | description = "Run data discovery utility"
47 | )
48 | @Log4j2
49 | public class DiscoverData implements Callable, IRequirementCommand {
50 |
51 | @ArgGroup(exclusive = false, multiplicity = "1", heading = "Model discovery settings%n")
52 | private ModelDiscoveryConfig modelDiscoveryConfig;
53 |
54 | @ArgGroup(exclusive = false, multiplicity = "0..1", heading = "Database connection settings%n")
55 | private DbConfig dbConfig;
56 |
57 | @ParentCommand
58 | private Discover discover;
59 |
60 | @Spec
61 | private CommandSpec spec;
62 |
63 | private List results;
64 |
65 | @Option(names = { "-o", "--output" }, description = "Generate a requirements xml file and write it out to the specified file")
66 | public void setOutputFile(File f) {
67 | discover.setOutputFile(f);
68 | }
69 |
70 | @Override
71 | public Integer call() throws Exception {
72 |
73 | if (dbConfig == null) {
74 | dbConfig = discover.getDbConfig();
75 | } else {
76 | discover.setDbConfig(dbConfig);
77 | }
78 |
79 | System.out.println("");
80 | System.out.println("Starting data discovery");
81 | log.warn("Discovery writes personal data to log files.");
82 |
83 | log.info("Datasource URL: {}, vendor: {}, schema: {}", dbConfig.getUrl(), dbConfig.getVendor(), dbConfig.getSchema());
84 | log.info("Username: {}, Password provided: {}", dbConfig.getUsername(), (StringUtils.isNotBlank(dbConfig.getPassword()) ? "yes" : "no"));
85 | log.info("Probability threshold: {}", modelDiscoveryConfig.getProbabilityThreshold());
86 | log.info("Calculate score: {}", (modelDiscoveryConfig.getCalculateScore()) ? "yes" : "no");
87 | log.info("Threshold count: {}", modelDiscoveryConfig.getThresholdCount());
88 | log.info("Threshold high-risk count: {}", modelDiscoveryConfig.getThresholdHighRisk());
89 | log.info("Limit: {}", modelDiscoveryConfig.getLimit());
90 | log.info("Built-in models: {}", StringUtils.join(modelDiscoveryConfig.getModels(), ", "));
91 | log.info("Custom models: {}", StringUtils.join(modelDiscoveryConfig.getFileModels(), ", "));
92 | log.info("Custom token model: {}", modelDiscoveryConfig.getTokenModel());
93 | log.info("Extensions: {}", StringUtils.join(modelDiscoveryConfig.getExtensions(), ", "));
94 |
95 | IDbFactory factory = IDbFactory.get(dbConfig);
96 | DatabaseDiscoverer dd = new DatabaseDiscoverer(modelDiscoveryConfig, factory);
97 | results = dd.discover();
98 |
99 | discover.afterSubcommand();
100 | return 0;
101 | }
102 |
103 | @Override
104 | public List getColumnMetaData() {
105 | return results;
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/DiscoverFiles.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender;
17 |
18 | import com.strider.datadefender.discoverer.FileDiscoverer;
19 | import java.io.File;
20 | import java.util.List;
21 | import java.util.concurrent.Callable;
22 |
23 | import picocli.CommandLine.ArgGroup;
24 | import picocli.CommandLine.Command;
25 | import picocli.CommandLine.Option;
26 | import picocli.CommandLine.ParentCommand;
27 |
28 | import lombok.extern.log4j.Log4j2;
29 | import org.apache.commons.lang3.StringUtils;
30 |
31 |
32 | /**
33 | * "discover" picocli subcommand, configures and executes the data discoverer.
34 | *
35 | * @author Zaahid Bateson
36 | */
37 | @Command(
38 | name = "files",
39 | version = "1.0",
40 | mixinStandardHelpOptions = true,
41 | description = "Run file discovery utility"
42 | )
43 | @Log4j2
44 | public class DiscoverFiles implements Callable {
45 |
46 | @ArgGroup(exclusive = false, multiplicity = "1", heading = "Model discovery settings%n")
47 | private ModelDiscoveryConfig modelDiscoveryConfig;
48 |
49 | @Option(names = { "-d", "--directory" }, description = "Adds a directory to list of directories to be scanned", required = true)
50 | private List directories;
51 |
52 | @Option(names = { "-x", "--exclude-extension" }, description = "Adds an extension to exclude from data discovery")
53 | private List excludeExtensions;
54 |
55 | @ParentCommand
56 | private Discover discover;
57 |
58 | @Override
59 | public Integer call() throws Exception {
60 | System.out.println("");
61 | System.out.println("Starting file discovery");
62 | log.warn("Discovery writes personal data to log files.");
63 |
64 | log.info("Probability threshold: {}", modelDiscoveryConfig.getProbabilityThreshold());
65 | log.info("Calculate score: {}", (modelDiscoveryConfig.getCalculateScore()) ? "yes" : "no");
66 | log.info("Threshold count: {}", modelDiscoveryConfig.getThresholdCount());
67 | log.info("Threshold high-risk count: {}", modelDiscoveryConfig.getThresholdHighRisk());
68 | log.info("Limit: {}", modelDiscoveryConfig.getLimit());
69 | log.info("Built-in models: {}", StringUtils.join(modelDiscoveryConfig.getModels(), ", "));
70 | log.info("Custom models: {}", StringUtils.join(modelDiscoveryConfig.getFileModels(), ", "));
71 | log.info("Custom token model: {}", modelDiscoveryConfig.getTokenModel());
72 | log.info("Extensions: {}", StringUtils.join(modelDiscoveryConfig.getExtensions(), ", "));
73 | log.info("Directories: {}", StringUtils.join(directories, ", "));
74 | log.info("File types not considered for analysis: {}", excludeExtensions);
75 |
76 | FileDiscoverer fd = new FileDiscoverer(modelDiscoveryConfig, directories, excludeExtensions);
77 | fd.discover();
78 |
79 | return 0;
80 | }
81 | }
82 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/Extract.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender;
17 |
18 | import com.strider.datadefender.extractor.IExtractor;
19 | import com.strider.datadefender.extractor.DataExtractor;
20 | import com.strider.datadefender.database.IDbFactory;
21 |
22 | import java.util.concurrent.Callable;
23 | import java.util.List;
24 |
25 | import org.apache.commons.lang3.StringUtils;
26 |
27 | import picocli.CommandLine.ArgGroup;
28 | import picocli.CommandLine.Command;
29 | import picocli.CommandLine.Model.CommandSpec;
30 | import picocli.CommandLine.ParameterException;
31 | import picocli.CommandLine.Parameters;
32 | import picocli.CommandLine.Spec;
33 |
34 | import lombok.extern.log4j.Log4j2;
35 |
36 | /**
37 | * "extract" picocli subcommand, configures and executes the data extractor.
38 | *
39 | * @author Zaahid Bateson
40 | */
41 | @Command(
42 | name = "extract",
43 | version = "1.0",
44 | mixinStandardHelpOptions = true,
45 | description = "Run data extraction utility -- generates files out of table "
46 | + "columns with the name 'table_columnName.txt' for each column "
47 | + "requested."
48 | )
49 | @Log4j2
50 | public class Extract implements Callable {
51 |
52 | @ArgGroup(exclusive = false, multiplicity = "1", heading = "Database connection settings%n")
53 | private DbConfig dbConfig;
54 |
55 | @Spec
56 | private CommandSpec spec;
57 |
58 | private List tableColumns;
59 |
60 | @Parameters(paramLabel = "columns", description = "Generate data for the specified table.columName(s)")
61 | public void setTableColumns(List tableColumns) {
62 | for (String tableColumn : tableColumns) {
63 | int loc = tableColumn.indexOf(".");
64 | if (loc < 1 || loc >= tableColumn.length() - 1) {
65 | throw new ParameterException(
66 | spec.commandLine(),
67 | String.format(
68 | "Columns must be specified in the form [table].[columnName], found: %s",
69 | tableColumn
70 | )
71 | );
72 | }
73 | }
74 | this.tableColumns = tableColumns;
75 | }
76 |
77 | @Override
78 | public Integer call() throws Exception {
79 | System.out.println("");
80 | System.out.println("Starting data extractor");
81 | log.info("Datasource URL: {}, vendor: {}, schema: {}", dbConfig.getUrl(), dbConfig.getVendor(), dbConfig.getSchema());
82 | log.info("Username: {}, Password provided: {}", dbConfig.getUsername(), (StringUtils.isNotBlank(dbConfig.getPassword()) ? "yes" : "no"));
83 | log.info("Extracting data from: {}", tableColumns);
84 |
85 | IDbFactory factory = IDbFactory.get(dbConfig);
86 |
87 | final IExtractor extractor = new DataExtractor(
88 | factory,
89 | dbConfig,
90 | tableColumns
91 | );
92 | try {
93 | extractor.extract();
94 | } catch (DataDefenderException e) {
95 | log.error(e.getMessage());
96 | log.debug("Exception occurred during data extraction", e);
97 | return 1;
98 | } catch (Throwable e) {
99 | log.error(e.getMessage(), e);
100 | return 1;
101 | }
102 | return 0;
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/IRequirementCommand.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender;
17 |
18 | import com.strider.datadefender.database.metadata.TableMetaData.ColumnMetaData;
19 | import java.util.List;
20 |
21 | /**
22 | *
23 | * @author Zaahid Bateson
24 | */
25 | public interface IRequirementCommand {
26 | List getColumnMetaData();
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/ModelDiscoveryConfig.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender;
17 |
18 | import com.strider.datadefender.discoverer.Discoverer;
19 | import java.io.File;
20 | import java.util.List;
21 | import java.util.Optional;
22 |
23 | import picocli.CommandLine.Option;
24 |
25 | import lombok.Getter;
26 | import lombok.extern.log4j.Log4j2;
27 |
28 | /**
29 | * Database configuration options for picocli.
30 | *
31 | * @author Zaahid Bateson
32 | */
33 | @Getter
34 | @Log4j2
35 | public class ModelDiscoveryConfig {
36 |
37 | @Option(names = { "-l", "--limit" }, description = "Limit discovery to a set number of rows in a table", defaultValue = "1000")
38 | private Integer limit;
39 |
40 | private List models;
41 |
42 | @Option(names = { "-e", "--extension" }, description = "Adds a call to an extension method "
43 | + "(e.g. com.strider.datadefender.specialcase.SinDetector.detectSin)")
44 | private List extensions;
45 |
46 | @Option(names = { "--model-file" }, description = "Adds a custom made opennlp TokenizerME file for data discovery.")
47 | private List fileModels;
48 |
49 | @Option(names = { "--token-model" }, description = "Override the default built-in token model (English tokens, "
50 | + "en-token.bin) with a custom token file for use by opennlp's TokenizerModel")
51 | private File tokenModel;
52 |
53 | @Option(names = { "--probability-threshold" }, description = "Minimum NLP match score to return results for", defaultValue = "0.55")
54 | private Double probabilityThreshold;
55 |
56 | @Option(names = { "--no-score-calculation" }, description = "If set, includes a column score", negatable = true)
57 | private Boolean calculateScore = true;
58 |
59 | @Option(names = { "--threshold-count" }, description = "Reports if number of rows found are greater than the defined threshold", defaultValue = "6")
60 | private Integer thresholdCount;
61 |
62 | @Option(names = { "--threshold-high" }, description = "Reports if number of high risk columns found are greater than the defined threshold", defaultValue = "3")
63 | private Integer thresholdHighRisk;
64 |
65 | @Option(names = { "-m", "--model" }, description = "Adds a built-in configured opennlp TokenizerME model for data discovery. "
66 | + "Available models are: ${AVAILABLE-MODELS}")
67 | public void setModels(List models) {
68 | Optional unmatched = models.stream().filter((m) -> !Discoverer.BUILT_IN_MODELS.containsKey(m)).findFirst();
69 | if (unmatched.isPresent()) {
70 | log.error(
71 | "A built-in model with the name \"{}\" does not exist. Please specify one of: {}",
72 | unmatched.get(),
73 | System.getProperty("AVAILABLE-MODELS")
74 | );
75 | throw new IllegalArgumentException("Unmatched built-in model.");
76 | }
77 | this.models = models;
78 | }
79 | }
80 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/TestRequirement.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender;
17 |
18 | import com.strider.datadefender.anonymizer.DatabaseAnonymizer;
19 | import com.strider.datadefender.anonymizer.IAnonymizer;
20 | import com.strider.datadefender.database.IDbFactory;
21 | import com.strider.datadefender.requirement.Requirement;
22 | import com.strider.datadefender.requirement.registry.ClassAndFunctionRegistry;
23 |
24 | import java.util.concurrent.Callable;
25 | import java.util.List;
26 |
27 | import org.apache.commons.collections4.CollectionUtils;
28 | import org.apache.commons.lang3.StringUtils;
29 |
30 | import picocli.CommandLine.ArgGroup;
31 | import picocli.CommandLine.Option;
32 | import picocli.CommandLine.Command;
33 | import picocli.CommandLine.Parameters;
34 |
35 | import lombok.extern.log4j.Log4j2;
36 |
37 | /**
38 | * test-requirement cli subcommand for testing the requirements file.
39 | *
40 | * @author Zaahid Bateson
41 | */
42 | @Command(
43 | name = "test-requirement",
44 | version = "1.0",
45 | mixinStandardHelpOptions = true,
46 | description = "Loads the requirement file without attempting to anonymize or process anything to check for syntax issues"
47 | )
48 | @Log4j2
49 | public class TestRequirement implements Callable {
50 |
51 | @Option(names = { "-r", "--requirement-file" }, paramLabel = "", description = "Requirement XML file", required = true)
52 | private Requirement requirement;
53 |
54 | @Override
55 | public Integer call() throws Exception {
56 | System.out.println("");
57 | System.out.println("Requirements file loaded successfully");
58 | return 0;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/anonymizer/DatabaseAnonymizerException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.anonymizer;
17 |
18 | /**
19 | * Package-level exception
20 | * @author Armenak Grigoryan
21 | */
22 | public class DatabaseAnonymizerException extends Exception {
23 | private static final long serialVersionUID = 1L;
24 |
25 | public DatabaseAnonymizerException(final String msg) {
26 | super(msg);
27 | }
28 |
29 | public DatabaseAnonymizerException(final String msg, final Throwable t) {
30 | super(msg, t);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/anonymizer/IAnonymizer.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.anonymizer;
17 |
18 | import com.strider.datadefender.DataDefenderException;
19 |
20 | /**
21 | * Defines contract for all Anonymizes
22 | * @author strider
23 | */
24 | public interface IAnonymizer {
25 |
26 | /**
27 | * Anonymizes data.
28 | *
29 | * @throws DataDefenderException
30 | */
31 | void anonymize() throws DataDefenderException, InstantiationException;
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/anonymizer/functions/Address.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.anonymizer.functions;
17 |
18 | import java.io.IOException;
19 |
20 | import org.apache.commons.lang3.RandomUtils;
21 |
22 | import lombok.extern.log4j.Log4j2;
23 |
24 | /**
25 | * Built-in anonymization helper functions for address field anonymization.
26 | *
27 | * @author Armenak Grigoryan
28 | */
29 | @Log4j2
30 | public class Address extends Core {
31 |
32 | public String randomCountry() throws IOException {
33 | return randomStringFromStream(
34 | "resource:countries.txt",
35 | () -> Lipsum.class.getResourceAsStream("countries.txt")
36 | );
37 | }
38 |
39 | public String randomCity() throws IOException {
40 | return randomStringFromStream(
41 | "resource:cities.txt",
42 | () -> Lipsum.class.getResourceAsStream("cities.txt")
43 | );
44 | }
45 |
46 | public String randomStreet() throws IOException {
47 | return randomStringFromStream(
48 | "resource:streets.txt",
49 | () -> Lipsum.class.getResourceAsStream("streets.txt")
50 | );
51 | }
52 |
53 | public String randomProvinceState() throws IOException {
54 | return randomStringFromStream(
55 | "resource:provinces_states.txt",
56 | () -> Lipsum.class.getResourceAsStream("provinces_states.txt")
57 | );
58 | }
59 |
60 | public String randomProvinceStateCode() throws IOException {
61 | return randomStringFromStream(
62 | "resource:provinces_states_codes.txt",
63 | () -> Lipsum.class.getResourceAsStream("provinces_states_codes.txt")
64 | );
65 | }
66 |
67 | public String randomCanadianPostalCode() {
68 | return randomStringFromPattern("[A-Z][0-9][A-Z] [0-9][A-Z][0-9]");
69 | }
70 |
71 | public String randomUsZipCode() {
72 | return randomStringFromPattern("[0-9]{5}");
73 | }
74 |
75 | public String randomUsZipCodeNineDigit() {
76 | return randomStringFromPattern("[0-9]{5}-[0-9]{4}");
77 | }
78 |
79 | public String randomCanadianOrUsFiveDigitPostalCode() {
80 | if (RandomUtils.nextBoolean()) {
81 | return randomCanadianPostalCode();
82 | }
83 | return randomUsZipCode();
84 | }
85 |
86 | public String randomCanadianOrUsFiveOrNineDigitPostalCode() {
87 | if (RandomUtils.nextBoolean()) {
88 | return randomCanadianPostalCode();
89 | } else if (RandomUtils.nextBoolean()) {
90 | return randomUsZipCode();
91 |
92 | }
93 | return randomUsZipCodeNineDigit();
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/database/DatabaseException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | */
17 | package com.strider.datadefender.database;
18 |
19 | import com.strider.datadefender.DataDefenderException;
20 |
21 | /**
22 | * Package level exception. Extends application level exception.
23 | * @author Armenak Grigoryan
24 | */
25 | public class DatabaseException extends DataDefenderException {
26 | private static final long serialVersionUID = 1L;
27 |
28 | public DatabaseException(final String msg) {
29 | super(msg);
30 | }
31 |
32 | public DatabaseException(final String msg, final Throwable t) {
33 | super(msg, t);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/database/DbConnection.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.database;
17 |
18 | import com.strider.datadefender.DbConfig;
19 | import com.strider.datadefender.utils.ISupplierWithException;
20 |
21 | import java.sql.Connection;
22 | import java.sql.SQLException;
23 | import java.sql.DriverManager;
24 |
25 | import org.apache.commons.lang3.StringUtils;
26 |
27 | import lombok.extern.log4j.Log4j2;
28 |
29 | /**
30 | * Handles standard database connections with username/password provided.
31 | */
32 | @Log4j2
33 | public class DbConnection implements IDbConnection {
34 |
35 | protected final DbConfig config;
36 |
37 | /**
38 | * Default constructor, initializes config.
39 | * @param config
40 | */
41 | public DbConnection(final DbConfig config) {
42 | this.config = config;
43 | }
44 |
45 | /**
46 | * Handles the actual creating of the connection, by running the supplier
47 | * method provided by subclasses.
48 | *
49 | * @param supplier
50 | * @return
51 | * @throws DatabaseException
52 | */
53 | protected Connection doConnect(
54 | final ISupplierWithException supplier
55 | ) throws DatabaseException {
56 |
57 | Connection conn = null;
58 | try {
59 | log.info("Establishing database connection");
60 | conn = supplier.get();
61 | conn.setAutoCommit(false);
62 | } catch (SQLException e) {
63 | if (conn != null) {
64 | try {
65 | conn.close();
66 | } catch (SQLException e2) {
67 | // ignore
68 | }
69 | }
70 | throw new DatabaseException(e.getMessage(), e);
71 | }
72 | return conn;
73 | }
74 |
75 | /**
76 | * Default implementation calls DriverManager.getConnection with the
77 | * provided jdbc url, username and password.
78 | *
79 | * @return Connection
80 | * @throws DatabaseAnonymizerException
81 | */
82 | @Override
83 | public Connection connect() throws DatabaseException {
84 | return doConnect(() -> DriverManager.getConnection(
85 | config.getUrl(),
86 | StringUtils.trimToNull(config.getUsername()),
87 | StringUtils.trimToNull(config.getPassword())
88 | ));
89 | }
90 | }
91 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/database/IDbConnection.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.database;
17 |
18 | import java.sql.Connection;
19 |
20 | /**
21 | * Interface for all classes implementing database connection
22 | *
23 | * @author Armenak Grigoryan
24 | */
25 | public interface IDbConnection {
26 | Connection connect() throws DatabaseException;
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/database/MsSqlDbConnection.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.database;
17 |
18 | import java.sql.Connection;
19 | import static java.sql.DriverManager.getConnection;
20 |
21 | import com.strider.datadefender.DataDefenderException;
22 | import com.strider.datadefender.DbConfig;
23 | import org.apache.commons.lang3.StringUtils;
24 |
25 | /**
26 | *
27 | * @author sdi
28 | */
29 | public class MsSqlDbConnection extends DbConnection {
30 |
31 | public MsSqlDbConnection(DbConfig config) throws DataDefenderException {
32 | super(config);
33 | }
34 |
35 | /**
36 | * Establishes database connection
37 | *
38 | * @return Connection
39 | * @throws DatabaseException
40 | */
41 | @Override
42 | public Connection connect() throws DatabaseException {
43 | return doConnect(() -> getConnection(this.getUrl()));
44 | }
45 |
46 | /**
47 | * Get connection URL.
48 | * @return String
49 | */
50 | protected String getUrl() {
51 | StringBuilder sqlServerUrl = new StringBuilder(config.getUrl());
52 | if (!StringUtils.isBlank(config.getUsername())) {
53 | sqlServerUrl.append(";user=").append(config.getUsername());
54 | }
55 | if (!StringUtils.isBlank(config.getPassword())) {
56 | sqlServerUrl.append(";password=").append(config.getPassword());
57 | }
58 | return sqlServerUrl.toString();
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/database/metadata/IMetaData.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.database.metadata;
17 |
18 | import java.sql.ResultSet;
19 | import java.sql.SQLException;
20 | import java.util.List;
21 |
22 | /**
23 | * Public interface to define the contract for all database-specific
24 | * metadata classes.
25 | *
26 | * @author armenak
27 | */
28 | public interface IMetaData {
29 | List getMetaData() throws SQLException;
30 | TableMetaData getMetaDataFor(final ResultSet rs) throws SQLException;
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/database/metadata/MySqlMetaData.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.database.metadata;
17 |
18 | import com.strider.datadefender.DbConfig;
19 | import java.sql.Connection;
20 | import java.sql.DatabaseMetaData;
21 | import java.sql.ResultSet;
22 | import java.sql.SQLException;
23 |
24 | /**
25 | * Overridden to omit using schema in some cases, as it's not supported.
26 | * @author armenak
27 | */
28 | public class MySqlMetaData extends MetaData {
29 |
30 | public MySqlMetaData(DbConfig config, Connection connection) {
31 | super(config, connection);
32 | }
33 |
34 | public MySqlMetaData(DbConfig config, Connection connection, SqlTypeToClass sqlTypeMap) {
35 | super(config, connection, sqlTypeMap);
36 | }
37 |
38 | @Override
39 | protected ResultSet getTableResultSet(final DatabaseMetaData md) throws SQLException {
40 | return md.getTables(null, null, "%", new String[] { "TABLE" });
41 | }
42 |
43 | @Override
44 | protected ResultSet getColumnResultSet(final DatabaseMetaData md, final String tableName) throws SQLException {
45 | return md.getColumns(null, null, tableName, null);
46 | }
47 |
48 | @Override
49 | protected ResultSet getForeignKeysResultSet(final DatabaseMetaData md, final String tableName) throws SQLException {
50 | return md.getImportedKeys(null, null, tableName);
51 | }
52 |
53 | @Override
54 | protected ResultSet getPrimaryKeysResultSet(final DatabaseMetaData md, final String tableName) throws SQLException {
55 | return md.getPrimaryKeys(null, null, tableName);
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/database/metadata/SqlTypeToClass.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.database.metadata;
17 |
18 | import java.math.BigDecimal;
19 | import java.sql.Array;
20 | import java.sql.Blob;
21 | import java.sql.Clob;
22 | import java.sql.Date;
23 | import java.sql.Time;
24 | import java.sql.Timestamp;
25 | import java.sql.Types;
26 |
27 | /**
28 | * Maps java.sql.Types to Class objects.
29 | *
30 | * @author Zaahid Bateson
31 | */
32 | public class SqlTypeToClass {
33 | public Class getTypeFrom(int type) {
34 | switch (type) {
35 | case Types.CHAR:
36 | case Types.VARCHAR:
37 | case Types.LONGVARCHAR:
38 | case Types.NCHAR:
39 | case Types.NVARCHAR:
40 | case Types.LONGNVARCHAR:
41 | case Types.OTHER:
42 | return String.class;
43 | case Types.BINARY:
44 | case Types.VARBINARY:
45 | case Types.LONGVARBINARY:
46 | return Byte[].class;
47 | case Types.NUMERIC:
48 | case Types.DECIMAL:
49 | return BigDecimal.class;
50 | case Types.BIT:
51 | return Boolean.class;
52 | case Types.TINYINT:
53 | case Types.SMALLINT:
54 | return Short.class;
55 | case Types.INTEGER:
56 | return Integer.class;
57 | case Types.BIGINT:
58 | return Long.class;
59 | case Types.REAL:
60 | return Float.class;
61 | case Types.FLOAT:
62 | case Types.DOUBLE:
63 | return Double.class;
64 | case Types.DATE:
65 | return Date.class;
66 | case Types.TIME:
67 | return Time.class;
68 | case Types.TIMESTAMP:
69 | return Timestamp.class;
70 | case Types.BLOB:
71 | return Blob.class;
72 | case Types.CLOB:
73 | return Clob.class;
74 | case Types.ARRAY:
75 | return Array.class;
76 | case Types.NULL:
77 | return null;
78 | default:
79 | throw new IllegalArgumentException("Unsupported or unknown type");
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/database/sqlbuilder/ISqlBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.database.sqlbuilder;
17 |
18 | import com.strider.datadefender.DbConfig.Vendor;
19 |
20 | /**
21 | * Interface for all classes implementing SQL builder.
22 | *
23 | * @author Armenak Grigoryan
24 | */
25 | public interface ISqlBuilder {
26 |
27 | /**
28 | * Add a limit to returned rows for the passed sqlString.
29 | *
30 | * @param sqlString
31 | * @param limit
32 | * @return
33 | */
34 | String buildSelectWithLimit(String sqlString, int limit);
35 |
36 | /**
37 | * Prefix table name with schema if present.
38 | *
39 | * @param tableName
40 | * @return
41 | */
42 | String prefixSchema(String tableName);
43 |
44 | /**
45 | * Method to get DB Vendor
46 | * @return
47 | */
48 | Vendor getVendor();
49 | }
50 |
51 |
52 | //~ Formatted by Jindent --- http://www.jindent.com
53 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/database/sqlbuilder/MsSqlBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.database.sqlbuilder;
17 |
18 | import com.strider.datadefender.DbConfig;
19 | import org.apache.commons.lang3.StringUtils;
20 |
21 | import lombok.extern.log4j.Log4j2;
22 |
23 | /**
24 | * MS SQL Server implementation of the ISqlBuilder
25 | *
26 | * @author Armenak Grigoryan
27 | * @author Luis Marques
28 | */
29 | @Log4j2
30 | public class MsSqlBuilder extends SqlBuilder {
31 |
32 | public MsSqlBuilder(DbConfig config) {
33 | super(config);
34 | }
35 |
36 | /**
37 | * Uses TOP to limit the passed query.
38 | *
39 | * @param sqlString
40 | * @param limit
41 | * @return
42 | */
43 | @Override
44 | public String buildSelectWithLimit(final String sqlString, final int limit) {
45 | String query = sqlString.replaceFirst("(?i)(SELECT)(\\s+)", "$1 TOP " + limit + " $2");
46 | log.debug("Query after adding limit: [{}]", query);
47 | return query;
48 | }
49 |
50 | /**
51 | * Prefixes the schema name, followed by a "." character if set.
52 | * Additionally surrounds schema name (if set) and tableName with square
53 | * brackets, so the end result is either "[tableName]" or
54 | * "[schemaName].[tableName]".
55 | *
56 | * @param tableName
57 | * @return
58 | */
59 | @Override
60 | public String prefixSchema(final String tableName) {
61 | final String schema = config.getSchema();
62 | if (StringUtils.isNotBlank(schema)) {
63 | return "[" + schema + "].[" + tableName + "]";
64 | }
65 | return "[" + tableName + "]";
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/database/sqlbuilder/OracleSqlBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | */
17 | package com.strider.datadefender.database.sqlbuilder;
18 |
19 | import com.strider.datadefender.DbConfig;
20 | import org.apache.commons.lang3.StringUtils;
21 |
22 | import lombok.extern.log4j.Log4j2;
23 |
24 | /**
25 | * Oracle implementation of the ISqlBuilder
26 | *
27 | * @author Armenak Grigoryan
28 | */
29 | @Log4j2
30 | public class OracleSqlBuilder extends SqlBuilder {
31 |
32 | public OracleSqlBuilder(DbConfig config) {
33 | super(config);
34 | }
35 |
36 | /**
37 | * Uses ROWNUM to limit the passed query.
38 | *
39 | * @param sqlString
40 | * @param limit
41 | * @return
42 | */
43 | @Override
44 | public String buildSelectWithLimit(final String sqlString, final int limit) {
45 | String sql = "SELECT q.* FROM (" + StringUtils.stripEnd(sqlString.trim(), ";") + ") q WHERE ROWNUM <= " + limit;
46 | log.debug("Query after adding limit: [{}]", sql);
47 | return sql;
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/database/sqlbuilder/SqlBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.database.sqlbuilder;
17 |
18 | import com.strider.datadefender.DbConfig;
19 | import com.strider.datadefender.DbConfig.Vendor;
20 |
21 | import org.apache.commons.lang3.StringUtils;
22 |
23 | import lombok.extern.log4j.Log4j2;
24 | import lombok.RequiredArgsConstructor;
25 |
26 | /**
27 | * Provides 'default' implementation which can be overridden.
28 | * @author Akira Matsuo
29 | */
30 | @Log4j2
31 | @RequiredArgsConstructor
32 | public class SqlBuilder implements ISqlBuilder {
33 |
34 | protected final DbConfig config;
35 |
36 | /**
37 | * Appends "LIMIT {n}" to the end of the query.
38 | *
39 | * @param sqlString
40 | * @param limit
41 | * @return
42 | */
43 | @Override
44 | public String buildSelectWithLimit(final String sqlString, final int limit) {
45 | final StringBuilder sql = new StringBuilder(sqlString);
46 | if (limit != 0) {
47 | sql.append(" LIMIT ").append(limit);
48 | }
49 | log.debug("Query after adding limit: [{}]", sql);
50 | return sql.toString();
51 | }
52 |
53 | /**
54 | * Prepends the schema name followed by a single "." to the passed tableName
55 | * if a schema name is configured.
56 | *
57 | * @param tableName
58 | * @return
59 | */
60 | @Override
61 | public String prefixSchema(final String tableName) {
62 | final String schema = config.getSchema();
63 | if (StringUtils.isNotBlank(schema)) {
64 | if(config.getVendor() == Vendor.POSTGRESQL) {
65 | return schema + "." + "\"" + tableName + "\"";
66 | }else {
67 | return schema + "." + tableName;
68 | }
69 | }
70 | return tableName;
71 | }
72 |
73 | /**
74 | * Method to get DB Vendor
75 | * @return
76 | */
77 | @Override
78 | public Vendor getVendor() {
79 | return config.getVendor();
80 | }
81 | }
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/discoverer/ColumnDiscoverer.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2014-1018, Armenak Grigoryan, and individual contributors as indicated
4 | * by the @authors tag. See the copyright.txt in the distribution for a
5 | * full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | */
17 | package com.strider.datadefender.discoverer;
18 |
19 | import com.strider.datadefender.DataDefenderException;
20 | import com.strider.datadefender.database.metadata.IMetaData;
21 | import com.strider.datadefender.database.metadata.TableMetaData;
22 | import com.strider.datadefender.report.ReportUtil;
23 | import com.strider.datadefender.utils.Score;
24 | import com.strider.datadefender.database.IDbFactory;
25 | import com.strider.datadefender.database.metadata.TableMetaData.ColumnMetaData;
26 |
27 | import java.io.IOException;
28 | import java.sql.SQLException;
29 | import java.util.ArrayList;
30 | import java.util.LinkedHashSet;
31 | import java.util.List;
32 | import java.util.regex.Pattern;
33 | import java.util.stream.Collectors;
34 |
35 | import org.apache.commons.collections.CollectionUtils;
36 | import org.apache.commons.lang3.StringUtils;
37 |
38 | import lombok.extern.log4j.Log4j2;
39 |
40 | /**
41 | * @author Armenak Grigoryan
42 | */
43 | @Log4j2
44 | public class ColumnDiscoverer {
45 |
46 | private IDbFactory factory;
47 | private List patterns;
48 |
49 | public ColumnDiscoverer(IDbFactory factory, List patterns) {
50 | this.factory = factory;
51 | this.patterns = patterns;
52 | }
53 |
54 | public List discover() throws DataDefenderException, IOException, SQLException {
55 | log.info("Column discovery in process");
56 |
57 | final IMetaData metaData = factory.fetchMetaData();
58 | final List list = metaData.getMetaData();
59 |
60 | List columns = list.stream().flatMap((t) -> t.getColumns().stream())
61 | .filter((c) -> patterns.stream().anyMatch((p) -> p.matcher(c.getColumnName().toLowerCase()).matches()))
62 | .collect(Collectors.toList());
63 |
64 | log.info("Preparing report ...");
65 |
66 | // Report column names
67 | List uniqueMatches = null;
68 | if (CollectionUtils.isNotEmpty(columns)) {
69 | uniqueMatches = new ArrayList<>(new LinkedHashSet<>(columns));
70 | log.info("-----------------");
71 | log.info("List of suspects:");
72 | log.info("-----------------");
73 | uniqueMatches.sort((a, b) -> a.compareTo(b));
74 |
75 | final Score score = new Score();
76 |
77 | for (final ColumnMetaData entry : uniqueMatches) {
78 |
79 | // Row count
80 | final int rowCount = ReportUtil.rowCount(factory, entry.getTable().getTableName());
81 |
82 | // Getting 5 sample values
83 | final List sampleDataList = ReportUtil.sampleData(factory, entry);
84 |
85 | // Output
86 | log.info("Column : " + entry);
87 | log.info(StringUtils.repeat('=', entry.toString().length() + 30));
88 | log.info("Number of rows in the table: " + rowCount);
89 | log.info("Score : " + score.columnScore(rowCount));
90 | log.info("Sample data");
91 | log.info(StringUtils.repeat('-', 11));
92 |
93 | for (final String sampleData : sampleDataList) {
94 | log.info(sampleData);
95 | }
96 |
97 | log.info("");
98 | }
99 |
100 | log.info("Overall score: " + score.dataStoreScore());
101 | } else {
102 | log.info("No suspects have been found. Please refine your criteria.");
103 | }
104 |
105 | return uniqueMatches;
106 | }
107 | }
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/discoverer/Discoverer.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
4 | * by the @authors tag. See the copyright.txt in the distribution for a
5 | * full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | */
17 | package com.strider.datadefender.discoverer;
18 |
19 | import com.strider.datadefender.DataDefenderException;
20 | import com.strider.datadefender.ModelDiscoveryConfig;
21 | import com.strider.datadefender.database.metadata.TableMetaData.ColumnMetaData;
22 | import com.strider.datadefender.requirement.file.Generator;
23 |
24 | import java.io.File;
25 | import java.io.IOException;
26 | import java.io.InputStream;
27 | import java.util.List;
28 | import java.util.Map;
29 | import java.util.stream.Collectors;
30 |
31 | import javax.xml.bind.JAXBException;
32 |
33 | import opennlp.tools.namefind.NameFinderME;
34 | import opennlp.tools.namefind.TokenNameFinderModel;
35 | import opennlp.tools.tokenize.TokenizerME;
36 | import opennlp.tools.tokenize.TokenizerModel;
37 |
38 | import lombok.Data;
39 | import lombok.extern.log4j.Log4j2;
40 |
41 | /**
42 | * Holds common logic for Discoverers.
43 | * @author Akira Matsuo
44 | */
45 | @Log4j2
46 | public abstract class Discoverer {
47 |
48 | public static final String DEFAULT_TOKEN_MODEL = "en-token.bin";
49 | public static final Map BUILT_IN_MODELS = Map.of(
50 | "date", "en-ner-date.bin",
51 | "location", "en-ner-location.bin",
52 | "money", "en-ner-money.bin",
53 | "organization", "en-ner-organization.bin",
54 | "person", "en-ner-person.bin",
55 | "time", "en-ner-time.bin"
56 | );
57 |
58 | @Data
59 | public static class ColumnMatch {
60 | final private ColumnMetaData column;
61 | final private double averageProbability;
62 | final private String model;
63 | final private List probabilityList;
64 | }
65 |
66 | protected List matches;
67 |
68 | protected final ModelDiscoveryConfig config;
69 | protected final TokenizerME tokenizer;
70 |
71 | public Discoverer(ModelDiscoveryConfig config) throws IOException {
72 | this.config = config;
73 | if (config.getTokenModel() != null) {
74 | tokenizer = new TokenizerME(new TokenizerModel(config.getTokenModel()));
75 | } else {
76 | try (InputStream stream = Discoverer.class.getResourceAsStream(DEFAULT_TOKEN_MODEL)) {
77 | tokenizer = new TokenizerME(new TokenizerModel(stream));
78 | }
79 | }
80 | }
81 |
82 | public double calculateAverage(final List values) {
83 | Double sum = 0.0;
84 |
85 | if (!values.isEmpty()) {
86 | for (final Probability value : values) {
87 | sum += value.getProbabilityValue();
88 | }
89 |
90 | return sum / values.size();
91 | }
92 |
93 | return sum;
94 | }
95 |
96 | private Model createModelFrom(TokenNameFinderModel tnf, String modelName) {
97 | NameFinderME nameFinder = new NameFinderME(tnf);
98 | return new Model(tokenizer, nameFinder, modelName);
99 | }
100 |
101 | /**
102 | * Creates model POJO based on OpenNLP model file
103 | *
104 | * @param modelName
105 | * @return Model
106 | */
107 | public Model createModel(final File modelFile) throws IOException {
108 | return createModelFrom(new TokenNameFinderModel(modelFile), modelFile.getName());
109 | }
110 |
111 | /**
112 | * Creates model POJO based on a built-in OpenNLP model
113 | *
114 | * @param modelName
115 | * @return Model
116 | */
117 | public Model createModel(final String modelName) throws IOException {
118 | try (InputStream stream = Discoverer.class.getResourceAsStream(BUILT_IN_MODELS.get(modelName))) {
119 | return createModelFrom(new TokenNameFinderModel(stream), modelName);
120 | }
121 | }
122 | }
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/discoverer/FileDiscoveryException.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
4 | * by the @authors tag. See the copyright.txt in the distribution for a
5 | * full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | */
18 |
19 |
20 |
21 | package com.strider.datadefender.discoverer;
22 |
23 | /**
24 | * Application-level exception
25 | * @author Armenak Grigoryan
26 | */
27 | public class FileDiscoveryException extends Exception {
28 | private static final long serialVersionUID = 1L;
29 |
30 | public FileDiscoveryException(final String msg) {
31 | super(msg);
32 | }
33 |
34 | public FileDiscoveryException(final String msg, final Throwable t) {
35 | super(msg, t);
36 | }
37 | }
38 |
39 |
40 | //~ Formatted by Jindent --- http://www.jindent.com
41 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/discoverer/IDiscoverer.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
4 | * by the @authors tag. See the copyright.txt in the distribution for a
5 | * full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | */
18 |
19 |
20 |
21 | package com.strider.datadefender.discoverer;
22 |
23 | import com.strider.datadefender.anonymizer.DatabaseAnonymizerException;
24 |
25 | /**
26 | * Defines contract for all discoverers
27 | * @author Armenak Grigoryan
28 | */
29 | public interface IDiscoverer {
30 |
31 | /**
32 | * Discovers data or data containers with data which can be be the subject
33 | * for data anonymization. Results found should be stored in matches member variable.
34 | * @param dbFactory
35 | * @param properties
36 | * @param tables Optional list of tables to anonymize -
37 | * if the collection is empty, all tables specified in requirements
38 | * are anonymized.
39 | * @throws com.strider.datadefender.AnonymizerException
40 | * @returns List of results introduced for testing purposes.
41 | */
42 |
43 | // List discover(IDBFactory dbFactory, Properties dataDiscoveryProperties, Set tables) throws DatabaseAnonymizerException;
44 | // List discover(Properties dataDiscoveryProperties) throws DatabaseAnonymizerException;
45 |
46 | /**
47 | * Creates a sample requirement file from a list of sorted matches found by the discovery method.
48 | * The requirement file will most likely require customization (for example; anonymzation function) before you want to run the Anonymizer against it.
49 | * @param fileName
50 | * @throws DatabaseAnonymizerException
51 | */
52 | void createRequirement(String fileName) throws DatabaseAnonymizerException;
53 | }
54 |
55 |
56 | //~ Formatted by Jindent --- http://www.jindent.com
57 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/discoverer/Model.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2014-2015, Armenak Grigoryan, and individual contributors as indicated
4 | * by the @authors tag. See the copyright.txt in the distribution for a
5 | * full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | */
18 |
19 |
20 |
21 | package com.strider.datadefender.discoverer;
22 |
23 | import opennlp.tools.namefind.NameFinderME;
24 | import opennlp.tools.tokenize.Tokenizer;
25 |
26 | public class Model {
27 | final private Tokenizer tokenizer;
28 | final private NameFinderME nameFinder;
29 | final private String name;
30 |
31 | public Model(final Tokenizer tokenizer, final NameFinderME nameFinder, final String name) {
32 | this.name = name;
33 | this.tokenizer = tokenizer;
34 | this.nameFinder = nameFinder;
35 | }
36 |
37 | public String getName() {
38 | return this.name;
39 | }
40 |
41 | public NameFinderME getNameFinder() {
42 | return this.nameFinder;
43 | }
44 |
45 | public Tokenizer getTokenizer() {
46 | return this.tokenizer;
47 | }
48 | }
49 |
50 |
51 | //~ Formatted by Jindent --- http://www.jindent.com
52 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/discoverer/Probability.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2014-2020, Armenak Grigoryan, and individual contributors as indicated
4 | * by the @authors tag. See the copyright.txt in the distribution for a
5 | * full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | */
18 |
19 | package com.strider.datadefender.discoverer;
20 |
21 | import java.util.Comparator;
22 |
23 | /**
24 | * This class represents the probability of sentence in database column
25 | *
26 | * @author Armenak Grigoryan
27 | */
28 | public class Probability {
29 | private final String sentence;
30 | private final Double probabilityValue;
31 |
32 | public Probability(final String sentence, final Double probabilityValue) {
33 | this.sentence = sentence;
34 | this.probabilityValue = probabilityValue;
35 | }
36 |
37 | public Double getProbabilityValue() {
38 | return this.probabilityValue;
39 | }
40 |
41 | public String getSentence() {
42 | return this.sentence;
43 | }
44 |
45 | /**
46 | * @return comparator used for sorting
47 | */
48 |
49 | public static Comparator compare() {
50 | return Comparator.comparing(Probability::getSentence)
51 | .thenComparing(Probability::getProbabilityValue);
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/extensions/BiographicFunctions.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2016, Armenak Grigoryan, Matthew Eaton, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.extensions;
17 |
18 | import com.strider.datadefender.anonymizer.functions.Core;
19 |
20 | import java.util.ArrayList;
21 | import java.util.List;
22 |
23 | import lombok.extern.log4j.Log4j2;
24 | import org.apache.commons.lang3.StringUtils;
25 |
26 | /**
27 | * @author Matthew Eaton
28 | */
29 | @Log4j2
30 | public class BiographicFunctions extends Core {
31 |
32 | /**
33 | * Algorithm is taken from https://en.wikipedia.org/wiki/Social_Insurance_Number
34 | * @param sin
35 | * @return boolean true, if SIN is valid, otherwise false
36 | */
37 | public static boolean isValidSIN(final String sin) {
38 | boolean valid = false;
39 |
40 | if (sin.length() < 9) {
41 | log.debug("SIN length is < 9");
42 |
43 | return valid;
44 | }
45 |
46 | if (!StringUtils.isNumeric(sin)) {
47 | log.debug("SIN " + sin + " is not number");
48 |
49 | return valid;
50 | }
51 |
52 | final int[] sinArray = new int[sin.length()];
53 | final int[] checkArray = {
54 | 1, 2, 1, 2, 1, 2, 1, 2, 1
55 | };
56 | final List sinList = new ArrayList();
57 |
58 | for (int i = 0; i < 9; i++) {
59 | sinArray[i] = Integer.valueOf(sin.substring(i, i + 1));
60 | sinArray[i] = sinArray[i] * checkArray[i];
61 | }
62 |
63 | int sum = 0;
64 |
65 | for (int i = 0; i < 9; i++) {
66 | final String tmp = String.valueOf(sinArray[i]);
67 |
68 | if (tmp.length() == 1) {
69 | sinList.add(Integer.valueOf(tmp));
70 | sum += Integer.valueOf(tmp);
71 | } else {
72 | sinList.add(Integer.valueOf(tmp.substring(0, 1)));
73 | sum += Integer.valueOf(tmp.substring(0, 1));
74 | sinList.add(Integer.valueOf(tmp.substring(1, 2)));
75 | sum += Integer.valueOf(tmp.substring(1, 2));
76 | }
77 | }
78 |
79 | if ((sum % 10) == 0) {
80 | valid = true;
81 | }
82 |
83 | return valid;
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/extensions/ExtensionExample.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.extensions;
17 |
18 | import com.strider.datadefender.anonymizer.functions.Core;
19 |
20 | import static java.lang.Math.random;
21 | import static java.lang.Math.round;
22 | import static java.lang.String.valueOf;
23 |
24 | /**
25 | * @author Armenak Grigoryan
26 | */
27 | public class ExtensionExample extends Core {
28 |
29 | /**
30 | * Generates random 9-digit student number
31 | * @return String
32 | */
33 | public String randomStudentNumber() {
34 | return valueOf(round(random() * 100000000));
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/extractor/IExtractor.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2014, Armenak Grigoryan, Matthew Eaton, and individual contributors as indicated
4 | * by the @authors tag. See the copyright.txt in the distribution for a
5 | * full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | */
18 | package com.strider.datadefender.extractor;
19 |
20 | import com.strider.datadefender.database.DatabaseException;
21 |
22 | /**
23 | * Defines contract for all generators
24 | * @author Matthew Eaton
25 | */
26 | public interface IExtractor {
27 |
28 | /**
29 | * Extracts data from table columns and generates files
30 | *
31 | * @throws DatabaseException
32 | */
33 | void extract() throws DatabaseException;
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/file/metadata/FileMatchMetaData.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.file.metadata;
17 |
18 | /**
19 | * Data object to hold all metadata for matching data in Discovery applications.
20 | * Currently this object holds column and table metadata; ie, duplicating info.
21 | * But since the numbers of tables/columns will always be
22 | * limited in size, don't really see an immediate need to refactor this.
23 | * @author Armenak Grigoryan
24 | */
25 | public class FileMatchMetaData {
26 | private String model = "";
27 | private final String directory;
28 | private final String fileName;
29 | private double averageProbability;
30 |
31 | public FileMatchMetaData(final String directory, final String fileName) {
32 | this.directory = directory;
33 | this.fileName = fileName;
34 | }
35 |
36 | public double getAverageProbability() {
37 | return this.averageProbability;
38 | }
39 |
40 | public void setAverageProbability(final double averageProbability) {
41 | this.averageProbability = averageProbability;
42 | }
43 |
44 | public String getDirectory() {
45 | return this.directory;
46 | }
47 |
48 | public String getFileName() {
49 | return this.fileName;
50 | }
51 |
52 | public String getModel() {
53 | return this.model;
54 | }
55 |
56 | public void setModel(final String model) {
57 | this.model = model;
58 | }
59 |
60 | @Override
61 | public String toString() {
62 | return this.directory + "." + this.fileName;
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/functions/NamedParameter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.functions;
17 |
18 | import java.lang.annotation.Documented;
19 | import java.lang.annotation.ElementType;
20 | import java.lang.annotation.Target;
21 |
22 | /**
23 | * Declares a parameter's name for reflection.
24 | *
25 | * Provides an alternative to compiling with -parameters so a method's
26 | * parameters can be named and referenced by name.
27 | *
28 | * @author Zaahid Bateson
29 | */
30 | @Documented
31 | @Target({ ElementType.PARAMETER })
32 | public @interface NamedParameter {
33 | /**
34 | * The name of the parameter that should be used to reference it in
35 | * external configuration.
36 | * @return
37 | */
38 | public String value();
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/functions/Utils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.functions;
17 |
18 | import lombok.extern.log4j.Log4j2;
19 |
20 | /**
21 | *
22 | * @author Armenak Grigoryan
23 | */
24 | @Log4j2
25 | public class Utils {
26 |
27 | /**
28 | * The string used to separator package and class name
29 | */
30 | public static final String SEPARATOR = ".";
31 |
32 | /**
33 | * Returns fully specified class name.
34 | *
35 | * @param fullMethodName Fully specified method name.
36 | * @return Method name.
37 | *
38 | * @throws RuntimeException Parameter is an empty string.
39 | */
40 | public static String getClassName(final String fullMethodName) {
41 | if (fullMethodName.length() == 0) {
42 | log.error("Please specify fully specified methid name in Requirement document");
43 |
44 | return "";
45 | }
46 |
47 | final int index = fullMethodName.lastIndexOf(SEPARATOR);
48 |
49 | if (index != -1) {
50 | return fullMethodName.substring(0, index);
51 | }
52 |
53 | return "";
54 | }
55 |
56 | /**
57 | * Returns the method name.
58 | *
59 | * @param fullMethodName Fully specified method name.
60 | * @return Method name.
61 | * @throws com.strider.datadefender.DatabaseAnonymizerException
62 | */
63 | public static String getMethodName(final String fullMethodName) {
64 | if (fullMethodName.length() == 0) {
65 | log.error("Please specify fully specified methid name in Requirement document");
66 |
67 | return "";
68 | }
69 |
70 | final int index = fullMethodName.lastIndexOf(SEPARATOR);
71 |
72 | if (index != -1) {
73 | return fullMethodName.substring(index + 1);
74 | }
75 |
76 | return "";
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/requirement/ClassAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.requirement;
17 |
18 | import com.strider.datadefender.requirement.registry.ClassAndFunctionRegistry;
19 | import javax.xml.bind.annotation.adapters.XmlAdapter;
20 |
21 | import org.apache.commons.lang3.ClassUtils;
22 | import org.apache.commons.lang3.StringUtils;
23 |
24 | /**
25 | * XmlAdapter to get a Class type from a String, and vice-versa.
26 | *
27 | * @author Zaahid Bateson
28 | */
29 | public class ClassAdapter extends XmlAdapter> {
30 |
31 | private ClassAndFunctionRegistry registry;
32 |
33 | public ClassAdapter() {
34 | this(ClassAndFunctionRegistry.singleton());
35 | }
36 |
37 | public ClassAdapter(ClassAndFunctionRegistry registry) {
38 | this.registry = registry;
39 | }
40 |
41 | @Override
42 | public Class> unmarshal(String value) throws Exception {
43 | String t = StringUtils.trimToEmpty(value);
44 | if (StringUtils.isBlank(t)) {
45 | return String.class;
46 | }
47 | return registry.getClassForName(value);
48 | }
49 |
50 | @Override
51 | public String marshal(Class> bt) throws Exception {
52 | return registry.getNameForClass(bt);
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/requirement/Column.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.requirement;
17 |
18 | import com.strider.datadefender.requirement.plan.Plan;
19 | import com.strider.datadefender.requirement.plan.PlanRef;
20 | import java.lang.reflect.InvocationTargetException;
21 | import java.sql.ResultSet;
22 | import java.sql.SQLException;
23 | import java.util.ArrayList;
24 | import java.util.List;
25 |
26 | import javax.xml.bind.annotation.XmlAccessType;
27 | import javax.xml.bind.annotation.XmlAccessorType;
28 | import javax.xml.bind.annotation.XmlAttribute;
29 | import javax.xml.bind.annotation.XmlElement;
30 | import javax.xml.bind.annotation.XmlElementWrapper;
31 | import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
32 |
33 | import org.apache.commons.collections4.CollectionUtils;
34 | import org.apache.commons.lang3.ClassUtils;
35 |
36 | import lombok.Data;
37 | import lombok.extern.log4j.Log4j2;
38 |
39 | import static java.util.Collections.unmodifiableList;
40 | import org.apache.commons.beanutils.ConvertUtils;
41 |
42 | /**
43 | * JAXB class that defines column elements in Requirement.xml file
44 | *
45 | * @author Armenak Grigoryan
46 | */
47 | @Log4j2
48 | @Data
49 | @XmlAccessorType(XmlAccessType.NONE)
50 | public class Column {
51 |
52 | @XmlAttribute
53 | private String name;
54 |
55 | @XmlAttribute(name = "skip-empty")
56 | private boolean ignoreEmpty = true;
57 |
58 | @XmlJavaTypeAdapter(ClassAdapter.class)
59 | @XmlAttribute
60 | private Class> type = String.class;
61 |
62 | @XmlElement
63 | private Plan plan;
64 |
65 | @XmlElement(name = "plan-ref")
66 | private PlanRef planRef;
67 |
68 | @XmlElementWrapper(name = "exclusions")
69 | @XmlElement(name = "exclude")
70 | private List exclusions;
71 |
72 | public Column() {
73 | }
74 |
75 | public Column(String name) {
76 | this.name = name;
77 | }
78 |
79 | /**
80 | * Returns a list of exclusions
81 | *
82 | * @return List
83 | */
84 | public List getExclusions() {
85 | final List lst = new ArrayList<>();
86 | if (!CollectionUtils.isEmpty(exclusions)) {
87 | lst.addAll(exclusions);
88 | }
89 | if (ignoreEmpty) {
90 | lst.add(new Exclude(true));
91 | }
92 | return unmodifiableList(lst);
93 | }
94 |
95 | /**
96 | * Returns the plan used by this column, either the one defined under it,
97 | * or the one referenced by planRef.
98 | *
99 | * @return
100 | */
101 | public Plan getResolvedPlan() {
102 | if (planRef != null) {
103 | return planRef.getRef();
104 | }
105 | return plan;
106 | }
107 |
108 | /**
109 | * Calls all functions defined under Functions in order.
110 | *
111 | * @param rs ResultSet
112 | * @return
113 | * @throws SQLException
114 | * @throws IllegalAccessException
115 | * @throws InvocationTargetException
116 | * @throws java.lang.InstantiationException
117 | */
118 | public Object invokeFunctionChain(ResultSet rs)
119 | throws SQLException,
120 | IllegalAccessException,
121 | InvocationTargetException,
122 | InstantiationException {
123 |
124 | Object startingValue = null;
125 | Class> argType = getResolvedPlan().getDynamicArgumentType();
126 | if (argType != null && ClassUtils.isAssignable(ResultSet.class, argType)) {
127 | startingValue = rs;
128 | } else {
129 | startingValue = rs.getObject(name, type);
130 | }
131 | return ConvertUtils.convert(getResolvedPlan().invoke(startingValue), type);
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/requirement/Requirement.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | */
17 | package com.strider.datadefender.requirement;
18 |
19 | import com.strider.datadefender.requirement.plan.GlobalPlan;
20 | import com.strider.datadefender.requirement.registry.ClassAndFunctionRegistry;
21 |
22 | import java.util.List;
23 | import java.util.stream.Collectors;
24 | import javax.xml.bind.Unmarshaller;
25 |
26 | import javax.xml.bind.annotation.XmlAccessType;
27 | import javax.xml.bind.annotation.XmlAccessorType;
28 | import javax.xml.bind.annotation.XmlAttribute;
29 | import javax.xml.bind.annotation.XmlElement;
30 | import javax.xml.bind.annotation.XmlElementWrapper;
31 | import javax.xml.bind.annotation.XmlRootElement;
32 |
33 | import org.apache.commons.collections4.CollectionUtils;
34 | import org.apache.commons.lang3.StringUtils;
35 |
36 | import lombok.AccessLevel;
37 | import lombok.Data;
38 | import lombok.Getter;
39 | import lombok.Setter;
40 | import lombok.extern.log4j.Log4j2;
41 |
42 | /**
43 | * JAXB class that defines elements in Requirement.xml file
44 | *
45 | * @author Armenak Grigoryan
46 | */
47 | @Data
48 | @Log4j2
49 | @XmlAccessorType(XmlAccessType.NONE)
50 | @XmlRootElement(name = "anonymizer")
51 | public class Requirement {
52 |
53 | @XmlAccessorType(XmlAccessType.NONE)
54 | @Data
55 | public static class AutoresolvePackage {
56 | @XmlAttribute
57 | private String name;
58 |
59 | @Getter(AccessLevel.NONE)
60 | @Setter(AccessLevel.NONE)
61 | private ClassAndFunctionRegistry registry;
62 |
63 | public AutoresolvePackage() {
64 | this(ClassAndFunctionRegistry.singleton());
65 | }
66 |
67 | public AutoresolvePackage(String name) {
68 | this();
69 | this.name = name;
70 | }
71 |
72 | public AutoresolvePackage(String name, boolean register) {
73 | this(name);
74 | if (register) {
75 | registry.registerAutoResolvePackage(name);
76 | }
77 | }
78 |
79 | public AutoresolvePackage(ClassAndFunctionRegistry registry) {
80 | this.registry = registry;
81 | }
82 |
83 | public void afterUnmarshal(Unmarshaller unmarshaller, Object parent) {
84 | log.debug("Found autoresolve package: {}", name);
85 | registry.registerAutoResolvePackage(name);
86 | }
87 | }
88 |
89 | @XmlElement(name = "anonymizer-version")
90 | private double anonymizerVersion = 2.0d;
91 |
92 | @XmlElement
93 | private String project;
94 |
95 | @XmlElement(name = "project-version")
96 | private String version;
97 |
98 | @XmlElementWrapper(name = "autoresolve-classes")
99 | @XmlElement(name = "package")
100 | private List autoresolve;
101 |
102 | @XmlElementWrapper(name = "column-plans")
103 | @XmlElement(name = "plan")
104 | private List plans;
105 |
106 | @XmlElementWrapper(name = "tables")
107 | @XmlElement(name = "table")
108 | private List tables;
109 |
110 | /**
111 | * Returns a list of Table elements that match entries in the passed filter.
112 | * Attempts to filter out differences with schema, so 'schema.tablename' matches 'tablename'.
113 | *
114 | * @param filter
115 | * @return
116 | */
117 | public List getFilteredTables(List filter) {
118 | if (CollectionUtils.isEmpty(filter)) {
119 | return tables;
120 | }
121 | return tables.stream().filter((req) ->
122 | filter.stream().anyMatch((s) -> {
123 | String r = req.getName();
124 | if (s.equalsIgnoreCase(r)) {
125 | return true;
126 | } else if (s.contains(".") && !r.contains(".")) {
127 | return StringUtils.endsWithIgnoreCase(s, "." + r);
128 | } else if (r.contains(".") && !s.contains(".")) {
129 | return StringUtils.endsWithIgnoreCase(r, "." + s);
130 | }
131 | return false;
132 | })
133 | ).collect(Collectors.toList());
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/requirement/RequirementException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | *
16 | */
17 | package com.strider.datadefender.requirement;
18 |
19 | import com.strider.datadefender.DataDefenderException;
20 |
21 | /**
22 | * Package level exception. Extends application level exception.
23 | * @author Zaahid Bateson
24 | */
25 | public class RequirementException extends DataDefenderException {
26 | public RequirementException(final String msg) {
27 | super(msg);
28 | }
29 | public RequirementException(final String msg, final Throwable t) {
30 | super(msg, t);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/requirement/Table.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.requirement;
17 |
18 | import java.util.List;
19 |
20 | import javax.xml.bind.annotation.XmlAccessType;
21 | import javax.xml.bind.annotation.XmlAccessorType;
22 | import javax.xml.bind.annotation.XmlAttribute;
23 | import javax.xml.bind.annotation.XmlElement;
24 | import javax.xml.bind.annotation.XmlElementWrapper;
25 |
26 | import lombok.Data;
27 | import org.apache.commons.collections4.CollectionUtils;
28 |
29 | /**
30 | * JAXB class that defines parameter table in Requirement.xml file
31 | *
32 | * @author Armenak Grigoryan
33 | */
34 | @XmlAccessorType(XmlAccessType.NONE)
35 | @Data
36 | public class Table {
37 |
38 | @XmlAttribute
39 | private String name;
40 |
41 | @XmlAttribute(name = "primary-key")
42 | private String primaryKey;
43 |
44 | @XmlElement
45 | private String where;
46 |
47 | @XmlElementWrapper(name = "primary-key")
48 | @XmlElement(name = "key")
49 | private List primaryKeys;
50 |
51 | @XmlElementWrapper(name = "columns")
52 | @XmlElement(name = "column")
53 | private List columns;
54 |
55 | @XmlElementWrapper(name = "exclusions")
56 | @XmlElement(name = "exclude")
57 | private List exclusions;
58 |
59 | public Table() {
60 | }
61 |
62 | public Table(String name) {
63 | this.name = name;
64 | }
65 |
66 | public List getPrimaryKeyColumnNames() {
67 | if (CollectionUtils.isNotEmpty(primaryKeys)) {
68 | return primaryKeys;
69 | }
70 | return List.of(primaryKey);
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/requirement/file/JaxbValidationEventHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 Zaahid Bateson.
3 | *
4 | * This library is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU Lesser General Public
6 | * License as published by the Free Software Foundation; either
7 | * version 2.1 of the License, or (at your option) any later version.
8 | *
9 | * This library is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 | * Lesser General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU Lesser General Public
15 | * License along with this library; if not, write to the Free Software
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 | * MA 02110-1301 USA
18 | */
19 | package com.strider.datadefender.requirement.file;
20 |
21 |
22 | import org.w3c.dom.Node;
23 |
24 | import javax.xml.bind.ValidationEvent;
25 | import javax.xml.bind.ValidationEventHandler;
26 | import javax.xml.bind.ValidationEventLocator;
27 | import java.net.URL;
28 | import java.util.Map;
29 |
30 | import org.apache.logging.log4j.Level;
31 | import lombok.extern.log4j.Log4j2;
32 | import org.apache.commons.lang3.exception.ExceptionUtils;
33 |
34 | /**
35 | *
36 | * @author Zaahid Bateson
37 | */
38 | @Log4j2
39 | public class JaxbValidationEventHandler implements ValidationEventHandler {
40 |
41 | @Override
42 | public boolean handleEvent(ValidationEvent event) {
43 |
44 | if (event == null) {
45 | throw new IllegalArgumentException();
46 | }
47 |
48 | Map severityToLevel = Map.of(
49 | ValidationEvent.WARNING, Level.WARN,
50 | ValidationEvent.ERROR, Level.ERROR,
51 | ValidationEvent.FATAL_ERROR, Level.FATAL
52 | );
53 |
54 | Level level = severityToLevel.getOrDefault(event.getSeverity(), Level.ERROR);
55 | String location = getFormattedLocation(event.getLocator());
56 | String message = event.getMessage();
57 | if (message == null && event.getLinkedException() != null) {
58 | message = ExceptionUtils.getRootCauseMessage(event.getLinkedException());
59 | }
60 | log.log(level, "{}\n\tLocation: {},{}", message, location, event.getLinkedException());
61 | return event.getSeverity() == ValidationEvent.WARNING;
62 | }
63 |
64 | private String getFormattedLocation(ValidationEventLocator locator) {
65 |
66 | String ret = "Location unavailable";
67 | if (locator != null) {
68 |
69 | ret = "";
70 |
71 | int line = locator.getLineNumber();
72 | URL url = locator.getURL();
73 | Object obj = locator.getObject();
74 | Node node = locator.getNode();
75 |
76 | if (line > -1) {
77 | ret += "Line: " + line;
78 | if (url != null) {
79 | ret += " In: " + url;
80 | }
81 | }
82 | if (obj != null) {
83 | ret += " Object: " + obj;
84 | }
85 | if (node != null) {
86 | ret += " Node: " + node;
87 | }
88 | }
89 |
90 | return ret;
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/requirement/file/Loader.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2014, Armenak Grigoryan, Matthew Eaton, and individual contributors as indicated
4 | * by the @authors tag. See the copyright.txt in the distribution for a
5 | * full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | */
18 | package com.strider.datadefender.requirement.file;
19 |
20 | import java.io.File;
21 | import java.io.FileInputStream;
22 | import java.io.FileNotFoundException;
23 |
24 | import javax.xml.bind.JAXBContext;
25 | import javax.xml.bind.JAXBException;
26 | import javax.xml.bind.Unmarshaller;
27 | import static javax.xml.bind.JAXBContext.newInstance;
28 |
29 | import com.strider.datadefender.requirement.Requirement;
30 | import com.strider.datadefender.requirement.registry.ClassAndFunctionRegistry;
31 | import java.lang.reflect.InvocationTargetException;
32 | import javax.xml.XMLConstants;
33 | import javax.xml.validation.Schema;
34 | import javax.xml.validation.SchemaFactory;
35 |
36 | import lombok.RequiredArgsConstructor;
37 | import lombok.extern.log4j.Log4j2;
38 | import org.xml.sax.SAXException;
39 |
40 | /**
41 | * Utility class to help handling requirement objects
42 | * @author Matthew Eaton
43 | */
44 | @Log4j2
45 | @RequiredArgsConstructor
46 | public class Loader {
47 |
48 | private final JAXBContext jaxbContext;
49 | private final Unmarshaller unmarshaller;
50 |
51 | public Loader() throws JAXBException {
52 |
53 | jaxbContext = newInstance(Requirement.class);
54 | unmarshaller = jaxbContext.createUnmarshaller();
55 | unmarshaller.setEventHandler(new JaxbValidationEventHandler());
56 | }
57 |
58 | /**
59 | * Load requirement XML file and return a Requirement object representing
60 | * it.
61 | *
62 | * @param requirementFile Requirement filename and path
63 | * @param version required version
64 | * @return Requirement object loaded based on file
65 | * @throws javax.xml.bind.JAXBException
66 | * @throws java.io.FileNotFoundException
67 | * @throws java.lang.NoSuchMethodException
68 | * @throws java.lang.InstantiationException
69 | * @throws java.lang.IllegalAccessException
70 | * @throws java.lang.reflect.InvocationTargetException
71 | * @throws org.xml.sax.SAXException
72 | */
73 | public Requirement load(final String requirementFile) throws
74 | FileNotFoundException,
75 | JAXBException,
76 | NoSuchMethodException,
77 | InstantiationException,
78 | IllegalAccessException,
79 | IllegalArgumentException,
80 | InvocationTargetException,
81 | SAXException {
82 |
83 | Requirement requirement = null;
84 | log.info("Loading requirement file: {}", requirementFile);
85 |
86 | SchemaFactory schemaFactory = SchemaFactory.newInstance(XMLConstants.W3C_XML_SCHEMA_NS_URI);
87 | Schema schema = schemaFactory.newSchema(Loader.class.getResource("requirement.xsd"));
88 |
89 | unmarshaller.setSchema(schema);
90 | requirement = (Requirement) unmarshaller.unmarshal(
91 | new FileInputStream(new File(requirementFile))
92 | );
93 | ClassAndFunctionRegistry.singleton().registerFunctions(requirement);
94 | return requirement;
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/requirement/package-info.java:
--------------------------------------------------------------------------------
1 | @XmlSchema(
2 | namespace = "https://armenak.github.io/DataDefender/anonymizer",
3 | elementFormDefault = XmlNsForm.QUALIFIED,
4 | xmlns = { @XmlNs(namespaceURI = "https://armenak.github.io/DataDefender/anonymizer", prefix = "") }
5 | )
6 | package com.strider.datadefender.requirement;
7 |
8 | import javax.xml.bind.annotation.XmlNs;
9 | import javax.xml.bind.annotation.XmlSchema;
10 | import javax.xml.bind.annotation.XmlNsForm;
11 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/requirement/plan/ArrayElement.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.requirement.plan;
17 |
18 | import javax.xml.bind.annotation.XmlAccessType;
19 | import javax.xml.bind.annotation.XmlAccessorType;
20 | import javax.xml.bind.annotation.XmlAttribute;
21 |
22 | import lombok.Data;
23 |
24 | /**
25 | * JAXB class defining values for array parameters.
26 | *
27 | * Represents the value of a single array element for a given Parameter.
28 | *
29 | * @see Parameter.getArrayElements
30 | * @author Zaahid Bateson
31 | */
32 | @XmlAccessorType(XmlAccessType.NONE)
33 | @Data
34 | public class ArrayElement {
35 | /**
36 | * The array element's value
37 | */
38 | @XmlAttribute
39 | private String value;
40 |
41 | @XmlAttribute(name = "pass-current-value")
42 | private boolean isDynamicValue = false;
43 | }
44 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/requirement/plan/FunctionAttributeAdapter.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.requirement.plan;
17 |
18 | import javax.xml.bind.annotation.adapters.XmlAdapter;
19 |
20 | /**
21 | * XmlAdapter to get a Function type from a String attribute.
22 | *
23 | * @author Zaahid Bateson
24 | */
25 | public class FunctionAttributeAdapter extends XmlAdapter {
26 |
27 | @Override
28 | public Function unmarshal(String value) throws Exception {
29 | return new Function(value, true);
30 | }
31 |
32 | @Override
33 | public String marshal(Function f) throws Exception {
34 | return (f != null) ? f.getFunctionName() : null;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/requirement/plan/GlobalPlan.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.requirement.plan;
17 |
18 | import java.lang.reflect.InvocationTargetException;
19 |
20 | import javax.xml.bind.Unmarshaller;
21 | import javax.xml.bind.annotation.XmlAccessType;
22 | import javax.xml.bind.annotation.XmlAccessorType;
23 | import javax.xml.bind.annotation.XmlAttribute;
24 | import javax.xml.bind.annotation.XmlID;
25 |
26 | import lombok.extern.log4j.Log4j2;
27 | import lombok.Getter;
28 | import lombok.NoArgsConstructor;
29 | import lombok.Setter;
30 | import org.apache.commons.collections4.CollectionUtils;
31 |
32 | /**
33 | *
34 | * @author Zaahid Bateson
35 | */
36 | @Log4j2
37 | @Getter
38 | @Setter
39 | @NoArgsConstructor
40 | @XmlAccessorType(XmlAccessType.NONE)
41 | public class GlobalPlan extends Plan {
42 |
43 | @XmlID
44 | @XmlAttribute
45 | private String id;
46 |
47 | public GlobalPlan(String id) {
48 | this.id = id;
49 | }
50 |
51 | /**
52 | * Uses functionName and parameters to find the method to associate with
53 | * 'Function'.
54 | *
55 | * @param unmarshaller
56 | * @param parent
57 | * @throws ClassNotFoundException
58 | * @throws InstantiationException
59 | * @throws IllegalAccessException
60 | * @throws InvocationTargetException
61 | */
62 | @Override
63 | public void afterUnmarshal(Unmarshaller unmarshaller, Object parent)
64 | throws ClassNotFoundException,
65 | InstantiationException,
66 | IllegalAccessException,
67 | InvocationTargetException {
68 |
69 | log.debug("Unmarshalling GlobalPlan with id {}", id);
70 | log.debug("Number of functions: {}", CollectionUtils.size(getFunctions()));
71 | // do nothing
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/requirement/plan/Invokable.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.requirement.plan;
17 |
18 | /**
19 | * Defines a single "invoke" method with the hopes to make Plan/Function
20 | * not just chainable but also nestable.
21 | *
22 | * @author Zaahid Bateson
23 | */
24 | public interface Invokable {
25 | /**
26 | * Invokes the underlying function with the passed runningValue for dynamic
27 | * arguments.
28 | *
29 | * @param runningValue
30 | * @return
31 | * @throws Exception
32 | */
33 | Object invoke(Object runningValue) throws Exception;
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/requirement/plan/PlanRef.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.requirement.plan;
17 |
18 | import com.strider.datadefender.requirement.Column;
19 | import java.lang.reflect.InvocationTargetException;
20 |
21 | import javax.xml.bind.Unmarshaller;
22 | import javax.xml.bind.annotation.XmlAccessType;
23 | import javax.xml.bind.annotation.XmlAccessorType;
24 | import javax.xml.bind.annotation.XmlAttribute;
25 | import javax.xml.bind.annotation.XmlIDREF;
26 |
27 | import lombok.extern.log4j.Log4j2;
28 | import lombok.Data;
29 | import lombok.NoArgsConstructor;
30 |
31 | /**
32 | *
33 | * @author Zaahid Bateson
34 | */
35 | @Log4j2
36 | @Data
37 | @NoArgsConstructor
38 | @XmlAccessorType(XmlAccessType.NONE)
39 | public class PlanRef {
40 |
41 | @XmlIDREF
42 | @XmlAttribute(name = "ref-id")
43 | private GlobalPlan ref;
44 |
45 | public PlanRef(GlobalPlan ref) {
46 | this.ref = ref;
47 | }
48 |
49 | /**
50 | * Uses functionName and parameters to find the method to associate with
51 | * 'Function'.
52 | *
53 | * @param unmarshaller
54 | * @param parent
55 | * @throws ClassNotFoundException
56 | * @throws InstantiationException
57 | * @throws IllegalAccessException
58 | * @throws InvocationTargetException
59 | */
60 | public void afterUnmarshal(Unmarshaller unmarshaller, Object parent)
61 | throws ClassNotFoundException,
62 | InstantiationException,
63 | IllegalAccessException,
64 | InvocationTargetException {
65 |
66 | log.debug("Unmarshalling plan-ref");
67 | log.debug("ref-id: {}", () -> ref.getId());
68 |
69 | if (!(parent instanceof Column)) {
70 | return;
71 | }
72 | final Class> columnType = ((Column) parent).getType();
73 | ref.initialize(columnType);
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/requirement/plan/package-info.java:
--------------------------------------------------------------------------------
1 | @XmlSchema(
2 | namespace = "https://armenak.github.io/DataDefender/anonymizer",
3 | elementFormDefault = XmlNsForm.QUALIFIED,
4 | xmlns = { @XmlNs(namespaceURI = "https://armenak.github.io/DataDefender/anonymizer", prefix = "") }
5 | )
6 | package com.strider.datadefender.requirement.plan;
7 |
8 | import javax.xml.bind.annotation.XmlNs;
9 | import javax.xml.bind.annotation.XmlSchema;
10 | import javax.xml.bind.annotation.XmlNsForm;
11 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/requirement/registry/DatabaseAwareRequirementFunction.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.requirement.registry;
17 |
18 | import com.strider.datadefender.database.IDbFactory;
19 |
20 | /**
21 | * Configures a member variable IDbFactory in a concrete 'initialize' method.
22 | *
23 | * @author Zaahid Bateson
24 | */
25 | public abstract class DatabaseAwareRequirementFunction extends RequirementFunction {
26 |
27 | protected IDbFactory dbFactory;
28 |
29 | public final void initialize(IDbFactory dbFactory) {
30 | this.dbFactory = dbFactory;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/requirement/registry/RequirementFunction.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.requirement.registry;
17 |
18 | /**
19 | * Specifies that the class contains functions for use by anonymizer functions.
20 | *
21 | * This identifies classes that the anonymizer should try to construct, versus
22 | * classes that identify the return type of a column (and methods that operate
23 | * on them, for example a function java.lang.String#substring) that should not
24 | * be constructed.
25 | *
26 | * @author Zaahid Bateson
27 | */
28 | public abstract class RequirementFunction {
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/specialcase/EmailDetector.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2014-2020, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.specialcase;
17 |
18 | import com.strider.datadefender.discoverer.Discoverer.ColumnMatch;
19 | import org.apache.commons.validator.routines.EmailValidator;
20 |
21 | import com.strider.datadefender.database.metadata.TableMetaData;
22 | import com.strider.datadefender.database.metadata.TableMetaData.ColumnMetaData;
23 |
24 | import lombok.extern.log4j.Log4j2;
25 | import org.apache.commons.lang3.StringUtils;
26 |
27 | /**
28 | * @author Armenak Grigoryan
29 | */
30 | @Log4j2
31 | public class EmailDetector implements SpecialCase {
32 |
33 | public static ColumnMatch detectEmail(final ColumnMetaData metaData, final String text) {
34 | if (StringUtils.isNotBlank(text) && isValidEmail(text)) {
35 | log.debug("Email detected: " + text);
36 | return new ColumnMatch(metaData, 1.0, "email", null);
37 | } else {
38 | log.debug("Email " + text + " is not a valid email");
39 | }
40 |
41 | return null;
42 | }
43 |
44 | /**
45 | * @param email Email address
46 | * @return true if email is valid, otherwise false
47 | */
48 | private static boolean isValidEmail(final String email) {
49 |
50 | EmailValidator eValidator = EmailValidator.getInstance();
51 | if (eValidator.isValid(email)) {
52 | log.debug("*************** Email " + email + " is valid");
53 | return true;
54 | } else {
55 | return false;
56 | }
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/specialcase/PhiDetector.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2020, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.specialcase;
17 |
18 | import com.strider.datadefender.discoverer.Discoverer.ColumnMatch;
19 | import java.io.BufferedReader;
20 | import java.io.FileReader;
21 | import java.io.IOException;
22 |
23 | import java.util.ArrayList;
24 | import java.util.List;
25 | import java.util.Locale;
26 |
27 | import com.strider.datadefender.discoverer.Probability;
28 | import com.strider.datadefender.database.metadata.TableMetaData.ColumnMetaData;
29 | import java.util.Objects;
30 |
31 | import lombok.extern.log4j.Log4j2;
32 | import org.apache.commons.lang3.StringUtils;
33 |
34 | /**
35 | * @author Armenak Grigoryan
36 | */
37 | @Log4j2
38 | public class PhiDetector implements SpecialCase {
39 |
40 | private static final String PHI_FILE = "phi.txt";
41 | private static List phiList = new ArrayList();
42 |
43 | static {
44 | try {
45 | log.info("*** reading from " + PHI_FILE);
46 |
47 | try (BufferedReader br = new BufferedReader(new FileReader(PHI_FILE))) {
48 | for (String line; (line = br.readLine()) != null; ) {
49 | phiList.add(line);
50 | }
51 | }
52 | } catch (IOException ioe) {
53 | log.error(ioe.toString());
54 | }
55 | }
56 |
57 | /**
58 | * Generates random 9-digit student number
59 | * @param data
60 | * @param text
61 | * @return String
62 | */
63 | public static ColumnMatch isPhiTerm(final ColumnMetaData data, final String text) {
64 | if (StringUtils.isNotBlank(text)
65 | && Objects.equals(String.class, data.getColumnType())
66 | && phiList.contains(text.trim().toLowerCase(Locale.ENGLISH))) {
67 |
68 | log.debug("PHI detected: " + text);
69 | return new ColumnMatch(
70 | data,
71 | 100.0,
72 | "phi",
73 | List.of(new Probability(text, 1.00))
74 | );
75 | }
76 | return null;
77 | }
78 | }
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/specialcase/SpecialCase.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2014-2017, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.specialcase;
17 |
18 | /**
19 | * Marker interface for all special case classes
20 | *
21 | * @author Armenak Grigoryan
22 | */
23 | public interface SpecialCase {}
24 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/utils/ApplicationLock.java:
--------------------------------------------------------------------------------
1 | /*
2 | * This is free software; you can redistribute it and/or modify it
3 | * under the terms of the GNU Lesser General Public License as
4 | * published by the Free Software Foundation; either version 2.1 of
5 | * the License, or (at your option) any later version.
6 | *
7 | * This software is distributed in the hope that it will be useful,
8 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 | * Lesser General Public License for more details.
11 | */
12 | package com.strider.datadefender.utils;
13 |
14 | import java.io.File;
15 | import java.io.FileNotFoundException;
16 | import java.io.IOException;
17 | import java.io.RandomAccessFile;
18 |
19 | import java.nio.channels.FileChannel;
20 | import java.nio.channels.FileLock;
21 | import java.nio.channels.OverlappingFileLockException;
22 |
23 | import com.strider.datadefender.DataDefenderException;
24 | import lombok.extern.log4j.Log4j2;
25 |
26 | /**
27 | * Most of the code is copied from this page: http://www.rgagnon.com/javadetails/java-0288.html
28 | *
29 | * Modified by Armenak Grigoryan
30 | */
31 | @Log4j2
32 | public class ApplicationLock {
33 |
34 | private final String appName;
35 | private File file;
36 | private FileChannel channel;
37 | private FileLock lock;
38 |
39 | /**
40 | * Constructor
41 | *
42 | * @param appName application name
43 | */
44 | public ApplicationLock(final String appName) {
45 | this.appName = appName;
46 | }
47 |
48 | private void closeLock() throws DataDefenderException {
49 | try {
50 | lock.release();
51 | } catch (IOException e) {
52 | throw new DataDefenderException("Problem releasing file lock", e);
53 | }
54 |
55 | try {
56 | channel.close();
57 | } catch (IOException e) {
58 | throw new DataDefenderException("Problem closing channel", e);
59 | }
60 | }
61 |
62 | private void deleteFile() {
63 | file.delete();
64 | }
65 |
66 | /**
67 | * Returns true if there is another instance of the application is running.
68 | * Otherwise returns false.
69 | *
70 | * @return boolean
71 | * @throws com.strider.datadefender.DataDefenderException
72 | */
73 | public boolean isAppActive() throws DataDefenderException {
74 | try {
75 | file = new File(System.getProperty("user.home"), appName + ".tmp");
76 | channel = new RandomAccessFile(file, "rw").getChannel();
77 | log.debug("Creating lock file " + file.getName());
78 |
79 | try {
80 | lock = channel.tryLock();
81 | log.debug("Locking file ...");
82 | } catch (OverlappingFileLockException | IOException e) {
83 |
84 | // already locked
85 | log.error("File " + file.getName() + " already locket");
86 | closeLock();
87 |
88 | return true;
89 | }
90 |
91 | if (lock == null) {
92 | closeLock();
93 |
94 | return true;
95 | }
96 |
97 | Runtime.getRuntime().addShutdownHook(new Thread() {
98 |
99 | // destroy the lock when the JVM is closing
100 | @Override
101 | public void run() {
102 | try {
103 | log.debug("Closing lock file");
104 | closeLock();
105 | deleteFile();
106 | } catch (DataDefenderException ae) {
107 | log.error("Problem closing file lock");
108 | }
109 | }
110 | });
111 |
112 | return false;
113 | } catch (FileNotFoundException fnfe) {
114 | closeLock();
115 |
116 | return true;
117 | }
118 | }
119 | }
120 |
121 |
122 | //~ Formatted by Jindent --- http://www.jindent.com
123 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/utils/Encoder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2021, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.utils;
17 |
18 | import java.io.UnsupportedEncodingException;
19 |
20 | import java.security.InvalidKeyException;
21 | import java.security.MessageDigest;
22 | import java.security.NoSuchAlgorithmException;
23 | import java.util.Arrays;
24 | import java.util.Base64;
25 |
26 | import javax.crypto.BadPaddingException;
27 | import javax.crypto.Cipher;
28 | import javax.crypto.IllegalBlockSizeException;
29 | import javax.crypto.NoSuchPaddingException;
30 | import javax.crypto.spec.SecretKeySpec;
31 |
32 | import lombok.extern.log4j.Log4j2;
33 |
34 | /**
35 | * This class implements determenistic data anonymization
36 | * by encoding the data using "salt" and decoding it.
37 | *
38 | * @author Armenak Grigoryan
39 | */
40 | @Log4j2
41 | public final class Encoder {
42 |
43 | private static SecretKeySpec secretKey;
44 | private static byte[] key;
45 |
46 | /**
47 | * Empty constructor
48 | */
49 | public Encoder() {
50 | }
51 |
52 | public static void setKey(String myKey) {
53 | MessageDigest sha = null;
54 |
55 | try {
56 | key = myKey.getBytes("UTF-8");
57 | sha = MessageDigest.getInstance("SHA-1");
58 | key = sha.digest(key);
59 | key = Arrays.copyOf(key, 16);
60 | secretKey = new SecretKeySpec(key, "AES");
61 | }
62 | catch (NoSuchAlgorithmException | UnsupportedEncodingException e) {
63 | log.debug(e);
64 | }
65 | }
66 |
67 |
68 | public String encrypt(String strToEncrypt, String secret) {
69 |
70 | try {
71 | setKey(secret);
72 | Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
73 | cipher.init(Cipher.ENCRYPT_MODE, secretKey);
74 | return Base64.getEncoder().encodeToString(cipher.doFinal(strToEncrypt.getBytes("UTF-8")));
75 | } catch (UnsupportedEncodingException | InvalidKeyException | NoSuchAlgorithmException |
76 | BadPaddingException | IllegalBlockSizeException | NoSuchPaddingException e) {
77 | log.error("Error while encrypting: " + e.toString());
78 | }
79 |
80 | return null;
81 |
82 | }
83 |
84 |
85 | public String decrypt(String strToDecrypt, String secret) {
86 | try {
87 | setKey(secret);
88 | Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5PADDING");
89 | cipher.init(Cipher.DECRYPT_MODE, secretKey);
90 | return new String(cipher.doFinal(Base64.getDecoder().decode(strToDecrypt)));
91 | } catch (InvalidKeyException | NoSuchAlgorithmException | BadPaddingException |
92 | IllegalBlockSizeException | NoSuchPaddingException e) {
93 | log.error("Error while decrypting: " + e.toString());
94 | }
95 | return null;
96 | }
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/utils/ICloseableNoException.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2015, Armenak Grigoryan, and individual contributors as indicated
4 | * by the @authors tag. See the copyright.txt in the distribution for a
5 | * full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | */
18 |
19 |
20 |
21 | package com.strider.datadefender.utils;
22 |
23 | /**
24 | * Just hide the Exception thrown by close() as we don't need to throw one.
25 | * @author Akira Matsuo
26 | */
27 | public interface ICloseableNoException extends AutoCloseable {
28 | @Override
29 | void close();
30 | }
31 |
32 |
33 | //~ Formatted by Jindent --- http://www.jindent.com
34 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/utils/IConsumerWithException.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2015, Armenak Grigoryan, and individual contributors as indicated
4 | * by the @authors tag. See the copyright.txt in the distribution for a
5 | * full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | */
18 |
19 |
20 |
21 | package com.strider.datadefender.utils;
22 |
23 | /**
24 | * @author Akira Matsuo
25 | *
26 | * @param
27 | * Much like a java.util.Consumer but throws an exception.
28 | */
29 | @FunctionalInterface
30 | public interface IConsumerWithException {
31 | void accept(T obj) throws E;
32 | }
33 |
34 |
35 | //~ Formatted by Jindent --- http://www.jindent.com
36 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/utils/ISupplierWithException.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2015, Armenak Grigoryan, and individual contributors as indicated
4 | * by the @authors tag. See the copyright.txt in the distribution for a
5 | * full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | */
18 | package com.strider.datadefender.utils;
19 |
20 | /**
21 | * @author Akira Matsuo
22 | *
23 | * @param
24 | * Much like a java.util.Supplier but throws an exception.
25 | * @param
26 | */
27 | @FunctionalInterface
28 | public interface ISupplierWithException {
29 | T get() throws E;
30 | }
31 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/utils/LikeMatcher.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
4 | * by the @authors tag. See the copyright.txt in the distribution for a
5 | * full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | */
18 |
19 |
20 |
21 | package com.strider.datadefender.utils;
22 |
23 | import java.util.Locale;
24 | import java.util.regex.Pattern;
25 |
26 | /**
27 | * Simple matcher to mimic SQL LIKE queries.
28 | *
29 | * At the moment only "%", "_" and "?" are supported.
30 | *
31 | * @author Zaahid Bateson
32 | */
33 | public class LikeMatcher {
34 | final private String regex;
35 |
36 | /**
37 | * Initializes a LikeMatcher with the given pattern.
38 | *
39 | * @param pattern the LIKE query pattern
40 | */
41 | public LikeMatcher(final String pattern) {
42 |
43 | // splitting on '?', '_', and '%' with look-behind and look-ahead so they're included in the split array
44 | final String[] parts = pattern.split("((?<=[\\?\\_\\%])|(?=[\\?\\_\\%]))");
45 | final StringBuilder reg = new StringBuilder("^");
46 |
47 | for (final String part : parts) {
48 | if ("%".equals(part)) {
49 | reg.append(".*?");
50 | } else if ("?".equals(part) || "_".equals(part)) {
51 | reg.append('.');
52 | } else {
53 | reg.append(Pattern.quote(part.toLowerCase(Locale.ENGLISH)));
54 | }
55 | }
56 |
57 | reg.append('$');
58 | this.regex = reg.toString();
59 | }
60 |
61 | /**
62 | * Returns true if the given string matches the Like pattern.
63 | *
64 | * @param str the string to test against
65 | * @return
66 | */
67 | public boolean matches(final String str) {
68 | return str.toLowerCase(Locale.ENGLISH).matches(regex);
69 | }
70 | }
71 |
72 |
73 | //~ Formatted by Jindent --- http://www.jindent.com
74 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/utils/Score.java:
--------------------------------------------------------------------------------
1 | /*
2 | *
3 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
4 | * by the @authors tag. See the copyright.txt in the distribution for a
5 | * full listing of individual contributors.
6 | *
7 | * This is free software; you can redistribute it and/or modify it
8 | * under the terms of the GNU Lesser General Public License as
9 | * published by the Free Software Foundation; either version 2.1 of
10 | * the License, or (at your option) any later version.
11 | *
12 | * This software is distributed in the hope that it will be useful,
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 | * Lesser General Public License for more details.
16 | *
17 | */
18 |
19 |
20 |
21 | package com.strider.datadefender.utils;
22 |
23 | import java.util.ArrayList;
24 | import java.util.List;
25 |
26 | /**
27 | * This class calculates the risk score for an individual column and for entire data store.
28 | *
29 | * @author Armenak Grigoryan
30 | */
31 | public class Score {
32 | private static final int SCORE_LOW = 1;
33 | private static final int SCORE_MEDIUM = 2;
34 | private static final int SCORE_HIGH = 3;
35 | private static final List averageScore = new ArrayList<>();
36 |
37 | public String columnScore(final int rowCount) {
38 | int score = 0;
39 |
40 | if (rowCount == 0) {
41 | score = 0;
42 | } else if ((rowCount > 0) && (rowCount <= 100)) {
43 | score = SCORE_LOW;
44 | } else if ((rowCount > 100) && (rowCount <= 1000)) {
45 | score = SCORE_MEDIUM;
46 | } else {
47 | score = SCORE_HIGH;
48 | }
49 |
50 | averageScore.add(score);
51 |
52 | return getScoreDefinition(score);
53 | }
54 |
55 | public String dataStoreScore() {
56 | float averageDataStoreScore = 0;
57 | int tmp = 0;
58 |
59 | for (final int score : averageScore) {
60 | tmp += score;
61 | }
62 |
63 | if ((averageScore != null) && (averageScore.size() > 0)) {
64 | averageDataStoreScore = tmp / averageScore.size();
65 | }
66 |
67 | return getScoreDefinition(Math.round(averageDataStoreScore));
68 | }
69 |
70 | public String getScoreDefinition(final int score) {
71 | String scoreDefinition = "";
72 |
73 | switch (score) {
74 | case 1:
75 | scoreDefinition = "Low";
76 | break;
77 | case 2:
78 | scoreDefinition = "Medium";
79 | break;
80 | case 3:
81 | scoreDefinition = "High";
82 | break;
83 | default:
84 | scoreDefinition = "Undefined";
85 | break;
86 | }
87 |
88 | return scoreDefinition;
89 | }
90 | }
91 |
92 |
93 | //~ Formatted by Jindent --- http://www.jindent.com
94 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/utils/Xeger.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2009 Wilfred Springer
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Modified by Armenak Grigoryan
17 | */
18 | package com.strider.datadefender.utils;
19 |
20 | import java.util.List;
21 | import java.util.Random;
22 |
23 | import dk.brics.automaton.Automaton;
24 | import dk.brics.automaton.RegExp;
25 | import dk.brics.automaton.State;
26 | import dk.brics.automaton.Transition;
27 |
28 | /**
29 | * An object that will generate text from a regular expression. In a way, it's
30 | * the opposite of a regular expression matcher: an instance of this class will
31 | * produce text that is guaranteed to match the regular expression passed in.
32 | */
33 | public class Xeger {
34 | private final Automaton automaton;
35 | private final Random random;
36 |
37 | /**
38 | * As {@link nl.flotsam.xeger.Xeger#Xeger(String, java.util.Random)}, creating a {@link java.util.Random} instance
39 | * implicityly.
40 | * @param regex
41 | */
42 | public Xeger(final String regex) {
43 | this(regex, new Random());
44 | }
45 |
46 | /**
47 | * Constructs a new instance, accepting the regular expression and the randomizer.
48 | *
49 | * @param regex The regular expression. (Not null
.)
50 | * @param random The object that will randomize the way the String is generated. (Not null
.)
51 | * @throws IllegalArgumentException If the regular expression is invalid.
52 | */
53 | public Xeger(final String regex, final Random random) {
54 | assert regex != null;
55 | assert random != null;
56 | this.automaton = new RegExp(regex).toAutomaton();
57 | this.random = random;
58 | }
59 |
60 | private void appendChoice(final StringBuilder builder, final Transition transition) {
61 | final char c = (char) XegerUtils.getRandomInt(transition.getMin(), transition.getMax(), random);
62 |
63 | builder.append(c);
64 | }
65 |
66 | /**
67 | * Generates a random String that is guaranteed to match the regular expression passed to the constructor.
68 | * @return String
69 | */
70 | public String generate() {
71 | final StringBuilder builder = new StringBuilder();
72 |
73 | generate(builder, automaton.getInitialState());
74 |
75 | return builder.toString();
76 | }
77 |
78 | private void generate(final StringBuilder builder, final State state) {
79 | final List transitions = state.getSortedTransitions(true);
80 |
81 | if (transitions.isEmpty()) {
82 | assert state.isAccept();
83 |
84 | return;
85 | }
86 |
87 | final int nroptions = state.isAccept()
88 | ? transitions.size()
89 | : transitions.size() - 1;
90 | final int option = XegerUtils.getRandomInt(0, nroptions, random);
91 |
92 | if (state.isAccept() && (option == 0)) { // 0 is considered stop
93 | return;
94 | }
95 |
96 | // Moving on to next transition
97 | final Transition transition = transitions.get(option - (state.isAccept()
98 | ? 1
99 | : 0));
100 |
101 | appendChoice(builder, transition);
102 | generate(builder, transition.getDest());
103 | }
104 | }
105 |
106 |
107 | //~ Formatted by Jindent --- http://www.jindent.com
108 |
--------------------------------------------------------------------------------
/src/main/java/com/strider/datadefender/utils/XegerUtils.java:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright 2009 Wilfred Springer
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | *
16 | * Modified by Armenak Grigoryan
17 | */
18 |
19 |
20 |
21 | package com.strider.datadefender.utils;
22 |
23 | import java.util.Random;
24 |
25 | public class XegerUtils {
26 |
27 | /**
28 | * Generates a random number within the given bounds.
29 | *
30 | * @param min The minimum number (inclusive).
31 | * @param max The maximum number (inclusive).
32 | * @param random The object used as the randomizer.
33 | * @return A random number in the given range.
34 | */
35 | public final static int getRandomInt(final int min, final int max, final Random random) {
36 | final int dif = max - min;
37 | final float number = random.nextFloat(); // 0 <= number < 1
38 |
39 | return min + Math.round(number * dif);
40 | }
41 | }
42 |
43 |
44 | //~ Formatted by Jindent --- http://www.jindent.com
45 |
--------------------------------------------------------------------------------
/src/main/resources/com/strider/datadefender/anonymizer/functions/cities.txt:
--------------------------------------------------------------------------------
1 | Tokyo
2 | Jakarta
3 | Chongqing
4 | Manila
5 | Delhi
6 | Seoul
7 | Mumbai
8 | Shanghai
9 | São Paulo
10 | Beijing
11 | New York City
12 | Lagos
13 | Mexico City
14 | Guangzhou
15 | Dhaka
16 | Osaka
17 | Cairo
18 | Karachi
19 | Moscow
20 | Bangkok
21 | Chengdu
22 | Los Angeles
23 | Kolkata
24 | Buenos Aires
25 | Istanbul
26 | Tehran
27 | London
28 | Shenzhen
29 | Tianjin
30 | Kinshasa
31 | Rio de Janeiro
32 | Paris
33 | Baoding
34 | Lahore
35 | Lima
36 | Bangalore
37 | Ho Chi Minh City
38 | Harbin
39 | Wuhan
40 | Shijiazhuang
41 | Bogotá
42 | Suzhou
43 | Linyi
44 | Chennai
45 | Nagoya
46 | Nanyang
47 | Zhengzhou
48 | Hyderabad
49 | Surabaya
50 | Hangzhou
51 | Johannesburg
52 | Chicago
53 | Xi'an
54 | Quanzhou
55 | Taipei
56 | Dongguan
57 | Bandung
58 | Hanoi
59 | Shenyang
60 | Baghdad
61 | Onitsha
62 | Kuala Lumpur
63 | Ahmedabad
64 | Luanda
65 | Washington, D.C.
66 | Dallas
67 | Hong Kong
68 | Pune
69 | Nanjing
70 | Boston
71 | Santiago
72 | Houston
73 | Riyadh
74 | Düsseldorf
75 | Madrid
76 | Toronto
77 | Surat
78 | San Francisco
79 |
--------------------------------------------------------------------------------
/src/main/resources/com/strider/datadefender/anonymizer/functions/countries.txt:
--------------------------------------------------------------------------------
1 | Afghanistan
2 | Albania
3 | Algeria
4 | Andorra
5 | Angola
6 | Antigua and Barbuda
7 | Argentina
8 | Armenia
9 | Australia
10 | Austria
11 | Azerbaijan
12 | Bahamas
13 | Bahrain
14 | Bangladesh
15 | Barbados
16 | Belarus
17 | Belgium
18 | Belize
19 | Benin
20 | Bhutan
21 | Bolivia
22 | Bosnia and Herzegovina
23 | Botswana
24 | Brazil
25 | Brunei
26 | Bulgaria
27 | Burkina Faso
28 | Burundi
29 | Côte d'Ivoire
30 | Cabo Verde
31 | Cambodia
32 | Cameroon
33 | Canada
34 | Central African Republic
35 | Chad
36 | Chile
37 | China
38 | Colombia
39 | Comoros
40 | Congo (Congo-Brazzaville)
41 | Costa Rica
42 | Croatia
43 | Cuba
44 | Cyprus
45 | Czechia (Czech Republic)
46 | Democratic Republic of the Congo
47 | Denmark
48 | Djibouti
49 | Dominica
50 | Dominican Republic
51 | Ecuador
52 | Egypt
53 | El Salvador
54 | Equatorial Guinea
55 | Eritrea
56 | Estonia
57 | Eswatini (fmr. "Swaziland")
58 | Ethiopia
59 | Fiji
60 | Finland
61 | France
62 | Gabon
63 | Gambia
64 | Georgia
65 | Germany
66 | Ghana
67 | Greece
68 | Grenada
69 | Guatemala
70 | Guinea
71 | Guinea-Bissau
72 | Guyana
73 | Haiti
74 | Holy See
75 | Honduras
76 | Hungary
77 | Iceland
78 | India
79 | Indonesia
80 | Iran
81 | Iraq
82 | Ireland
83 | Israel
84 | Italy
85 | Jamaica
86 | Japan
87 | Jordan
88 | Kazakhstan
89 | Kenya
90 | Kiribati
91 | Kuwait
92 | Kyrgyzstan
93 | Laos
94 | Latvia
95 | Lebanon
96 | Lesotho
97 | Liberia
98 | Libya
99 | Liechtenstein
100 | Lithuania
101 | Luxembourg
102 | Madagascar
103 | Malawi
104 | Malaysia
105 | Maldives
106 | Mali
107 | Malta
108 | Marshall Islands
109 | Mauritania
110 | Mauritius
111 | Mexico
112 | Micronesia
113 | Moldova
114 | Monaco
115 | Mongolia
116 | Montenegro
117 | Morocco
118 | Mozambique
119 | Myanmar (formerly Burma)
120 | Namibia
121 | Nauru
122 | Nepal
123 | Netherlands
124 | New Zealand
125 | Nicaragua
126 | Niger
127 | Nigeria
128 | North Korea
129 | North Macedonia
130 | Norway
131 | Oman
132 | Pakistan
133 | Palau
134 | Palestine State
135 | Panama
136 | Papua New Guinea
137 | Paraguay
138 | Peru
139 | Philippines
140 | Poland
141 | Portugal
142 | Qatar
143 | Romania
144 | Russia
145 | Rwanda
146 | Saint Kitts and Nevis
147 | Saint Lucia
148 | Saint Vincent and the Grenadines
149 | Samoa
150 | San Marino
151 | Sao Tome and Principe
152 | Saudi Arabia
153 | Senegal
154 | Serbia
155 | Seychelles
156 | Sierra Leone
157 | Singapore
158 | Slovakia
159 | Slovenia
160 | Solomon Islands
161 | Somalia
162 | South Africa
163 | South Korea
164 | South Sudan
165 | Spain
166 | Sri Lanka
167 | Sudan
168 | Suriname
169 | Sweden
170 | Switzerland
171 | Syria
172 | Tajikistan
173 | Tanzania
174 | Thailand
175 | Timor-Leste
176 | Togo
177 | Tonga
178 | Trinidad and Tobago
179 | Tunisia
180 | Turkey
181 | Turkmenistan
182 | Tuvalu
183 | Uganda
184 | Ukraine
185 | United Arab Emirates
186 | United Kingdom
187 | United States of America
188 | Uruguay
189 | Uzbekistan
190 | Vanuatu
191 | Venezuela
192 | Vietnam
193 | Yemen
194 | Zambia
195 | Zimbabwe
196 |
--------------------------------------------------------------------------------
/src/main/resources/com/strider/datadefender/anonymizer/functions/provinces_states.txt:
--------------------------------------------------------------------------------
1 | Alabama
2 | Alaska
3 | Arizona
4 | Arkansas
5 | California
6 | Colorado
7 | Connecticut
8 | Delaware
9 | District of Columbia
10 | Florida
11 | Georgia
12 | Guam
13 | Hawaii
14 | Idaho
15 | Illinois
16 | Indiana
17 | Iowa
18 | Kansas
19 | Kentucky
20 | Louisiana
21 | Maine
22 | Maryland
23 | Massachusetts
24 | Michigan
25 | Minnesota
26 | Mississippi
27 | Missouri
28 | Montana
29 | Nebraska
30 | Nevada
31 | New Hampshire
32 | New Jersey
33 | New Mexico
34 | New York
35 | North Carolina
36 | North Dakota
37 | Ohio
38 | Oklahoma
39 | Oregon
40 | Pennsylvania
41 | Puerto Rico
42 | Rhode Island
43 | South Carolina
44 | South Dakota
45 | Tennessee
46 | Texas
47 | Utah
48 | Vermont
49 | Virgin Islands
50 | Virginia
51 | Washington
52 | West Virginia
53 | Wisconsin
54 | Wyoming
55 | Alberta
56 | British Columbia
57 | Manitoba
58 | New Brunswick
59 | Newfoundland
60 | Northwest Territories
61 | Nova Scotia
62 | Ontario
63 | Prince Edward Island
64 | Quebec
65 | Saskatchewan
66 | Yukon Territory
67 |
--------------------------------------------------------------------------------
/src/main/resources/com/strider/datadefender/anonymizer/functions/provinces_states_codes.txt:
--------------------------------------------------------------------------------
1 | AL
2 | AK
3 | AZ
4 | AR
5 | CA
6 | CO
7 | CT
8 | DE
9 | DC
10 | FL
11 | GA
12 | GU
13 | HI
14 | ID
15 | IL
16 | IN
17 | IA
18 | KS
19 | KY
20 | LA
21 | ME
22 | MD
23 | MA
24 | MI
25 | MN
26 | MS
27 | MO
28 | MT
29 | NE
30 | NV
31 | NH
32 | NJ
33 | NM
34 | NY
35 | NC
36 | ND
37 | OH
38 | OK
39 | OR
40 | PA
41 | PR
42 | RI
43 | SC
44 | SD
45 | TN
46 | TX
47 | UT
48 | VT
49 | VI
50 | VA
51 | WA
52 | WV
53 | WI
54 | WY
55 | AB
56 | BC
57 | MB
58 | NB
59 | NF
60 | NT
61 | NS
62 | ON
63 | PE
64 | PQ
65 | SK
66 | YT
67 |
--------------------------------------------------------------------------------
/src/main/resources/com/strider/datadefender/discoverer/en-ner-date.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/armenak/DataDefender/40a43c621d88b326fee206e45fd1b7e8760a6a0b/src/main/resources/com/strider/datadefender/discoverer/en-ner-date.bin
--------------------------------------------------------------------------------
/src/main/resources/com/strider/datadefender/discoverer/en-ner-location.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/armenak/DataDefender/40a43c621d88b326fee206e45fd1b7e8760a6a0b/src/main/resources/com/strider/datadefender/discoverer/en-ner-location.bin
--------------------------------------------------------------------------------
/src/main/resources/com/strider/datadefender/discoverer/en-ner-money.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/armenak/DataDefender/40a43c621d88b326fee206e45fd1b7e8760a6a0b/src/main/resources/com/strider/datadefender/discoverer/en-ner-money.bin
--------------------------------------------------------------------------------
/src/main/resources/com/strider/datadefender/discoverer/en-ner-organization.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/armenak/DataDefender/40a43c621d88b326fee206e45fd1b7e8760a6a0b/src/main/resources/com/strider/datadefender/discoverer/en-ner-organization.bin
--------------------------------------------------------------------------------
/src/main/resources/com/strider/datadefender/discoverer/en-ner-person.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/armenak/DataDefender/40a43c621d88b326fee206e45fd1b7e8760a6a0b/src/main/resources/com/strider/datadefender/discoverer/en-ner-person.bin
--------------------------------------------------------------------------------
/src/main/resources/com/strider/datadefender/discoverer/en-ner-time.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/armenak/DataDefender/40a43c621d88b326fee206e45fd1b7e8760a6a0b/src/main/resources/com/strider/datadefender/discoverer/en-ner-time.bin
--------------------------------------------------------------------------------
/src/main/resources/com/strider/datadefender/discoverer/en-sent.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/armenak/DataDefender/40a43c621d88b326fee206e45fd1b7e8760a6a0b/src/main/resources/com/strider/datadefender/discoverer/en-sent.bin
--------------------------------------------------------------------------------
/src/main/resources/com/strider/datadefender/discoverer/en-token.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/armenak/DataDefender/40a43c621d88b326fee206e45fd1b7e8760a6a0b/src/main/resources/com/strider/datadefender/discoverer/en-token.bin
--------------------------------------------------------------------------------
/src/main/resources/filediscovery.properties:
--------------------------------------------------------------------------------
1 | probability_threshold=0.5
2 | english_tokens=/Users/strider/work/strider/file_discovery/en-token.bin
3 | english_sentenses=/Users/strider/work/strider/file_discovery/en-sent.bin
4 | generic=/Users/strider/work/strider/file_discovery/en-ner-person.bin
5 | location=/Users/strider/work/strider/file_discovery/en-ner-location.bin
6 | date=/Users/strider/work/strider/file_discovery/en-ner-date.bin
7 | money=/Users/strider/work/strider/file_discovery/en-ner-money.bin
8 | organization=/Users/strider/work/strider/file_discovery/en-ner-organization.bin
9 | time=/Users/strider/work/strider/file_discovery/en-ner-time.bin
10 | names=/Users/strider/work/strider/file_discovery/names.dict
11 | limit=100
12 | models=generic,money,time,location,organization
13 | directories=/Users/strider/work/strider/file_discovery/files
14 | extensions=com.strider.datadefender.specialcase.SinDetector.detectSin
15 | threshold_count=6
16 | threshold_highrisk=3
17 | score_calculation=yes
--------------------------------------------------------------------------------
/src/main/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | status=error
2 | dest=err
3 |
4 | appender.console.type=Console
5 | appender.console.name=STDOUT
6 | appender.console.layout.type=PatternLayout
7 | appender.console.layout.pattern=[%highlight{%p}{FATAL=red, ERROR=red, WARN=yellow bright, INFO=blue bright, DEBUG=green bright}] %m%n
8 | appender.console.filter.threshold.type=DynamicThresholdFilter
9 | appender.console.filter.threshold.defaultThreshold=warn
10 | appender.console.filter.threshold.key=console-level
11 | appender.console.filter.threshold.keyValuePair.type=KeyValuePair
12 | appender.console.filter.threshold.keyValuePair.key=info
13 | appender.console.filter.threshold.keyValuePair.value=info
14 | appender.console.filter.threshold.keyValuePair2.type=KeyValuePair
15 | appender.console.filter.threshold.keyValuePair2.key=debug
16 | appender.console.filter.threshold.keyValuePair2.value=debug
17 | appender.console.filter.threshold.onMatch=ACCEPT
18 | appender.console.filter.threshold.onMismatch=DENY
19 |
20 | appender.rolling.type=RollingFile
21 | appender.rolling.name=FILE
22 | appender.rolling.fileName=logs/datadefender.log
23 | appender.rolling.filePattern=logs/datadefender-%d{yy-MM-dd-hh-mm-ss}.log
24 | appender.rolling.layout.type=PatternLayout
25 | appender.rolling.layout.pattern=%d{HH:mm:ss} %c{2.} [%p] - %m%n
26 | appender.rolling.policies.type=OnStartupTriggeringPolicy
27 | appender.rolling.filter.threshold.type=DynamicThresholdFilter
28 | appender.rolling.filter.threshold.defaultThreshold=info
29 | appender.rolling.filter.threshold.key=file-level
30 | appender.rolling.filter.threshold.keyValuePair.type=KeyValuePair
31 | appender.rolling.filter.threshold.keyValuePair.key=debug
32 | appender.rolling.filter.threshold.keyValuePair.value=debug
33 | appender.rolling.filter.threshold.onMatch=ACCEPT
34 | appender.rolling.filter.threshold.onMismatch=DENY
35 |
36 | rootLogger.level=all
37 | rootLogger.appenderRef.file.ref=FILE
38 | rootLogger.appenderRef.console.ref=STDOUT
39 |
--------------------------------------------------------------------------------
/src/main/resources/phi.txt:
--------------------------------------------------------------------------------
1 | Schizophrenia
2 | Schizophrenic
3 | Depression
4 | Depressed
5 | Police
6 | RCMP
7 | Suicide
8 | Suicidal
9 | Psycho
10 |
--------------------------------------------------------------------------------
/src/run-scripts/datadefender:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | java -cp ".:extensions/*:extensions:lib:DataDefender.jar" com.strider.datadefender.DataDefender "$@"
3 |
--------------------------------------------------------------------------------
/src/run-scripts/datadefender.bat:
--------------------------------------------------------------------------------
1 | java -cp ".;extensions/*;extensions;lib;DataDefender.jar" com.strider.datadefender.DataDefender %*
2 |
--------------------------------------------------------------------------------
/src/test/java/com/strider/datadefender/anonymizer/functions/LipsumTest.java:
--------------------------------------------------------------------------------
1 | package com.strider.datadefender.anonymizer.functions;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import static org.junit.jupiter.api.Assertions.*;
5 |
6 | /**
7 | *
8 | * @author Zaahid Bateson
9 | */
10 | public class LipsumTest {
11 |
12 | @Test
13 | public void testSentences() throws Exception {
14 | Lipsum test = new Lipsum();
15 | String sentences = test.sentences(3, 3);
16 | assertTrue(sentences.matches("([^\\.]+\\.){3}"));
17 | }
18 |
19 | @Test
20 | public void testParagraphs() throws Exception {
21 | Lipsum test = new Lipsum();
22 | String paragraphs = test.paragraphs(3);
23 | assertTrue(paragraphs.matches("^[^\r]+\r\n\r\n[^\r]+\r\n\r\n[^\r]+$"));
24 | }
25 |
26 | @Test
27 | public void testSimilar() throws Exception {
28 | Lipsum test = new Lipsum();
29 |
30 | String sentences = test.similar("This is a test. It is excellent. Should have a minimum of two sentences.");
31 | System.out.println("Testing for 3 sentences generated by similar text");
32 | assertTrue(sentences.matches("([^\\.]+\\.){2,}"));
33 |
34 | String paras = test.similar("This is also a test.\n\nIt is better.\n\nShould have three paragraphs.");
35 | System.out.println("Testing for 3 paragraphs generated by text with 3 paragraphs");
36 | assertTrue(paras.matches("^[^\r]+\r\n\r\n[^\r]+\r\n\r\n[^\r]+$"));
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/src/test/java/com/strider/datadefender/database/DbConnectionTest.java:
--------------------------------------------------------------------------------
1 | package com.strider.datadefender.database;
2 |
3 | import com.strider.datadefender.DbConfig;
4 |
5 | import java.sql.Connection;
6 |
7 | import org.junit.jupiter.api.Test;
8 | import org.junit.jupiter.api.extension.ExtendWith;
9 | import org.mockito.junit.jupiter.MockitoExtension;
10 | import org.mockito.Mock;
11 |
12 | import static org.junit.jupiter.api.Assertions.*;
13 | import static org.mockito.Mockito.*;
14 |
15 | /**
16 | * Using mock to test Connection.
17 | * @author Akira Matsuo
18 | */
19 | @ExtendWith(MockitoExtension.class)
20 | public class DbConnectionTest {
21 |
22 | @Mock
23 | DbConfig config;
24 | @Mock
25 | Connection mockConnection;
26 |
27 | @Test
28 | public void testConnect() throws Exception {
29 | final DbConnection test = new DbConnection(config) {
30 | @Override
31 | public Connection connect() throws DatabaseException {
32 | return doConnect(() -> mockConnection);
33 | }
34 | };
35 | assertEquals(mockConnection, test.connect());
36 | verify(mockConnection).setAutoCommit(false);
37 | }
38 |
39 | @Test
40 | public void testConnectSupplier() throws Exception {
41 | when(config.getUrl()).thenReturn("jdbc:h2:mem:utest;MODE=MySQL;DB_CLOSE_DELAY=-1");
42 | when(config.getUsername()).thenReturn("username");
43 | when(config.getUsername()).thenReturn("password");
44 |
45 | final DbConnection test = new DbConnection(config);
46 | final Connection con = test.connect();
47 | assertNotNull(con);
48 | assertFalse(con.isClosed());
49 | assertFalse(con.getAutoCommit());
50 |
51 | verify(config, atLeast(1)).getUrl();
52 | verify(config, atLeast(1)).getUsername();
53 | verify(config, atLeast(1)).getPassword();
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/test/java/com/strider/datadefender/database/IDbFactoryTest.java:
--------------------------------------------------------------------------------
1 | package com.strider.datadefender.database;
2 |
3 | import com.strider.datadefender.DataDefenderException;
4 | import com.strider.datadefender.DbConfig;
5 | import com.strider.datadefender.DbConfig.Vendor;
6 |
7 | import org.junit.jupiter.api.Test;
8 | import org.junit.jupiter.api.extension.ExtendWith;
9 | import org.mockito.Mock;
10 | import org.mockito.junit.jupiter.MockitoExtension;
11 |
12 | import static org.junit.jupiter.api.Assertions.*;
13 | import static org.mockito.Mockito.*;
14 |
15 | /**
16 | * @author Akira Matsuo
17 | */
18 | @ExtendWith(MockitoExtension.class)
19 | public class IDbFactoryTest {
20 |
21 | @Mock
22 | DbConfig config;
23 |
24 | @Test
25 | public void testInvalidNoProps() {
26 | when(config.getVendor()).thenReturn(Vendor.H2);
27 | assertThrows(DatabaseException.class, () -> IDbFactory.get(config).getConnection());
28 | }
29 |
30 | @Test
31 | public void testInvalidProps() throws DatabaseException, DataDefenderException {
32 | when(config.getVendor()).thenReturn(null);
33 | assertThrows(IllegalArgumentException.class, () ->
34 | IDbFactory.get(config).getConnection()
35 | );
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/test/java/com/strider/datadefender/database/metadata/MetaDataTest.java:
--------------------------------------------------------------------------------
1 | package com.strider.datadefender.database.metadata;
2 |
3 | import com.strider.datadefender.DbConfig;
4 | import com.strider.datadefender.database.metadata.TableMetaData.ColumnMetaData;
5 |
6 | import java.sql.Connection;
7 | import java.sql.DatabaseMetaData;
8 | import java.sql.ResultSet;
9 | import java.sql.Types;
10 | import java.util.List;
11 |
12 | import org.junit.jupiter.api.BeforeEach;
13 | import org.junit.jupiter.api.Test;
14 | import org.junit.jupiter.api.extension.ExtendWith;
15 | import org.mockito.junit.jupiter.MockitoExtension;
16 | import org.mockito.Mock;
17 |
18 | import static org.junit.jupiter.api.Assertions.*;
19 | import static org.mockito.Mockito.*;
20 |
21 | /**
22 | *
23 | * @author Akira Matsuo
24 | *
25 | * Tests the default implementation of MetaData that's used for Oracle and MSSQL.
26 | *
27 | */
28 | @ExtendWith(MockitoExtension.class)
29 | public class MetaDataTest {
30 |
31 | @Mock
32 | Connection mockConnection;
33 | @Mock
34 | DbConfig mockConfig;
35 | @Mock
36 | SqlTypeToClass mockSqlTypeMap;
37 | @Mock
38 | ResultSet mockTableRs;
39 | @Mock
40 | ResultSet mockColumnRs;
41 | @Mock
42 | DatabaseMetaData mockDbMetaData;
43 | @Mock
44 | ResultSet emptyRs;
45 |
46 | @BeforeEach
47 | public void setUp() throws Exception {
48 |
49 | System.out.println("Setting up...");
50 |
51 | when(mockConfig.getSchema()).thenReturn("such-schema");
52 | when(mockConnection.getMetaData()).thenReturn(mockDbMetaData);
53 |
54 | when(mockDbMetaData.getTables(any(), any(), any(), any())).thenReturn(mockTableRs);
55 | when(mockTableRs.next()).thenReturn(Boolean.TRUE).thenReturn(false);
56 | when(mockTableRs.getString("TABLE_NAME")).thenReturn("such-table");
57 |
58 | when(mockDbMetaData.getPrimaryKeys(any(), any(), any())).thenReturn(emptyRs);
59 | when(mockDbMetaData.getImportedKeys(any(), any(), any())).thenReturn(emptyRs);
60 | when(emptyRs.next()).thenReturn(false);
61 |
62 | when(mockDbMetaData.getColumns(any(), any(), any(), any())).thenReturn(mockColumnRs);
63 | when(mockColumnRs.next()).thenReturn(Boolean.TRUE).thenReturn(Boolean.FALSE);
64 | when(mockColumnRs.getString("COLUMN_NAME")).thenReturn("such-column");
65 | when(mockColumnRs.getInt("COLUMN_SIZE")).thenReturn(1337);
66 | when(mockColumnRs.getInt("DATA_TYPE")).thenReturn(Types.CHAR);
67 | when(mockSqlTypeMap.getTypeFrom(Types.CHAR)).thenReturn(String.class);
68 | }
69 |
70 | @Test
71 | public void testGetMetaData() throws Throwable {
72 |
73 | MetaData test = new MetaData(mockConfig, mockConnection, mockSqlTypeMap);
74 | List ret = test.getMetaData();
75 |
76 | verify(mockDbMetaData, times(1)).getTables(isNull(), eq("such-schema"), isNull(), eq(new String[] { "TABLE" }));
77 | verify(mockTableRs, times(2)).next();
78 | verify(mockDbMetaData, times(1)).getColumns(isNull(), eq("such-schema"), eq("such-table"), isNull());
79 | verify(mockColumnRs, times(2)).next();
80 | verify(mockColumnRs).getString(eq("COLUMN_NAME"));
81 | verify(mockColumnRs).getInt(eq("COLUMN_SIZE"));
82 | verify(mockColumnRs).getInt(eq("DATA_TYPE"));
83 |
84 | assertNotNull(ret);
85 | assertEquals(1, ret.size());
86 | assertNotNull(ret.get(0));
87 | assertEquals("such-schema", ret.get(0).getSchemaName());
88 | assertEquals("such-table", ret.get(0).getTableName());
89 |
90 | assertNotNull(ret.get(0).getColumns());
91 | assertEquals(1, ret.get(0).getColumns().size());
92 |
93 | ColumnMetaData col = ret.get(0).getColumn(1);
94 | assertNotNull(col);
95 | assertEquals("such-column", col.getColumnName());
96 | assertSame(col, ret.get(0).getColumn("such-column"));
97 | assertEquals(1337, col.getColumnSize());
98 | assertEquals(String.class, col.getColumnType());
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/test/java/com/strider/datadefender/database/sqlbuilder/SqlBuilderTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * To change this license header, choose License Headers in Project Properties.
3 | * To change this template file, choose Tools | Templates
4 | * and open the template in the editor.
5 | */
6 | package com.strider.datadefender.database.sqlbuilder;
7 |
8 | import com.strider.datadefender.DbConfig;
9 | import org.junit.jupiter.api.Test;
10 | import org.junit.jupiter.api.extension.ExtendWith;
11 | import org.mockito.junit.jupiter.MockitoExtension;
12 | import org.mockito.Mock;
13 |
14 | import static org.junit.jupiter.api.Assertions.*;
15 | import static org.mockito.Mockito.*;
16 |
17 | /**
18 | *
19 | * @author Zaahid Bateson
20 | */
21 | @ExtendWith(MockitoExtension.class)
22 | public class SqlBuilderTest {
23 |
24 | @Mock
25 | DbConfig mockConfig;
26 |
27 | @Test
28 | public void testBuildSelectWithLimit() {
29 | SqlBuilder test = new SqlBuilder(mockConfig);
30 | String sql = test.buildSelectWithLimit("toost", 1);
31 | assertEquals("toost LIMIT 1", sql);
32 | }
33 |
34 | @Test
35 | public void testBuildSelectWithZeroLimit() {
36 | SqlBuilder test = new SqlBuilder(mockConfig);
37 | String sql = test.buildSelectWithLimit("toost", 0);
38 | assertEquals("toost", sql);
39 | }
40 |
41 | @Test
42 | public void testPrefixSchema() {
43 | when(mockConfig.getSchema()).thenReturn("scheems");
44 | SqlBuilder test = new SqlBuilder(mockConfig);
45 | String tableName = test.prefixSchema("tablas");
46 | assertEquals("scheems.tablas", tableName);
47 | }
48 |
49 | @Test
50 | public void testPrefixBlankSchema() {
51 | when(mockConfig.getSchema()).thenReturn(null).thenReturn("").thenReturn(" ");
52 | SqlBuilder test = new SqlBuilder(mockConfig);
53 | assertEquals("tablas", test.prefixSchema("tablas"));
54 | assertEquals("tablas", test.prefixSchema("tablas"));
55 | assertEquals("tablas", test.prefixSchema("tablas"));
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/test/java/com/strider/datadefender/functions/UtilsTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.functions;
17 |
18 | import com.strider.datadefender.anonymizer.DatabaseAnonymizerException;
19 |
20 | import org.junit.jupiter.api.Test;
21 | import static org.junit.jupiter.api.Assertions.*;
22 |
23 | /**
24 | * @author Armenak Grigoryan
25 | */
26 | public class UtilsTest {
27 |
28 | /**
29 | * Initializes logger
30 | */
31 | private final String FULL_CLASS_NAME = "com.strider.datadefender.anonymizer.functions.Core";
32 | private final String EXPECTED_RESULTS_1 = "com.strider.datadefender.anonymizer.functions";
33 | private final String EXPECTED_RESULTS_2 = "Core";
34 |
35 | @Test
36 | public void testGetClassName() throws Exception {
37 | System.out.println("Executing testGetClassName...");
38 | final String result = Utils.getClassName(FULL_CLASS_NAME);
39 | assertEquals(EXPECTED_RESULTS_1, result);
40 | }
41 |
42 | @Test
43 | public void testGetMethodName() throws DatabaseAnonymizerException {
44 | System.out.println("Executing testGetMethodName...");
45 | final String result = Utils.getMethodName(FULL_CLASS_NAME);
46 | assertEquals(EXPECTED_RESULTS_2, result);
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/src/test/java/com/strider/datadefender/utils/EncoderTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014-2021, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 |
17 | package com.strider.datadefender.utils;
18 |
19 |
20 | import java.io.IOException;
21 |
22 | import lombok.extern.log4j.Log4j2;
23 |
24 | import org.junit.jupiter.api.AfterEach;
25 | import org.junit.jupiter.api.AfterAll;
26 | import org.junit.jupiter.api.BeforeEach;
27 | import org.junit.jupiter.api.BeforeAll;
28 | import org.junit.jupiter.api.Test;
29 | import static org.junit.jupiter.api.Assertions.*;
30 |
31 | import com.strider.datadefender.anonymizer.functions.Bio;
32 | import java.io.BufferedReader;
33 | import java.io.File;
34 | import java.io.FileReader;
35 |
36 | /**
37 | *
38 | * @author strider
39 | */
40 | @Log4j2
41 | public class EncoderTest {
42 |
43 | private static String hash = null;
44 |
45 | /**
46 | * Static block to load hash string for "salting" the encryption
47 | */
48 | static {
49 | String file = System.getProperty("user.dir") + "/hash.txt";
50 | File f = new File(file);
51 | try {
52 | BufferedReader reader = new BufferedReader(new FileReader(f));
53 | hash = reader.readLine();
54 | reader.close();
55 | } catch (IOException ex) {
56 | log.error("Problem finding file hash.txt", ex);
57 | }
58 | }
59 |
60 |
61 | public EncoderTest() {
62 | }
63 |
64 | @BeforeAll
65 | public static void setUpClass() {
66 | }
67 |
68 | @AfterAll
69 | public static void tearDownClass() {
70 | }
71 |
72 | @BeforeEach
73 | public void setUp() {
74 | }
75 |
76 | @AfterEach
77 | public void tearDown() {
78 | }
79 |
80 | /**
81 | * Test of encode method, of class Encoder.
82 | */
83 | @Test
84 | public void testRandomFirstNameWithParameter() {
85 | log.debug("Testing enocode() method");
86 |
87 | String originalValue = "Armenak Grigoryan";
88 |
89 | String encryptedValue = new Bio().randomFirstName(originalValue);
90 | log.debug("Encrypted value=" + encryptedValue);
91 |
92 | String decryptedValue = new Encoder().decrypt(encryptedValue, hash);
93 | log.debug("Decrypted value=" + decryptedValue);
94 |
95 | assertEquals(originalValue, decryptedValue);
96 | }
97 |
98 | @Test
99 | public void testRandomFirstNameWithoutParameter() {
100 | log.debug("Testing randomFirstName() method");
101 |
102 | String randomFirstName = "";
103 | try {
104 | randomFirstName = new Bio().randomFirstName();
105 | } catch (IOException ex) {
106 | log.error("Problem generating random first name", ex);
107 | }
108 |
109 | assertTrue(randomFirstName != null);
110 | }
111 |
112 | }
113 |
--------------------------------------------------------------------------------
/src/test/java/com/strider/datadefender/utils/LikeMatcherTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014, Armenak Grigoryan, and individual contributors as indicated
3 | * by the @authors tag. See the copyright.txt in the distribution for a
4 | * full listing of individual contributors.
5 | *
6 | * This is free software; you can redistribute it and/or modify it
7 | * under the terms of the GNU Lesser General Public License as
8 | * published by the Free Software Foundation; either version 2.1 of
9 | * the License, or (at your option) any later version.
10 | *
11 | * This software is distributed in the hope that it will be useful,
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 | * Lesser General Public License for more details.
15 | */
16 | package com.strider.datadefender.utils;
17 |
18 | import org.junit.jupiter.api.Test;
19 | import static org.junit.jupiter.api.Assertions.*;
20 |
21 | /**
22 | *
23 | * @author Zaahid Bateson
24 | */
25 | public class LikeMatcherTest {
26 | private static final String TEST_NAME_1 = "ZaahiD";
27 |
28 | @Test
29 | public void testMatchingAtBeginning() {
30 | System.out.println("Testing match begginning of string");
31 |
32 | final LikeMatcher matcher = new LikeMatcher("%hid");
33 |
34 | assertTrue(matcher.matches(TEST_NAME_1));
35 | assertTrue(matcher.matches("aaHID"));
36 | assertTrue(matcher.matches("HID"));
37 | assertFalse(matcher.matches("Zaahid is not here"));
38 | assertFalse(matcher.matches("hiding away"));
39 | }
40 |
41 | @Test
42 | public void testMatchingAtEnd() {
43 | System.out.println("Testing match at end of string");
44 |
45 | final LikeMatcher matcher = new LikeMatcher("za%");
46 |
47 | assertTrue(matcher.matches(TEST_NAME_1));
48 | assertTrue(matcher.matches("ZAA"));
49 | assertTrue(matcher.matches("za"));
50 | assertFalse(matcher.matches("Not Zaahid"));
51 | assertFalse(matcher.matches("Some Za"));
52 | }
53 |
54 | @Test
55 | public void testMixedMatcher() {
56 | System.out.println("Testing match with a mix of '%', '?', and '_'");
57 |
58 | final LikeMatcher matcher = new LikeMatcher("%Z_?h?d%");
59 |
60 | assertTrue(matcher.matches(TEST_NAME_1));
61 | assertFalse(matcher.matches("ZaHID"));
62 | assertFalse(matcher.matches("Zhd"));
63 | assertTrue(matcher.matches("Zaphod"));
64 | assertTrue(matcher.matches("Zaahid really is Zaphod"));
65 | assertTrue(matcher.matches("Yes, Zaahid is here"));
66 | }
67 |
68 | @Test
69 | public void testMultiMatcher() {
70 | System.out.println("Testing match with multiple %'s");
71 |
72 | final LikeMatcher matcher = new LikeMatcher("Z%h%d");
73 |
74 | assertTrue(matcher.matches(TEST_NAME_1));
75 | assertTrue(matcher.matches("ZaHID"));
76 | assertTrue(matcher.matches("Zhd"));
77 | assertFalse(matcher.matches("Zaahid is not here"));
78 | assertFalse(matcher.matches("Someone is hiding Zaahid"));
79 | }
80 |
81 | @Test
82 | public void testSingleCharMatcher() {
83 | System.out.println("Testing match with '?' and '_'");
84 |
85 | final LikeMatcher matcher = new LikeMatcher("Z_?h?d");
86 |
87 | assertTrue(matcher.matches(TEST_NAME_1));
88 | assertFalse(matcher.matches("ZaHID"));
89 | assertFalse(matcher.matches("Zhd"));
90 | assertTrue(matcher.matches("Zaphod"));
91 | }
92 | }
93 |
94 |
95 | //~ Formatted by Jindent --- http://www.jindent.com
96 |
--------------------------------------------------------------------------------
/src/test/java/com/strider/datadefender/utils/XegerTest.java:
--------------------------------------------------------------------------------
1 | package com.strider.datadefender.utils;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import static org.junit.jupiter.api.Assertions.*;
5 |
6 | /**
7 | *
8 | * @author strider
9 | */
10 | public class XegerTest {
11 |
12 | private static final String REGEXP_1 = "[ab]{4,6}c";
13 | private static final String REGEXP_2 = "[0-9]{3}-[0-9]{3}-[0-9]{3}";
14 |
15 | /**
16 | * Test of generate method, of class Xeger.
17 | */
18 | @Test
19 | public void testGenerate() {
20 | System.out.println("Generate string");
21 |
22 | final Xeger instance = new Xeger(REGEXP_1);
23 |
24 | for (int i = 0; i < 100; i++) {
25 | final String text = instance.generate();
26 |
27 | assertTrue(text.matches(REGEXP_1));
28 | }
29 | }
30 |
31 | /**
32 | * Test of generate method, of class Xeger.
33 | */
34 | @Test
35 | public void testGenerateSIN() {
36 | System.out.println("Generate SIN");
37 |
38 | final Xeger instance = new Xeger(REGEXP_2);
39 | final String text = instance.generate();
40 |
41 | System.out.println(text);
42 | assertTrue(text.matches(REGEXP_2));
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/test/resources/AppPropertiesTest.properties:
--------------------------------------------------------------------------------
1 | # sample test properties file
2 | xxx=yyy
--------------------------------------------------------------------------------
/src/test/resources/Requirement-H2DB-DG.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Test H2DB Client
4 | 1.0
5 |
6 |
7 |
8 |
9 | com.strider.datadefender.functions.CoreFunctions.randomFirstName
10 |
11 |
12 |
13 |
14 |
15 | com.strider.datadefender.functions.CoreFunctions.randomFirstName
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/test/resources/Requirement-H2DB.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Test H2DB Client
4 | 1.0
5 |
6 |
7 |
8 |
9 | com.strider.datadefender.functions.CoreFunctions.randomFirstName
10 |
11 |
12 |
13 |
14 |
15 | com.strider.datadefender.functions.CoreFunctions.randomLastName
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/test/resources/core-test.txt:
--------------------------------------------------------------------------------
1 | toost
2 | bloost
3 |
--------------------------------------------------------------------------------
/src/test/resources/log4j2.properties:
--------------------------------------------------------------------------------
1 | status=error
2 | dest=err
3 |
4 | appender.console.type=Console
5 | appender.console.name=STDOUT
6 | appender.console.layout.type=PatternLayout
7 | appender.console.layout.pattern=%d{HH:mm:ss} %c{2.} [%p] - %m%n
8 |
9 | rootLogger.level=debug
10 | rootLogger.appenderRef.console.ref=STDOUT
11 |
--------------------------------------------------------------------------------
/src/test/resources/names.txt:
--------------------------------------------------------------------------------
1 | mysql
2 | mssql
3 | oracle
4 | h2db
--------------------------------------------------------------------------------