├── CONTRIBUTING.md ├── LICENSE.txt ├── NOTICE.txt ├── README.md ├── pom.xml └── src ├── main └── java │ └── com │ └── acciente │ └── oacc │ ├── AccessControlContext.java │ ├── AuthenticationException.java │ ├── AuthenticationProvider.java │ ├── AuthorizationException.java │ ├── Credentials.java │ ├── CredentialsException.java │ ├── DomainCreatePermission.java │ ├── DomainCreatePermissions.java │ ├── DomainPermission.java │ ├── DomainPermissions.java │ ├── IncorrectCredentialsException.java │ ├── InvalidCredentialsException.java │ ├── NotAuthenticatedException.java │ ├── NotAuthorizedException.java │ ├── OaccException.java │ ├── PasswordCredentials.java │ ├── Resource.java │ ├── ResourceClassInfo.java │ ├── ResourceCreatePermission.java │ ├── ResourceCreatePermissions.java │ ├── ResourcePermission.java │ ├── ResourcePermissions.java │ ├── Resources.java │ ├── SysPermission.java │ ├── UnsupportedCredentialsException.java │ ├── encryptor │ ├── PasswordEncryptor.java │ ├── TransitioningPasswordEncryptor.java │ ├── bcrypt │ │ ├── BCryptPasswordEncryptor.java │ │ └── PasswordEncoderDecoder.java │ └── jasypt │ │ ├── DecodedPassword.java │ │ ├── JasyptPasswordEncryptor.java │ │ ├── LegacyJasyptPasswordEncryptor.java │ │ ├── PasswordEncoderDecoder.java │ │ └── StandardByteDigesterPool.java │ ├── normalizer │ ├── TextNormalizer.java │ ├── icu4j │ │ ├── ICU4Jv26TextNormalizer.java │ │ ├── ICU4Jv46TextNormalizer.java │ │ └── Normalizer2Factory.java │ └── jdk │ │ └── JDKTextNormalizer.java │ └── sql │ ├── SQLAccessControlContextFactory.java │ ├── SQLAccessControlSystemInitializer.java │ ├── SQLDialect.java │ ├── SQLProfile.java │ └── internal │ ├── PasswordUtils.java │ ├── ResourceClassInternalInfo.java │ ├── SQLAccessControlContext.java │ ├── SQLAccessControlSystemInitializer.java │ ├── SQLPasswordAuthenticationProvider.java │ ├── SchemaNameValidator.java │ ├── encryptor │ └── PasswordEncryptors.java │ └── persister │ ├── CommonDomainPersister.java │ ├── CommonGrantDomainCreatePermissionPostCreateSysPersister.java │ ├── CommonGrantDomainCreatePermissionSysPersister.java │ ├── CommonGrantDomainPermissionSysPersister.java │ ├── CommonGrantGlobalResourcePermissionPersister.java │ ├── CommonGrantGlobalResourcePermissionSysPersister.java │ ├── CommonGrantResourceCreatePermissionPostCreatePersister.java │ ├── CommonGrantResourceCreatePermissionPostCreateSysPersister.java │ ├── CommonGrantResourceCreatePermissionSysPersister.java │ ├── CommonGrantResourcePermissionPersister.java │ ├── CommonGrantResourcePermissionSysPersister.java │ ├── CommonResourcePersister.java │ ├── DialectSpecificSQLGenerator.java │ ├── DomainPersister.java │ ├── GrantDomainCreatePermissionPostCreateSysPersister.java │ ├── GrantDomainCreatePermissionSysPersister.java │ ├── GrantDomainPermissionSysPersister.java │ ├── GrantGlobalResourcePermissionPersister.java │ ├── GrantGlobalResourcePermissionSysPersister.java │ ├── GrantResourceCreatePermissionPostCreatePersister.java │ ├── GrantResourceCreatePermissionPostCreateSysPersister.java │ ├── GrantResourceCreatePermissionSysPersister.java │ ├── GrantResourcePermissionPersister.java │ ├── GrantResourcePermissionSysPersister.java │ ├── NonRecursiveDomainPersister.java │ ├── NonRecursiveGrantDomainCreatePermissionPostCreateSysPersister.java │ ├── NonRecursiveGrantDomainCreatePermissionSysPersister.java │ ├── NonRecursiveGrantDomainPermissionSysPersister.java │ ├── NonRecursiveGrantGlobalResourcePermissionPersister.java │ ├── NonRecursiveGrantGlobalResourcePermissionSysPersister.java │ ├── NonRecursiveGrantResourceCreatePermissionPostCreatePersister.java │ ├── NonRecursiveGrantResourceCreatePermissionPostCreateSysPersister.java │ ├── NonRecursiveGrantResourceCreatePermissionSysPersister.java │ ├── NonRecursiveGrantResourcePermissionPersister.java │ ├── NonRecursiveGrantResourcePermissionSysPersister.java │ ├── NonRecursivePersisterHelper.java │ ├── NonRecursiveResourcePersister.java │ ├── Persister.java │ ├── RecursiveDomainPersister.java │ ├── RecursiveGrantDomainCreatePermissionPostCreateSysPersister.java │ ├── RecursiveGrantDomainCreatePermissionSysPersister.java │ ├── RecursiveGrantDomainPermissionSysPersister.java │ ├── RecursiveGrantGlobalResourcePermissionPersister.java │ ├── RecursiveGrantGlobalResourcePermissionSysPersister.java │ ├── RecursiveGrantResourceCreatePermissionPostCreatePersister.java │ ├── RecursiveGrantResourceCreatePermissionPostCreateSysPersister.java │ ├── RecursiveGrantResourceCreatePermissionSysPersister.java │ ├── RecursiveGrantResourcePermissionPersister.java │ ├── RecursiveGrantResourcePermissionSysPersister.java │ ├── RecursiveResourcePersister.java │ ├── ResourceClassPermissionPersister.java │ ├── ResourceClassPersister.java │ ├── ResourcePasswordPersister.java │ ├── ResourcePersister.java │ ├── SQLConnection.java │ ├── SQLPasswordStrings.java │ ├── SQLResult.java │ ├── SQLStatement.java │ ├── SQLStrings.java │ └── id │ ├── DomainId.java │ ├── Id.java │ ├── ResourceClassId.java │ ├── ResourceId.java │ └── ResourcePermissionId.java └── test ├── java └── com │ └── acciente │ └── oacc │ ├── TestAccessControlBase.java │ ├── TestAccessControl_TransitioningPasswordEncryptor.java │ ├── TestAccessControl_assertDomainCreatePermissions.java │ ├── TestAccessControl_assertDomainPermissions.java │ ├── TestAccessControl_assertGlobalResourcePermissions.java │ ├── TestAccessControl_assertPostCreateDomainPermissions.java │ ├── TestAccessControl_assertPostCreateResourcePermissions.java │ ├── TestAccessControl_assertResourceCreatePermissions.java │ ├── TestAccessControl_assertResourcePermissions.java │ ├── TestAccessControl_authenticate.java │ ├── TestAccessControl_createAuthenticatableResource.java │ ├── TestAccessControl_createDomain.java │ ├── TestAccessControl_createResource.java │ ├── TestAccessControl_createResourceClass.java │ ├── TestAccessControl_createResourcePermission.java │ ├── TestAccessControl_customAuthenticationProvider.java │ ├── TestAccessControl_deleteDomain.java │ ├── TestAccessControl_deleteResource.java │ ├── TestAccessControl_getAccessorResourcesByResourcePermissions.java │ ├── TestAccessControl_getAuthenticatedResource.java │ ├── TestAccessControl_getDomainCreatePermissions.java │ ├── TestAccessControl_getDomainDescendants.java │ ├── TestAccessControl_getDomainNameByResource.java │ ├── TestAccessControl_getDomainPermissions.java │ ├── TestAccessControl_getEffectiveDomainCreatePermissions.java │ ├── TestAccessControl_getEffectiveDomainPermissions.java │ ├── TestAccessControl_getEffectiveGlobalResourcePermissions.java │ ├── TestAccessControl_getEffectiveResourceCreatePermissions.java │ ├── TestAccessControl_getEffectiveResourcePermissions.java │ ├── TestAccessControl_getGlobalResourcePermissions.java │ ├── TestAccessControl_getResourceClassInfo.java │ ├── TestAccessControl_getResourceClassInfoByResource.java │ ├── TestAccessControl_getResourceClassNames.java │ ├── TestAccessControl_getResourceCreatePermissions.java │ ├── TestAccessControl_getResourcePermissionNames.java │ ├── TestAccessControl_getResourcePermissions.java │ ├── TestAccessControl_getResourcesByResourcePermissions.java │ ├── TestAccessControl_getResourcesByResourcePermissionsAndDomain.java │ ├── TestAccessControl_getSessionResource.java │ ├── TestAccessControl_grantDomainCreatePermissions.java │ ├── TestAccessControl_grantDomainPermissions.java │ ├── TestAccessControl_grantGlobalResourcePermissions.java │ ├── TestAccessControl_grantResourceCreatePermissions.java │ ├── TestAccessControl_grantResourcePermissions.java │ ├── TestAccessControl_hasDomainCreatePermissions.java │ ├── TestAccessControl_hasDomainPermissions.java │ ├── TestAccessControl_hasGlobalResourcePermissions.java │ ├── TestAccessControl_hasPostCreateDomainPermissions.java │ ├── TestAccessControl_hasPostCreateResourcePermissions.java │ ├── TestAccessControl_hasResourceCreatePermissions.java │ ├── TestAccessControl_hasResourcePermissions.java │ ├── TestAccessControl_impersonate.java │ ├── TestAccessControl_revokeDomainCreatePermissions.java │ ├── TestAccessControl_revokeDomainPermissions.java │ ├── TestAccessControl_revokeGlobalResourcePermissions.java │ ├── TestAccessControl_revokeResourceCreatePermissions.java │ ├── TestAccessControl_revokeResourcePermissions.java │ ├── TestAccessControl_serialize.java │ ├── TestAccessControl_setCredentials.java │ ├── TestAccessControl_setDomainCreatePermissions.java │ ├── TestAccessControl_setDomainPermissions.java │ ├── TestAccessControl_setExternalId.java │ ├── TestAccessControl_setGlobalResourcePermissions.java │ ├── TestAccessControl_setResourceCreatePermissions.java │ ├── TestAccessControl_setResourcePermissions.java │ ├── TestAccessControl_unauthenticate.java │ ├── TestAccessControl_unauthenticatedApiCalls.java │ ├── TestAccessControl_unimpersonate.java │ ├── TestDomainCreatePermission.java │ ├── TestDomainPermission.java │ ├── TestResource.java │ ├── TestResourceCreatePermission.java │ ├── TestResourcePermission.java │ ├── TestSQLAccessControlContextFactory.java │ ├── encryptor │ ├── TransitioningPasswordEncryptorTest.java │ ├── bcrypt │ │ ├── BCryptPasswordEncryptorTest.java │ │ └── PasswordEncoderDecoderTest.java │ └── jasypt │ │ ├── JasyptPasswordEncryptorTest.java │ │ ├── LegacyJasyptPasswordEncryptorTest.java │ │ ├── PasswordEncoderDecoderTest.java │ │ └── StandardByteDigesterPoolTest.java │ ├── helper │ ├── CaseSensitiveChecker.java │ ├── DbBase.java │ ├── OACC_Domain.java │ ├── OACC_Grant_DomCreatePerm_PostCreate_Sys.java │ ├── OACC_Grant_DomCreatePerm_Sys.java │ ├── OACC_Grant_DomPerm_Sys.java │ ├── OACC_Grant_Global_ResPerm.java │ ├── OACC_Grant_Global_ResPerm_Sys.java │ ├── OACC_Grant_ResCreatePerm.java │ ├── OACC_Grant_ResCreatePerm_PostCreate_Sys.java │ ├── OACC_Grant_ResPerm.java │ ├── OACC_Grant_ResPerm_Sys.java │ ├── OACC_Resource.java │ ├── OACC_ResourceClass.java │ ├── OACC_ResourceClassPermission.java │ ├── OACC_ResourcePassword.java │ ├── SQLAccessControlSystemResetUtil.java │ ├── TestConfigLoader.java │ └── Test_OACC_Resource.java │ ├── normalizer │ ├── TextNormalizerInstanceTest.java │ ├── TextNormalizerTest.java │ └── icu4j │ │ ├── ICU4Jv26TextNormalizerParityTest.java │ │ ├── ICU4Jv26TextNormalizerWorstCaseExpansionTest.java │ │ ├── ICU4Jv46TextNormalizerParityTest.java │ │ └── ICU4Jv46TextNormalizerWorstCaseExpansionTest.java │ └── sql │ ├── TestSQLAccessControlSystemInitializer.java │ └── TestSchemaNameValidator.java └── resources ├── dbconfig_db2.properties ├── dbconfig_hsqldb.properties ├── dbconfig_mariadb.properties ├── dbconfig_mysql.properties ├── dbconfig_oracle.properties ├── dbconfig_postgresql.properties ├── dbconfig_sqlite.properties └── dbconfig_sqlserver.properties /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## So you'd like to contribute to OACC… 2 | 3 | --- 4 | 5 | Thanks - that's awesome! After all, the OACC framework is an open-source project that welcomes and encourages contributions from community members like you. 6 | 7 | To make this process as effortless as possible, please take a minute and read this guide before contributing. 8 | 9 | Thanks again - you rock! 10 | 11 | ### Reporting Bugs 12 | - Report bugs as issues on GitHub _- after first searching for duplicates -_ and include detailed steps for reproduction (version, DBMS, code) 13 | - For questions about possible bugs or documentation-related issues, please ask on the [OACC mailing list](https://groups.google.com/forum/#!forum/oacc-users) 14 | 15 | ### Contributing Code 16 | - For API changes, new features, elaborate enhancements or radical refactorings, please discuss on the [OACC mailing list](https://groups.google.com/forum/#!forum/oacc-users) first 17 | - When in doubt or for any questions, please ask on the [OACC mailing list](https://groups.google.com/forum/#!forum/oacc-users) before investing a lot of your time 18 | - You will need to fill out the [Acciente Contributor's License Agreement (CLA)](https://github.com/acciente/acciente-cla) before we can accept and merge your code contribution(s) 19 | - In general, please make sure to: 20 | + add a test for any new feature/enhancement 21 | + run the test suite for any changes 22 | + apply the boy-scout rule: _"Leave the code cleaner than you found it"_ 23 | + make an effort to adhere to the existing coding style (ask on the [OACC mailing list](https://groups.google.com/forum/#!forum/oacc-users) if you can't determine it) 24 | + update the existing documentation (javadocs & comments) if you change the API (did you discuss this on the mailing list first?) 25 | + include the Acciente copyright notice at the top of new files 26 | + properly scope your commits, and include meaningful commit messages in a format that answers why a change was made and/or how it addressed an issue 27 | 28 | ### Writing Documentation 29 | - To improve the existing documentation or to create new guides or tutorials, please submit your documentations to the [OACC mailing list](https://groups.google.com/forum/#!forum/oacc-users) 30 | - Be sure to share your links to any external tutorials, articles, blog posts, best practices, etc. on the [OACC mailing list](https://groups.google.com/forum/#!forum/oacc-users) -------------------------------------------------------------------------------- /NOTICE.txt: -------------------------------------------------------------------------------- 1 | Acciente OACC 2 | Copyright 2009-2018, Acciente LLC 3 | 4 | This product includes software developed at 5 | Acciente LLC (http://acciente.com/). -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | OACC Java Application Security Framework 2 | ======================================== 3 | 4 | ## What is OACC? 5 | 6 | OACC - pronounced _[oak]_ - is a fully featured API to both **enforce** and **manage** your application's authentication and authorization needs. 7 | 8 | In a nutshell, OACC provides _permission-based_ authorization services and allows your application to enforce security by answering the question: 9 | 10 | Is entity 'A' allowed to perform action 'p' on entity 'B'? 11 | 12 | ## Features 13 | 14 | - **Fully implemented API** 15 | All the functionality to manage your application's security model, out of the box. 16 | 17 | - **Single access-control paradigm** 18 | Always operate at the resource level. Manage permissions exclusively between resources. 19 | 20 | - **Flexible security model** 21 | Secure any operation between your domain objects and the actors on them. 22 | 23 | - **Permission delegation** 24 | Authorize subjects to delegate their permissions to others with _GRANT OPTIONS_. 25 | 26 | - **Identity delegation** 27 | Authorize an authenticated subject to securely "impersonate" another subject. 28 | 29 | - **Efficient query methods** 30 | Find resources by permission with efficient symmetric query methods. 31 | 32 | Learn more about all of OACC's authorization and authentication features on the [Features page](http://oaccframework.org/oacc-features.html) of the project website. 33 | 34 | ## License 35 | 36 | OACC is open source software released under the commercial friendly [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0). 37 | 38 | ## Supported Environments 39 | 40 | OACC persists all security relationships in database tables and currently supports the following databases: 41 | 42 | - IBM DB2 10.5 43 | - Microsoft SQL Server 12.0 (2014) 44 | - Oracle 11g R2 45 | - PostgreSQL 9.3 46 | - HSQLDB 2.3 47 | - MySQL 5.6 / MariaDB 10.0 48 | - SQLite 3.8 49 | 50 | OACC is compatible with Java™ SE 7 (Java™ version 1.7.0), or higher. 51 | 52 | ## Get Started 53 | 54 | The easiest way to include the latest OACC release into your project is to declare the following Maven coordinates as a dependency in your POM file: 55 | 56 | ```xml 57 | 58 | com.acciente.oacc 59 | acciente-oacc 60 | 2.0.0 61 | 62 | ``` 63 | 64 | To _install, configure and initialize_ the **OACC database**, please refer to the [Get Started Tutorial](http://oaccframework.org/getting-started-tutorial.html) on the project website. 65 | 66 | The [_SecureTodo_ sample application](http://oaccframework.org/secure-todo-example.html) illustrates how to integrate OACC into a Java application and how to address several real-world authorization scenarios. The writeup is also available in the [Github repository](https://github.com/acciente/oacc-example-securetodo) that contains the full source code. 67 | 68 | ## Documentation 69 | 70 | You can find more information about OACC, including the latest Javadocs, releases, and tutorials on the project website: 71 | [oaccframework.org](http://oaccframework.org). 72 | 73 | ## About Acciente 74 | 75 | [Acciente, LLC](http://www.acciente.com) is a software company located in Scottsdale, Arizona specializing in systems architecture and software design for medium to large scale software projects. 76 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/AuthenticationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc; 19 | 20 | public class AuthenticationException extends OaccException { 21 | private static final long serialVersionUID = 1L; 22 | 23 | public AuthenticationException(String message) { 24 | super(message); 25 | } 26 | 27 | public AuthenticationException(String message, Throwable cause) { 28 | super(message, cause); 29 | } 30 | 31 | public AuthenticationException(Throwable cause) { 32 | super(cause); 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/AuthenticationProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc; 19 | 20 | /** 21 | * Provides the mechanism to authenticate a resource based on specified credentials and to update those credentials. 22 | *

23 | * An application can provide an implementation of this interface to provide a custom authentication 24 | * mechanism for resources. Such a custom authentication provider is free to use password, biometric or 25 | * any other means for authentication. 26 | */ 27 | public interface AuthenticationProvider { 28 | /** 29 | * Authenticates the specified resource using the supplied credentials. 30 | * 31 | * @param resource the resource to be authenticated 32 | * @param credentials the credentials to authenticate the resource 33 | * @throws com.acciente.oacc.IncorrectCredentialsException if authentication failed due to incorrect credentials 34 | */ 35 | void authenticate(Resource resource, Credentials credentials); 36 | 37 | /** 38 | * Verifies that the specified resource is authenticated. 39 | *

40 | * The authentication provider implementation should throw a NotAuthenticatedException if the 41 | * specified resource is currently NOT authenticated, or should throw an UnsupportedOperationException 42 | * if it does not support reporting of the authentication status without credentials. 43 | * 44 | * @param resource the resource to be authenticated 45 | */ 46 | void authenticate(Resource resource); 47 | 48 | /** 49 | * Authenticates the specified resource using the supplied credentials. 50 | *

51 | * This authentication method requires a custom authentication provider and is not supported by the built-in 52 | * authentication provider. It is intended for use where the resource identification is embedded in the credentials, 53 | * such as in authentication protocols using encrypted authentication tokens. When using this method the custom 54 | * authentication provider must return the resource to OACC from the custom authentication provider implementation. 55 | * 56 | * @param credentials the credentials to authenticate the resource 57 | * @throws com.acciente.oacc.IncorrectCredentialsException if authentication failed due to incorrect credentials 58 | */ 59 | Resource authenticate(Credentials credentials); 60 | 61 | /** 62 | * Checks if the the authentication credentials are valid for the specified resource class and domain. 63 | *

64 | * This method may check if the credentials satisfy the minimum strength requirements, for example. 65 | * 66 | * @param resourceClassName the resource class for which to validate the specified credentials 67 | * @param domainName the domain for which to validate the specified credentials 68 | * @param credentials the authentication credentials to validate 69 | * @throws com.acciente.oacc.InvalidCredentialsException if the credentials are invalid 70 | */ 71 | void validateCredentials(String resourceClassName, String domainName, Credentials credentials); 72 | 73 | /** 74 | * Sets (or resets) the authentication credentials of the specified resource. 75 | * 76 | * @param resource the resource for which the credentials should be set 77 | * @param credentials the new authentication credentials for the resource 78 | */ 79 | void setCredentials(Resource resource, Credentials credentials); 80 | 81 | /** 82 | * Removes the authentication credentials of the specified resource. 83 | * 84 | * @param resource the resource for which the credentials should be removed 85 | */ 86 | void deleteCredentials(Resource resource); 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/AuthorizationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc; 19 | 20 | public class AuthorizationException extends OaccException { 21 | private static final long serialVersionUID = 1L; 22 | 23 | public AuthorizationException(String message) { 24 | super(message); 25 | } 26 | 27 | public AuthorizationException(String message, Throwable cause) { 28 | super(message, cause); 29 | } 30 | 31 | public AuthorizationException(Throwable cause) { 32 | super(cause); 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/Credentials.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc; 19 | 20 | /** 21 | * This is the most general interface that is used to indicate that an object that contains OACC credentials. 22 | * The built-in {@link AuthenticationProvider} in OACC only supports the more specific {@link PasswordCredentials} 23 | * sub-interface of {@link Credentials}. Other custom implementations of Credentials must be paired with 24 | * an implementation of AuthenticationProvider that understands the respective implementation of the 25 | * Credentials interface. 26 | */ 27 | public interface Credentials { 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/CredentialsException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc; 19 | 20 | public class CredentialsException extends AuthenticationException { 21 | private static final long serialVersionUID = 1L; 22 | 23 | public CredentialsException(String message) { 24 | super(message); 25 | } 26 | 27 | public CredentialsException(String message, Throwable cause) { 28 | super(message, cause); 29 | } 30 | 31 | public CredentialsException(Throwable cause) { 32 | super(cause); 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/DomainPermission.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc; 19 | 20 | /** 21 | * The interface for the type of permission that governs domain management. 22 | *

23 | * A DomainPermission is the type of permission used to grant an accessor permission to manage 24 | * a domain. A DomainPermission is never application-defined, but is always a system permission; 25 | * the supported system permissions values are *SUPER-USER, *CREATE-CHILD-DOMAIN and *DELETE. 26 | *

27 | * To create an instance of this class use {@link DomainPermissions#getInstance(String)} or one 28 | * of its variants. 29 | */ 30 | public interface DomainPermission { 31 | /** 32 | * Determine if this is system permission. 33 | * 34 | * @return true if this is a system permission, false otherwise. 35 | */ 36 | boolean isSystemPermission(); 37 | 38 | /** 39 | * Retrieves the permission name. 40 | * 41 | * @return the name of the permission. 42 | */ 43 | String getPermissionName(); 44 | 45 | /** 46 | * Retrieve the id of a system permission. 47 | *

48 | * Applications should not use this id, but refer to the system permission by name instead. 49 | *

50 | * Note that if this is not a system permission an exception is thrown. 51 | * 52 | * @return the internal id of the system permission. Applications should not use this id. 53 | * @throws IllegalStateException if this method is called on a non-system permission. 54 | */ 55 | long getSystemPermissionId(); 56 | 57 | /** 58 | * Retrieves the value of the "grant option". 59 | * 60 | * @return true if this permission includes the privilege to be granted to others, false otherwise. 61 | */ 62 | boolean isWithGrantOption(); 63 | 64 | 65 | /** 66 | * Determines if this permission can be granted by a grantor holding the specified other permission. 67 | * 68 | * @param other another permission to compare with 69 | * @return true if this permission can be granted by a holder of the specified other permission, 70 | * false otherwise. 71 | */ 72 | boolean isGrantableFrom(DomainPermission other); 73 | 74 | /** 75 | * Compare this permission with the specified other permission for equality, but ignoring the grant option. 76 | * 77 | * @param other another permission to compare with 78 | * @return true if the specified other permission is equal to this permission ignoring the 79 | * value of the {@link #isWithGrantOption()} property. 80 | */ 81 | boolean equalsIgnoreGrantOption(Object other); 82 | 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/IncorrectCredentialsException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc; 19 | 20 | public class IncorrectCredentialsException extends CredentialsException { 21 | private static final long serialVersionUID = 1L; 22 | 23 | public IncorrectCredentialsException(String message) { 24 | super(message); 25 | } 26 | 27 | public IncorrectCredentialsException(String message, Throwable cause) { 28 | super(message, cause); 29 | } 30 | 31 | public IncorrectCredentialsException(Throwable cause) { 32 | super(cause); 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/InvalidCredentialsException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc; 19 | 20 | public class InvalidCredentialsException extends CredentialsException { 21 | private static final long serialVersionUID = 1L; 22 | 23 | public InvalidCredentialsException(String message) { 24 | super(message); 25 | } 26 | 27 | public InvalidCredentialsException(String message, Throwable cause) { 28 | super(message, cause); 29 | } 30 | 31 | public InvalidCredentialsException(Throwable cause) { 32 | super(cause); 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/NotAuthenticatedException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc; 19 | 20 | public class NotAuthenticatedException extends AuthorizationException { 21 | private static final long serialVersionUID = 1L; 22 | 23 | public NotAuthenticatedException(String message) { 24 | super(message); 25 | } 26 | 27 | public NotAuthenticatedException(String message, Throwable cause) { 28 | super(message, cause); 29 | } 30 | 31 | public NotAuthenticatedException(Throwable cause) { 32 | super(cause); 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/OaccException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc; 19 | 20 | public class OaccException extends RuntimeException { 21 | private static final long serialVersionUID = 1L; 22 | 23 | public OaccException(String message) { 24 | super(message); 25 | } 26 | 27 | public OaccException(String message, Throwable cause) { 28 | super(message, cause); 29 | } 30 | 31 | public OaccException(Throwable cause) { 32 | super(cause); 33 | } 34 | } -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/PasswordCredentials.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc; 19 | 20 | import java.util.Arrays; 21 | 22 | /** 23 | * This is a {@link Credentials} implementation that may be used by an {@link AuthenticationProvider} 24 | * that provides password-based authentication. The built-in {@link AuthenticationProvider} requires that the 25 | * {@link Credentials} object passed be an instance of this class. If you implement a custom password-based 26 | * {@link AuthenticationProvider}, it is recommended that you accept instances of this class, but you are 27 | * not required to. If you accept instances of this class it allows switching to your implementation from 28 | * the built-in implementation without any changes in the calling code. 29 | * . 30 | */ 31 | public abstract class PasswordCredentials implements Credentials { 32 | /** 33 | * Returns the password contained in this credentials instance 34 | * 35 | * @return a password as a char array 36 | */ 37 | public abstract char[] getPassword(); 38 | 39 | public static PasswordCredentials newInstance(char[] password) { 40 | return new Impl(password); 41 | } 42 | 43 | private static class Impl extends PasswordCredentials { 44 | private final char[] password; 45 | 46 | private Impl(char[] password) { 47 | this.password = password; 48 | } 49 | 50 | @Override 51 | public char[] getPassword() { 52 | return password; 53 | } 54 | 55 | @Override 56 | public boolean equals(Object other) { 57 | if (this == other) { 58 | return true; 59 | } 60 | if (other == null || getClass() != other.getClass()) { 61 | return false; 62 | } 63 | 64 | Impl impl = (Impl) other; 65 | 66 | return Arrays.equals(password, impl.password); 67 | } 68 | 69 | @Override 70 | public int hashCode() { 71 | return Arrays.hashCode(password); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/Resource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc; 19 | 20 | /** 21 | * A resource is the abstraction for a secured application object. 22 | *

23 | * A resource is created and associated with every object in the application that needs to have access control. 24 | * All security relationships for the application object are defined via its corresponding resource. 25 | * 26 | * To create a new resource use {@link AccessControlContext#createResource} 27 | * or one of its variants in {@link AccessControlContext}. 28 | * 29 | * To create a Resource instance using a previously persisted resource id use the 30 | * factory method {@link Resources#getInstance(long)}, or one of its siblings. 31 | */ 32 | public interface Resource { 33 | /** 34 | * Get the id of this resource. 35 | * 36 | * This id is typically persisted as an attribute of the application object that it is associated with. 37 | * @return The id of this resource. 38 | */ 39 | Long getId(); 40 | 41 | /** 42 | * Get the optional external id of this resource. 43 | * 44 | * The optional external id is any String representation that uniquely identifies a resource from the 45 | * application model and can be used as a surrogate to the {@link #getId() id} of this resource. 46 | * @return The external id of this resource. 47 | */ 48 | String getExternalId(); 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/ResourceClassInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc; 19 | 20 | import java.io.Serializable; 21 | 22 | public class ResourceClassInfo implements Serializable { 23 | private static final long serialVersionUID = 1L; 24 | 25 | private final String resourceClassName; 26 | private final boolean authenticatable; 27 | private final boolean unauthenticatedCreateAllowed; 28 | 29 | public ResourceClassInfo(String resourceClassName, 30 | boolean authenticatable, 31 | boolean unauthenticatedCreateAllowed) { 32 | this.resourceClassName = resourceClassName; 33 | this.authenticatable = authenticatable; 34 | this.unauthenticatedCreateAllowed = unauthenticatedCreateAllowed; 35 | } 36 | 37 | public String getResourceClassName() { 38 | return resourceClassName; 39 | } 40 | 41 | public boolean isAuthenticatable() { 42 | return authenticatable; 43 | } 44 | 45 | public boolean isUnauthenticatedCreateAllowed() { 46 | return unauthenticatedCreateAllowed; 47 | } 48 | 49 | @Override 50 | public boolean equals(Object other) { 51 | if (this == other) { 52 | return true; 53 | } 54 | if (other == null || getClass() != other.getClass()) { 55 | return false; 56 | } 57 | 58 | ResourceClassInfo otherResourceClassInfo = (ResourceClassInfo) other; 59 | 60 | if (authenticatable != otherResourceClassInfo.authenticatable) { 61 | return false; 62 | } 63 | if (unauthenticatedCreateAllowed != otherResourceClassInfo.unauthenticatedCreateAllowed) { 64 | return false; 65 | } 66 | if (!resourceClassName.equals(otherResourceClassInfo.resourceClassName)) { 67 | return false; 68 | } 69 | 70 | return true; 71 | } 72 | 73 | @Override 74 | public int hashCode() { 75 | int result = resourceClassName.hashCode(); 76 | result = 31 * result + (authenticatable ? 1 : 0); 77 | result = 31 * result + (unauthenticatedCreateAllowed ? 1 : 0); 78 | return result; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/ResourcePermission.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc; 19 | 20 | /** 21 | * The interface for the type of permission that represents and governs an action on a resource. 22 | *

23 | * A ResourcePermission is the type of permission used to grant an accessor resource access to 24 | * another resource. The kind of "access" that a resource permission represents is determined 25 | * by the application and is typically described in the permission name. In addition to such 26 | * application-defined resource permissions, OACC provides a set of pre-defined common "system" 27 | * resource permissions: *INHERIT, *IMPERSONATE, *RESET-CREDENTIALS, *DELETE and *QUERY. 28 | *

29 | * To create an instance of this class use {@link ResourcePermissions#getInstance(String)} or one 30 | * of its variants. 31 | */ 32 | public interface ResourcePermission { 33 | /** 34 | * Determines if this is system permission. 35 | * 36 | * @return true if this is a system permission, false otherwise. 37 | */ 38 | boolean isSystemPermission(); 39 | 40 | /** 41 | * Retrieves the permission name. 42 | * 43 | * @return the name of the permission. 44 | */ 45 | String getPermissionName(); 46 | 47 | /** 48 | * Retrieve the id of a system permission. 49 | *

50 | * Applications should not use this id, but refer to the system permission by name instead. 51 | *

52 | * Note that if this is not a system permission an exception is thrown. 53 | * 54 | * @return the internal id of the system permission. Applications should not use this id. 55 | * @throws IllegalStateException if this method is called on a non-system permission. 56 | */ 57 | long getSystemPermissionId(); 58 | 59 | /** 60 | * Retrieves the value of the "grant option". 61 | * 62 | * @return true if this permission includes the privilege to be granted to others, false otherwise. 63 | */ 64 | boolean isWithGrantOption(); 65 | 66 | /** 67 | * Determines if this permission can be granted by a grantor holding the specified other permission. 68 | * 69 | * @param other another permission to compare with 70 | * @return true if this permission can be granted by a holder of the specified other permission, 71 | * false otherwise. 72 | */ 73 | boolean isGrantableFrom(ResourcePermission other); 74 | 75 | /** 76 | * Compare this permission with the specified other permission for equality, but ignoring the grant option. 77 | * 78 | * @param other another permission to compare with 79 | * @return true if the specified other permission is equal to this permission ignoring the 80 | * value of the {@link #isWithGrantOption()} property. 81 | */ 82 | boolean equalsIgnoreGrantOption(Object other); 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/Resources.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc; 19 | 20 | import java.io.Serializable; 21 | 22 | public class Resources { 23 | public static Resource getInstance(long resourceId) { 24 | return new ResourceImpl(resourceId, null); 25 | } 26 | 27 | public static Resource getInstance(long resourceId, String externalId) { 28 | return new ResourceImpl(resourceId, externalId); 29 | } 30 | 31 | public static Resource getInstance(String externalId) { 32 | return new ResourceImpl(externalId); 33 | } 34 | 35 | private static class ResourceImpl implements Resource, Serializable { 36 | private static final long serialVersionUID = 1L; 37 | 38 | private final Long resourceId; 39 | private final String externalId; 40 | 41 | private ResourceImpl(long resourceId, 42 | String externalId) { 43 | this.resourceId = resourceId; 44 | this.externalId = externalId; 45 | } 46 | 47 | private ResourceImpl(String externalId) { 48 | this.resourceId = null; 49 | this.externalId = externalId; 50 | } 51 | 52 | @Override 53 | public Long getId() { 54 | return resourceId; 55 | } 56 | 57 | @Override 58 | public String getExternalId() { 59 | return externalId; 60 | } 61 | 62 | @Override 63 | public boolean equals(Object other) { 64 | if (this == other) { 65 | return true; 66 | } 67 | if (other == null || getClass() != other.getClass()) { 68 | return false; 69 | } 70 | 71 | ResourceImpl otherResource = (ResourceImpl) other; 72 | 73 | if (resourceId != null ? !resourceId.equals(otherResource.resourceId) : otherResource.resourceId != null) { 74 | return false; 75 | } 76 | return !(externalId != null ? !externalId.equals(otherResource.externalId) : otherResource.externalId != null); 77 | } 78 | 79 | @Override 80 | public int hashCode() { 81 | int result = resourceId != null ? resourceId.hashCode() : 0; 82 | result = 31 * result + (externalId != null ? externalId.hashCode() : 0); 83 | return result; 84 | } 85 | 86 | @Override 87 | /** 88 | * sample output: 89 | * | externalId != null | externalId == null 90 | * -------------------|---------------------------------------|-------------------- 91 | * resourceId != null | {resourceId: 1234, externalId: "007"} | {resourceId: 1234} 92 | * resourceId == null | {externalId: "007"} | {} 93 | */ 94 | public String toString() { 95 | if (resourceId != null && externalId != null) { 96 | return "{resourceId: " + String.valueOf(resourceId) + ", externalId: \"" + externalId + "\"}"; 97 | } 98 | 99 | if (resourceId != null) { 100 | return "{resourceId: " + String.valueOf(resourceId) + "}"; 101 | } 102 | 103 | if (externalId != null) { 104 | return "{externalId: \"" + externalId + "\"}"; 105 | } 106 | 107 | return "{}"; 108 | } 109 | } 110 | } 111 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/SysPermission.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc; 19 | 20 | import java.io.Serializable; 21 | 22 | class SysPermission implements Serializable { 23 | private static final long serialVersionUID = 1L; 24 | 25 | private final long systemPermissionId; 26 | private final String permissionName; 27 | 28 | SysPermission(int systemPermissionId, String permissionName) { 29 | if (systemPermissionId == 0) { 30 | throw new IllegalArgumentException("System permission ID must be non-zero"); 31 | } 32 | 33 | if (!permissionName.startsWith("*")) { 34 | throw new IllegalArgumentException("System permission names MUST start with *"); 35 | } 36 | 37 | this.systemPermissionId = systemPermissionId; 38 | this.permissionName = permissionName.intern(); 39 | } 40 | 41 | public long getSystemPermissionId() { 42 | return systemPermissionId; 43 | } 44 | 45 | public String getPermissionName() { 46 | return permissionName; 47 | } 48 | 49 | @Override 50 | public int hashCode() { 51 | int result = (int) (systemPermissionId ^ (systemPermissionId >>> 32)); 52 | result = 31 * result + permissionName.hashCode(); 53 | return result; 54 | } 55 | 56 | @Override 57 | public boolean equals(Object o) { 58 | if (this == o) { 59 | return true; 60 | } 61 | if (o == null || getClass() != o.getClass()) { 62 | return false; 63 | } 64 | 65 | SysPermission that = (SysPermission) o; 66 | 67 | if (systemPermissionId != that.systemPermissionId) { 68 | return false; 69 | } 70 | if (!permissionName.equals(that.permissionName)) { 71 | return false; 72 | } 73 | 74 | return true; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/UnsupportedCredentialsException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc; 19 | 20 | public class UnsupportedCredentialsException extends InvalidCredentialsException { 21 | private static final long serialVersionUID = 1L; 22 | 23 | public UnsupportedCredentialsException(String message) { 24 | super(message); 25 | } 26 | 27 | public UnsupportedCredentialsException(String message, Throwable cause) { 28 | super(message, cause); 29 | } 30 | 31 | public UnsupportedCredentialsException(Throwable cause) { 32 | super(cause); 33 | } 34 | 35 | public UnsupportedCredentialsException(Class unsupportedCredentialsClass) { 36 | super("Unsupported credentials implementation: " + unsupportedCredentialsClass); 37 | } 38 | } -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/encryptor/PasswordEncryptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.encryptor; 19 | 20 | /** 21 | * This interface is used to configure the password encryption scheme employed 22 | * by the built-in {@link com.acciente.oacc.sql.internal.SQLPasswordAuthenticationProvider 23 | * SQLPasswordAuthenticationProvider}. 24 | * The goal is to enable using different password encryption algorithms with 25 | * the built-in authentication provider. 26 | *

27 | * In OACC v2.0.0-rc.7 and prior the built-in authentication provider always used 28 | * Jasypt internally and did not allow other options. Now there are factory methods 29 | * in {@link com.acciente.oacc.sql.SQLAccessControlContextFactory SQLAccessControlContextFactory} 30 | * to specify the PasswordEncryptor to be used in the built-in authentication provider. 31 | *

32 | * The following password encryptor implementations are provided: 33 | *

66 | */ 67 | public interface PasswordEncryptor { 68 | /** 69 | * Encrypts a password. 70 | * 71 | * @param password the plaintext password as a cleanable char[] 72 | * @return the BASE-64 digest of encrypting the specified password 73 | */ 74 | String encryptPassword(char[] password); 75 | 76 | /** 77 | * Checks an unencrypted password against an encrypted one to see if they match. 78 | * 79 | * @param plainPassword the plaintext password as a cleanable char[] 80 | * @param encryptedPassword the (BASE-64) digest from an earlier encryption against which to check the plaintext password 81 | * @return true if passwords match, false otherwise 82 | */ 83 | boolean checkPassword(char[] plainPassword, 84 | String encryptedPassword); 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/encryptor/TransitioningPasswordEncryptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | 19 | package com.acciente.oacc.encryptor; 20 | 21 | import java.io.Serializable; 22 | 23 | /** 24 | * The purpose of this password encryptor is to provide a means to transition from an existing (aka "old") password 25 | * encryptor to a new password encryptor in an environment where OACC is already deployed -- where existing passwords 26 | * in the tables are encrypted using the old password encryptor. 27 | */ 28 | public class TransitioningPasswordEncryptor implements PasswordEncryptor, Serializable { 29 | private final PasswordEncryptor newPasswordEncryptor; 30 | private final PasswordEncryptor oldPasswordEncryptor; 31 | 32 | /** 33 | * Creates a password encryptor that delegates all password hash encryption to the password encryptor provided in the 34 | * newPasswordEncryptor parameter. For decryption/comparison of existing passwords this password 35 | * encryptor first delegates to the password encryptor provided in the newPasswordEncryptor parameter if 36 | * that attempts fails by throwing an {@link IllegalArgumentException}, this password encryptor retries by 37 | * delegating to the password encryptor provided in the oldPasswordEncryptor parameter. 38 | * 39 | * @param newPasswordEncryptor the new password encryptor to use for hashing all new passwords hashes for storage 40 | * @param oldPasswordEncryptor the password encryptor that was to hash the passwords already stored in the tables, in 41 | * other words passwords that have not yet been updated since the transition to the 42 | * newPasswordEncryptor began. 43 | * @return a {@link TransitioningPasswordEncryptor} instance. 44 | */ 45 | public static TransitioningPasswordEncryptor newInstance(PasswordEncryptor newPasswordEncryptor, 46 | PasswordEncryptor oldPasswordEncryptor) { 47 | return new TransitioningPasswordEncryptor(newPasswordEncryptor, oldPasswordEncryptor); 48 | } 49 | 50 | private TransitioningPasswordEncryptor(PasswordEncryptor newPasswordEncryptor, 51 | PasswordEncryptor oldPasswordEncryptor) { 52 | this.newPasswordEncryptor = newPasswordEncryptor; 53 | this.oldPasswordEncryptor = oldPasswordEncryptor; 54 | } 55 | 56 | @Override 57 | public String encryptPassword(char[] password) { 58 | // encryption always uses the new password encryptor 59 | return newPasswordEncryptor.encryptPassword(password); 60 | } 61 | 62 | @Override 63 | public boolean checkPassword(char[] plainPassword, String encryptedPassword) { 64 | try { 65 | // first try the new password encryptor, this will work if the password was created by new password encryptor 66 | return newPasswordEncryptor.checkPassword(plainPassword, encryptedPassword); 67 | } 68 | catch (IllegalArgumentException e) { 69 | // if the new password encryptor fails with a password format exception, it is likely an old password, so 70 | // use the old password encryptor to decrypt the password 71 | return oldPasswordEncryptor.checkPassword(plainPassword, encryptedPassword); 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/encryptor/bcrypt/BCryptPasswordEncryptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.encryptor.bcrypt; 19 | 20 | import com.acciente.oacc.encryptor.PasswordEncryptor; 21 | import com.acciente.oacc.normalizer.TextNormalizer; 22 | import org.bouncycastle.crypto.generators.OpenBSDBCrypt; 23 | 24 | import java.io.Serializable; 25 | import java.security.SecureRandom; 26 | 27 | /** 28 | * Password encryptor implementation that uses the OpenBSD BCrypt algorithm for creating password hashes. 29 | */ 30 | public class BCryptPasswordEncryptor implements PasswordEncryptor, Serializable { 31 | private static final long serialVersionUID = 1L; 32 | 33 | public static final String NAME = "bcrypt"; 34 | 35 | private static final int BCRYPT_COST_FACTOR_MIN = 4; 36 | private static final int BCRYPT_COST_FACTOR_MAX = 31; 37 | private static final int BCRYPT_SALT_SIZE = 16; 38 | 39 | private static final PasswordEncoderDecoder passwordEncoderDecoder = new PasswordEncoderDecoder(); 40 | private static final SecureRandom secureRandom = new SecureRandom(); 41 | 42 | private final int costFactor; 43 | 44 | /** 45 | * Returns a password encryptor that uses the BCrypt algorithm with the specified cost factor. 46 | * 47 | * @param costFactor the BCrypt cost factor, must be between 4 and 31 (inclusive). 48 | * @return a BCryptPasswordEncryptor instance configured as described above. 49 | * @throws IllegalArgumentException if the specified BCrypt cost factor is not between 4 and 31 (inclusive). 50 | */ 51 | public static BCryptPasswordEncryptor newInstance(int costFactor) { 52 | assertCostFactorValid(costFactor); 53 | return new BCryptPasswordEncryptor(costFactor); 54 | } 55 | 56 | private BCryptPasswordEncryptor(int costFactor) { 57 | this.costFactor = costFactor; 58 | } 59 | 60 | @Override 61 | public String encryptPassword(char[] plainPassword) { 62 | if (plainPassword == null) { 63 | return null; 64 | } 65 | final char[] normalizedChars = TextNormalizer.getInstance().normalizeToNfc(plainPassword); 66 | 67 | final String bcryptString = OpenBSDBCrypt.generate(normalizedChars, gensalt(), costFactor /* log rounds */); 68 | 69 | return passwordEncoderDecoder.encode(bcryptString); 70 | } 71 | 72 | @Override 73 | public boolean checkPassword(char[] plainPassword, String storedPassword) { 74 | if (plainPassword == null) { 75 | return (storedPassword == null); 76 | } 77 | else if (storedPassword == null) { 78 | return false; 79 | } 80 | 81 | final String bcryptString = passwordEncoderDecoder.decode(storedPassword); 82 | final char[] normalizedChars = TextNormalizer.getInstance().normalizeToNfc(plainPassword); 83 | 84 | return OpenBSDBCrypt.checkPassword(bcryptString, normalizedChars); 85 | } 86 | 87 | /** 88 | * Returns the cost factor in use by this instance. 89 | * 90 | * @return the integer cost factor used by this instance. 91 | */ 92 | public int getCostFactor() { 93 | return costFactor; 94 | } 95 | 96 | private static byte[] gensalt() { 97 | final byte[] saltBytes = new byte[BCRYPT_SALT_SIZE]; 98 | secureRandom.nextBytes(saltBytes); 99 | return saltBytes; 100 | } 101 | 102 | private static void assertCostFactorValid(int computedCostFactorMin) { 103 | if (computedCostFactorMin < BCRYPT_COST_FACTOR_MIN || computedCostFactorMin > BCRYPT_COST_FACTOR_MAX) { 104 | throw new IllegalArgumentException("The cost factor must be between " + BCRYPT_COST_FACTOR_MIN + " and " + 105 | BCRYPT_COST_FACTOR_MAX + " (inclusive)"); 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/encryptor/bcrypt/PasswordEncoderDecoder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | 19 | package com.acciente.oacc.encryptor.bcrypt; 20 | 21 | import org.bouncycastle.crypto.generators.OpenBSDBCrypt; 22 | 23 | public class PasswordEncoderDecoder { 24 | private static final String MARKER = BCryptPasswordEncryptor.NAME + ":"; 25 | 26 | /** 27 | * Encodes the OACC password header into the BCrypt string (OpenBSD standard BCrypt hash implementation). 28 | * 29 | * @param bcryptString the BCrypt string returned by an OpenBSD standard BCrypt hashing implementation that "includes 30 | * version, cost factor, salt and hash, separated by '$'" (from the Javadoc for 31 | * {@link OpenBSDBCrypt#generate(char[], byte[], int)}. 32 | * @return a fully-encoded password ready for persistent storage. 33 | */ 34 | String encode(String bcryptString) { 35 | return MARKER + bcryptString; 36 | 37 | } 38 | 39 | /** 40 | * Decodes the encoded BCrypt string (OpenBSD standard BCrypt hash implementation) from an encoded password. 41 | * 42 | * @param encodedPassword an encoded password that was previously returned by {{@link #encode(String)}}. 43 | * @return a BCrypt string (OpenBSD standard BCrypt hashing implementation). 44 | */ 45 | String decode(String encodedPassword) { 46 | if (encodedPassword.startsWith(MARKER)) { 47 | return encodedPassword.substring(MARKER.length()); 48 | } 49 | else { 50 | throw new IllegalArgumentException("Unexpected marker for BCrypt password: " + 51 | encodedPassword.substring(0, MARKER.length())); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/encryptor/jasypt/DecodedPassword.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | 19 | package com.acciente.oacc.encryptor.jasypt; 20 | 21 | class DecodedPassword { 22 | private final String algorithm; 23 | private final int iterations; 24 | private final int saltSizeBytes; 25 | private final byte[] digest; 26 | 27 | private DecodedPassword(Builder builder) { 28 | algorithm = builder.algorithm; 29 | iterations = builder.iterations; 30 | saltSizeBytes = builder.saltSizeBytes; 31 | digest = builder.digest; 32 | } 33 | 34 | String getAlgorithm() { 35 | return algorithm; 36 | } 37 | 38 | int getIterations() { 39 | return iterations; 40 | } 41 | 42 | int getSaltSizeBytes() { 43 | return saltSizeBytes; 44 | } 45 | 46 | byte[] getDigest() { 47 | return digest; 48 | } 49 | 50 | static final class Builder { 51 | private String algorithm; 52 | private int iterations; 53 | private int saltSizeBytes; 54 | private byte[] digest; 55 | 56 | public Builder() { 57 | } 58 | 59 | public Builder algorithm(String val) { 60 | algorithm = val; 61 | return this; 62 | } 63 | 64 | public Builder iterations(int val) { 65 | iterations = val; 66 | return this; 67 | } 68 | 69 | public Builder saltSizeBytes(int val) { 70 | saltSizeBytes = val; 71 | return this; 72 | } 73 | 74 | public Builder digest(byte[] val) { 75 | digest = val; 76 | return this; 77 | } 78 | 79 | public DecodedPassword build() { 80 | return new DecodedPassword(this); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/encryptor/jasypt/LegacyJasyptPasswordEncryptor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.encryptor.jasypt; 19 | 20 | import com.acciente.oacc.encryptor.PasswordEncryptor; 21 | import com.acciente.oacc.normalizer.TextNormalizer; 22 | import org.jasypt.contrib.org.apache.commons.codec_1_3.binary.Base64; 23 | import org.jasypt.digest.StandardByteDigester; 24 | 25 | import java.nio.ByteBuffer; 26 | import java.nio.CharBuffer; 27 | import java.nio.charset.StandardCharsets; 28 | import java.util.Arrays; 29 | 30 | /** 31 | * Password encryptor implementation that was the sole password encryptor in OACC v2.0.0.rc7 and prior. 32 | */ 33 | public final class LegacyJasyptPasswordEncryptor implements PasswordEncryptor { 34 | private final StandardByteDigester digester; 35 | private final Base64 base64; 36 | 37 | /** 38 | * Returns an instance of the legacy password encryptor implementation used in OACC v2.0.0.rc7 (and prior). 39 | */ 40 | public static LegacyJasyptPasswordEncryptor newInstance() { 41 | return new LegacyJasyptPasswordEncryptor(); 42 | } 43 | 44 | private LegacyJasyptPasswordEncryptor() { 45 | this.digester = new StandardByteDigester(); 46 | this.digester.setAlgorithm("SHA-256"); 47 | this.digester.setIterations(100000); 48 | this.digester.setSaltSizeBytes(16); 49 | this.digester.initialize(); 50 | this.base64 = new Base64(); 51 | } 52 | 53 | @Override 54 | public String encryptPassword(final char[] password) { 55 | if (password == null) { 56 | return null; 57 | } 58 | 59 | final byte[] digest = this.digester.digest(getCleanedBytes(password)); 60 | 61 | return new String(this.base64.encode(digest), StandardCharsets.US_ASCII); 62 | } 63 | 64 | @Override 65 | public boolean checkPassword(final char[] plainPassword, 66 | final String encryptedPassword) { 67 | if (plainPassword == null) { 68 | return (encryptedPassword == null); 69 | } 70 | else if (encryptedPassword == null) { 71 | return false; 72 | } 73 | 74 | return this.digester.matches(getCleanedBytes(plainPassword), 75 | this.base64.decode(encryptedPassword.getBytes(StandardCharsets.US_ASCII))); 76 | } 77 | 78 | private byte[] getCleanedBytes(char[] password) { 79 | final char[] normalizedChars = TextNormalizer.getInstance().normalizeToNfc(password); 80 | final ByteBuffer byteBuffer = StandardCharsets.UTF_8.encode(CharBuffer.wrap(normalizedChars)); 81 | final byte[] byteArray = new byte[byteBuffer.remaining()]; 82 | byteBuffer.get(byteArray); 83 | Arrays.fill(byteBuffer.array(), (byte) 0); 84 | return byteArray; 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/encryptor/jasypt/StandardByteDigesterPool.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.encryptor.jasypt; 19 | 20 | import org.jasypt.digest.StandardByteDigester; 21 | 22 | import java.util.Map; 23 | import java.util.concurrent.ConcurrentHashMap; 24 | 25 | /** 26 | * Keeps a pool of Jasypt digester instances, there is one instance in the pool per unique digester configuration. 27 | */ 28 | class StandardByteDigesterPool { 29 | private final Map>> algorithmMap = new ConcurrentHashMap<>(); 30 | 31 | public StandardByteDigester getStandardByteDigester(String algorithm, int iterations, int saltSizeBytes) { 32 | final Map saltSizeBytesMap = getInnerMap(getInnerMap(algorithmMap, algorithm), iterations); 33 | 34 | StandardByteDigester standardByteDigester = saltSizeBytesMap.get(saltSizeBytes); 35 | if (standardByteDigester == null) { 36 | standardByteDigester = newStandardByteDigester(algorithm, iterations, saltSizeBytes); 37 | saltSizeBytesMap.put(saltSizeBytes, standardByteDigester); 38 | } 39 | 40 | return standardByteDigester; 41 | } 42 | 43 | private static Map getInnerMap(Map> outerMap, K outerKey) { 44 | Map innerMap = outerMap.get(outerKey); 45 | if (innerMap == null) { 46 | innerMap = new ConcurrentHashMap<>(); 47 | outerMap.put(outerKey, innerMap); 48 | } 49 | return innerMap; 50 | } 51 | 52 | private static StandardByteDigester newStandardByteDigester(String algorithm, int iterations, int saltSizeBytes) { 53 | final StandardByteDigester standardByteDigester = new StandardByteDigester(); 54 | standardByteDigester.setAlgorithm(algorithm); 55 | standardByteDigester.setIterations(iterations); 56 | standardByteDigester.setSaltSizeBytes(saltSizeBytes); 57 | standardByteDigester.initialize(); 58 | return standardByteDigester; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/normalizer/TextNormalizer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | 19 | package com.acciente.oacc.normalizer; 20 | 21 | import com.acciente.oacc.normalizer.icu4j.ICU4Jv26TextNormalizer; 22 | import com.acciente.oacc.normalizer.icu4j.ICU4Jv46TextNormalizer; 23 | import com.acciente.oacc.normalizer.jdk.JDKTextNormalizer; 24 | 25 | /** 26 | * Normalizes Unicode text to handle characters that have more than one canonically equivalent representation. 27 | *

28 | * This is important when comparing hashed passwords because plaintext that visually looks the same might actually 29 | * be represented differently binarily, without the user being aware. For example, `é` (the letter `e` with accent acute) 30 | * may be represented as a single Unicode character (U+00E9) or composed of two characters (U+0065 + U+0301), but both 31 | * representations are canonically equivalent. 32 | *

33 | * This class first tries to use the ICU4J library for normalization because it normalizes character arrays 34 | * without converting to String. If ICU4J is not available, then it falls back to the text normalizer 35 | * provided by the JDK, which produces an **intermediate String representation** of the text. 36 | *

37 | * In other words, if you need to prevent a cleanable char[] password being turned into a temporary 38 | * String during Unicode character normalization, you need to include a dependency to ICU4J. 39 | */ 40 | public abstract class TextNormalizer { 41 | /** 42 | * Get an instance of a text normalizer. 43 | *

44 | * If the ICU4J library is available, the returned instance will use an ICU4J normalizer, which handles character 45 | * arrays without converting to String. Otherwise (if ICU4J is not available), the fallback instance 46 | * returned uses the normalizer provided by the JDK, which produces an **intermediate String 47 | * representation** of the normalized text. 48 | * 49 | * @return a text normalizer instance 50 | */ 51 | public static TextNormalizer getInstance() { 52 | try { 53 | // first see if a newer version of ICU4J is available 54 | return ICU4Jv46TextNormalizer.getInstance(); 55 | } 56 | catch (NoClassDefFoundError e1) { 57 | try { 58 | // next see if an older version of ICU4J is available 59 | return ICU4Jv26TextNormalizer.getInstance(); 60 | } 61 | catch (NoClassDefFoundError e2) { 62 | // otherwise fallback to the non-cleanable JDK based implementation 63 | return JDKTextNormalizer.getInstance(); 64 | } 65 | } 66 | } 67 | 68 | /** 69 | * Returns the canonically equivalent normalized (NFC) version of a Unicode character array. 70 | *

71 | * Note: 72 | * If the ICU4J library for normalization is not available, the fallback Normalizer provided by the JDK 73 | * will produce an intermediate String representation of the normalized text! 74 | * 75 | * @param source any Unicode text 76 | * @return a character array containing the normalized representation of the source text 77 | */ 78 | public abstract char[] normalizeToNfc(char[] source); 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/normalizer/icu4j/ICU4Jv26TextNormalizer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | 19 | package com.acciente.oacc.normalizer.icu4j; 20 | 21 | import com.acciente.oacc.normalizer.TextNormalizer; 22 | import com.ibm.icu.text.Normalizer; 23 | 24 | public class ICU4Jv26TextNormalizer extends TextNormalizer { 25 | // constants 26 | private static final char ZERO_CHAR = '\0'; 27 | 28 | // we use the singleton holder pattern to lazy initialize the singleton instance 29 | // in a thread safe manner without the need for any explicit locking 30 | // (see https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom). 31 | private static class LazyInitSingletonHolder { 32 | private static final TextNormalizer INSTANCE = new ICU4Jv26TextNormalizer(); 33 | } 34 | 35 | private ICU4Jv26TextNormalizer() { 36 | // this "no-op" call to the Normalize class is *very* important, without it when the 37 | // com.ibm.icu.text.Normalizer class is not present in the classpath a load of the 38 | // class will not fail until it is attempted in the normalizeToNfc() method below -- which 39 | // is too late. The class load needs to fail here to cause the getInstance() method below to 40 | // propagate the class load exception and correctly trigger the fallback to the JDK based 41 | // TextNormalizer implementation in the parent class's TextNormalizer#getInstance(). 42 | Normalizer.normalize("", Normalizer.NFC, 0); 43 | } 44 | 45 | public static TextNormalizer getInstance() { 46 | return LazyInitSingletonHolder.INSTANCE; 47 | } 48 | 49 | @Override 50 | public char[] normalizeToNfc(char[] source) { 51 | int destBufferSize = 3 * source.length; 52 | char[] result = null; 53 | do { 54 | char[] destBuffer = new char[destBufferSize]; 55 | try { 56 | final int destBufferUsedCount = Normalizer.normalize(source, destBuffer, Normalizer.NFC, 0); 57 | result = copyContents(destBuffer, destBufferUsedCount); 58 | } 59 | catch (IndexOutOfBoundsException e) { 60 | // NOTE: since we allocate an initial buffer that is 3x of 61 | // the source text length we never expect this to happen 62 | 63 | // try the next loop iteration with a larger buffer 64 | destBufferSize += source.length; 65 | } 66 | finally { 67 | // zero out the current dest buffer 68 | zeroOut(destBuffer); 69 | } 70 | } while (result == null); 71 | 72 | return result; 73 | } 74 | 75 | /** 76 | * Returns a copy of the contents of specified char array 77 | * 78 | * @param source char array to copy from 79 | * @param countToCopy the number of characters to copy from the source 80 | * 81 | * @return a character array with 82 | */ 83 | private char[] copyContents(char[] source, int countToCopy) { 84 | final char[] copy = new char[countToCopy]; 85 | System.arraycopy(source, 0, copy, 0, countToCopy); 86 | return copy; 87 | } 88 | 89 | /** 90 | * Sets all contents in the specified char array to {@value ZERO_CHAR}. 91 | * 92 | * @param dest the char array to zero out 93 | */ 94 | private void zeroOut(char[] dest) { 95 | for (int i = 0; i < dest.length; i++) { 96 | dest[i] = ZERO_CHAR; 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/normalizer/icu4j/Normalizer2Factory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | 19 | package com.acciente.oacc.normalizer.icu4j; 20 | 21 | import com.ibm.icu.text.Normalizer2; 22 | 23 | public class Normalizer2Factory { 24 | public static Normalizer2 getNFCInstance() { 25 | return Normalizer2.getInstance(null, "nfc", Normalizer2.Mode.COMPOSE); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/normalizer/jdk/JDKTextNormalizer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | 19 | package com.acciente.oacc.normalizer.jdk; 20 | 21 | import com.acciente.oacc.normalizer.TextNormalizer; 22 | 23 | import java.nio.CharBuffer; 24 | import java.text.Normalizer; 25 | 26 | public class JDKTextNormalizer extends TextNormalizer { 27 | // we use the singleton holder pattern to lazy initialize the singleton instance 28 | // in a thread safe manner without the need for any explicit locking 29 | // (see https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom). 30 | private static class LazyInitSingletonHolder { 31 | private static final TextNormalizer INSTANCE = new JDKTextNormalizer(); 32 | } 33 | 34 | private JDKTextNormalizer() { 35 | } 36 | 37 | public static TextNormalizer getInstance() { 38 | return LazyInitSingletonHolder.INSTANCE; 39 | } 40 | 41 | @Override 42 | public char[] normalizeToNfc(char[] source) { 43 | return Normalizer.normalize(CharBuffer.wrap(source), Normalizer.Form.NFC).toCharArray(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/SQLDialect.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql; 19 | 20 | public enum SQLDialect { 21 | DB2_10_5, 22 | Oracle_11_2, 23 | PostgreSQL_9_3, 24 | SQLServer_12_0, 25 | SQLite_3_8, 26 | MySQL_5_6, 27 | HSQLDB_2_3, 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/PasswordUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal; 19 | 20 | import com.acciente.oacc.Resource; 21 | 22 | public class PasswordUtils { 23 | /** 24 | * Computes a password string that is bound to the resource with which the password is 25 | * associated. As a result of this binding, if the encrypted password of resource A 26 | * were used to overwrite the encrypted password of a resource B, it would still not be 27 | * possible to authenticate as resource B using the password for resource A. 28 | * @param resource 29 | * @param password 30 | * @return 31 | */ 32 | public static char[] computeBoundPassword(Resource resource, char[] password) { 33 | final char[] resIdAsCharArray = String.valueOf(resource.getId()).toCharArray(); 34 | final int tailLength = password.length - password.length / 2; 35 | char[] boundPassword = new char[password.length + resIdAsCharArray.length + tailLength]; 36 | 37 | System.arraycopy(password, 0, boundPassword, 0, password.length); 38 | System.arraycopy(resIdAsCharArray, 0, boundPassword, password.length, resIdAsCharArray.length); 39 | System.arraycopy(password, password.length / 2, boundPassword, password.length + resIdAsCharArray.length, tailLength); 40 | 41 | return boundPassword; 42 | } 43 | 44 | /** 45 | * This method zeroes out all the elements of the passed in character array 46 | * @param password a char array containing a password 47 | */ 48 | public static void cleanPassword(char[] password) { 49 | if (password != null) { 50 | for (int i = 0; i < password.length; i++) { 51 | password[i] = 0; 52 | } 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/ResourceClassInternalInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal; 19 | 20 | import com.acciente.oacc.sql.internal.persister.id.Id; 21 | import com.acciente.oacc.sql.internal.persister.id.ResourceClassId; 22 | 23 | public class ResourceClassInternalInfo { 24 | private final long resourceClassId; 25 | private final String resourceClassName; 26 | private final boolean authenticatable; 27 | private final boolean unauthenticatedCreateAllowed; 28 | 29 | public ResourceClassInternalInfo(Id resourceClassId, 30 | String resourceClassName, 31 | boolean authenticatable, 32 | boolean unauthenticatedCreateAllowed) { 33 | this.resourceClassId = resourceClassId.getValue(); 34 | this.resourceClassName = resourceClassName; 35 | this.authenticatable = authenticatable; 36 | this.unauthenticatedCreateAllowed = unauthenticatedCreateAllowed; 37 | } 38 | 39 | public long getResourceClassId() { 40 | return resourceClassId; 41 | } 42 | 43 | public String getResourceClassName() { 44 | return resourceClassName; 45 | } 46 | 47 | public boolean isAuthenticatable() { 48 | return authenticatable; 49 | } 50 | 51 | public boolean isUnauthenticatedCreateAllowed() { 52 | return unauthenticatedCreateAllowed; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/SchemaNameValidator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal; 19 | 20 | import java.util.regex.Pattern; 21 | 22 | public class SchemaNameValidator { 23 | // breakdown of the regex: (?U)^\w+|^"\w+"|^'\w+'|^\[\w+\]|^`\w+` 24 | // ------------------------------------------------------------ 25 | // (?U) embedded flag to set UNICODE_CHARACTER_CLASS 26 | // ^\w+ match sequence of unicode word characters 27 | // |^"\w+" or match sequence of unicode word characters delimited by double quotes 28 | // |^'\w+' or match sequence of unicode word characters delimited by single quotes 29 | // |^\[\w+\] or match sequence of unicode word characters delimited by square brackets 30 | // |^`\w+` or match sequence of unicode word characters delimited by backticks 31 | public static final String OPTIONALLY_DELIMITED_UNICODE_WORD_REGEX = "(?U)^\\w+|^\"\\w+\"|^'\\w+'|^\\[\\w+\\]|^`\\w+`"; 32 | public static final Pattern OPTIONALLY_DELIMITED_UNICODE_WORD_PATTERN = Pattern.compile(OPTIONALLY_DELIMITED_UNICODE_WORD_REGEX); 33 | 34 | /** 35 | * Validates the specified schema name. 36 | *

37 | * The specified schema name is only considered valid if it consists of a single sequence of unicode word characters, 38 | * or is null. Blank schema names are not valid. 39 | * The unicode word can optionally be surrounded by SQL delimiters. 40 | * Valid SQL delimiters include the following characters: 41 | *

    42 | *
  • double-quote (")
  • 43 | *
  • single-quote (')
  • 44 | *
  • square brackets ([])
  • 45 | *
  • backtick (`)
  • 46 | *
47 | * A unicode word can consist of the following 48 | * [Javadoc Reference]: 49 | *
    50 | *
  • Alphabetical letter characters
  • 51 | *
  • Digits
  • 52 | *
  • Connector punctuation (e.g. underscore "_")
  • 53 | *
  • Nonspacing marks
  • 54 | *
  • Enclosing marks
  • 55 | *
  • Spacing combining marks
  • 56 | *
57 | * 58 | * @param schemaName the schema name String to be validated 59 | * @return true if the specified schema name is null or a (optionally delimited) unicode word, false otherwise 60 | */ 61 | public static boolean isValid(String schemaName) { 62 | return schemaName == null || OPTIONALLY_DELIMITED_UNICODE_WORD_PATTERN.matcher(schemaName).matches(); 63 | } 64 | 65 | /** 66 | * Asserts the specified schema name is valid. 67 | * 68 | * See {@link #isValid(String)}. 69 | * @param schemaName the schema name String to be validated 70 | * @throws IllegalArgumentException if the specified schema name is not valid according to {@link #isValid(String)}} 71 | */ 72 | public static void assertValid(String schemaName) { 73 | if (!isValid(schemaName)) { 74 | throw new IllegalArgumentException("Invalid database schema name - it can only consist of (optionally delimited) " 75 | + "unicode word characters, or be null, but it was: " + schemaName); 76 | } 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/encryptor/PasswordEncryptors.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.encryptor; 19 | 20 | import com.acciente.oacc.encryptor.PasswordEncryptor; 21 | import com.acciente.oacc.encryptor.bcrypt.BCryptPasswordEncryptor; 22 | import com.acciente.oacc.encryptor.jasypt.JasyptPasswordEncryptor; 23 | 24 | import java.util.Arrays; 25 | import java.util.List; 26 | 27 | /** 28 | * Internally used helper class to get an instance of the {@link PasswordEncryptor} identified 29 | * by the name of the {@link PasswordEncryptor}. This is where the NAME constant that is expected to 30 | * be defined in every {@link PasswordEncryptor} implementation is used. 31 | */ 32 | public class PasswordEncryptors { 33 | private static final int BCRYPT_MIN_COST_FACTOR = 10; 34 | 35 | private static final String JASYPT_ALGORITHM = "SHA-256"; 36 | private static final int JASYPT_ITERATIONS = 100000; 37 | private static final int JASYPT_SALT_SIZE_BYTES = 16; 38 | 39 | public static PasswordEncryptor getPasswordEncryptor(String encryptorName) { 40 | if (encryptorName == null) { 41 | throw new IllegalArgumentException("Encryptor name cannot be null"); 42 | } 43 | 44 | if (encryptorName.equalsIgnoreCase(BCryptPasswordEncryptor.NAME)) { 45 | return BCryptPasswordEncryptor.newInstance(BCRYPT_MIN_COST_FACTOR); 46 | } 47 | 48 | if (encryptorName.equalsIgnoreCase(JasyptPasswordEncryptor.NAME)) { 49 | return JasyptPasswordEncryptor.newInstance(JASYPT_ALGORITHM, JASYPT_ITERATIONS, JASYPT_SALT_SIZE_BYTES); 50 | } 51 | 52 | throw new IllegalArgumentException("Encryptor name " + encryptorName + " not recognized"); 53 | } 54 | 55 | public static List getSupportedEncryptorNames() { 56 | return Arrays.asList(BCryptPasswordEncryptor.NAME, JasyptPasswordEncryptor.NAME); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/persister/DialectSpecificSQLGenerator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.persister; 19 | 20 | import com.acciente.oacc.sql.SQLDialect; 21 | 22 | class DialectSpecificSQLGenerator { 23 | private final String withClause; 24 | private final String unionClause; 25 | private final String nextSeqValueStatementPrefix; 26 | private final String nextSeqValueStatementSuffix; 27 | private final String nextSeqValueFragmentPrefix; 28 | private final String nextSeqValueFragmentSuffix; 29 | 30 | private static final DialectSpecificSQLGenerator DB2_10_5 = new DialectSpecificSQLGenerator("WITH", "UNION ALL", "VALUES ( NEXT VALUE FOR ", " )", "NEXT VALUE FOR ", ""); 31 | private static final DialectSpecificSQLGenerator Oracle_11_2 = new DialectSpecificSQLGenerator("WITH", "UNION ALL", "SELECT ", ".NEXTVAL FROM DUAL", "", ".NEXTVAL"); 32 | private static final DialectSpecificSQLGenerator PostgreSQL_9_3 = new DialectSpecificSQLGenerator("WITH RECURSIVE", "UNION ALL", "SELECT nextval('", "')", "nextval('", "')"); 33 | private static final DialectSpecificSQLGenerator SQLServer_12_0 = new DialectSpecificSQLGenerator("WITH", "UNION ALL", "SELECT NEXT VALUE FOR ", "", "NEXT VALUE FOR ", ""); 34 | private static final DialectSpecificSQLGenerator SQLite_3_8 = new DialectSpecificSQLGenerator("WITH RECURSIVE", "UNION ALL", null, null, null, null); 35 | private static final DialectSpecificSQLGenerator MySQL_5_6 = new DialectSpecificSQLGenerator(null, null, null, null, null, null); 36 | private static final DialectSpecificSQLGenerator HSQLDB_2_3 = new DialectSpecificSQLGenerator(null, null, "VALUES NEXT VALUE FOR ", "", "NEXT VALUE FOR ", ""); 37 | 38 | static DialectSpecificSQLGenerator getInstance(SQLDialect sqlDialect) { 39 | switch (sqlDialect) { 40 | case DB2_10_5: 41 | return DB2_10_5; 42 | case Oracle_11_2: 43 | return Oracle_11_2; 44 | case PostgreSQL_9_3: 45 | return PostgreSQL_9_3; 46 | case SQLServer_12_0: 47 | return SQLServer_12_0; 48 | case SQLite_3_8: 49 | return SQLite_3_8; 50 | case MySQL_5_6: 51 | return MySQL_5_6; 52 | case HSQLDB_2_3: 53 | return HSQLDB_2_3; 54 | default: 55 | throw new IllegalArgumentException("Unsupported SQL dialect: " + sqlDialect); 56 | } 57 | } 58 | 59 | String getWithClause() { 60 | return withClause; 61 | } 62 | 63 | String getUnionClause() { 64 | return unionClause; 65 | } 66 | 67 | String nextSequenceValueStatement(String qualifiedSequenceName) { 68 | return nextSeqValueStatementPrefix + qualifiedSequenceName + nextSeqValueStatementSuffix; 69 | } 70 | 71 | String nextSequenceValueFragment(String qualifiedSequenceName) { 72 | return nextSeqValueFragmentPrefix + qualifiedSequenceName + nextSeqValueFragmentSuffix; 73 | } 74 | 75 | // private constructor to force use of constants 76 | private DialectSpecificSQLGenerator(String withClause, 77 | String unionClause, 78 | String nextSeqValueStatementPrefix, 79 | String nextSeqValueStatementSuffix, 80 | String nextSeqValueFragmentPrefix, 81 | String nextSeqValueFragmentSuffix) { 82 | this.withClause = withClause; 83 | this.unionClause = unionClause; 84 | this.nextSeqValueStatementPrefix = nextSeqValueStatementPrefix; 85 | this.nextSeqValueStatementSuffix = nextSeqValueStatementSuffix; 86 | this.nextSeqValueFragmentPrefix = nextSeqValueFragmentPrefix; 87 | this.nextSeqValueFragmentSuffix = nextSeqValueFragmentSuffix; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/persister/DomainPersister.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.persister; 19 | 20 | import com.acciente.oacc.Resource; 21 | import com.acciente.oacc.sql.internal.persister.id.DomainId; 22 | import com.acciente.oacc.sql.internal.persister.id.Id; 23 | 24 | import java.util.Set; 25 | 26 | public interface DomainPersister { 27 | Id getResourceDomainId(SQLConnection connection, 28 | String resourceDomainName); 29 | 30 | String getResourceDomainNameByResourceId(SQLConnection connection, 31 | Resource resource); 32 | 33 | Set getResourceDomainNameDescendants(SQLConnection connection, 34 | String resourceDomainName); 35 | 36 | void addResourceDomain(SQLConnection connection, 37 | String resourceDomainName); 38 | 39 | void addResourceDomain(SQLConnection connection, 40 | String resourceDomainName, 41 | Id parentResourceDomainId); 42 | 43 | void deleteDomain(SQLConnection connection, 44 | Id domainId); 45 | } 46 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/persister/GrantDomainCreatePermissionPostCreateSysPersister.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.persister; 19 | 20 | import com.acciente.oacc.DomainCreatePermission; 21 | import com.acciente.oacc.Resource; 22 | 23 | import java.util.Set; 24 | 25 | public interface GrantDomainCreatePermissionPostCreateSysPersister { 26 | Set getDomainCreatePostCreateSysPermissionsIncludeInherited(SQLConnection connection, 27 | Resource accessorResource); 28 | 29 | Set getDomainCreatePostCreateSysPermissions(SQLConnection connection, 30 | Resource accessorResource); 31 | 32 | void removeDomainCreatePostCreateSysPermissions(SQLConnection connection, 33 | Resource accessorResource); 34 | 35 | void removeDomainCreatePostCreateSysPermissions(SQLConnection connection, 36 | Resource accessorResource, 37 | Set domainCreatePermissions); 38 | 39 | void addDomainCreatePostCreateSysPermissions(SQLConnection connection, 40 | Resource accessorResource, 41 | Resource grantorResource, 42 | Set domainCreatePermissions); 43 | 44 | void updateDomainCreatePostCreateSysPermissions(SQLConnection connection, 45 | Resource accessorResource, 46 | Resource grantorResource, 47 | Set domainCreatePermissions); 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/persister/GrantDomainCreatePermissionSysPersister.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.persister; 19 | 20 | import com.acciente.oacc.DomainCreatePermission; 21 | import com.acciente.oacc.Resource; 22 | 23 | import java.util.Set; 24 | 25 | public interface GrantDomainCreatePermissionSysPersister { 26 | Set getDomainCreateSysPermissionsIncludeInherited(SQLConnection connection, 27 | Resource accessorResource); 28 | 29 | Set getDomainCreateSysPermissions(SQLConnection connection, 30 | Resource accessorResource); 31 | 32 | void addDomainCreateSysPermissions(SQLConnection connection, 33 | Resource accessorResource, 34 | Resource grantorResource, 35 | Set domainCreatePermissions); 36 | 37 | void updateDomainCreateSysPermissions(SQLConnection connection, 38 | Resource accessorResource, 39 | Resource grantorResource, 40 | Set domainCreatePermissions); 41 | 42 | void removeDomainCreateSysPermissions(SQLConnection connection, 43 | Resource accessorResource); 44 | 45 | void removeDomainCreateSysPermissions(SQLConnection connection, 46 | Resource accessorResource, 47 | Set domainCreatePermissions); 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/persister/GrantDomainPermissionSysPersister.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.persister; 19 | 20 | import com.acciente.oacc.DomainPermission; 21 | import com.acciente.oacc.Resource; 22 | import com.acciente.oacc.sql.internal.persister.id.DomainId; 23 | import com.acciente.oacc.sql.internal.persister.id.Id; 24 | import com.acciente.oacc.sql.internal.persister.id.ResourceClassId; 25 | 26 | import java.util.Map; 27 | import java.util.Set; 28 | 29 | public interface GrantDomainPermissionSysPersister { 30 | Set getResourcesByDomainSuperUserPermission(SQLConnection connection, 31 | Resource accessorResource, 32 | Id resourceClassId); 33 | 34 | Set getResourcesByDomainSuperUserPermission(SQLConnection connection, 35 | Resource accessorResource, 36 | Id resourceClassId, 37 | Id resourceDomainId); 38 | 39 | Set getDomainSysPermissionsIncludeInherited(SQLConnection connection, 40 | Resource accessorResource, 41 | Id resourceDomainId); 42 | 43 | Set getDomainSysPermissions(SQLConnection connection, 44 | Resource accessorResource, 45 | Id resourceDomainId); 46 | 47 | Map> getDomainSysPermissionsIncludeInherited(SQLConnection connection, 48 | Resource accessorResource); 49 | 50 | Map> getDomainSysPermissions(SQLConnection connection, 51 | Resource accessorResource); 52 | 53 | void addDomainSysPermissions(SQLConnection connection, 54 | Resource accessorResource, 55 | Resource grantorResource, 56 | Id resourceDomainId, 57 | Set requestedDomainPermissions); 58 | 59 | void updateDomainSysPermissions(SQLConnection connection, 60 | Resource accessorResource, 61 | Resource grantorResource, 62 | Id resourceDomainId, 63 | Set requestedDomainPermissions); 64 | 65 | void removeAllDomainSysPermissions(SQLConnection connection, 66 | Resource accessorResource); 67 | 68 | void removeAllDomainSysPermissions(SQLConnection connection, 69 | Id domainId); 70 | 71 | void removeDomainSysPermissions(SQLConnection connection, 72 | Resource accessorResource, 73 | Id resourceDomainId); 74 | 75 | void removeDomainSysPermissions(SQLConnection connection, 76 | Resource accessorResource, 77 | Id resourceDomainId, 78 | Set requestedDomainPermissions); 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/persister/GrantResourcePermissionSysPersister.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.persister; 19 | 20 | import com.acciente.oacc.Resource; 21 | import com.acciente.oacc.ResourcePermission; 22 | import com.acciente.oacc.sql.internal.persister.id.DomainId; 23 | import com.acciente.oacc.sql.internal.persister.id.Id; 24 | import com.acciente.oacc.sql.internal.persister.id.ResourceClassId; 25 | 26 | import java.util.Set; 27 | 28 | public interface GrantResourcePermissionSysPersister { 29 | Set getResourcesByResourceSysPermission(SQLConnection connection, 30 | Resource accessorResource, 31 | Id resourceClassId, 32 | ResourcePermission resourcePermission); 33 | 34 | Set getResourcesByResourceSysPermission(SQLConnection connection, 35 | Resource accessorResource, 36 | Id resourceClassId, 37 | Id resourceDomainId, 38 | ResourcePermission resourcePermission); 39 | 40 | Set getAccessorResourcesByResourceSysPermission(SQLConnection connection, 41 | Resource accessedResource, 42 | Id resourceClassId, 43 | ResourcePermission resourcePermission); 44 | 45 | Set getResourceSysPermissionsIncludeInherited(SQLConnection connection, 46 | Resource accessorResource, 47 | Resource accessedResource); 48 | 49 | Set getResourceSysPermissions(SQLConnection connection, 50 | Resource accessorResource, 51 | Resource accessedResource); 52 | 53 | void addResourceSysPermissions(SQLConnection connection, 54 | Resource accessorResource, 55 | Resource accessedResource, 56 | Id accessedResourceClassId, 57 | Set requestedResourcePermissions, 58 | Resource grantorResource); 59 | 60 | void updateResourceSysPermissions(SQLConnection connection, 61 | Resource accessorResource, 62 | Resource accessedResource, 63 | Id accessedResourceClassId, 64 | Set requestedResourcePermissions, 65 | Resource grantorResource); 66 | 67 | void removeAllResourceSysPermissionsAsAccessorOrAccessed(SQLConnection connection, 68 | Resource resource); 69 | 70 | void removeResourceSysPermissions(SQLConnection connection, 71 | Resource accessorResource, 72 | Resource accessedResource); 73 | 74 | void removeResourceSysPermissions(SQLConnection connection, 75 | Resource accessorResource, 76 | Resource accessedResource, 77 | Id accessedResourceClassId, 78 | Set requestedResourcePermissions); 79 | } 80 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/persister/NonRecursiveGrantDomainCreatePermissionPostCreateSysPersister.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.persister; 19 | 20 | import com.acciente.oacc.DomainCreatePermission; 21 | import com.acciente.oacc.Resource; 22 | import com.acciente.oacc.sql.SQLProfile; 23 | import com.acciente.oacc.sql.internal.persister.id.Id; 24 | import com.acciente.oacc.sql.internal.persister.id.ResourceId; 25 | 26 | import java.io.Serializable; 27 | import java.sql.SQLException; 28 | import java.util.HashSet; 29 | import java.util.Set; 30 | 31 | public class NonRecursiveGrantDomainCreatePermissionPostCreateSysPersister extends CommonGrantDomainCreatePermissionPostCreateSysPersister implements Serializable { 32 | private static final long serialVersionUID = 1L; 33 | 34 | public NonRecursiveGrantDomainCreatePermissionPostCreateSysPersister(SQLProfile sqlProfile, 35 | SQLStrings sqlStrings) { 36 | super(sqlProfile, sqlStrings); 37 | } 38 | 39 | @Override 40 | public Set getDomainCreatePostCreateSysPermissionsIncludeInherited(SQLConnection connection, 41 | Resource accessorResource) { 42 | SQLStatement statement = null; 43 | 44 | try { 45 | // first get all the resources from which the accessor inherits any permissions 46 | final Set> accessorResourceIds 47 | = NonRecursivePersisterHelper.getInheritedAccessorResourceIds(sqlStrings, connection, accessorResource); 48 | 49 | // now accumulate the permissions on the accessed resource from each of the (inherited) accessors 50 | Set domainCreatePermissions = new HashSet<>(); 51 | statement = connection.prepareStatement(sqlStrings.SQL_findInGrantDomainCreatePermissionPostCreateSys_withoutInheritance_PostCreateSysPermissionID_PostCreateIsWithGrant_IsWithGrant_BY_AccessorID); 52 | 53 | for (Id accessorResourceId : accessorResourceIds) { 54 | statement.setResourceId(1, accessorResourceId); 55 | SQLResult resultSet = statement.executeQuery(); 56 | 57 | while (resultSet.next()) { 58 | domainCreatePermissions.add(getDomainCreatePostCreateSysPermission(resultSet)); 59 | } 60 | resultSet.close(); 61 | } 62 | 63 | return domainCreatePermissions; 64 | } 65 | catch (SQLException e) { 66 | throw new RuntimeException(e); 67 | } 68 | finally { 69 | closeStatement(statement); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/persister/NonRecursiveGrantDomainCreatePermissionSysPersister.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.persister; 19 | 20 | import com.acciente.oacc.DomainCreatePermission; 21 | import com.acciente.oacc.Resource; 22 | import com.acciente.oacc.sql.SQLProfile; 23 | import com.acciente.oacc.sql.internal.persister.id.Id; 24 | import com.acciente.oacc.sql.internal.persister.id.ResourceId; 25 | 26 | import java.io.Serializable; 27 | import java.sql.SQLException; 28 | import java.util.HashSet; 29 | import java.util.Set; 30 | 31 | public class NonRecursiveGrantDomainCreatePermissionSysPersister extends CommonGrantDomainCreatePermissionSysPersister implements Serializable { 32 | private static final long serialVersionUID = 1L; 33 | 34 | public NonRecursiveGrantDomainCreatePermissionSysPersister(SQLProfile sqlProfile, 35 | SQLStrings sqlStrings) { 36 | super(sqlProfile, sqlStrings); 37 | } 38 | 39 | @Override 40 | public Set getDomainCreateSysPermissionsIncludeInherited(SQLConnection connection, 41 | Resource accessorResource) { 42 | SQLStatement statement = null; 43 | 44 | try { 45 | // first get all the resources from which the accessor inherits any permissions 46 | final Set> accessorResourceIds 47 | = NonRecursivePersisterHelper.getInheritedAccessorResourceIds(sqlStrings, connection, accessorResource); 48 | 49 | // now accumulate the domain create permissions from each of the (inherited) accessors 50 | Set domainCreatePermissions = new HashSet<>(); 51 | statement = connection.prepareStatement(sqlStrings.SQL_findInGrantDomainCreatePermissionSys_withoutInheritance_SysPermissionID_BY_AccessorID); 52 | 53 | for (Id accessorResourceId : accessorResourceIds) { 54 | statement.setResourceId(1, accessorResourceId); 55 | SQLResult resultSet = statement.executeQuery(); 56 | 57 | while (resultSet.next()) { 58 | domainCreatePermissions.add(getDomainCreateSysPermission(resultSet)); 59 | } 60 | resultSet.close(); 61 | } 62 | 63 | return domainCreatePermissions; 64 | } 65 | catch (SQLException e) { 66 | throw new RuntimeException(e); 67 | } 68 | finally { 69 | closeStatement(statement); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/persister/NonRecursiveResourcePersister.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.persister; 19 | 20 | import com.acciente.oacc.sql.SQLProfile; 21 | import com.acciente.oacc.sql.internal.persister.id.DomainId; 22 | import com.acciente.oacc.sql.internal.persister.id.Id; 23 | 24 | import java.io.Serializable; 25 | import java.sql.SQLException; 26 | import java.util.Set; 27 | 28 | public class NonRecursiveResourcePersister extends CommonResourcePersister implements Serializable { 29 | private static final long serialVersionUID = 1L; 30 | 31 | public NonRecursiveResourcePersister(SQLProfile sqlProfile, 32 | SQLStrings sqlStrings) { 33 | super(sqlProfile, sqlStrings); 34 | } 35 | 36 | @Override 37 | public boolean isDomainEmpty(SQLConnection connection, Id domainId) { 38 | SQLStatement statement = null; 39 | 40 | try { 41 | boolean isEmpty = true; 42 | SQLResult resultSet; 43 | 44 | final Set> descendantDomainIds 45 | = NonRecursivePersisterHelper.getDescendantDomainIdsOrderedByAscendingLevel(sqlStrings, 46 | connection, 47 | domainId); 48 | 49 | statement = connection.prepareStatement(sqlStrings.SQL_findInResource_withoutInheritance_COUNTResourceID_BY_DomainID); 50 | for (Id descendantDomainId : descendantDomainIds) { 51 | statement.setResourceDomainId(1, descendantDomainId); 52 | resultSet = statement.executeQuery(); 53 | 54 | if (!resultSet.next()) { 55 | throw new IllegalArgumentException("Could not read resource count for domain: " + domainId); 56 | } 57 | 58 | final int count = resultSet.getInteger("COUNTResourceID"); 59 | resultSet.close(); 60 | 61 | if (count > 0) { 62 | isEmpty = false; 63 | break; 64 | } 65 | } 66 | 67 | return isEmpty; 68 | } 69 | catch (SQLException e) { 70 | throw new RuntimeException(e); 71 | } 72 | finally { 73 | closeStatement(statement); 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/persister/Persister.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.persister; 19 | 20 | import java.io.Serializable; 21 | import java.sql.SQLException; 22 | 23 | /** 24 | * Base class for persisters 25 | */ 26 | public abstract class Persister implements Serializable { 27 | private static final long serialVersionUID = 1L; 28 | 29 | protected static void closeStatement(SQLStatement statement) { 30 | try { 31 | if (statement != null) { 32 | statement.close(); 33 | } 34 | } 35 | catch (SQLException e) { 36 | throw new RuntimeException(e); 37 | } 38 | } 39 | 40 | // data verification helpers 41 | 42 | protected void assertOneRowInserted(int rowCount) { 43 | if (rowCount != 1) { 44 | throw new IllegalStateException("Security table data insert, 1 row expected, got: " + rowCount); 45 | } 46 | } 47 | 48 | protected void assertOneRowUpdated(int rowCount) { 49 | if (rowCount != 1) { 50 | throw new IllegalStateException("Security table data update, 1 row expected, got: " + rowCount); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/persister/RecursiveGrantDomainCreatePermissionPostCreateSysPersister.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.persister; 19 | 20 | import com.acciente.oacc.DomainCreatePermission; 21 | import com.acciente.oacc.Resource; 22 | import com.acciente.oacc.sql.SQLProfile; 23 | 24 | import java.io.Serializable; 25 | import java.sql.SQLException; 26 | import java.util.HashSet; 27 | import java.util.Set; 28 | 29 | public class RecursiveGrantDomainCreatePermissionPostCreateSysPersister extends CommonGrantDomainCreatePermissionPostCreateSysPersister implements Serializable { 30 | private static final long serialVersionUID = 1L; 31 | 32 | public RecursiveGrantDomainCreatePermissionPostCreateSysPersister(SQLProfile sqlProfile, 33 | SQLStrings sqlStrings) { 34 | super(sqlProfile, sqlStrings); 35 | } 36 | 37 | @Override 38 | public Set getDomainCreatePostCreateSysPermissionsIncludeInherited(SQLConnection connection, 39 | Resource accessorResource) { 40 | SQLStatement statement = null; 41 | 42 | try { 43 | statement = connection.prepareStatement(sqlStrings.SQL_findInGrantDomainCreatePermissionPostCreateSys_PostCreateSysPermissionID_PostCreateIsWithGrant_IsWithGrant_BY_AccessorID); 44 | statement.setResourceId(1, accessorResource); 45 | SQLResult resultSet = statement.executeQuery(); 46 | 47 | // first collect the create permissions that this resource has to domains 48 | Set domainCreatePermissions = new HashSet<>(); 49 | while (resultSet.next()) { 50 | domainCreatePermissions.add(getDomainCreatePostCreateSysPermission(resultSet)); 51 | } 52 | resultSet.close(); 53 | 54 | return domainCreatePermissions; 55 | } 56 | catch (SQLException e) { 57 | throw new RuntimeException(e); 58 | } 59 | finally { 60 | closeStatement(statement); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/persister/RecursiveGrantDomainCreatePermissionSysPersister.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.persister; 19 | 20 | import com.acciente.oacc.DomainCreatePermission; 21 | import com.acciente.oacc.Resource; 22 | import com.acciente.oacc.sql.SQLProfile; 23 | 24 | import java.io.Serializable; 25 | import java.sql.SQLException; 26 | import java.util.HashSet; 27 | import java.util.Set; 28 | 29 | public class RecursiveGrantDomainCreatePermissionSysPersister extends CommonGrantDomainCreatePermissionSysPersister implements Serializable { 30 | private static final long serialVersionUID = 1L; 31 | 32 | public RecursiveGrantDomainCreatePermissionSysPersister(SQLProfile sqlProfile, 33 | SQLStrings sqlStrings) { 34 | super(sqlProfile, sqlStrings); 35 | } 36 | 37 | @Override 38 | public Set getDomainCreateSysPermissionsIncludeInherited(SQLConnection connection, 39 | Resource accessorResource) { 40 | SQLStatement statement = null; 41 | 42 | try { 43 | statement = connection.prepareStatement(sqlStrings.SQL_findInGrantDomainCreatePermissionSys_SysPermissionID_IsWithGrant_BY_AccessorID); 44 | statement.setResourceId(1, accessorResource); 45 | SQLResult resultSet = statement.executeQuery(); 46 | 47 | // collect the create permissions that this resource has to domains 48 | Set domainCreatePermissions = new HashSet<>(); 49 | while (resultSet.next()) { 50 | domainCreatePermissions.add(getDomainCreateSysPermission(resultSet)); 51 | } 52 | resultSet.close(); 53 | 54 | return domainCreatePermissions; 55 | } 56 | catch (SQLException e) { 57 | throw new RuntimeException(e); 58 | } 59 | finally { 60 | closeStatement(statement); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/persister/RecursiveResourcePersister.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.persister; 19 | 20 | import com.acciente.oacc.sql.SQLProfile; 21 | import com.acciente.oacc.sql.internal.persister.id.DomainId; 22 | import com.acciente.oacc.sql.internal.persister.id.Id; 23 | 24 | import java.io.Serializable; 25 | import java.sql.SQLException; 26 | 27 | public class RecursiveResourcePersister extends CommonResourcePersister implements Serializable { 28 | private static final long serialVersionUID = 1L; 29 | 30 | public RecursiveResourcePersister(SQLProfile sqlProfile, 31 | SQLStrings sqlStrings) { 32 | super(sqlProfile, sqlStrings); 33 | } 34 | 35 | @Override 36 | public boolean isDomainEmpty(SQLConnection connection, Id resourceDomainId) { 37 | SQLStatement statement = null; 38 | 39 | try { 40 | SQLResult resultSet; 41 | 42 | statement = connection.prepareStatement(sqlStrings.SQL_findInResource_COUNTResourceID_BY_DomainID); 43 | statement.setResourceDomainId(1, resourceDomainId); 44 | resultSet = statement.executeQuery(); 45 | 46 | if (!resultSet.next()) { 47 | throw new IllegalArgumentException("Could not read resource count for domain: " + resourceDomainId); 48 | } 49 | 50 | final int count = resultSet.getInteger("COUNTResourceID"); 51 | 52 | resultSet.close(); 53 | 54 | return count == 0; 55 | } 56 | catch (SQLException e) { 57 | throw new RuntimeException(e); 58 | } 59 | finally { 60 | closeStatement(statement); 61 | } 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/persister/ResourceClassPermissionPersister.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.persister; 19 | 20 | import com.acciente.oacc.sql.SQLProfile; 21 | import com.acciente.oacc.sql.internal.persister.id.Id; 22 | import com.acciente.oacc.sql.internal.persister.id.ResourceClassId; 23 | import com.acciente.oacc.sql.internal.persister.id.ResourcePermissionId; 24 | 25 | import java.io.Serializable; 26 | import java.sql.SQLException; 27 | import java.util.LinkedList; 28 | import java.util.List; 29 | 30 | public class ResourceClassPermissionPersister extends Persister implements Serializable { 31 | private static final long serialVersionUID = 1L; 32 | 33 | protected final SQLProfile sqlProfile; 34 | private final SQLStrings sqlStrings; 35 | 36 | public ResourceClassPermissionPersister(SQLProfile sqlProfile, 37 | SQLStrings sqlStrings) { 38 | this.sqlProfile = sqlProfile; 39 | this.sqlStrings = sqlStrings; 40 | } 41 | 42 | public Id getResourceClassPermissionId(SQLConnection connection, 43 | Id resourceClassId, 44 | String permissionName) { 45 | SQLStatement statement = null; 46 | try { 47 | Id permissionId = null; 48 | 49 | // check if the permission name is already defined! 50 | statement = connection.prepareStatement(sqlStrings.SQL_findInResourceClassPermission_PermissionID_BY_ResourceClassID_PermissionName); 51 | statement.setResourceClassId(1, resourceClassId); 52 | statement.setString(2, permissionName); 53 | SQLResult resultSet = statement.executeQuery(); 54 | 55 | if (resultSet.next()) { 56 | permissionId = resultSet.getResourcePermissionId("PermissionId"); 57 | } 58 | resultSet.close(); 59 | 60 | return permissionId; 61 | } 62 | catch (SQLException e) { 63 | throw new RuntimeException(e); 64 | } 65 | finally { 66 | closeStatement(statement); 67 | } 68 | } 69 | 70 | public List getPermissionNames(SQLConnection connection, String resourceClassName) { 71 | SQLStatement statement = null; 72 | 73 | try { 74 | List resourceClassNames = new LinkedList<>(); 75 | 76 | statement = connection.prepareStatement(sqlStrings.SQL_findInResourceClassPermission_PermissionName_BY_ResourceClassName); 77 | statement.setString(1, resourceClassName); 78 | SQLResult resultSet = statement.executeQuery(); 79 | 80 | while (resultSet.next()) { 81 | resourceClassNames.add(resultSet.getString("PermissionName")); 82 | } 83 | 84 | return resourceClassNames; 85 | } 86 | catch (SQLException e) { 87 | throw new RuntimeException(e); 88 | } 89 | finally { 90 | closeStatement(statement); 91 | } 92 | } 93 | 94 | public void addResourceClassPermission(SQLConnection connection, 95 | Id resourceClassId, 96 | String permissionName) { 97 | SQLStatement statement = null; 98 | 99 | try { 100 | // finally add the new permission 101 | statement = connection.prepareStatement(sqlStrings.SQL_createInResourceClassPermission_WITH_ResourceClassID_PermissionName); 102 | statement.setResourceClassId(1, resourceClassId); 103 | statement.setString(2, permissionName); 104 | assertOneRowInserted(statement.executeUpdate()); 105 | } 106 | catch (SQLException e) { 107 | throw new RuntimeException(e); 108 | } 109 | finally { 110 | closeStatement(statement); 111 | } 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/persister/ResourcePersister.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.persister; 19 | 20 | import com.acciente.oacc.Resource; 21 | import com.acciente.oacc.sql.internal.persister.id.DomainId; 22 | import com.acciente.oacc.sql.internal.persister.id.Id; 23 | import com.acciente.oacc.sql.internal.persister.id.ResourceClassId; 24 | import com.acciente.oacc.sql.internal.persister.id.ResourceId; 25 | 26 | public interface ResourcePersister { 27 | void verifyResourceExists(SQLConnection connection, 28 | Resource resource); 29 | 30 | Resource createResource(SQLConnection connection, 31 | Id resourceClassId, 32 | Id resourceDomainId, 33 | String externalId); 34 | 35 | Resource setExternalId(SQLConnection connection, 36 | Id resourceId, 37 | String externalId); 38 | 39 | void deleteResource(SQLConnection connection, 40 | Resource resource); 41 | 42 | Id getDomainIdByResource(SQLConnection connection, 43 | Resource resource); 44 | 45 | Id getNextResourceId(SQLConnection connection); 46 | 47 | boolean isDomainEmpty(SQLConnection connection, 48 | Id resourceDomainId); 49 | 50 | Resource resolveResourceByExternalId(SQLConnection connection, 51 | String externalId); 52 | 53 | Resource resolveResourceByResourceId(SQLConnection connection, 54 | Resource resource); 55 | } 56 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/persister/SQLConnection.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.persister; 19 | 20 | import java.sql.Connection; 21 | import java.sql.SQLException; 22 | 23 | public class SQLConnection { 24 | private final Connection connection; 25 | 26 | public SQLConnection(Connection connection) { 27 | this.connection = connection; 28 | } 29 | 30 | public SQLStatement prepareStatement(String sql) throws SQLException { 31 | return new SQLStatement(connection.prepareStatement(sql)); 32 | } 33 | 34 | public SQLStatement prepareStatement(String sql, String[] generatedKeyColumns) throws SQLException { 35 | return new SQLStatement(connection.prepareStatement(sql, generatedKeyColumns)); 36 | } 37 | 38 | public void close() throws SQLException { 39 | this.connection.close(); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/persister/SQLPasswordStrings.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.persister; 19 | 20 | import java.io.Serializable; 21 | 22 | public class SQLPasswordStrings implements Serializable { 23 | private static final long serialVersionUID = 1L; 24 | 25 | // SQL string constants 26 | 27 | // ResourcePassword 28 | public final String SQL_findInResourcePassword_Password_BY_ResourceID; 29 | public final String SQL_createInResourcePassword_WITH_ResourceID_Password; 30 | public final String SQL_updateInResourcePassword_Password_BY_ResourceID; 31 | public final String SQL_removeInResourcePassword_BY_ResourceID; 32 | 33 | public static SQLPasswordStrings getSQLPasswordStrings(String schemaName) { 34 | return new SQLPasswordStrings(schemaName); 35 | } 36 | 37 | private SQLPasswordStrings(String schemaName) { 38 | final String schemaNameAndTablePrefix = schemaName != null ? schemaName + ".OAC_" : "OAC_"; 39 | 40 | // GrantDomainCreatePermissionSys 41 | SQL_findInResourcePassword_Password_BY_ResourceID 42 | = "SELECT Password FROM " 43 | + schemaNameAndTablePrefix 44 | + "ResourcePassword WHERE ResourceId = ?"; 45 | 46 | SQL_createInResourcePassword_WITH_ResourceID_Password 47 | = "INSERT INTO " 48 | + schemaNameAndTablePrefix 49 | + "ResourcePassword ( ResourceId, Password ) VALUES ( ?, ? )"; 50 | 51 | SQL_updateInResourcePassword_Password_BY_ResourceID 52 | = "UPDATE " + schemaNameAndTablePrefix + "ResourcePassword SET Password = ? WHERE ResourceId = ?"; 53 | 54 | SQL_removeInResourcePassword_BY_ResourceID 55 | = "DELETE FROM " + schemaNameAndTablePrefix + "ResourcePassword WHERE ResourceId = ?"; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/persister/SQLStatement.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.persister; 19 | 20 | import com.acciente.oacc.Resource; 21 | import com.acciente.oacc.sql.internal.persister.id.DomainId; 22 | import com.acciente.oacc.sql.internal.persister.id.Id; 23 | import com.acciente.oacc.sql.internal.persister.id.ResourceClassId; 24 | import com.acciente.oacc.sql.internal.persister.id.ResourceId; 25 | import com.acciente.oacc.sql.internal.persister.id.ResourcePermissionId; 26 | 27 | import java.sql.PreparedStatement; 28 | import java.sql.SQLException; 29 | 30 | public class SQLStatement { 31 | private final PreparedStatement statement; 32 | 33 | SQLStatement(PreparedStatement statement) { 34 | this.statement = statement; 35 | } 36 | 37 | public void setResourceId(int parameterIndex, Id resourceId) throws SQLException { 38 | statement.setLong(parameterIndex, resourceId.getValue()); 39 | } 40 | 41 | public void setResourceId(int parameterIndex, Resource resource) throws SQLException { 42 | statement.setLong(parameterIndex, resource.getId()); 43 | } 44 | 45 | public void setResourceClassId(int parameterIndex, Id id) throws SQLException { 46 | statement.setLong(parameterIndex, id.getValue()); 47 | } 48 | 49 | public void setResourceDomainId(int parameterIndex, Id id) throws SQLException { 50 | statement.setLong(parameterIndex, id.getValue()); 51 | } 52 | 53 | public void setResourceCreateSystemPermissionId(int parameterIndex, long resourceCreateSystemPermissionId) throws SQLException { 54 | statement.setLong(parameterIndex, resourceCreateSystemPermissionId); 55 | } 56 | 57 | public void setResourceSystemPermissionId(int parameterIndex, long resourceSystemPermissionId) throws SQLException { 58 | statement.setLong(parameterIndex, resourceSystemPermissionId); 59 | } 60 | 61 | public void setResourcePermissionId(int parameterIndex, 62 | Id resourcePermissionId) throws SQLException { 63 | statement.setLong(parameterIndex, resourcePermissionId.getValue()); 64 | } 65 | 66 | public void setDomainCreateSystemPermissionId(int parameterIndex, long domainCreateSystemPermissionId) throws SQLException { 67 | statement.setLong(parameterIndex, domainCreateSystemPermissionId); 68 | } 69 | 70 | public void setDomainSystemPermissionId(int parameterIndex, long domainSystemPermissionId) throws SQLException { 71 | statement.setLong(parameterIndex, domainSystemPermissionId); 72 | } 73 | 74 | public void setBoolean(int parameterIndex, boolean value) throws SQLException { 75 | statement.setInt(parameterIndex, bool2int(value)); 76 | } 77 | 78 | public void setString(int parameterIndex, String value) throws SQLException { 79 | statement.setString(parameterIndex, value); 80 | } 81 | 82 | public void setNull(int parameterIndex, int sqlType) throws SQLException { 83 | statement.setNull(parameterIndex, sqlType); 84 | } 85 | 86 | SQLResult executeQuery() throws SQLException { 87 | return new SQLResult(statement.executeQuery()); 88 | } 89 | 90 | int executeUpdate() throws SQLException { 91 | return statement.executeUpdate(); 92 | } 93 | 94 | public SQLResult getGeneratedKeys() throws SQLException { 95 | return new SQLResult(statement.getGeneratedKeys()); 96 | } 97 | 98 | void close() throws SQLException { 99 | statement.close(); 100 | } 101 | 102 | // helpers 103 | 104 | private static int bool2int(boolean value) { 105 | return value ? 1 : 0; 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/persister/id/DomainId.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.persister.id; 19 | 20 | public interface DomainId { 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/persister/id/Id.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.persister.id; 19 | 20 | public class Id { 21 | private final long idValue; 22 | 23 | private Id(long idValue) { 24 | this.idValue = idValue; 25 | } 26 | 27 | public long getValue() { 28 | return idValue; 29 | } 30 | 31 | public static Id from(Long idValue) { 32 | if (idValue == null) { 33 | return null; 34 | } 35 | return new Id<>(idValue); 36 | } 37 | 38 | public static Id from(Integer idValue) { 39 | if (idValue == null) { 40 | return null; 41 | } 42 | return new Id<>(idValue); 43 | } 44 | 45 | @Override 46 | public boolean equals(Object other) { 47 | if (this == other) { 48 | return true; 49 | } 50 | if (other == null || getClass() != other.getClass()) { 51 | return false; 52 | } 53 | 54 | Id otherId = (Id) other; 55 | 56 | if (idValue != otherId.idValue) { 57 | return false; 58 | } 59 | 60 | return true; 61 | } 62 | 63 | @Override 64 | public int hashCode() { 65 | return (int) (idValue ^ (idValue >>> 32)); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/persister/id/ResourceClassId.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.persister.id; 19 | 20 | public interface ResourceClassId { 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/persister/id/ResourceId.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.persister.id; 19 | 20 | public interface ResourceId { 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/acciente/oacc/sql/internal/persister/id/ResourcePermissionId.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.sql.internal.persister.id; 19 | 20 | public interface ResourcePermissionId { 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/TestAccessControl_getResourceClassNames.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc; 19 | 20 | import org.junit.Test; 21 | 22 | import java.util.List; 23 | 24 | import static org.hamcrest.CoreMatchers.hasItems; 25 | import static org.hamcrest.CoreMatchers.is; 26 | import static org.hamcrest.CoreMatchers.not; 27 | import static org.hamcrest.CoreMatchers.nullValue; 28 | import static org.junit.Assert.assertThat; 29 | 30 | public class TestAccessControl_getResourceClassNames extends TestAccessControlBase { 31 | @Test 32 | public void getResourceClassNames_empty_asSystemResource() { 33 | authenticateSystemResource(); 34 | 35 | // verify 36 | final List resourceClassNames = accessControlContext.getResourceClassNames(); 37 | assertThat(resourceClassNames, is(not(nullValue()))); 38 | assertThat(resourceClassNames.isEmpty(), is(true)); 39 | } 40 | 41 | @Test 42 | public void getResourceClassNames_validAsSystemResource() { 43 | authenticateSystemResource(); 44 | 45 | final String resourceClassName1 = generateResourceClass(true, false); 46 | final String resourceClassName2 = generateResourceClass(false, true); 47 | 48 | // verify 49 | final List resourceClassNames = accessControlContext.getResourceClassNames(); 50 | assertThat(resourceClassNames, is(not(nullValue()))); 51 | assertThat(resourceClassNames.size(), is(2)); 52 | assertThat(resourceClassNames, hasItems(resourceClassName1, resourceClassName2)); 53 | } 54 | 55 | @Test 56 | public void getResourceClassNames_validAsAuthenticated() { 57 | authenticateSystemResource(); 58 | 59 | final char[] password = generateUniquePassword(); 60 | final Resource accessorResource = generateAuthenticatableResource(password); 61 | final String accessorResourceClassName 62 | = accessControlContext.getResourceClassInfoByResource(accessorResource).getResourceClassName(); 63 | 64 | final String resourceClassName1 = generateResourceClass(true, false); 65 | final String resourceClassName2 = generateResourceClass(false, true); 66 | 67 | // authenticate and verify 68 | accessControlContext.authenticate(accessorResource, PasswordCredentials.newInstance(password)); 69 | 70 | final List resourceClassNames = accessControlContext.getResourceClassNames(); 71 | assertThat(resourceClassNames, is(not(nullValue()))); 72 | assertThat(resourceClassNames.size(), is(3)); 73 | assertThat(resourceClassNames, hasItems(resourceClassName1, resourceClassName2, accessorResourceClassName)); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/TestAccessControl_unauthenticate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc; 19 | 20 | import com.acciente.oacc.helper.TestConfigLoader; 21 | import org.junit.Test; 22 | 23 | import static org.hamcrest.CoreMatchers.containsString; 24 | import static org.hamcrest.CoreMatchers.is; 25 | import static org.junit.Assert.assertThat; 26 | import static org.junit.Assert.fail; 27 | 28 | public class TestAccessControl_unauthenticate extends TestAccessControlBase { 29 | @Test 30 | public void unauthenticate_authenticatedSystemUser() { 31 | accessControlContext.authenticate(getSystemResource(), 32 | PasswordCredentials.newInstance(TestConfigLoader.getOaccRootPassword())); 33 | 34 | assertThat(accessControlContext.getAuthenticatedResource(), is(SYS_RESOURCE)); 35 | assertThat(accessControlContext.getSessionResource(), is(SYS_RESOURCE)); 36 | 37 | // unauthenticate and verify 38 | accessControlContext.unauthenticate(); 39 | 40 | // the current contract specifies the getting authenticated or session resources should fail when unauthenticated 41 | // assertThat(accessControlContext.getAuthenticatedResource(), is(nullValue())); 42 | // assertThat(accessControlContext.getSessionResource(), is(nullValue())); 43 | try { 44 | accessControlContext.getAuthenticatedResource(); 45 | fail("calling getAuthenticatedResource() from an unauthenticated context should have failed"); 46 | } 47 | catch (NotAuthenticatedException e) { 48 | assertThat(e.getMessage().toLowerCase(), containsString("not authenticated")); 49 | } 50 | 51 | try { 52 | accessControlContext.getSessionResource(); 53 | fail("calling getSessionResource() from an unauthenticated context should have failed"); 54 | } 55 | catch (NotAuthenticatedException e) { 56 | assertThat(e.getMessage().toLowerCase(), containsString("not authenticated")); 57 | } 58 | 59 | // check idempotency 60 | accessControlContext.unauthenticate(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/TestAccessControl_unimpersonate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc; 19 | 20 | import org.junit.Test; 21 | 22 | import static org.hamcrest.CoreMatchers.is; 23 | import static org.junit.Assert.assertThat; 24 | 25 | public class TestAccessControl_unimpersonate extends TestAccessControlBase { 26 | @Test 27 | public void unimpersonate_valid_asSystemResource() { 28 | authenticateSystemResource(); 29 | 30 | final Resource impersonatedResource = generateAuthenticatableResource(generateUniquePassword()); 31 | accessControlContext.impersonate(impersonatedResource); 32 | 33 | // verify 34 | accessControlContext.unimpersonate(); 35 | 36 | assertThat(accessControlContext.getAuthenticatedResource(), is(SYS_RESOURCE)); 37 | assertThat(accessControlContext.getSessionResource(), is(SYS_RESOURCE)); 38 | } 39 | 40 | @Test 41 | public void unimpersonate_unimpersonated_succeedsAsSystemResource() { 42 | authenticateSystemResource(); 43 | 44 | generateAuthenticatableResource(generateUniquePassword()); 45 | 46 | // verify 47 | accessControlContext.unimpersonate(); 48 | 49 | assertThat(accessControlContext.getAuthenticatedResource(), is(SYS_RESOURCE)); 50 | assertThat(accessControlContext.getSessionResource(), is(SYS_RESOURCE)); 51 | } 52 | 53 | @Test 54 | public void unimpersonate_valid_asAuthenticatedResource() { 55 | authenticateSystemResource(); 56 | 57 | final char[] password = generateUniquePassword(); 58 | final Resource accessorResource = generateAuthenticatableResource(password); 59 | final Resource impersonatedResource = generateAuthenticatableResource(generateUniquePassword()); 60 | 61 | // set up accessor --IMPERSONATE-> impersonatedResource 62 | accessControlContext.setResourcePermissions(accessorResource, 63 | impersonatedResource, 64 | setOf(ResourcePermissions.getInstance(ResourcePermissions.IMPERSONATE))); 65 | // authenticate & impersonate 66 | accessControlContext.authenticate(accessorResource, PasswordCredentials.newInstance(password)); 67 | accessControlContext.impersonate(impersonatedResource); 68 | 69 | // verify 70 | accessControlContext.unimpersonate(); 71 | 72 | assertThat(accessControlContext.getAuthenticatedResource(), is(accessorResource)); 73 | assertThat(accessControlContext.getSessionResource(), is(accessorResource)); 74 | } 75 | 76 | @Test 77 | public void unimpersonate_unimpersonated_succeedsAsAuthenticatedResource() { 78 | authenticateSystemResource(); 79 | 80 | final char[] password = generateUniquePassword(); 81 | final Resource accessorResource = generateAuthenticatableResource(password); 82 | final Resource impersonatedResource = generateAuthenticatableResource(generateUniquePassword()); 83 | 84 | // set up accessor --IMPERSONATE-> impersonatedResource 85 | accessControlContext.setResourcePermissions(accessorResource, 86 | impersonatedResource, 87 | setOf(ResourcePermissions.getInstance(ResourcePermissions.IMPERSONATE))); 88 | // authenticate 89 | accessControlContext.authenticate(accessorResource, PasswordCredentials.newInstance(password)); 90 | 91 | // verify 92 | accessControlContext.unimpersonate(); 93 | 94 | assertThat(accessControlContext.getAuthenticatedResource(), is(accessorResource)); 95 | assertThat(accessControlContext.getSessionResource(), is(accessorResource)); 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/TestResource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc; 19 | 20 | import org.junit.Test; 21 | 22 | import static org.hamcrest.CoreMatchers.is; 23 | import static org.junit.Assert.assertThat; 24 | 25 | public class TestResource { 26 | @Test 27 | public void toString_resourceIdOnly() { 28 | final long resourceId = 123L; 29 | final String stringRepresentation = Resources.getInstance(resourceId).toString(); 30 | assertThat(stringRepresentation, is("{resourceId: " + resourceId + "}")); 31 | } 32 | 33 | @Test 34 | public void toString_externalIdOnly() { 35 | final String externalId = "007"; 36 | final String stringRepresentation = Resources.getInstance(externalId).toString(); 37 | assertThat(stringRepresentation, is("{externalId: \"" + externalId + "\"}")); 38 | } 39 | 40 | @Test 41 | public void toString_resourceIdAndExternalId() { 42 | final long resourceId = 123L; 43 | final String externalId = "007"; 44 | final String stringRepresentation = Resources.getInstance(resourceId, externalId).toString(); 45 | assertThat(stringRepresentation, is("{resourceId: " + resourceId 46 | + ", externalId: \"" + externalId + "\"}")); 47 | } 48 | 49 | @Test 50 | public void toString_neitherResourceIdNorExternalId() { 51 | final String stringRepresentation = Resources.getInstance(null).toString(); 52 | assertThat(stringRepresentation, is("{}")); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/TestSQLAccessControlContextFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc; 19 | 20 | import com.acciente.oacc.encryptor.PasswordEncryptor; 21 | import com.acciente.oacc.helper.TestConfigLoader; 22 | import com.acciente.oacc.sql.SQLAccessControlContextFactory; 23 | import com.acciente.oacc.sql.internal.SQLPasswordAuthenticationProvider; 24 | import org.junit.Test; 25 | 26 | import javax.sql.DataSource; 27 | import java.sql.Connection; 28 | import java.sql.SQLException; 29 | 30 | import static org.hamcrest.CoreMatchers.containsString; 31 | import static org.junit.Assert.assertThat; 32 | import static org.junit.Assert.fail; 33 | 34 | public class TestSQLAccessControlContextFactory { 35 | @Test 36 | public void getAccessControlContext_invalidSchemaName_shouldFail() throws SQLException { 37 | final String invalidSchemaName = "oacc.temp;drop database oaccdb;--"; 38 | 39 | final DataSource dataSource = TestConfigLoader.getDataSource(); 40 | final Connection connection = dataSource.getConnection(); 41 | 42 | try { 43 | SQLAccessControlContextFactory.getAccessControlContext(dataSource, 44 | invalidSchemaName, 45 | null, 46 | (PasswordEncryptor) null); 47 | fail("getting access control context with invalid schema name should have failed"); 48 | } 49 | catch (IllegalArgumentException e) { 50 | assertThat(e.getMessage().toLowerCase(), containsString("invalid database schema name")); 51 | } 52 | try { 53 | SQLAccessControlContextFactory.getAccessControlContext(dataSource, 54 | invalidSchemaName, 55 | null, 56 | (SQLPasswordAuthenticationProvider) null); 57 | fail("getting access control context with invalid schema name should have failed"); 58 | } 59 | catch (IllegalArgumentException e) { 60 | assertThat(e.getMessage().toLowerCase(), containsString("invalid database schema name")); 61 | } 62 | 63 | try { 64 | SQLAccessControlContextFactory.getAccessControlContext(connection, 65 | invalidSchemaName, 66 | null, 67 | (PasswordEncryptor) null); 68 | fail("getting access control context with invalid schema name should have failed"); 69 | } 70 | catch (IllegalArgumentException e) { 71 | assertThat(e.getMessage().toLowerCase(), containsString("invalid database schema name")); 72 | } 73 | try { 74 | SQLAccessControlContextFactory.getAccessControlContext(connection, 75 | invalidSchemaName, 76 | null, 77 | (SQLPasswordAuthenticationProvider) null); 78 | fail("getting access control context with invalid schema name should have failed"); 79 | } 80 | catch (IllegalArgumentException e) { 81 | assertThat(e.getMessage().toLowerCase(), containsString("invalid database schema name")); 82 | } 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/encryptor/bcrypt/PasswordEncoderDecoderTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | 19 | package com.acciente.oacc.encryptor.bcrypt; 20 | 21 | import org.junit.Test; 22 | 23 | import static org.hamcrest.core.Is.is; 24 | import static org.hamcrest.core.StringEndsWith.endsWith; 25 | import static org.junit.Assert.assertThat; 26 | import static org.junit.Assert.fail; 27 | 28 | public class PasswordEncoderDecoderTest { 29 | private static final String MARKER = "bcrypt:"; 30 | private static final String BCRYPT_STRING = "$2a$12$HfshGe6U0YWGy0ylODEFx.aOIq44QupzArT1LYuAwffwLqHAhGZIW"; 31 | private static final String ENCODED_PASSWORD = MARKER + BCRYPT_STRING; 32 | private static final String ENCODED_INVALID_PASSWORD = "jasypt:(the-content-in-parens-does-not-matter)"; 33 | 34 | private final PasswordEncoderDecoder encoderDecoder = new PasswordEncoderDecoder(); 35 | 36 | @Test 37 | public void encodePassword() throws Exception { 38 | final String encodedPassword = encoderDecoder.encode(BCRYPT_STRING); 39 | 40 | assertThat(encodedPassword, is(ENCODED_PASSWORD)); 41 | } 42 | 43 | @Test 44 | public void decodePassword() throws Exception { 45 | final String bcryptString = encoderDecoder.decode(ENCODED_PASSWORD); 46 | 47 | assertThat(bcryptString, is(BCRYPT_STRING)); 48 | } 49 | 50 | @Test 51 | public void decodePasswordCheckExceptionDoesNotContainFullEncodedPassword() throws Exception { 52 | try { 53 | encoderDecoder.decode(ENCODED_INVALID_PASSWORD); 54 | fail("Expected IllegalArgumentException, but not thrown"); 55 | } 56 | catch (IllegalArgumentException e) { 57 | assertThat(e.getMessage(), endsWith(ENCODED_INVALID_PASSWORD.substring(0, MARKER.length()))); 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/encryptor/jasypt/JasyptPasswordEncryptorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | 19 | package com.acciente.oacc.encryptor.jasypt; 20 | 21 | import org.junit.Test; 22 | 23 | import static org.hamcrest.core.Is.is; 24 | import static org.hamcrest.core.IsEqual.equalTo; 25 | import static org.hamcrest.core.IsNot.not; 26 | import static org.hamcrest.core.IsNull.nullValue; 27 | import static org.hamcrest.core.StringStartsWith.startsWith; 28 | import static org.junit.Assert.assertThat; 29 | 30 | public class JasyptPasswordEncryptorTest { 31 | private final JasyptPasswordEncryptor encryptor = JasyptPasswordEncryptor.newInstance("SHA-256", 100000, 16); 32 | 33 | @Test 34 | public void encryptNullPassword() throws Exception { 35 | final char[] testPassword = null; 36 | 37 | final String encryptedPassword = encryptor.encryptPassword(testPassword); 38 | 39 | assertThat(encryptedPassword, is(nullValue())); 40 | } 41 | 42 | @Test 43 | public void encryptPasswordDifferentHashesForSamePassword() throws Exception { 44 | final char[] testPassword = "SomePasswordHere".toCharArray(); 45 | 46 | final String encryptedPasswordPass1 = encryptor.encryptPassword(testPassword); 47 | final String encryptedPasswordPass2 = encryptor.encryptPassword(testPassword); 48 | 49 | assertThat(encryptedPasswordPass1, not(equalTo(encryptedPasswordPass2))); 50 | } 51 | 52 | @Test 53 | public void encryptPasswordHeaderMarkerPresent() throws Exception { 54 | final char[] testPassword = "SomePasswordHere".toCharArray(); 55 | 56 | final String encryptedPasswordPass = encryptor.encryptPassword(testPassword); 57 | 58 | assertThat(encryptedPasswordPass, startsWith(JasyptPasswordEncryptor.NAME + ":")); 59 | } 60 | 61 | @Test 62 | public void checkNullPasswords() throws Exception { 63 | final char[] testPassword = null; 64 | 65 | final String encryptedPassword = encryptor.encryptPassword(testPassword); 66 | 67 | assertThat(encryptor.checkPassword(testPassword, encryptedPassword), is(true)); 68 | } 69 | 70 | @Test 71 | public void checkNullPassword() throws Exception { 72 | final char[] testPassword = "SomePasswordHere".toCharArray(); 73 | 74 | final String encryptedPassword = encryptor.encryptPassword(testPassword); 75 | 76 | assertThat(encryptor.checkPassword(null, encryptedPassword), is(false)); 77 | } 78 | 79 | @Test 80 | public void checkNullStoredPassword() throws Exception { 81 | final char[] testPassword = "SomePasswordHere".toCharArray(); 82 | 83 | assertThat(encryptor.checkPassword(testPassword, null), is(false)); 84 | } 85 | 86 | @Test 87 | public void checkPassword() throws Exception { 88 | final char[] testPassword = "SomePasswordHere".toCharArray(); 89 | 90 | final String encryptedPasswordPass1 = encryptor.encryptPassword(testPassword); 91 | 92 | assertThat(encryptor.checkPassword(testPassword, encryptedPasswordPass1), is(true)); 93 | } 94 | 95 | @Test 96 | public void checkNormalizedPassword() throws Exception { 97 | final char[] combiningSequencePwd = new char[]{'A', 0x30a}; // A, combining-ring-above 98 | final char[] singleCharacterPwd = new char[]{0x00c5}; // latin-capital-a-with-ring-above (Å) 99 | 100 | final String encryptedPasswordPass1 = encryptor.encryptPassword(combiningSequencePwd); 101 | 102 | assertThat(encryptor.checkPassword(singleCharacterPwd, encryptedPasswordPass1), is(true)); 103 | } 104 | } -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/encryptor/jasypt/LegacyJasyptPasswordEncryptorTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | 19 | package com.acciente.oacc.encryptor.jasypt; 20 | 21 | import org.junit.Test; 22 | 23 | import static org.hamcrest.core.Is.is; 24 | import static org.hamcrest.core.IsEqual.equalTo; 25 | import static org.hamcrest.core.IsNot.not; 26 | import static org.hamcrest.core.IsNull.nullValue; 27 | import static org.hamcrest.core.StringStartsWith.startsWith; 28 | import static org.junit.Assert.assertThat; 29 | 30 | public class LegacyJasyptPasswordEncryptorTest { 31 | private final LegacyJasyptPasswordEncryptor encryptor = LegacyJasyptPasswordEncryptor.newInstance(); 32 | 33 | @Test 34 | public void encryptNullPassword() throws Exception { 35 | final char[] testPassword = null; 36 | 37 | final String encryptedPassword = encryptor.encryptPassword(testPassword); 38 | 39 | assertThat(encryptedPassword, is(nullValue())); 40 | } 41 | 42 | @Test 43 | public void encryptPasswordDifferentHashesForSamePassword() throws Exception { 44 | final char[] testPassword = "SomePasswordHere".toCharArray(); 45 | 46 | final String encryptedPasswordPass1 = encryptor.encryptPassword(testPassword); 47 | final String encryptedPasswordPass2 = encryptor.encryptPassword(testPassword); 48 | 49 | assertThat(encryptedPasswordPass1, not(equalTo(encryptedPasswordPass2))); 50 | } 51 | 52 | @Test 53 | public void encryptPasswordHeaderMarkerNotPresent() throws Exception { 54 | final char[] testPassword = "SomePasswordHere".toCharArray(); 55 | 56 | final String encryptedPasswordPass = encryptor.encryptPassword(testPassword); 57 | 58 | assertThat(encryptedPasswordPass, not(startsWith(JasyptPasswordEncryptor.NAME + ":"))); 59 | } 60 | 61 | @Test 62 | public void checkNullPasswords() throws Exception { 63 | final char[] testPassword = null; 64 | 65 | final String encryptedPassword = encryptor.encryptPassword(testPassword); 66 | 67 | assertThat(encryptor.checkPassword(testPassword, encryptedPassword), is(true)); 68 | } 69 | 70 | @Test 71 | public void checkNullPassword() throws Exception { 72 | final char[] testPassword = "SomePasswordHere".toCharArray(); 73 | 74 | final String encryptedPassword = encryptor.encryptPassword(testPassword); 75 | 76 | assertThat(encryptor.checkPassword(null, encryptedPassword), is(false)); 77 | } 78 | 79 | @Test 80 | public void checkNullStoredPassword() throws Exception { 81 | final char[] testPassword = "SomePasswordHere".toCharArray(); 82 | 83 | assertThat(encryptor.checkPassword(testPassword, null), is(false)); 84 | } 85 | 86 | @Test 87 | public void checkPassword() throws Exception { 88 | final char[] testPassword = "SomePasswordHere".toCharArray(); 89 | 90 | final String encryptedPasswordPass1 = encryptor.encryptPassword(testPassword); 91 | 92 | assertThat(encryptor.checkPassword(testPassword, encryptedPasswordPass1), is(true)); 93 | } 94 | 95 | @Test 96 | public void checkNormalizedPassword() throws Exception { 97 | final char[] combiningSequencePwd = new char[]{'A', 0x30a}; // A, combining-ring-above 98 | final char[] singleCharacterPwd = new char[]{0x00c5}; // latin-capital-a-with-ring-above (Å) 99 | 100 | final String encryptedPasswordPass1 = encryptor.encryptPassword(combiningSequencePwd); 101 | 102 | assertThat(encryptor.checkPassword(singleCharacterPwd, encryptedPasswordPass1), is(true)); 103 | } 104 | } -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/encryptor/jasypt/PasswordEncoderDecoderTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | 19 | package com.acciente.oacc.encryptor.jasypt; 20 | 21 | import org.jasypt.contrib.org.apache.commons.codec_1_3.binary.Base64; 22 | import org.junit.Test; 23 | 24 | import java.nio.charset.StandardCharsets; 25 | 26 | import static org.hamcrest.core.Is.is; 27 | import static org.hamcrest.core.StringEndsWith.endsWith; 28 | import static org.hamcrest.core.StringStartsWith.startsWith; 29 | import static org.junit.Assert.assertThat; 30 | import static org.junit.Assert.fail; 31 | 32 | public class PasswordEncoderDecoderTest { 33 | private final PasswordEncoderDecoder encoderDecoder = new PasswordEncoderDecoder(); 34 | 35 | private static final Base64 base64 = new Base64(); 36 | private static final String MARKER = "jasypt:"; 37 | private static final String DELIMITER = "$"; 38 | 39 | private static final String DECODED_PASSWORD_ALGORITHM = "TEST-algorithm"; 40 | private static final int DECODED_PASSWORD_ITERATIONS = 1243322; 41 | private static final int DECODED_PASSWORD_SALT_SIZE_BYTES = 33; 42 | private static final byte[] DECODED_PASSWORD_DIGEST = "TEST-digest".getBytes(); 43 | 44 | private static final String ENCODED_PASSWORD = MARKER + 45 | DECODED_PASSWORD_ALGORITHM + DELIMITER + 46 | DECODED_PASSWORD_ITERATIONS + DELIMITER + 47 | DECODED_PASSWORD_SALT_SIZE_BYTES + DELIMITER + 48 | new String(base64.encode(DECODED_PASSWORD_DIGEST), StandardCharsets.US_ASCII); 49 | 50 | private static final String ENCODED_LEGACY_PASSWORD = 51 | new String(base64.encode(DECODED_PASSWORD_DIGEST), StandardCharsets.US_ASCII); 52 | 53 | private static final String ENCODED_INVALID_PASSWORD = "jasypt:(the-content-in-parens-does-not-matter)"; 54 | 55 | @Test 56 | public void testEncodePassword() throws Exception { 57 | final String encodedPassword = encoderDecoder.encode(DECODED_PASSWORD_ALGORITHM, 58 | DECODED_PASSWORD_ITERATIONS, 59 | DECODED_PASSWORD_SALT_SIZE_BYTES, 60 | DECODED_PASSWORD_DIGEST); 61 | assertThat(encodedPassword, is(ENCODED_PASSWORD)); 62 | } 63 | 64 | @Test 65 | public void testDecodePassword() throws Exception { 66 | final DecodedPassword decodedPassword = encoderDecoder.decode(ENCODED_PASSWORD); 67 | 68 | assertThat(decodedPassword.getAlgorithm(), is(DECODED_PASSWORD_ALGORITHM)); 69 | assertThat(decodedPassword.getIterations(), is(DECODED_PASSWORD_ITERATIONS)); 70 | assertThat(decodedPassword.getSaltSizeBytes(), is(DECODED_PASSWORD_SALT_SIZE_BYTES)); 71 | assertThat(decodedPassword.getDigest(), is(DECODED_PASSWORD_DIGEST)); 72 | } 73 | 74 | @Test 75 | public void testDecodeLegacyPassword() throws Exception { 76 | try { 77 | encoderDecoder.decode(ENCODED_LEGACY_PASSWORD); 78 | fail("Expected an IllegalArgumentException"); 79 | } 80 | catch (IllegalArgumentException e) { 81 | assertThat(e.getMessage(), startsWith("Unexpected marker for Jasypt password:")); 82 | } 83 | } 84 | 85 | @Test 86 | public void decodePasswordCheckExceptionDoesNotContainFullEncodedPassword() throws Exception { 87 | try { 88 | encoderDecoder.decode(ENCODED_INVALID_PASSWORD); 89 | fail("Expected IllegalArgumentException, but not thrown"); 90 | } 91 | catch (IllegalArgumentException e) { 92 | assertThat(e.getMessage(), endsWith(ENCODED_INVALID_PASSWORD.substring(0, MARKER.length()))); 93 | } 94 | } 95 | } -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/encryptor/jasypt/StandardByteDigesterPoolTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.encryptor.jasypt; 19 | 20 | import org.jasypt.digest.StandardByteDigester; 21 | import org.junit.Test; 22 | 23 | import static org.hamcrest.core.IsNot.not; 24 | import static org.hamcrest.core.IsNull.nullValue; 25 | import static org.hamcrest.core.IsSame.sameInstance; 26 | import static org.junit.Assert.assertThat; 27 | 28 | public class StandardByteDigesterPoolTest { 29 | private final StandardByteDigesterPool pool = new StandardByteDigesterPool(); 30 | 31 | @Test 32 | public void testSameInstanceReturned() throws Exception { 33 | final StandardByteDigester digester_1 = pool.getStandardByteDigester("SHA-256", 1000, 16); 34 | final StandardByteDigester digester_2 = pool.getStandardByteDigester("SHA-256", 1000, 16); 35 | 36 | assertThat(digester_1, not(nullValue())); 37 | assertThat(digester_2, not(nullValue())); 38 | assertThat(digester_2, sameInstance(digester_1)); 39 | } 40 | 41 | @Test 42 | public void testDifferentInstanceReturned() throws Exception { 43 | final StandardByteDigester digester_1 = pool.getStandardByteDigester("SHA-256", 1000, 16); 44 | final StandardByteDigester digester_2 = pool.getStandardByteDigester("SHA-256", 2000, 16); 45 | 46 | assertThat(digester_1, not(nullValue())); 47 | assertThat(digester_2, not(nullValue())); 48 | assertThat(digester_2, not(sameInstance(digester_1))); 49 | } 50 | 51 | @Test 52 | public void testDifferentInstanceThenSameInstanceReturned() throws Exception { 53 | final StandardByteDigester digester_1 = pool.getStandardByteDigester("SHA-256", 1000, 16); 54 | final StandardByteDigester digester_2 = pool.getStandardByteDigester("SHA-256", 2000, 16); 55 | final StandardByteDigester digester_3 = pool.getStandardByteDigester("SHA-256", 1000, 16); 56 | final StandardByteDigester digester_4 = pool.getStandardByteDigester("SHA-256", 2000, 16); 57 | 58 | assertThat(digester_1, not(nullValue())); 59 | assertThat(digester_2, not(nullValue())); 60 | assertThat(digester_3, not(nullValue())); 61 | assertThat(digester_4, not(nullValue())); 62 | 63 | assertThat(digester_2, not(sameInstance(digester_1))); 64 | assertThat(digester_3, sameInstance(digester_1)); 65 | assertThat(digester_4, sameInstance(digester_2)); 66 | } 67 | } -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/helper/CaseSensitiveChecker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.helper; 19 | 20 | import javax.sql.DataSource; 21 | import java.sql.Connection; 22 | import java.sql.PreparedStatement; 23 | import java.sql.ResultSet; 24 | import java.sql.SQLException; 25 | 26 | public class CaseSensitiveChecker { 27 | private static final String SENTINEL_VALUE__lower = "test_domain_case_sensitivity"; 28 | private static final String SENTINEL_VALUE__UPPER = SENTINEL_VALUE__lower.toUpperCase(); 29 | private static final String INSERT_SENTINEL_VALUE = "INSERT INTO " 30 | + DbBase.getSchemaAndTableNamePrefix(TestConfigLoader.getDatabaseSchema()) 31 | + "Domain (DomainID, DomainName) VALUES (?, ?)"; 32 | private static final String SELECT_SENTINEL_VALUES = "SELECT DomainID, DomainName FROM " 33 | + DbBase.getSchemaAndTableNamePrefix(TestConfigLoader.getDatabaseSchema()) 34 | + "Domain WHERE DomainName = ?"; 35 | private static final String DELETE_SENTINEL_VALUES = "DELETE FROM " 36 | + DbBase.getSchemaAndTableNamePrefix(TestConfigLoader.getDatabaseSchema()) 37 | + "Domain WHERE DomainName = ? OR DomainName = ?"; 38 | 39 | public static boolean isDatabaseCaseSensitive(DataSource dataSource) throws SQLException { 40 | boolean isSensitive = true; 41 | boolean hasSentinels = false; 42 | 43 | try (Connection connection = dataSource.getConnection(); 44 | PreparedStatement deleteSentinelsStmt = connection.prepareStatement(DELETE_SENTINEL_VALUES); 45 | PreparedStatement insertSentinelStmt = connection.prepareStatement(INSERT_SENTINEL_VALUE); 46 | PreparedStatement selectSentinelsStmt = connection.prepareStatement(SELECT_SENTINEL_VALUES);) { 47 | deleteSentinelsStmt.setString(1, SENTINEL_VALUE__lower); 48 | deleteSentinelsStmt.setString(2, SENTINEL_VALUE__UPPER); 49 | deleteSentinelsStmt.executeUpdate(); 50 | 51 | insertSentinelStmt.setInt(1, -999); 52 | insertSentinelStmt.setString(2, SENTINEL_VALUE__lower); 53 | insertSentinelStmt.executeUpdate(); 54 | hasSentinels = true; 55 | 56 | insertSentinelStmt.setInt(1, -998); 57 | insertSentinelStmt.setString(2, SENTINEL_VALUE__UPPER); 58 | insertSentinelStmt.executeUpdate(); 59 | 60 | selectSentinelsStmt.setString(1, SENTINEL_VALUE__lower); 61 | final ResultSet resultSet = selectSentinelsStmt.executeQuery(); 62 | resultSet.next(); 63 | isSensitive = ! resultSet.next(); 64 | System.out.println("Database is " + (isSensitive ? "case sensitive" : "not case sensitive") ); 65 | } 66 | finally { 67 | if (hasSentinels) { 68 | try (Connection connection = dataSource.getConnection(); 69 | PreparedStatement deleteSentinelsStmt = connection.prepareStatement(DELETE_SENTINEL_VALUES);) { 70 | deleteSentinelsStmt.setString(1, SENTINEL_VALUE__lower); 71 | deleteSentinelsStmt.setString(2, SENTINEL_VALUE__UPPER); 72 | deleteSentinelsStmt.executeUpdate(); 73 | } 74 | } 75 | } 76 | 77 | return isSensitive; 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/helper/DbBase.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.helper; 19 | 20 | import java.sql.ResultSet; 21 | import java.sql.SQLException; 22 | 23 | public class DbBase { 24 | protected static String getSchemaAndTableNamePrefix(String schemaName) { 25 | return schemaName != null ? schemaName + ".OAC_" : "OAC_"; 26 | } 27 | 28 | protected static Long getLong(ResultSet resultSet, String columnLabel) throws SQLException { 29 | final long longValue = resultSet.getLong(columnLabel); 30 | if (resultSet.wasNull()) { 31 | return null; 32 | } 33 | return longValue; 34 | } 35 | 36 | protected static Short getShort(ResultSet resultSet, String columnLabel) throws SQLException { 37 | final short shortValue = resultSet.getShort(columnLabel); 38 | if (resultSet.wasNull()) { 39 | return null; 40 | } 41 | return shortValue; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/helper/OACC_Grant_Global_ResPerm.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.helper; 19 | 20 | import java.sql.Connection; 21 | import java.sql.PreparedStatement; 22 | import java.sql.ResultSet; 23 | import java.sql.SQLException; 24 | 25 | public class OACC_Grant_Global_ResPerm extends DbBase { 26 | 27 | private static String getQualifiedTableName(String schemaName) { 28 | return getSchemaAndTableNamePrefix(schemaName) + "Grant_Global_ResPerm"; 29 | } 30 | 31 | private static String getPKColumnNames() { 32 | return "AccessorResourceID, AccessedDomainID, ResourceClassID, PermissionId"; 33 | } 34 | 35 | public static class Finder { 36 | public static int getNumberOfRows(Connection con, String schemaName) throws SQLException { 37 | 38 | try (PreparedStatement preparedStatement 39 | = con.prepareStatement("SELECT COUNT(*) FROM (SELECT DISTINCT " + getPKColumnNames() + " FROM " + getQualifiedTableName(schemaName) + ") T"); 40 | ) { 41 | ResultSet resultSet = preparedStatement.executeQuery(); 42 | resultSet.next(); 43 | return resultSet.getInt(1); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/helper/OACC_Grant_Global_ResPerm_Sys.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.helper; 19 | 20 | import java.sql.Connection; 21 | import java.sql.PreparedStatement; 22 | import java.sql.ResultSet; 23 | import java.sql.SQLException; 24 | 25 | public class OACC_Grant_Global_ResPerm_Sys extends DbBase { 26 | 27 | private static String getQualifiedTableName(String schemaName) { 28 | return getSchemaAndTableNamePrefix(schemaName) + "Grant_Global_ResPerm_Sys"; 29 | } 30 | 31 | private static String getPKColumnNames() { 32 | return "AccessorResourceID, AccessedDomainID, ResourceClassID, SysPermissionID"; 33 | } 34 | 35 | public static class Finder { 36 | public static int getNumberOfRows(Connection con, String schemaName) throws SQLException { 37 | 38 | try (PreparedStatement preparedStatement 39 | = con.prepareStatement("SELECT COUNT(*) FROM (SELECT DISTINCT " + getPKColumnNames() + " FROM " + getQualifiedTableName(schemaName) + ") T"); 40 | ) { 41 | ResultSet resultSet = preparedStatement.executeQuery(); 42 | resultSet.next(); 43 | return resultSet.getInt(1); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/helper/OACC_Grant_ResCreatePerm.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.helper; 19 | 20 | import java.sql.Connection; 21 | import java.sql.PreparedStatement; 22 | import java.sql.ResultSet; 23 | import java.sql.SQLException; 24 | 25 | public class OACC_Grant_ResCreatePerm extends DbBase { 26 | 27 | private static String getQualifiedTableName(String schemaName) { 28 | return getSchemaAndTableNamePrefix(schemaName) + "Grant_ResCrPerm_PostCr"; 29 | } 30 | 31 | private static String getPKColumnNames() { 32 | return "AccessorResourceID, AccessedDomainID, ResourceClassId, PostCreatePermissionId"; 33 | } 34 | 35 | public static class Finder { 36 | public static int getNumberOfRows(Connection con, String schemaName) throws SQLException { 37 | 38 | try (PreparedStatement preparedStatement 39 | = con.prepareStatement("SELECT COUNT(*) FROM (SELECT DISTINCT " + getPKColumnNames() + " FROM " + getQualifiedTableName(schemaName) + ") T"); 40 | ) { 41 | ResultSet resultSet = preparedStatement.executeQuery(); 42 | resultSet.next(); 43 | return resultSet.getInt(1); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/helper/OACC_Grant_ResCreatePerm_PostCreate_Sys.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.helper; 19 | 20 | import java.sql.Connection; 21 | import java.sql.PreparedStatement; 22 | import java.sql.ResultSet; 23 | import java.sql.SQLException; 24 | 25 | public class OACC_Grant_ResCreatePerm_PostCreate_Sys extends DbBase { 26 | 27 | private static String getQualifiedTableName(String schemaName) { 28 | return getSchemaAndTableNamePrefix(schemaName) + "Grant_ResCrPerm_PostCr_Sys"; 29 | } 30 | 31 | private static String getPKColumnNames() { 32 | return "AccessorResourceID, AccessedDomainID, ResourceClassId, PostCreateSysPermissionId"; 33 | } 34 | 35 | public static class Finder { 36 | public static int getNumberOfRows(Connection con, String schemaName) throws SQLException { 37 | 38 | try (PreparedStatement preparedStatement 39 | = con.prepareStatement("SELECT COUNT(*) FROM (SELECT DISTINCT " + getPKColumnNames() + " FROM " + getQualifiedTableName(schemaName) + ") T"); 40 | ) { 41 | ResultSet resultSet = preparedStatement.executeQuery(); 42 | resultSet.next(); 43 | return resultSet.getInt(1); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/helper/OACC_Grant_ResPerm.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.helper; 19 | 20 | import java.sql.Connection; 21 | import java.sql.PreparedStatement; 22 | import java.sql.ResultSet; 23 | import java.sql.SQLException; 24 | 25 | public class OACC_Grant_ResPerm extends DbBase { 26 | 27 | private static String getQualifiedTableName(String schemaName) { 28 | return getSchemaAndTableNamePrefix(schemaName) + "Grant_ResPerm"; 29 | } 30 | 31 | private static String getPKColumnNames() { 32 | return "AccessorResourceID, AccessedResourceID, ResourceClassID, PermissionID"; 33 | } 34 | 35 | public static class Finder { 36 | public static int getNumberOfRows(Connection con, String schemaName) throws SQLException { 37 | 38 | try (PreparedStatement preparedStatement 39 | = con.prepareStatement("SELECT COUNT(*) FROM (SELECT DISTINCT " + getPKColumnNames() + " FROM " + getQualifiedTableName(schemaName) + ") T"); 40 | ) { 41 | ResultSet resultSet = preparedStatement.executeQuery(); 42 | resultSet.next(); 43 | return resultSet.getInt(1); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/helper/OACC_Grant_ResPerm_Sys.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.helper; 19 | 20 | import java.sql.Connection; 21 | import java.sql.PreparedStatement; 22 | import java.sql.ResultSet; 23 | import java.sql.SQLException; 24 | 25 | public class OACC_Grant_ResPerm_Sys extends DbBase { 26 | 27 | private static String getQualifiedTableName(String schemaName) { 28 | return getSchemaAndTableNamePrefix(schemaName) + "Grant_ResPerm_Sys"; 29 | } 30 | 31 | private static String getPKColumnNames() { 32 | return "AccessorResourceID, AccessedResourceID, ResourceClassID, SysPermissionID"; 33 | } 34 | 35 | public static class Finder { 36 | public static int getNumberOfRows(Connection con, String schemaName) throws SQLException { 37 | 38 | try (PreparedStatement preparedStatement 39 | = con.prepareStatement("SELECT COUNT(*) FROM (SELECT DISTINCT " + getPKColumnNames() + " FROM " + getQualifiedTableName(schemaName) + ") T"); 40 | ) { 41 | ResultSet resultSet = preparedStatement.executeQuery(); 42 | resultSet.next(); 43 | return resultSet.getInt(1); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/helper/OACC_ResourceClassPermission.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.helper; 19 | 20 | import java.sql.Connection; 21 | import java.sql.PreparedStatement; 22 | import java.sql.ResultSet; 23 | import java.sql.SQLException; 24 | 25 | public class OACC_ResourceClassPermission extends DbBase { 26 | 27 | private static String getQualifiedTableName(String schemaName) { 28 | return getSchemaAndTableNamePrefix(schemaName) + "ResourceClassPermission"; 29 | } 30 | 31 | private static String getPKColumnNames() { 32 | return "ResourceClassID, PermissionID"; 33 | } 34 | 35 | public static class Finder { 36 | public static int getNumberOfRows(Connection con, String schemaName) throws SQLException { 37 | 38 | try (PreparedStatement preparedStatement 39 | = con.prepareStatement("SELECT COUNT(*) FROM (SELECT DISTINCT " + getPKColumnNames() + " FROM " + getQualifiedTableName(schemaName) + ") T"); 40 | ) { 41 | ResultSet resultSet = preparedStatement.executeQuery(); 42 | resultSet.next(); 43 | return resultSet.getInt(1); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/helper/Test_OACC_Resource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.helper; 19 | 20 | import com.acciente.oacc.Resources; 21 | import com.acciente.oacc.encryptor.PasswordEncryptor; 22 | import com.acciente.oacc.sql.internal.PasswordUtils; 23 | import org.junit.Test; 24 | 25 | import static org.hamcrest.CoreMatchers.is; 26 | import static org.hamcrest.CoreMatchers.not; 27 | import static org.hamcrest.MatcherAssert.assertThat; 28 | 29 | public class Test_OACC_Resource { 30 | 31 | @Test 32 | public void meta_checkPasswords() { 33 | PasswordEncryptor passwordEncryptor = TestConfigLoader.getPasswordEncryptor(); 34 | final char[] plaintext = "abc".toCharArray(); 35 | final String digest_01 = passwordEncryptor.encryptPassword(plaintext); 36 | final String digest_02 = passwordEncryptor.encryptPassword(plaintext); 37 | final String digest_null = passwordEncryptor.encryptPassword(null); 38 | assertThat(digest_01, is(not(digest_02))); 39 | assertThat(passwordEncryptor.checkPassword(plaintext, digest_01), is(true)); 40 | assertThat(passwordEncryptor.checkPassword(plaintext, digest_02), is(true)); 41 | assertThat(passwordEncryptor.checkPassword(null, digest_null), is(true)); 42 | assertThat(passwordEncryptor.checkPassword(null, digest_01), is(false)); 43 | assertThat(passwordEncryptor.checkPassword(plaintext, digest_null), is(false)); 44 | } 45 | 46 | @Test 47 | public void meta_equalityOfResourcesWithEncryptedPasswords() { 48 | PasswordEncryptor passwordEncryptor = TestConfigLoader.getPasswordEncryptor(); 49 | final char[] plaintext = "abc".toCharArray(); 50 | final String digest_01 = passwordEncryptor.encryptPassword(PasswordUtils.computeBoundPassword( 51 | Resources.getInstance(0), plaintext)); 52 | final String digest_02 = passwordEncryptor.encryptPassword(PasswordUtils.computeBoundPassword( 53 | Resources.getInstance(0), plaintext)); 54 | 55 | final OACC_ResourcePassword resource_01_digest = new OACC_ResourcePassword.Builder(0L).password(digest_01).build(); 56 | final OACC_ResourcePassword resource_01_plain = new OACC_ResourcePassword.Builder(0L).password_plaintext(plaintext).build(); 57 | final OACC_ResourcePassword resource_02_digest = new OACC_ResourcePassword.Builder(0L).password(digest_02).build(); 58 | final OACC_ResourcePassword resource_02_plain = new OACC_ResourcePassword.Builder(0L).password_plaintext(plaintext).build(); 59 | 60 | assertThat(digest_01, is(not(digest_02))); 61 | // verify equals() 62 | assertThat(resource_01_digest, is(not(resource_02_digest))); 63 | 64 | assertThat(resource_01_plain, is(resource_02_plain)); 65 | 66 | assertThat(resource_01_digest, is(resource_01_plain)); 67 | assertThat(resource_02_digest, is(resource_01_plain)); 68 | assertThat(resource_01_plain, is(resource_01_digest)); 69 | assertThat(resource_01_plain, is(resource_02_digest)); 70 | 71 | // verify hashCode() 72 | assertThat(resource_01_plain.hashCode(), is(resource_02_plain.hashCode())); 73 | 74 | assertThat(resource_01_digest.hashCode(), is(resource_01_plain.hashCode())); 75 | assertThat(resource_02_digest.hashCode(), is(resource_01_plain.hashCode())); 76 | assertThat(resource_01_plain.hashCode(), is(resource_01_digest.hashCode())); 77 | assertThat(resource_01_plain.hashCode(), is(resource_02_digest.hashCode())); 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/normalizer/TextNormalizerInstanceTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | package com.acciente.oacc.normalizer; 19 | 20 | import com.acciente.oacc.normalizer.icu4j.ICU4Jv46TextNormalizer; 21 | import org.junit.Test; 22 | 23 | import static org.hamcrest.core.IsEqual.equalTo; 24 | import static org.junit.Assert.assertThat; 25 | 26 | public class TextNormalizerInstanceTest { 27 | /** 28 | * This test should pass if and only if ICU4J 4.6 or higher is in the classpath 29 | */ 30 | @Test 31 | public void testReturnsICU4JTextNormalizer() { 32 | final TextNormalizer textNormalizer = TextNormalizer.getInstance(); 33 | assertThat(textNormalizer.getClass().getCanonicalName(), 34 | equalTo(ICU4Jv46TextNormalizer.class.getCanonicalName())); 35 | } 36 | } -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/normalizer/icu4j/ICU4Jv26TextNormalizerParityTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | 19 | package com.acciente.oacc.normalizer.icu4j; 20 | 21 | import com.acciente.oacc.normalizer.TextNormalizer; 22 | import com.ibm.icu.text.Normalizer; 23 | import org.junit.Test; 24 | import org.junit.runner.RunWith; 25 | import org.junit.runners.Parameterized; 26 | 27 | import static org.junit.Assert.assertArrayEquals; 28 | import static org.junit.Assert.assertEquals; 29 | 30 | @RunWith(Parameterized.class) 31 | public class ICU4Jv26TextNormalizerParityTest { 32 | private final TextNormalizer textNormalizer = ICU4Jv26TextNormalizer.getInstance(); 33 | 34 | @Parameterized.Parameters 35 | public static Object[] data() { 36 | return new Object[]{ 37 | "The big brown fox jumps over 2 picket fences ^^ !".toCharArray(), 38 | "¢£©®°ª¹²³ ¼½¾äöüÅé".toCharArray(), // latin-1 39 | new char[]{0x212b, 0x2126}, // angstrom-sign (Å), ohm-sign (Ω) 40 | new char[]{'A', 0x30a}, // A, combining-ring-above 41 | new char[]{'q', 0x307, 0x323}, // q, dot-above, dot-below 42 | new char[]{0x1e0b, 0x323}, // d-with-dot-above (ḋ), dot-below 43 | new char[]{'2', 0x2075} // 2, superscript-5 (⁵) 44 | }; 45 | } 46 | 47 | @Parameterized.Parameter 48 | public char[] srcCharArray; 49 | 50 | @Test 51 | public void testParityWithUnderlyingNormalizer() throws Exception { 52 | final char[] expectedResult = normalizeDirect(); 53 | final char[] actualResult = textNormalizer.normalizeToNfc(srcCharArray); 54 | 55 | assertEquals(actualResult.length, expectedResult.length); 56 | assertArrayEquals(expectedResult, actualResult); 57 | } 58 | 59 | private char[] normalizeDirect() { 60 | // normalize using direct call to underlying normalizer 61 | final String dest = Normalizer.normalize(new String(srcCharArray), Normalizer.NFC); 62 | return dest.toCharArray(); 63 | } 64 | } -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/normalizer/icu4j/ICU4Jv26TextNormalizerWorstCaseExpansionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | 19 | package com.acciente.oacc.normalizer.icu4j; 20 | 21 | import com.ibm.icu.text.Normalizer; 22 | import org.junit.Test; 23 | import org.junit.runner.RunWith; 24 | import org.junit.runners.Parameterized; 25 | import org.junit.runners.Parameterized.Parameter; 26 | import org.junit.runners.Parameterized.Parameters; 27 | 28 | import static org.hamcrest.Matchers.lessThanOrEqualTo; 29 | import static org.junit.Assert.assertThat; 30 | 31 | @RunWith(Parameterized.class) 32 | public class ICU4Jv26TextNormalizerWorstCaseExpansionTest { 33 | @Parameters 34 | public static Object[] data() { 35 | // ref: http://unicode.org/faq/normalization.html 36 | return new Object[]{ 37 | "foobar", 38 | "\ufb2c", 39 | "\ufb2c\ufb2c", 40 | "\ufb2c\ufb2c\ufb2c", 41 | "\ufb2c\ufb2c\ufb2c\ufb2c", 42 | "\u1f82", 43 | "\ufdfa", 44 | "\ufb2c\u1f82", 45 | "\ufb2c\u1f82\ufdfa", 46 | "\ufb2c\u1f82\ufdfa\ufb2c\u1f82\ufdfa" 47 | }; 48 | } 49 | 50 | @SuppressWarnings("WeakerAccess") 51 | @Parameter 52 | public String src; 53 | 54 | @Test 55 | public void testExpansion() throws Exception { 56 | final int expectedMaxExpansionSize = 3 * src.length(); 57 | 58 | // allocate the destination to be 3x of the source length 59 | char[] dest = new char[expectedMaxExpansionSize]; 60 | 61 | // normalize the text 62 | final int actualDestLen = Normalizer.normalize(src.toCharArray(), dest, Normalizer.NFC, 0); 63 | assertThat("Note: " + 64 | "if this test fails, then the ICU4J library in use does not maintain our bounded expansion " + 65 | "and could leak passwords; use a different library or adjust the expansion factor", 66 | actualDestLen, lessThanOrEqualTo(expectedMaxExpansionSize)); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/normalizer/icu4j/ICU4Jv46TextNormalizerParityTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | 19 | package com.acciente.oacc.normalizer.icu4j; 20 | 21 | import com.acciente.oacc.normalizer.TextNormalizer; 22 | import com.ibm.icu.text.Normalizer2; 23 | import org.junit.Test; 24 | import org.junit.runner.RunWith; 25 | import org.junit.runners.Parameterized; 26 | 27 | import java.nio.CharBuffer; 28 | 29 | import static org.junit.Assert.assertArrayEquals; 30 | import static org.junit.Assert.assertEquals; 31 | 32 | @RunWith(Parameterized.class) 33 | public class ICU4Jv46TextNormalizerParityTest { 34 | private final TextNormalizer textNormalizer = ICU4Jv46TextNormalizer.getInstance(); 35 | private final Normalizer2 normalizer = Normalizer2Factory.getNFCInstance(); 36 | 37 | @Parameterized.Parameters 38 | public static Object[] data() { 39 | return new Object[]{ 40 | "The big brown fox jumps over 2 picket fences ^^ !".toCharArray(), 41 | "¢£©®°ª¹²³ ¼½¾äöüÅé".toCharArray(), // latin-1 42 | new char[]{0x212b, 0x2126}, // angstrom-sign (Å), ohm-sign (Ω) 43 | new char[]{'A', 0x30a}, // A, combining-ring-above 44 | new char[]{'q', 0x307, 0x323}, // q, dot-above, dot-below 45 | new char[]{0x1e0b, 0x323}, // d-with-dot-above (ḋ), dot-below 46 | new char[]{'2', 0x2075} // 2, superscript-5 (⁵) 47 | }; 48 | } 49 | 50 | @Parameterized.Parameter 51 | public char[] srcCharArray; 52 | 53 | @Test 54 | public void testParityWithUnderlyingNormalizer() throws Exception { 55 | final char[] expectedResult = normalizeDirect(); 56 | final char[] actualResult = textNormalizer.normalizeToNfc(srcCharArray); 57 | 58 | assertEquals(actualResult.length, expectedResult.length); 59 | assertArrayEquals(expectedResult, actualResult); 60 | } 61 | 62 | private char[] normalizeDirect() { 63 | // normalize using direct call to underlying normalizer 64 | final StringBuilder destStringBuilder = new StringBuilder(2 * srcCharArray.length); 65 | normalizer.normalize(CharBuffer.wrap(srcCharArray), destStringBuilder); 66 | return destStringBuilder.toString().toCharArray(); 67 | } 68 | } -------------------------------------------------------------------------------- /src/test/java/com/acciente/oacc/normalizer/icu4j/ICU4Jv46TextNormalizerWorstCaseExpansionTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009-2018, Acciente LLC 3 | * 4 | * Acciente LLC licenses this file to you under the 5 | * Apache License, Version 2.0 (the "License"); you 6 | * may not use this file except in compliance with the 7 | * License. You may obtain a copy of the License at 8 | * 9 | * http://www.apache.org/licenses/LICENSE-2.0 10 | * 11 | * Unless required by applicable law or agreed to in 12 | * writing, software distributed under the License is 13 | * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES 14 | * OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing 16 | * permissions and limitations under the License. 17 | */ 18 | 19 | package com.acciente.oacc.normalizer.icu4j; 20 | 21 | import com.ibm.icu.text.Normalizer2; 22 | import org.junit.Before; 23 | import org.junit.Test; 24 | import org.junit.runner.RunWith; 25 | import org.junit.runners.Parameterized; 26 | import org.junit.runners.Parameterized.Parameter; 27 | import org.junit.runners.Parameterized.Parameters; 28 | 29 | import static org.hamcrest.Matchers.equalTo; 30 | import static org.hamcrest.Matchers.lessThanOrEqualTo; 31 | import static org.junit.Assert.assertEquals; 32 | import static org.junit.Assert.assertThat; 33 | 34 | @RunWith(Parameterized.class) 35 | public class ICU4Jv46TextNormalizerWorstCaseExpansionTest { 36 | private Normalizer2 normalizer; 37 | 38 | @Parameters 39 | public static Object[] data() { 40 | // ref: http://unicode.org/faq/normalization.html 41 | return new Object[]{ 42 | "foobar", 43 | "\ufb2c", 44 | "\ufb2c\ufb2c", 45 | "\ufb2c\ufb2c\ufb2c", 46 | "\ufb2c\ufb2c\ufb2c\ufb2c", 47 | "\u1f82", 48 | "\ufdfa", 49 | "\ufb2c\u1f82", 50 | "\ufb2c\u1f82\ufdfa", 51 | "\ufb2c\u1f82\ufdfa\ufb2c\u1f82\ufdfa" 52 | }; 53 | } 54 | 55 | @SuppressWarnings("WeakerAccess") 56 | @Parameter 57 | public String src; 58 | 59 | @Before 60 | public void setUp() throws Exception { 61 | normalizer = Normalizer2Factory.getNFCInstance(); 62 | } 63 | 64 | @Test 65 | public void testExpansion() throws Exception { 66 | final int expectedMaxExpansionSize = 3 * src.length(); 67 | 68 | // allocate the destination to be 3x of the source length 69 | StringBuilder dest = new StringBuilder(expectedMaxExpansionSize); 70 | assertEquals(expectedMaxExpansionSize, dest.capacity()); 71 | 72 | // normalize the text 73 | normalizer.normalize(src, dest); 74 | assertThat(dest.length(), lessThanOrEqualTo(expectedMaxExpansionSize)); 75 | assertThat("Note: " + 76 | "if this test fails, then the ICU4J library in use does not maintain our bounded expansion " + 77 | "and could leak passwords; use a different library or adjust the expansion factor", 78 | dest.capacity(), equalTo(expectedMaxExpansionSize)); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/test/resources/dbconfig_db2.properties: -------------------------------------------------------------------------------- 1 | # OACC-specific properties 2 | dataSourceClass=com.ibm.db2.jcc.DB2SimpleDataSource 3 | sqlProfile=DB2_10_5_RECURSIVE 4 | dbSchema=OACC 5 | pwdEncryptor=Jasypt 6 | oaccRootPwd=toomanysecrets 7 | 8 | # vendor-specific properties 9 | driverType=4 10 | serverName=localhost 11 | portNumber=50000 12 | databaseName=oaccdb 13 | user=oaccuser 14 | password=oaccpwd -------------------------------------------------------------------------------- /src/test/resources/dbconfig_hsqldb.properties: -------------------------------------------------------------------------------- 1 | # OACC-specific properties 2 | dataSourceClass=org.hsqldb.jdbc.JDBCPool 3 | sqlProfile=HSQLDB_2_3_NON_RECURSIVE 4 | dbSchema=OACC 5 | pwdEncryptor=Jasypt 6 | oaccRootPwd=toomanysecrets 7 | 8 | # vendor-specific properties 9 | url=jdbc:hsqldb:hsql://localhost:9001/oaccdb 10 | user=oaccuser 11 | password=oaccpwd 12 | 13 | -------------------------------------------------------------------------------- /src/test/resources/dbconfig_mariadb.properties: -------------------------------------------------------------------------------- 1 | # OACC-specific properties 2 | dataSourceClass=org.mariadb.jdbc.MariaDbDataSource 3 | sqlProfile=MySQL_5_6_NON_RECURSIVE 4 | # dbSchema= ## _dbSchema not supported because databaseName is provided_ ## 5 | pwdEncryptor=Jasypt 6 | oaccRootPwd=toomanysecrets 7 | 8 | # vendor-specific properties 9 | serverName=localhost 10 | portNumber=3306 11 | databaseName=OACCDB 12 | user=oaccuser 13 | password=oaccpwd 14 | properties=sessionVariables=sql_mode='STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,NO_AUTO_VALUE_ON_ZERO' -------------------------------------------------------------------------------- /src/test/resources/dbconfig_mysql.properties: -------------------------------------------------------------------------------- 1 | # OACC-specific properties 2 | dataSourceClass=com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource 3 | sqlProfile=MySQL_5_6_NON_RECURSIVE 4 | # dbSchema= ## _dbSchema not supported because databaseName is provided_ ## 5 | pwdEncryptor=Jasypt 6 | oaccRootPwd=toomanysecrets 7 | 8 | # vendor-specific properties 9 | serverName=localhost 10 | portNumber=3306 11 | databaseName=OACCDB 12 | user=oaccuser 13 | password=oaccpwd 14 | sessionVariables=sql_mode='STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION,NO_AUTO_VALUE_ON_ZERO' -------------------------------------------------------------------------------- /src/test/resources/dbconfig_oracle.properties: -------------------------------------------------------------------------------- 1 | # OACC-specific properties 2 | dataSourceClass=oracle.ucp.jdbc.PoolDataSourceImpl 3 | sqlProfile=Oracle_11_2_RECURSIVE 4 | dbSchema=OACC 5 | pwdEncryptor=Jasypt 6 | oaccRootPwd=toomanysecrets 7 | 8 | # vendor-specific properties 9 | URL=jdbc:oracle:thin:@localhost:1521:oaccdb 10 | user=oaccuser 11 | password=oaccpwd 12 | connectionFactoryClassName=oracle.jdbc.pool.OracleDataSource 13 | maxPoolSize=10 14 | -------------------------------------------------------------------------------- /src/test/resources/dbconfig_postgresql.properties: -------------------------------------------------------------------------------- 1 | # OACC-specific properties 2 | dataSourceClass=org.postgresql.ds.PGPoolingDataSource 3 | sqlProfile=PostgreSQL_9_3_NON_RECURSIVE 4 | dbSchema=OACC 5 | pwdEncryptor=BCrypt 6 | oaccRootPwd=toomanysecrets 7 | 8 | # vendor-specific properties 9 | serverName=localhost 10 | portNumber=5432 11 | databaseName=oaccdb 12 | user=oaccuser 13 | password=oaccpwd 14 | maxConnections=10 15 | -------------------------------------------------------------------------------- /src/test/resources/dbconfig_sqlite.properties: -------------------------------------------------------------------------------- 1 | # OACC-specific properties 2 | dataSourceClass=org.sqlite.javax.SQLiteConnectionPoolDataSource 3 | sqlProfile=SQLite_3_8_RECURSIVE 4 | # dbSchema= ## _dbSchema not supported_ ## 5 | pwdEncryptor=Jasypt 6 | oaccRootPwd=toomanysecrets 7 | 8 | # vendor-specific properties 9 | url=jdbc:sqlite:oacc.db 10 | synchronous=OFF 11 | enforceForeignKeys=true 12 | -------------------------------------------------------------------------------- /src/test/resources/dbconfig_sqlserver.properties: -------------------------------------------------------------------------------- 1 | # OACC-specific properties 2 | dataSourceClass=com.microsoft.sqlserver.jdbc.SQLServerXADataSource 3 | sqlProfile=SQLServer_12_0_RECURSIVE 4 | dbSchema=OACC 5 | pwdEncryptor=Jasypt 6 | oaccRootPwd=toomanysecrets 7 | 8 | # vendor-specific properties 9 | serverName=localhost 10 | portNumber=1433 11 | databaseName=oaccdb 12 | user=oaccuser 13 | password=oaccpwd --------------------------------------------------------------------------------