From 731b1152822c3a6ad217a66b9dd91d002b5d4d1c Mon Sep 17 00:00:00 2001 From: Georgy Litvinov Date: Tue, 6 Jun 2023 11:21:59 +0200 Subject: [PATCH 001/148] abac cleaned, squashed --- .../vedit/controller/BaseEditController.java | 66 +- .../vedit/controller/OperationController.java | 48 +- .../vitro/webapp/auth/RootUserSetup.java | 203 +++++ .../auth/attributes/AbstractAttribute.java | 70 ++ .../auth/attributes/AccessObjectType.java | 14 + .../auth/attributes/AccessOperation.java | 12 + .../webapp/auth/attributes/Attribute.java | 24 + .../auth/attributes/AttributeFactory.java | 69 ++ .../auth/attributes/AttributeGroup.java | 6 + .../webapp/auth/attributes/AttributeType.java | 14 + .../auth/attributes/AttributeValueTester.java | 105 +++ .../attributes/DataPropertyUriAttribute.java | 39 + .../ObjectPropertyUriAttribute.java | 39 + .../auth/attributes/ObjectTypeAttribute.java | 33 + .../auth/attributes/ObjectUriAttribute.java | 34 + .../auth/attributes/OperationAttribute.java | 33 + .../auth/attributes/OperationGroup.java | 7 + .../auth/attributes/ProximityChecker.java | 63 ++ .../auth/attributes/QueryResultsMapCache.java | 45 ++ .../StatementObjectUriAttribute.java | 34 + .../StatementPredicateUriAttribute.java | 34 + .../StatementSubjectUriAttribute.java | 34 + .../auth/attributes/SubjectRoleAttribute.java | 34 + .../auth/attributes/SubjectTypeAttribute.java | 35 + .../webapp/auth/attributes/TestType.java | 10 + .../ActiveIdentifierBundleFactories.java | 98 +-- .../auth/identifier/common/HasPermission.java | 72 -- ...a => IdentifierPermissionSetProvider.java} | 20 +- .../auth/identifier/common/IsBlacklisted.java | 147 +--- .../factory/BaseIdentifierBundleFactory.java | 11 +- .../BaseUserBasedIdentifierBundleFactory.java | 5 - .../factory/HasPermissionFactory.java | 90 --- .../factory/HasPermissionSetFactory.java | 16 +- .../HasProfileOrIsBlacklistedFactory.java | 8 +- .../factory/HasProxyEditingRightsFactory.java | 6 - .../identifier/factory/IsRootUserFactory.java | 6 - .../identifier/factory/IsUserFactory.java | 6 - .../webapp/auth/objects/AccessObject.java | 109 +++ .../webapp/auth/objects/AccessObjectImpl.java | 62 ++ .../auth/objects/AccessObjectStatement.java | 56 ++ .../objects/DataPropertyAccessObject.java | 16 + .../DataPropertyStatementAccessObject.java | 41 ++ .../objects/ObjectPropertyAccessObject.java | 16 + .../ObjectPropertyStatementAccessObject.java | 32 + .../webapp/auth/objects/RootAccessObject.java | 16 + .../auth/permissions/BrokenPermission.java | 26 - .../permissions/DisplayByRolePermission.java | 127 ---- .../permissions/EditByRolePermission.java | 105 --- .../webapp/auth/permissions/Permission.java | 76 -- .../auth/permissions/PermissionRegistry.java | 216 ------ .../permissions/PermissionSetsSmokeTest.java | 16 - .../permissions/PublishByRolePermission.java | 125 ---- .../auth/permissions/SimplePermission.java | 221 ++---- .../auth/policy/BaseSelfEditingPolicy.java | 61 -- .../auth/policy/BasicPolicyDecision.java | 20 +- .../auth/policy/CompositPolicyDecision.java | 23 - .../DisplayRestrictedDataToSelfPolicy.java | 179 ----- .../webapp/auth/policy/DynamicPolicy.java | 80 ++ .../auth/policy/EntityPolicyController.java | 79 ++ .../webapp/auth/policy/PermissionsPolicy.java | 56 -- .../vitro/webapp/auth/policy/Policies.java | 18 + .../auth/policy/PolicyDecisionLogger.java | 14 +- .../auth/policy/PolicyDecisionPoint.java | 43 ++ .../webapp/auth/policy/PolicyHelper.java | 160 ++-- .../vitro/webapp/auth/policy/PolicyList.java | 66 -- .../webapp/auth/policy/PolicyLoader.java | 641 ++++++++++++++++ .../vitro/webapp/auth/policy/PolicyStore.java | 91 +++ .../webapp/auth/policy/RequestPolicyList.java | 71 -- .../RestrictHomeMenuItemEditingPolicy.java | 70 -- .../webapp/auth/policy/RootUserPolicy.java | 233 ------ .../webapp/auth/policy/SelfEditingPolicy.java | 161 ---- .../webapp/auth/policy/ServletPolicyList.java | 122 --- .../policy/bean/PropertyRestrictionBean.java | 207 ------ .../bean/PropertyRestrictionBeanImpl.java | 247 ------- .../bean/PropertyRestrictionLevels.java | 68 -- .../bean/PropertyRestrictionListener.java | 35 +- .../policy/bean/RoleRestrictedProperty.java | 23 - ...Authorization.java => DecisionResult.java} | 2 +- .../ifaces/{PolicyIface.java => Policy.java} | 14 +- .../auth/policy/ifaces/PolicyDecision.java | 2 +- .../policy/setup/CommonPolicyFamilySetup.java | 31 +- .../AbstractRelationshipPolicy.java | 63 -- .../RelationshipChecker.java | 205 ------ .../AllowedAuthorizationRequest.java | 30 + .../auth/requestedAction/AuthHelper.java | 61 ++ .../requestedAction/AuthorizationRequest.java | 172 ++--- .../ForbiddenAuthorizationRequest.java | 36 + .../auth/requestedAction/RequestedAction.java | 41 -- .../SimpleAuthorizationRequest.java | 47 ++ .../SimpleRequestedAction.java | 48 -- .../requestedAction/admin/AddNewUser.java | 11 - .../requestedAction/admin/LoadOntology.java | 19 - .../admin/RebuildTextIndex.java | 10 - .../requestedAction/admin/RemoveUser.java | 19 - .../requestedAction/admin/ServerStatus.java | 11 - .../admin/UpdateTextIndex.java | 10 - .../requestedAction/admin/UploadFile.java | 18 - .../display/DisplayDataProperty.java | 24 - .../display/DisplayDataPropertyStatement.java | 29 - .../display/DisplayObjectProperty.java | 25 - .../DisplayObjectPropertyStatement.java | 39 - .../ifaces/AdminRequestedAction.java | 8 - .../ifaces/OntoRequestedAction.java | 8 - .../ifaces/RequiresActions.java | 36 - .../ifaces/SingleParameterAction.java | 25 - .../ontology/CreateOwlClass.java | 11 - .../ontology/DefineDataProperty.java | 11 - .../ontology/DefineObjectProperty.java | 11 - .../ontology/RemoveOwlClass.java | 11 - .../AbstractDataPropertyStatementAction.java | 72 -- ...AbstractObjectPropertyStatementAction.java | 55 -- .../AbstractPropertyStatementAction.java | 34 - .../propstmt/AddDataPropertyStatement.java | 24 - .../propstmt/AddObjectPropertyStatement.java | 19 - .../propstmt/DropDataPropertyStatement.java | 25 - .../propstmt/DropObjectPropertyStatement.java | 19 - .../propstmt/EditDataPropertyStatement.java | 23 - .../propstmt/EditObjectPropertyStatement.java | 18 - .../publish/PublishDataProperty.java | 24 - .../publish/PublishDataPropertyStatement.java | 26 - .../publish/PublishObjectProperty.java | 24 - .../PublishObjectPropertyStatement.java | 40 - .../resource/AbstractResourceAction.java | 33 - .../requestedAction/resource/AddResource.java | 11 - .../resource/DropResource.java | 11 - .../usepages/ManageRootAccount.java | 12 - .../usepages/UsePagesRequestedAction.java | 8 - .../vitro/webapp/auth/rules/AccessRule.java | 156 ++++ .../webapp/auth/rules/AccessRuleFactory.java | 30 + .../webapp/auth/rules/AccessRuleStore.java | 694 ++++++++++++++++++ .../webapp/auth/rules/SimpleAccessRule.java | 10 + .../vitro/webapp/beans/BaseResourceBean.java | 139 ---- .../vitro/webapp/beans/DataProperty.java | 4 +- .../vitro/webapp/beans/FauxProperty.java | 5 +- .../vitro/webapp/beans/ObjectProperty.java | 7 +- .../vitro/webapp/beans/ResourceBean.java | 20 - .../beans/SelfEditingConfiguration.java | 34 +- .../config/ConfigurationProperties.java | 100 +-- .../config/ConfigurationPropertiesSetup.java | 2 +- .../IndividualListRdfController.java | 11 +- .../controller/SparqlQueryBuilderServlet.java | 2 +- .../webapp/controller/VitroHttpServlet.java | 5 +- .../accounts/admin/UserAccountsDeleter.java | 5 +- .../accounts/admin/UserAccountsEditPage.java | 5 +- .../accounts/admin/UserAccountsListPage.java | 5 +- .../ajax/ManageProxiesAjaxController.java | 6 +- .../user/UserAccountsUserController.java | 5 +- .../controller/admin/ShowAuthController.java | 28 +- .../admin/ShowSourcesController.java | 3 +- .../controller/ajax/VitroAjaxController.java | 4 +- .../controller/api/VitroApiServlet.java | 2 +- .../authenticate/AdminLoginController.java | 3 +- .../authenticate/Authenticator.java | 6 +- .../authenticate/BasicAuthenticator.java | 34 +- .../authenticate/LoginRedirector.java | 18 +- .../authenticate/RestrictedAuthenticator.java | 7 +- .../dumprestore/DumpRestoreController.java | 4 +- .../edit/DatapropEditController.java | 29 +- .../edit/DatapropRetryController.java | 21 +- .../controller/edit/EntityEditController.java | 13 - .../edit/EntityRetryController.java | 5 - .../edit/FauxPropertyRetryController.java | 19 +- .../edit/NamespacePrefixRetryController.java | 2 +- .../edit/PropertyEditController.java | 46 +- .../edit/PropertyRetryController.java | 8 +- .../controller/edit/VclassEditController.java | 32 +- .../edit/VclassRetryController.java | 8 +- .../edit/utils/RoleLevelOptionsSetup.java | 100 --- .../freemarker/FileUploadController.java | 21 +- .../freemarker/FreemarkerHttpServlet.java | 10 +- .../freemarker/ImageUploadController.java | 28 +- .../ListVClassWebappsController.java | 1 - .../controller/freemarker/PageController.java | 44 +- .../NotAuthorizedResponseValues.java | 7 +- .../individual/IndividualRdfAssembler.java | 21 +- .../controller/jena/JenaExportController.java | 7 +- .../webapp/controller/json/JsonServlet.java | 60 +- .../mannlib/vitro/webapp/dao/PageDao.java | 2 +- .../mannlib/vitro/webapp/dao/PropertyDao.java | 5 - .../vitro/webapp/dao/VitroVocabulary.java | 14 +- .../filtering/DataPropertyDaoFiltering.java | 2 +- .../dao/filtering/DataPropertyFiltering.java | 46 -- .../dao/filtering/IndividualFiltering.java | 65 +- .../filtering/ObjectPropertyFiltering.java | 45 -- .../filters/FilterByDisplayPermission.java | 100 +++ .../filters/FilterByRoleLevelPermission.java | 149 ---- .../HideFromDisplayByPolicyFilter.java | 50 +- .../filtering/filters/VitroFilterUtils.java | 3 +- .../webapp/dao/jena/DataPropertyDaoJena.java | 90 --- .../webapp/dao/jena/FauxPropertyDaoJena.java | 28 - .../vitro/webapp/dao/jena/JenaBaseDao.java | 15 - .../vitro/webapp/dao/jena/JenaBaseDaoCon.java | 4 - .../vitro/webapp/dao/jena/JenaModelUtils.java | 6 - .../dao/jena/ObjectPropertyDaoJena.java | 97 +-- .../vitro/webapp/dao/jena/PageDaoJena.java | 8 +- .../vitro/webapp/dao/jena/VClassDaoJena.java | 39 - .../vitro/webapp/dao/jena/VClassJena.java | 112 +-- .../ManageLabelsForIndividualGenerator.java | 19 +- .../EditRequestDispatchController.java | 56 +- .../webapp/migration/auth/AuthMigrator.java | 269 +++++++ .../vitro/webapp/modelaccess/ModelAccess.java | 34 +- .../impl/ContextModelAccessImpl.java | 7 +- .../impl/RequestModelAccessImpl.java | 5 +- .../search/controller/IndexController.java | 3 +- .../web/jsptags/ConfirmAuthorization.java | 16 +- .../BaseIndividualTemplateModel.java | 19 +- .../DataPropertyStatementTemplateModel.java | 50 +- .../individual/DataPropertyTemplateModel.java | 28 +- .../individual/FauxDataPropertyWrapper.java | 5 + .../individual/FauxObjectPropertyWrapper.java | 50 +- .../individual/FauxPropertyWrapper.java | 2 + .../NameStatementTemplateModel.java | 9 +- .../ObjectPropertyStatementTemplateModel.java | 22 +- .../ObjectPropertyTemplateModel.java | 21 +- .../PropertyGroupTemplateModel.java | 53 +- .../individual/PropertyTemplateModel.java | 15 +- ...UncollatedObjectPropertyTemplateModel.java | 7 +- .../factory/HasPermissionFactoryTest.java | 277 ------- .../factory/IsRootUserFactoryTest.java | 2 +- .../identifier/factory/IsUserFactoryTest.java | 2 +- .../webapp/auth/policy/BasicPolicyTest.java | 82 +++ .../policy/EntityPolicyControllerTest.java | 40 + .../webapp/auth/policy/EntityPolicyTests.java | 112 +++ .../HomeMenuItemsRestrictionPolicyTest.java | 40 + .../NonModifiableStatementsPolicyTest.java | 73 ++ ...PolicyHelper_AuthorizationRequestTest.java | 130 ++-- .../auth/policy/PolicyHelper_ModelsTest.java | 33 +- .../policy/PolicyHelper_StatementsTest.java | 49 +- .../webapp/auth/policy/PolicyStoreTest.java | 66 ++ .../vitro/webapp/auth/policy/PolicyTest.java | 144 ++++ .../webapp/auth/policy/ProximityTest.java | 52 ++ .../auth/policy/RootUserPolicyTest.java | 21 + .../auth/policy/SelfEditingPolicyTest.java | 393 ---------- .../auth/policy/SelfEditingPolicy_2_Test.java | 297 -------- .../policy/SimplePermissionPolicyTest.java | 123 ++++ .../bean/PropertyRestrictionBeanImplTest.java | 511 ------------- .../AuthorizationRequestTest.java | 45 +- .../auth/rules/AccessRuleStoreTest.java | 104 +++ .../controller/edit/AuthenticateTest.java | 22 +- .../IndividualRdfAssemblerTest.java | 55 +- .../IndividualFilteringByStatementTest.java | 2 +- .../dao/jena/DataPropertyDaoJenaTest.java | 3 - .../dao/jena/ObjectPropertyDaoJenaTest.java | 3 - .../vitro/webapp/dao/jena/VClassDaoTest.java | 3 - .../vitro/webapp/dao/jena/VClassJenaTest.java | 87 +-- .../bean/PropertyRestrictionBeanStub.java | 122 --- .../vitro/webapp/beans/IndividualStub.java | 55 -- .../config/ConfigurationPropertiesStub.java | 2 +- .../modelaccess/ModelAccessFactoryStub.java | 2 + .../webapp/auth/rules/proximity_test_data.n3 | 4 + .../auth/rules/proximity_test_policy.n3 | 30 + .../webapp/auth/rules/test_policy_broken1.n3 | 29 + .../webapp/auth/rules/test_policy_broken2.n3 | 29 + .../webapp/auth/rules/test_policy_broken3.n3 | 30 + .../webapp/auth/rules/test_policy_broken4.n3 | 30 + .../webapp/auth/rules/test_policy_broken5.n3 | 42 ++ .../auth/rules/test_policy_broken_set.n3 | 52 ++ .../webapp/auth/rules/test_policy_key.n3 | 29 + .../webapp/auth/rules/test_policy_valid.n3 | 24 + .../auth/rules/test_policy_valid_set.n3 | 60 ++ .../rdf/auth/everytime/attribute_types.n3 | 54 ++ .../rdf/auth/everytime/attributes.n3 | 119 +++ .../resources/rdf/auth/everytime/decisions.n3 | 15 + .../rdf/auth/everytime/object_types.n3 | 30 + .../resources/rdf/auth/everytime/ontology.n3 | 138 ++++ .../rdf/auth/everytime/operation_groups.n3 | 18 + .../rdf/auth/everytime/operations.n3 | 31 + .../rdf/auth/everytime/permission_config.n3 | 144 +--- .../everytime/policy_admin_display_class.n3 | 41 ++ .../policy_admin_display_data_property.n3 | 53 ++ .../policy_admin_display_object_property.n3 | 53 ++ .../everytime/policy_admin_publish_class.n3 | 41 ++ .../policy_admin_publish_data_property.n3 | 53 ++ .../policy_admin_publish_object_property.n3 | 53 ++ .../policy_admin_simple_permissions.n3 | 37 + .../everytime/policy_admin_update_class.n3 | 41 ++ .../policy_admin_update_data_property.n3 | 53 ++ .../policy_admin_update_object_property.n3 | 53 ++ .../everytime/policy_curator_display_class.n3 | 41 ++ .../policy_curator_display_data_property.n3 | 53 ++ .../policy_curator_display_object_property.n3 | 53 ++ .../everytime/policy_curator_publish_class.n3 | 41 ++ .../policy_curator_publish_data_property.n3 | 53 ++ .../policy_curator_publish_object_property.n3 | 53 ++ .../policy_curator_simple_permissions.n3 | 37 + .../everytime/policy_curator_update_class.n3 | 41 ++ .../policy_curator_update_data_property.n3 | 53 ++ .../policy_curator_update_object_property.n3 | 53 ++ .../everytime/policy_editor_display_class.n3 | 41 ++ .../policy_editor_display_data_property.n3 | 53 ++ .../policy_editor_display_object_property.n3 | 53 ++ .../everytime/policy_editor_publish_class.n3 | 41 ++ .../policy_editor_publish_data_property.n3 | 53 ++ .../policy_editor_publish_object_property.n3 | 53 ++ .../policy_editor_simple_permissions.n3 | 37 + .../everytime/policy_editor_update_class.n3 | 41 ++ .../policy_editor_update_data_property.n3 | 53 ++ .../policy_editor_update_object_property.n3 | 53 ++ .../everytime/policy_menu_items_editing.n3 | 41 ++ .../policy_not_modifiable_statements.n3 | 104 +++ .../everytime/policy_public_display_class.n3 | 41 ++ .../policy_public_display_data_property.n3 | 53 ++ .../policy_public_display_object_property.n3 | 53 ++ .../policy_public_simple_permissions.n3 | 37 + .../everytime/policy_public_update_class.n3 | 41 ++ .../policy_public_update_data_property.n3 | 53 ++ .../policy_public_update_object_property.n3 | 53 ++ .../rdf/auth/everytime/policy_root_user.n3 | 20 + .../policy_self_editor_display_class.n3 | 41 ++ ...olicy_self_editor_display_data_property.n3 | 53 ++ ...icy_self_editor_display_object_property.n3 | 53 ++ .../policy_self_editor_publish_class.n3 | 41 ++ ...olicy_self_editor_publish_data_property.n3 | 53 ++ ...icy_self_editor_publish_object_property.n3 | 53 ++ .../policy_self_editor_simple_permissions.n3 | 37 + .../policy_self_editor_update_class.n3 | 41 ++ ...policy_self_editor_update_data_property.n3 | 53 ++ ...licy_self_editor_update_object_property.n3 | 53 ++ .../rdf/auth/everytime/subject_types.n3 | 12 + .../rdf/auth/everytime/test_types.n3 | 27 + .../rdf/auth/everytime/test_values.n3 | 78 ++ ...policy_admin_simple_permissions_dataset.n3 | 60 ++ ...licy_curator_simple_permissions_dataset.n3 | 39 + ...olicy_editor_simple_permissions_dataset.n3 | 33 + ...olicy_not_modifiable_statements_dataset.n3 | 27 + ...olicy_public_simple_permissions_dataset.n3 | 16 + ..._self_editor_simple_permissions_dataset.n3 | 25 + .../WEB-INF/resources/startup_listeners.txt | 10 +- .../edit/specific/dataprop_retry.jsp | 66 +- .../edit/specific/fauxProperty_retry.jsp | 65 +- .../edit/specific/property_retry.jsp | 66 +- .../templates/edit/specific/vclass_retry.jsp | 68 +- .../freemarker/lib/lib-properties.ftl | 3 - 333 files changed, 9392 insertions(+), 8061 deletions(-) create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/RootUserSetup.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AbstractAttribute.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AccessObjectType.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AccessOperation.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/Attribute.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AttributeFactory.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AttributeGroup.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AttributeType.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AttributeValueTester.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/DataPropertyUriAttribute.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/ObjectPropertyUriAttribute.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/ObjectTypeAttribute.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/ObjectUriAttribute.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/OperationAttribute.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/OperationGroup.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/ProximityChecker.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/QueryResultsMapCache.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/StatementObjectUriAttribute.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/StatementPredicateUriAttribute.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/StatementSubjectUriAttribute.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/SubjectRoleAttribute.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/SubjectTypeAttribute.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/TestType.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/HasPermission.java rename api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/{HasPermissionSet.java => IdentifierPermissionSetProvider.java} (69%) delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionFactory.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/AccessObject.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/AccessObjectImpl.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/AccessObjectStatement.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/DataPropertyAccessObject.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/DataPropertyStatementAccessObject.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/ObjectPropertyAccessObject.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/ObjectPropertyStatementAccessObject.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/RootAccessObject.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/BrokenPermission.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/DisplayByRolePermission.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/EditByRolePermission.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/Permission.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionRegistry.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/PublishByRolePermission.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/BaseSelfEditingPolicy.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/CompositPolicyDecision.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/DisplayRestrictedDataToSelfPolicy.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/DynamicPolicy.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/EntityPolicyController.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PermissionsPolicy.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/Policies.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyDecisionPoint.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyList.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyLoader.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyStore.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/RequestPolicyList.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/RestrictHomeMenuItemEditingPolicy.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/RootUserPolicy.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicy.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/ServletPolicyList.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionBean.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionBeanImpl.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionLevels.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/RoleRestrictedProperty.java rename api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/ifaces/{Authorization.java => DecisionResult.java} (89%) rename api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/ifaces/{PolicyIface.java => Policy.java} (55%) delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/specialrelationships/AbstractRelationshipPolicy.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/specialrelationships/RelationshipChecker.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/AllowedAuthorizationRequest.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/AuthHelper.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ForbiddenAuthorizationRequest.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/RequestedAction.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/SimpleAuthorizationRequest.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/SimpleRequestedAction.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/AddNewUser.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/LoadOntology.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/RebuildTextIndex.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/RemoveUser.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/ServerStatus.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/UpdateTextIndex.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/UploadFile.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayDataProperty.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayDataPropertyStatement.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayObjectProperty.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayObjectPropertyStatement.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/AdminRequestedAction.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/OntoRequestedAction.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/RequiresActions.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/SingleParameterAction.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ontology/CreateOwlClass.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ontology/DefineDataProperty.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ontology/DefineObjectProperty.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ontology/RemoveOwlClass.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractDataPropertyStatementAction.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractObjectPropertyStatementAction.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractPropertyStatementAction.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AddDataPropertyStatement.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AddObjectPropertyStatement.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/DropDataPropertyStatement.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/DropObjectPropertyStatement.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/EditDataPropertyStatement.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/EditObjectPropertyStatement.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/publish/PublishDataProperty.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/publish/PublishDataPropertyStatement.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/publish/PublishObjectProperty.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/publish/PublishObjectPropertyStatement.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/resource/AbstractResourceAction.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/resource/AddResource.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/resource/DropResource.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/usepages/ManageRootAccount.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/usepages/UsePagesRequestedAction.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/rules/AccessRule.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/rules/AccessRuleFactory.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/rules/AccessRuleStore.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/rules/SimpleAccessRule.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/edit/utils/RoleLevelOptionsSetup.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/filtering/filters/FilterByDisplayPermission.java delete mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/dao/filtering/filters/FilterByRoleLevelPermission.java create mode 100644 api/src/main/java/edu/cornell/mannlib/vitro/webapp/migration/auth/AuthMigrator.java delete mode 100644 api/src/test/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionFactoryTest.java create mode 100644 api/src/test/java/edu/cornell/mannlib/vitro/webapp/auth/policy/BasicPolicyTest.java create mode 100644 api/src/test/java/edu/cornell/mannlib/vitro/webapp/auth/policy/EntityPolicyControllerTest.java create mode 100644 api/src/test/java/edu/cornell/mannlib/vitro/webapp/auth/policy/EntityPolicyTests.java create mode 100644 api/src/test/java/edu/cornell/mannlib/vitro/webapp/auth/policy/HomeMenuItemsRestrictionPolicyTest.java create mode 100644 api/src/test/java/edu/cornell/mannlib/vitro/webapp/auth/policy/NonModifiableStatementsPolicyTest.java create mode 100644 api/src/test/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyStoreTest.java create mode 100644 api/src/test/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyTest.java create mode 100644 api/src/test/java/edu/cornell/mannlib/vitro/webapp/auth/policy/ProximityTest.java create mode 100644 api/src/test/java/edu/cornell/mannlib/vitro/webapp/auth/policy/RootUserPolicyTest.java delete mode 100644 api/src/test/java/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicyTest.java delete mode 100644 api/src/test/java/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicy_2_Test.java create mode 100644 api/src/test/java/edu/cornell/mannlib/vitro/webapp/auth/policy/SimplePermissionPolicyTest.java delete mode 100644 api/src/test/java/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionBeanImplTest.java create mode 100644 api/src/test/java/edu/cornell/mannlib/vitro/webapp/auth/rules/AccessRuleStoreTest.java delete mode 100644 api/src/test/java/stubs/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionBeanStub.java create mode 100644 api/src/test/resources/edu/cornell/mannlib/vitro/webapp/auth/rules/proximity_test_data.n3 create mode 100644 api/src/test/resources/edu/cornell/mannlib/vitro/webapp/auth/rules/proximity_test_policy.n3 create mode 100644 api/src/test/resources/edu/cornell/mannlib/vitro/webapp/auth/rules/test_policy_broken1.n3 create mode 100644 api/src/test/resources/edu/cornell/mannlib/vitro/webapp/auth/rules/test_policy_broken2.n3 create mode 100644 api/src/test/resources/edu/cornell/mannlib/vitro/webapp/auth/rules/test_policy_broken3.n3 create mode 100644 api/src/test/resources/edu/cornell/mannlib/vitro/webapp/auth/rules/test_policy_broken4.n3 create mode 100644 api/src/test/resources/edu/cornell/mannlib/vitro/webapp/auth/rules/test_policy_broken5.n3 create mode 100644 api/src/test/resources/edu/cornell/mannlib/vitro/webapp/auth/rules/test_policy_broken_set.n3 create mode 100644 api/src/test/resources/edu/cornell/mannlib/vitro/webapp/auth/rules/test_policy_key.n3 create mode 100644 api/src/test/resources/edu/cornell/mannlib/vitro/webapp/auth/rules/test_policy_valid.n3 create mode 100644 api/src/test/resources/edu/cornell/mannlib/vitro/webapp/auth/rules/test_policy_valid_set.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/attribute_types.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/attributes.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/decisions.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/object_types.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/ontology.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/operation_groups.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/operations.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_admin_display_class.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_admin_display_data_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_admin_display_object_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_admin_publish_class.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_admin_publish_data_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_admin_publish_object_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_admin_simple_permissions.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_admin_update_class.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_admin_update_data_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_admin_update_object_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_curator_display_class.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_curator_display_data_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_curator_display_object_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_curator_publish_class.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_curator_publish_data_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_curator_publish_object_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_curator_simple_permissions.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_curator_update_class.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_curator_update_data_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_curator_update_object_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_editor_display_class.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_editor_display_data_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_editor_display_object_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_editor_publish_class.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_editor_publish_data_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_editor_publish_object_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_editor_simple_permissions.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_editor_update_class.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_editor_update_data_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_editor_update_object_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_menu_items_editing.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_not_modifiable_statements.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_public_display_class.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_public_display_data_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_public_display_object_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_public_simple_permissions.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_public_update_class.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_public_update_data_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_public_update_object_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_root_user.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_self_editor_display_class.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_self_editor_display_data_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_self_editor_display_object_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_self_editor_publish_class.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_self_editor_publish_data_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_self_editor_publish_object_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_self_editor_simple_permissions.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_self_editor_update_class.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_self_editor_update_data_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/policy_self_editor_update_object_property.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/subject_types.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/test_types.n3 create mode 100644 home/src/main/resources/rdf/auth/everytime/test_values.n3 create mode 100644 home/src/main/resources/rdf/auth/firsttime/policy_admin_simple_permissions_dataset.n3 create mode 100644 home/src/main/resources/rdf/auth/firsttime/policy_curator_simple_permissions_dataset.n3 create mode 100644 home/src/main/resources/rdf/auth/firsttime/policy_editor_simple_permissions_dataset.n3 create mode 100644 home/src/main/resources/rdf/auth/firsttime/policy_not_modifiable_statements_dataset.n3 create mode 100644 home/src/main/resources/rdf/auth/firsttime/policy_public_simple_permissions_dataset.n3 create mode 100644 home/src/main/resources/rdf/auth/firsttime/policy_self_editor_simple_permissions_dataset.n3 diff --git a/api/src/main/java/edu/cornell/mannlib/vedit/controller/BaseEditController.java b/api/src/main/java/edu/cornell/mannlib/vedit/controller/BaseEditController.java index 65ecd722dc..e0164ca6de 100644 --- a/api/src/main/java/edu/cornell/mannlib/vedit/controller/BaseEditController.java +++ b/api/src/main/java/edu/cornell/mannlib/vedit/controller/BaseEditController.java @@ -9,19 +9,21 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; -import java.util.Collections; import java.util.Comparator; import java.util.Enumeration; import java.util.HashMap; -import java.util.Iterator; import java.util.LinkedList; import java.util.List; -import java.util.ListIterator; import java.util.Map; import java.util.Random; import javax.servlet.http.HttpServletRequest; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.OperationGroup; +import edu.cornell.mannlib.vitro.webapp.auth.policy.EntityPolicyController; +import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -190,7 +192,7 @@ public int compare(String str1, String str2) { } protected WebappDaoFactory getWebappDaoFactory() { - return ModelAccess.on(getServletContext()).getWebappDaoFactory(ASSERTIONS_ONLY); + return ModelAccess.getInstance().getWebappDaoFactory(ASSERTIONS_ONLY); } protected WebappDaoFactory getWebappDaoFactory(String userURI) { @@ -201,4 +203,60 @@ public String getDefaultLandingPage(HttpServletRequest request) { return(request.getContextPath() + DEFAULT_LANDING_PAGE); } + protected static void addAccessAttributes(HttpServletRequest req, String entityURI, AccessObjectType aot) { + // Add the permissionsEntityURI (if we are creating a new property, this will be empty) + req.setAttribute("_permissionsEntityURI", entityURI); + + // Get the available permission sets + List permissionSets = buildListOfSelectableRoles(ModelAccess.on(req).getWebappDaoFactory()); + List roleUris = new ArrayList<>(); + for (PermissionSet permissionSet : permissionSets) { + roleUris.add(permissionSet.getUri()); + } + req.setAttribute("roles", permissionSets); + // If the namespace is empty (e.e. we are creating a new record) + for (OperationGroup og : OperationGroup.values()){ + String groupName = og.toString().toLowerCase().split("_")[0]; + final String attributeName = groupName + "Roles"; + if (StringUtils.isEmpty(entityURI)) { + // predefined values + req.setAttribute(attributeName, roleUris); + } else { + // Get the permission sets that are granted permission for this entity + req.setAttribute(attributeName, EntityPolicyController.getGrantedRoles(entityURI, og, aot, roleUris)); + } + } + + } + + /** + * Create a list of all known PermissionSets. + */ + protected static List buildListOfSelectableRoles(WebappDaoFactory wadf) { + List permissionSets = new ArrayList<>(); + + // Get the non-public PermissionSets. + for (PermissionSet ps: wadf.getUserAccountsDao().getAllPermissionSets()) { + if (!ps.isForPublic()) { + permissionSets.add(ps); + } + } + + // Sort the non-public PermissionSets + permissionSets.sort(new Comparator() { + @Override + public int compare(PermissionSet ps1, PermissionSet ps2) { + return ps1.getUri().compareTo(ps2.getUri()); + } + }); + + // Add the public PermissionSets. + for (PermissionSet ps: wadf.getUserAccountsDao().getAllPermissionSets()) { + if (ps.isForPublic()) { + permissionSets.add(ps); + } + } + + return permissionSets; + } } diff --git a/api/src/main/java/edu/cornell/mannlib/vedit/controller/OperationController.java b/api/src/main/java/edu/cornell/mannlib/vedit/controller/OperationController.java index f925dfe362..674cace588 100644 --- a/api/src/main/java/edu/cornell/mannlib/vedit/controller/OperationController.java +++ b/api/src/main/java/edu/cornell/mannlib/vedit/controller/OperationController.java @@ -5,8 +5,11 @@ import java.io.IOException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Enumeration; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -15,6 +18,17 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessOperation; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.OperationGroup; +import edu.cornell.mannlib.vitro.webapp.auth.policy.EntityPolicyController; +import edu.cornell.mannlib.vitro.webapp.auth.rules.AccessRuleStore; +import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet; +import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.lang3.EnumUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -123,6 +137,39 @@ public void doPost (HttpServletRequest request, HttpServletResponse response) { return; } + // If contains restrictions + if (request.getParameter("_permissions") != null) { + // Get the namespace that we are editing + String entityUri = request.getParameter("_permissionsEntityURI"); + if (StringUtils.isEmpty(entityUri)) { + // If we don't have a namespace set, we are creating a new entity so use that namespace + if (!StringUtils.isEmpty(request.getParameter("Namespace")) && !StringUtils.isEmpty(request.getParameter("LocalName"))) { + entityUri = "" + request.getParameter("Namespace") + request.getParameter("LocalName"); + } + } + String entityType = request.getParameter("_permissionsEntityType"); + List permissionSets = buildListOfSelectableRoles(ModelAccess.on(request).getWebappDaoFactory()); + List roleUris = new ArrayList<>(); + for (PermissionSet permissionSet : permissionSets) { + roleUris.add(permissionSet.getUri()); + } + // Get the granted permissions from the request object + for (OperationGroup og : OperationGroup.values()) { + String operationGroupName = og.toString().toLowerCase().split("_")[0]; + String[] selectedRoles = request.getParameterValues(operationGroupName + "Roles"); + if(StringUtils.isBlank(entityUri)) { + log.error("EntityUri is blank"); + } else if (StringUtils.isBlank(entityType) || !EnumUtils.isValidEnum(AccessObjectType.class, entityType)) { + log.error("EntityType is not valid " + entityType); + } else { + if (selectedRoles == null) { + selectedRoles = new String[0]; + } + EntityPolicyController.updateEntityPolicy(entityUri, AccessObjectType.valueOf(entityType), og, Arrays.asList(selectedRoles), roleUris); + } + } + } + /* put request parameters and attributes into epo where the listeners can see */ epo.setRequestParameterMap(request.getParameterMap()); @@ -508,5 +555,4 @@ private boolean performEdit(EditProcessObject epo, Object newObj, String action) return SUCCESS; } - } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/RootUserSetup.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/RootUserSetup.java new file mode 100644 index 0000000000..05005c8f56 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/RootUserSetup.java @@ -0,0 +1,203 @@ +/* $This file is distributed under the terms of the license in LICENSE$ */ + +package edu.cornell.mannlib.vitro.webapp.auth; + +import java.util.TreeSet; + +import javax.servlet.ServletContext; +import javax.servlet.ServletContextEvent; +import javax.servlet.ServletContextListener; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; +import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status; +import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; +import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; +import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; + +/** + * + * On setup, check to see that the specified root user exists. If not, create + * it. If we can't create it, abort. + * + * If any other root users exist, warn about them. + */ +public class RootUserSetup implements ServletContextListener { + private static final Log log = LogFactory.getLog(RootUserSetup.class); + + private static final String PROPERTY_ROOT_USER_EMAIL = "rootUser.emailAddress"; + /* + * UQAM Add-Feature For parameterization of rootUser + */ + private static final String PROPERTY_ROOT_USER_PASSWORD = "rootUser.password"; + private static final String PROPERTY_ROOT_USER_PASSWORD_CHANGE_REQUIRED = "rootUser.passwordChangeRequired"; + + private static final String ROOT_USER_INITIAL_PASSWORD = "rootPassword"; + private static final String ROOT_USER_INITIAL_PASSWORD_CHANGE_REQUIRED = "true"; + + // ---------------------------------------------------------------------- + // Setup class + // ---------------------------------------------------------------------- + + private ServletContext ctx; + private StartupStatus ss; + private UserAccountsDao uaDao; + private ConfigurationProperties cp; + private String configuredRootUser; + private boolean configuredRootUserExists; + private TreeSet otherRootUsers; + + @Override + public void contextInitialized(ServletContextEvent sce) { + ctx = sce.getServletContext(); + ss = StartupStatus.getBean(ctx); + cp = ConfigurationProperties.getBean(ctx); + + try { + uaDao = ModelAccess.on(ctx).getWebappDaoFactory() + .getUserAccountsDao(); + configuredRootUser = getRootEmailFromConfig(); + + otherRootUsers = getEmailsOfAllRootUsers(); + configuredRootUserExists = otherRootUsers + .remove(configuredRootUser); + + if (configuredRootUserExists) { + if (otherRootUsers.isEmpty()) { + informThatRootUserExists(); + } else { + complainAboutMultipleRootUsers(); + } + } else { + createRootUser(); + if (!otherRootUsers.isEmpty()) { + complainAboutWrongRootUsers(); + } + } + } catch (Exception e) { + ss.fatal(this, "Failed to set up the RootUserPolicy", e); + } + } + + private String getRootEmailFromConfig() { + String email = ConfigurationProperties.getBean(ctx).getProperty( + PROPERTY_ROOT_USER_EMAIL); + if (email == null) { + throw new IllegalStateException( + "runtime.properties must contain a value for '" + + PROPERTY_ROOT_USER_EMAIL + "'"); + } else { + return email; + } + } + + private TreeSet getEmailsOfAllRootUsers() { + TreeSet rootUsers = new TreeSet(); + for (UserAccount ua : uaDao.getAllUserAccounts()) { + if (ua.isRootUser()) { + rootUsers.add(ua.getEmailAddress()); + } + } + return rootUsers; + } + + /** + * TODO The first and last name should be left blank, so the user will + * be forced to edit them. However, that's not in place yet. + */ + private void createRootUser() { + if (!Authenticator.isValidEmailAddress(configuredRootUser)) { + throw new IllegalStateException("Value for '" + + PROPERTY_ROOT_USER_EMAIL + + "' is not a valid email address: '" + + configuredRootUser + "'"); + } + + if (null != uaDao.getUserAccountByEmail(configuredRootUser)) { + throw new IllegalStateException("Can't create root user - " + + "an account already exists with email address '" + + configuredRootUser + "'"); + } + + UserAccount ua = new UserAccount(); + ua.setEmailAddress(configuredRootUser); + ua.setFirstName("root"); + ua.setLastName("user"); + // UQAM Add-Feature using getRootPasswordFromConfig() + ua.setArgon2Password(Authenticator.applyArgon2iEncoding( + getRootPasswordFromConfig())); + ua.setMd5Password(""); + // UQAM Add-Feature using getRootPasswdChangeRequiredFromConfig() + ua.setPasswordChangeRequired(getRootPasswdChangeRequiredFromConfig().booleanValue()); + ua.setStatus(Status.ACTIVE); + ua.setRootUser(true); + + uaDao.insertUserAccount(ua); + + StartupStatus.getBean(ctx).info(this, + "Created root user '" + configuredRootUser + "'"); + } + + private void informThatRootUserExists() { + ss.info(this, "Root user is " + configuredRootUser); + } + + private void complainAboutMultipleRootUsers() { + for (String other : otherRootUsers) { + ss.warning(this, "runtime.properties specifies '" + + configuredRootUser + "' as the value for '" + + PROPERTY_ROOT_USER_EMAIL + + "', but the system also contains this root user: " + + other); + } + ss.warning(this, "For security, " + + "it is best to delete unneeded root user accounts."); + } + + private void complainAboutWrongRootUsers() { + for (String other : otherRootUsers) { + ss.warning(this, "runtime.properties specifies '" + + configuredRootUser + "' as the value for '" + + PROPERTY_ROOT_USER_EMAIL + + "', but the system contains this root user instead: " + + other); + } + ss.warning(this, "Creating root user '" + configuredRootUser + "'"); + ss.warning(this, "For security, " + + "it is best to delete unneeded root user accounts."); + } + /* + * UQAM Add-Feature + * Add for getting rootUser.password property value from runtime.properties + */ + private String getRootPasswordFromConfig() { + String passwd = ConfigurationProperties.getBean(ctx).getProperty( + PROPERTY_ROOT_USER_PASSWORD); + if (passwd == null) { + passwd = ROOT_USER_INITIAL_PASSWORD; + } + return passwd; + } + + /* + * UQAM Add-Feature + * Add for getting rootUser.passwordChangeRequired property value from runtime.properties + */ + private Boolean getRootPasswdChangeRequiredFromConfig() { + String passwdCR = ConfigurationProperties.getBean(ctx).getProperty( + PROPERTY_ROOT_USER_PASSWORD_CHANGE_REQUIRED); + if (passwdCR == null) { + passwdCR = ROOT_USER_INITIAL_PASSWORD_CHANGE_REQUIRED; + } + return new Boolean(passwdCR); + } + @Override + public void contextDestroyed(ServletContextEvent sce) { + // Nothing to destroy + } + +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AbstractAttribute.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AbstractAttribute.java new file mode 100644 index 0000000000..2a4c2be105 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AbstractAttribute.java @@ -0,0 +1,70 @@ +package edu.cornell.mannlib.vitro.webapp.auth.attributes; + +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; + +public abstract class AbstractAttribute implements Attribute { + + private Set values = new HashSet<>(); + private String uri; + private TestType testType = TestType.EQUALS; + + public AbstractAttribute(String uri, String value) { + super(); + this.uri = uri; + values.add(value); + } + + public String getUri() { + return uri; + } + + public void setUri(String uri) { + this.uri = uri; + } + + public TestType getTestType() { + return testType; + } + + public void setTestType(TestType testType) { + this.testType = testType; + } + + @Override + public void addValue(String value) { + values.add(value); + } + + @Override + public Set getValues() { + return values; + } + + @Override + public boolean equals(Object object) { + if (!(object instanceof AbstractAttribute)) { + return false; + } + if (object == this) { + return true; + } + AbstractAttribute compared = (AbstractAttribute) object; + + return new EqualsBuilder() + .append(getUri(), compared.getUri()) + .append(getValues(), compared.getValues()) + .isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(15, 101) + .append(getUri()) + .append(getValues()) + .toHashCode(); + } +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AccessObjectType.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AccessObjectType.java new file mode 100644 index 0000000000..7d45bc5fa3 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AccessObjectType.java @@ -0,0 +1,14 @@ +package edu.cornell.mannlib.vitro.webapp.auth.attributes; + +public enum AccessObjectType { + ANY, + CLASS, + NAMED_OBJECT, + FAUX_PROPERTY, + DATA_PROPERTY, + OBJECT_PROPERTY, + DATA_PROPERTY_STATEMENT, + OBJECT_PROPERTY_STATEMENT, + ENTITY_URI, + ROOT_USER, +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AccessOperation.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AccessOperation.java new file mode 100644 index 0000000000..8945ebd05b --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AccessOperation.java @@ -0,0 +1,12 @@ +package edu.cornell.mannlib.vitro.webapp.auth.attributes; + +public enum AccessOperation { + ANY, + EXECUTE, + PUBLISH, + UPDATE, + DISPLAY, + ADD, + DROP, + EDIT +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/Attribute.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/Attribute.java new file mode 100644 index 0000000000..4f0e08db3d --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/Attribute.java @@ -0,0 +1,24 @@ +package edu.cornell.mannlib.vitro.webapp.auth.attributes; + +import java.util.Set; + +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; + +public interface Attribute { + + public void setUri(String uri); + + public String getUri(); + + public boolean match(AuthorizationRequest ar); + + public AttributeType getAttributeType(); + + public TestType getTestType(); + + Set getValues(); + + public void addValue(String value); + + public void setTestType(TestType valueOf); +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AttributeFactory.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AttributeFactory.java new file mode 100644 index 0000000000..4c780947f0 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AttributeFactory.java @@ -0,0 +1,69 @@ +package edu.cornell.mannlib.vitro.webapp.auth.attributes; + +import org.apache.jena.query.QuerySolution; + +import edu.cornell.mannlib.vitro.webapp.auth.rules.AccessRuleStore; + +public class AttributeFactory { + + public static Attribute createAttribute(QuerySolution qs) { + String typeId = qs.getLiteral(AccessRuleStore.TYPE_ID).getString(); + String attributeUri = qs.getResource(AccessRuleStore.ATTRIBUTE).getURI(); + AttributeType type = AttributeType.valueOf(typeId); + String testId = qs.getLiteral("testId").getString(); + String value = getValue(qs); + + Attribute at = null; + switch (type) { + case SUBJECT_ROLE_URI: + at = new SubjectRoleAttribute(attributeUri, value); + break; + case OPERATION: + at = new OperationAttribute(attributeUri, value); + break; + case OBJECT_URI: + at = new ObjectUriAttribute(attributeUri, value); + break; + case OBJECT_TYPE: + at = new ObjectTypeAttribute(attributeUri, value); + break; + case SUBJECT_TYPE: + at = new SubjectTypeAttribute(attributeUri, value); + break; + case STATEMENT_PREDICATE_URI: + at = new StatementPredicateUriAttribute(attributeUri, value); + break; + case STATEMENT_SUBJECT_URI: + at = new StatementSubjectUriAttribute(attributeUri, value); + break; + case STATEMENT_OBJECT_URI: + at = new StatementObjectUriAttribute(attributeUri, value); + break; + default : + at = null; + } + at.setTestType(TestType.valueOf(testId)); + return at; + } + + private static String getValue(QuerySolution qs) { + if (!qs.contains(AccessRuleStore.LITERAL_VALUE) || + !qs.get(AccessRuleStore.LITERAL_VALUE).isLiteral()) { + String value = qs.getResource(AccessRuleStore.ATTR_VALUE).getURI(); + return value; + } else { + String value = qs.getLiteral(AccessRuleStore.LITERAL_VALUE).toString(); + return value; + } + } + + public static void extendAttribute(Attribute attribute, QuerySolution qs) throws Exception { + String testId = qs.getLiteral("testId").getString(); + if (TestType.ONE_OF.toString().equals(testId) || + TestType.NOT_ONE_OF.toString().equals(testId)) { + attribute.addValue(getValue(qs)); + return; + } + throw new Exception(); + } +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AttributeGroup.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AttributeGroup.java new file mode 100644 index 0000000000..b7cade970a --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AttributeGroup.java @@ -0,0 +1,6 @@ +package edu.cornell.mannlib.vitro.webapp.auth.attributes; + +public enum AttributeGroup { + OBJECT_MATCH , + EXPENSIVE_COMPUTATION +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AttributeType.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AttributeType.java new file mode 100644 index 0000000000..7b6bb4ecab --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AttributeType.java @@ -0,0 +1,14 @@ +package edu.cornell.mannlib.vitro.webapp.auth.attributes; + +public enum AttributeType { + OPERATION, + SUBJECT_ROLE_URI, + OBJECT_URI, + OBJECT_TYPE, + STATEMENT_OBJECT_URI, + STATEMENT_PREDICATE_URI, + STATEMENT_SUBJECT_URI, + OBJECT_PROPERTY_URI, + DATA_PROPERTY_URI, + SUBJECT_TYPE +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AttributeValueTester.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AttributeValueTester.java new file mode 100644 index 0000000000..ce65904160 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/AttributeValueTester.java @@ -0,0 +1,105 @@ +package edu.cornell.mannlib.vitro.webapp.auth.attributes; + +import java.util.Arrays; +import java.util.List; +import java.util.Set; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.jena.rdf.model.Model; + +import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; + +public class AttributeValueTester { + private static final Log log = LogFactory.getLog(AttributeValueTester.class); + + static boolean test(Attribute attr, AuthorizationRequest ar, String... values) { + TestType testType = attr.getTestType(); + switch (testType) { + case EQUALS: + return equals(attr, values); + case NOT_EQUALS: + return !equals(attr, values); + case ONE_OF: + return contains(attr, values); + case NOT_ONE_OF: + return !contains(attr, values); + case STARTS_WITH: + return startsWith(attr, values); + case SPARQL_SELECT_QUERY_CONTAINS: + return sparqlQueryContains(attr, ar, values); + default: + return false; + } + } + + private static boolean sparqlQueryContains(Attribute attr, AuthorizationRequest ar, String[] inputValues) { + Set values = attr.getValues(); + final int valuesSize = values.size(); + if(valuesSize != 1) { + log.error("SparqlQueryContins value != 1"); + return false; + } + String queryTemplate = values.iterator().next(); + if (StringUtils.isBlank(queryTemplate)) { + log.error("SparqlQueryContins template is empty"); + return false; + } + AccessObject ao = ar.getAccessObject(); + Model m = ao.getStatementOntModel(); + if (m == null) { + log.error("SparqlQueryContains model is not provided"); + return false; + } + List personUris = ar.getEditorUris(); + if (personUris.isEmpty()) { + log.debug("SparqlQueryContins person uri is empty"); + return false; + } + List resourceUris = Arrays.asList(ao.getResourceUris()); + return ProximityChecker.isAanyRelated(m, resourceUris, personUris, queryTemplate); + } + + private static boolean contains(Attribute attr, String... inputValues) { + final Set values = attr.getValues(); + for (String inputValue : inputValues) { + if(values.contains(inputValue)){ + return true; + } + } + return false; + } + + private static boolean equals(Attribute attr, String... inputValues) { + Set values = attr.getValues(); + final int valuesSize = values.size(); + if(valuesSize != 1) { + return false; + } + String value = values.iterator().next(); + for (String inputValue : inputValues) { + if(value.equals(inputValue)){ + return true; + } + } + return false; + } + + private static boolean startsWith(Attribute attr, String... inputValues) { + Set values = attr.getValues(); + final int valuesSize = values.size(); + if(valuesSize != 1) { + return false; + } + String value = values.iterator().next(); + for (String inputValue : inputValues) { + if(inputValue != null && inputValue.startsWith(value)){ + return true; + } + } + return false; + } + +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/DataPropertyUriAttribute.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/DataPropertyUriAttribute.java new file mode 100644 index 0000000000..8e56ec8dbe --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/DataPropertyUriAttribute.java @@ -0,0 +1,39 @@ +package edu.cornell.mannlib.vitro.webapp.auth.attributes; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; +import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; + +public class DataPropertyUriAttribute extends AbstractAttribute { + + private static final Log log = LogFactory.getLog(DataPropertyUriAttribute.class); + + public DataPropertyUriAttribute(String uri, String objectUri) { + super(uri, objectUri); + } + + @Override + public boolean match(AuthorizationRequest ar) { + AccessObject ao = ar.getAccessObject(); + DataProperty dataProperty = ao.getDataProperty(); + String inputValue = dataProperty.getURI(); + if (dataProperty != null) { + inputValue = dataProperty.getURI(); + } + if (AttributeValueTester.test(this, ar, inputValue)) { + log.debug("Attribute value(s) match requested statement data property uri '" + inputValue + "'"); + return true; + } + log.debug("Attribute value(s) don't match requested statement data property uri '" + inputValue + "'"); + return false; + } + + @Override + public AttributeType getAttributeType() { + return AttributeType.OBJECT_PROPERTY_URI; + } + +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/ObjectPropertyUriAttribute.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/ObjectPropertyUriAttribute.java new file mode 100644 index 0000000000..14a746667c --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/ObjectPropertyUriAttribute.java @@ -0,0 +1,39 @@ +package edu.cornell.mannlib.vitro.webapp.auth.attributes; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; + +public class ObjectPropertyUriAttribute extends AbstractAttribute { + + private static final Log log = LogFactory.getLog(ObjectPropertyUriAttribute.class); + + public ObjectPropertyUriAttribute(String uri, String objectUri) { + super(uri, objectUri); + } + + @Override + public boolean match(AuthorizationRequest ar) { + AccessObject ao = ar.getAccessObject(); + ObjectProperty objectProperty = ao.getObjectProperty(); + String inputValue = objectProperty.getURI(); + if (objectProperty != null) { + inputValue = objectProperty.getURI(); + } + if (AttributeValueTester.test(this, ar, inputValue)) { + log.debug("Attribute value match requested statement object property uri '" + inputValue + "'"); + return true; + } + log.debug("Attribute value don't match requested statement object property uri '" + inputValue + "'"); + return false; + } + + @Override + public AttributeType getAttributeType() { + return AttributeType.OBJECT_PROPERTY_URI; + } + +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/ObjectTypeAttribute.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/ObjectTypeAttribute.java new file mode 100644 index 0000000000..343583bad5 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/ObjectTypeAttribute.java @@ -0,0 +1,33 @@ +package edu.cornell.mannlib.vitro.webapp.auth.attributes; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; + +public class ObjectTypeAttribute extends AbstractAttribute { + + private static final Log log = LogFactory.getLog(ObjectTypeAttribute.class); + + public ObjectTypeAttribute(String uri, String roleValue) { + super(uri, roleValue); + } + + @Override + public boolean match(AuthorizationRequest ar) { + AccessObject ao = ar.getAccessObject(); + final String inputValue = ao.getType().toString(); + if (AttributeValueTester.test(this, ar, inputValue)) { + log.debug("Attribute match requested object type '" + inputValue + "'"); + return true; + } + log.debug("Attribute don't match requested object type '" + inputValue + "'"); + return false; + } + + @Override + public AttributeType getAttributeType() { + return AttributeType.SUBJECT_TYPE; + } +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/ObjectUriAttribute.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/ObjectUriAttribute.java new file mode 100644 index 0000000000..53a3934969 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/ObjectUriAttribute.java @@ -0,0 +1,34 @@ +package edu.cornell.mannlib.vitro.webapp.auth.attributes; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; + +public class ObjectUriAttribute extends AbstractAttribute { + + private static final Log log = LogFactory.getLog(ObjectUriAttribute.class); + + public ObjectUriAttribute(String uri, String objectUri) { + super(uri, objectUri); + } + + @Override + public boolean match(AuthorizationRequest ar) { + AccessObject ao = ar.getAccessObject(); + final String inputValue = ao.getUri(); + if (AttributeValueTester.test(this, ar, inputValue)) { + log.debug("Attribute match requested '" + inputValue + "'"); + return true; + } + log.debug("Attribute don't match requested '" + inputValue + "'"); + return false; + } + + @Override + public AttributeType getAttributeType() { + return AttributeType.OBJECT_URI; + } + +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/OperationAttribute.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/OperationAttribute.java new file mode 100644 index 0000000000..8a459b5e5e --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/OperationAttribute.java @@ -0,0 +1,33 @@ +package edu.cornell.mannlib.vitro.webapp.auth.attributes; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; + +public class OperationAttribute extends AbstractAttribute { + + private static final Log log = LogFactory.getLog(OperationAttribute.class); + + public OperationAttribute(String uri, String roleValue) { + super(uri, roleValue); + } + + @Override + public boolean match(AuthorizationRequest ar) { + AccessOperation aop = ar.getAccessOperation(); + final String inputValue = aop.toString(); + if (AttributeValueTester.test(this, ar, inputValue)) { + log.debug("Attribute match requested operation '" + inputValue + "'"); + return true; + } + log.debug("Attribute don't match requested operation '" + inputValue + "'"); + return false; + } + + @Override + public AttributeType getAttributeType() { + return AttributeType.OPERATION; + } + +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/OperationGroup.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/OperationGroup.java new file mode 100644 index 0000000000..8ace7753eb --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/OperationGroup.java @@ -0,0 +1,7 @@ +package edu.cornell.mannlib.vitro.webapp.auth.attributes; + +public enum OperationGroup { + DISPLAY_GROUP, + UPDATE_GROUP, + PUBLISH_GROUP +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/ProximityChecker.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/ProximityChecker.java new file mode 100644 index 0000000000..4e7e20e566 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/ProximityChecker.java @@ -0,0 +1,63 @@ +/* $This file is distributed under the terms of the license in LICENSE$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.attributes; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.jena.query.ParameterizedSparqlString; +import org.apache.jena.query.Query; +import org.apache.jena.query.QueryExecution; +import org.apache.jena.query.QueryExecutionFactory; +import org.apache.jena.query.QueryFactory; +import org.apache.jena.query.QuerySolution; +import org.apache.jena.query.ResultSet; +import org.apache.jena.rdf.model.Model; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; + +public class ProximityChecker { + private static final Log log = LogFactory.getLog(ProximityChecker.class); + + public static boolean isAanyRelated(Model ontModel, List resourceUris, List personUris, String query) { + for (String personUri : personUris) { + List connectedResourceUris = getRelatedUris(ontModel, personUri, query); + for (String connectedResourceUri : connectedResourceUris) { + if (resourceUris.contains(connectedResourceUri)) { + return true; + } + } + } + return false; + } + private static List getRelatedUris(Model model, String personUri, String queryTemplate) { + HashMap> queryMap = QueryResultsMapCache.get(); + String queryMapKey = createQueryMapKey(personUri, queryTemplate); + if (queryMap.containsKey(queryMapKey)) { + return queryMap.get(queryMapKey); + } + + List resourceUris = new ArrayList<>(); + ParameterizedSparqlString pss = new ParameterizedSparqlString(); + pss.setCommandText(queryTemplate); + pss.setIri("personUri", personUri); + Query query = QueryFactory.create(pss.toString()); + QueryExecution queryExecution = QueryExecutionFactory.create(query, model); + try { + ResultSet resultSet = queryExecution.execSelect(); + while (resultSet.hasNext()) { + QuerySolution qs = resultSet.nextSolution(); + resourceUris.add(qs.getResource("resourceUri").getURI()); + } + } finally { + queryExecution.close(); + } + queryMap.put(queryMapKey, resourceUris); + QueryResultsMapCache.update(queryMap); + return resourceUris; + } + private static String createQueryMapKey(String personUri, String queryTemplate) { + return queryTemplate + "." + personUri; + } +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/QueryResultsMapCache.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/QueryResultsMapCache.java new file mode 100644 index 0000000000..0bc9515780 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/QueryResultsMapCache.java @@ -0,0 +1,45 @@ +package edu.cornell.mannlib.vitro.webapp.auth.attributes; + +import java.io.IOException; +import java.util.HashMap; +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +public class QueryResultsMapCache implements AutoCloseable { + private static final Log log = LogFactory.getLog(QueryResultsMapCache.class); + + private static ThreadLocal>> threadLocal = new ThreadLocal>>(); + + public QueryResultsMapCache() { + threadLocal.set(new HashMap>()); + log.debug("Query results map cache initialized"); + } + + @Override + public void close() throws IOException { + threadLocal.remove(); + log.debug("QueryResultsMapCache is closed"); + } + + public static HashMap> get() { + HashMap> queryResultsMap = threadLocal.get(); + if (queryResultsMap == null) { + queryResultsMap = new HashMap>(); + log.debug("Use a non-cached query results map"); + } else { + log.debug("Use cached query results map"); + } + return queryResultsMap; + } + + public static void update(HashMap> queryResultsMap) { + if (threadLocal.get() != null ) { + threadLocal.set(queryResultsMap); + log.debug("Query results map cache has been updated"); + } else { + log.debug("Query results map cache has not been updated as it wasn't initialized"); + } + } +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/StatementObjectUriAttribute.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/StatementObjectUriAttribute.java new file mode 100644 index 0000000000..aa8fbf6177 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/StatementObjectUriAttribute.java @@ -0,0 +1,34 @@ +package edu.cornell.mannlib.vitro.webapp.auth.attributes; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; + +public class StatementObjectUriAttribute extends AbstractAttribute { + + private static final Log log = LogFactory.getLog(StatementObjectUriAttribute.class); + + public StatementObjectUriAttribute(String uri, String objectUri) { + super(uri, objectUri); + } + + @Override + public boolean match(AuthorizationRequest ar) { + AccessObject ao = ar.getAccessObject(); + final String inputValue = ao.getStatementObject(); + if (AttributeValueTester.test(this, ar, inputValue)) { + log.debug("Attribute value match requested statement object uri '" + inputValue + "'"); + return true; + } + log.debug("Attribute value don't match requested statement object uri '" + inputValue + "'"); + return false; + } + + @Override + public AttributeType getAttributeType() { + return AttributeType.STATEMENT_OBJECT_URI; + } + +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/StatementPredicateUriAttribute.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/StatementPredicateUriAttribute.java new file mode 100644 index 0000000000..da8eaf55bb --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/StatementPredicateUriAttribute.java @@ -0,0 +1,34 @@ +package edu.cornell.mannlib.vitro.webapp.auth.attributes; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; + +public class StatementPredicateUriAttribute extends AbstractAttribute { + + private static final Log log = LogFactory.getLog(StatementPredicateUriAttribute.class); + + public StatementPredicateUriAttribute(String uri, String objectUri) { + super(uri, objectUri); + } + + @Override + public boolean match(AuthorizationRequest ar) { + AccessObject ao = ar.getAccessObject(); + final String inputValue = ao.getStatementPredicateUri(); + if (AttributeValueTester.test(this, ar, inputValue)) { + log.debug("Attribute value match requested statement predicate uri '" + inputValue + "'"); + return true; + } + log.debug("Attribute value don't match requested statement predicate uri '" + inputValue + "'"); + return false; + } + + @Override + public AttributeType getAttributeType() { + return AttributeType.STATEMENT_PREDICATE_URI; + } + +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/StatementSubjectUriAttribute.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/StatementSubjectUriAttribute.java new file mode 100644 index 0000000000..696681e9f3 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/StatementSubjectUriAttribute.java @@ -0,0 +1,34 @@ +package edu.cornell.mannlib.vitro.webapp.auth.attributes; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; + +public class StatementSubjectUriAttribute extends AbstractAttribute { + + private static final Log log = LogFactory.getLog(StatementSubjectUriAttribute.class); + + public StatementSubjectUriAttribute(String uri, String objectUri) { + super(uri, objectUri); + } + + @Override + public boolean match(AuthorizationRequest ar) { + AccessObject ao = ar.getAccessObject(); + final String inputValue = ao.getStatementSubject(); + if (AttributeValueTester.test(this, ar, inputValue)) { + log.debug("Attribute value match requested statement subject uri '" + inputValue + "'"); + return true; + } + log.debug("Attribute value don't match requested statement subject uri '" + inputValue + "'"); + return false; + } + + @Override + public AttributeType getAttributeType() { + return AttributeType.STATEMENT_SUBJECT_URI; + } + +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/SubjectRoleAttribute.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/SubjectRoleAttribute.java new file mode 100644 index 0000000000..c1ec86332a --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/SubjectRoleAttribute.java @@ -0,0 +1,34 @@ +package edu.cornell.mannlib.vitro.webapp.auth.attributes; + +import java.util.List; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; + +public class SubjectRoleAttribute extends AbstractAttribute { + + private static final Log log = LogFactory.getLog(SubjectRoleAttribute.class); + + public SubjectRoleAttribute(String uri, String roleValue) { + super(uri, roleValue); + } + + @Override + public boolean match(AuthorizationRequest ar) { + final List inputValues = ar.getRoleUris(); + if (AttributeValueTester.test(this, ar, inputValues.toArray(new String[0]))) { + log.debug("Attribute match requested '" + inputValues + "'"); + return true; + } + log.debug("Attribute don't match requested '" + inputValues + "'"); + return false; + } + + @Override + public AttributeType getAttributeType() { + return AttributeType.SUBJECT_ROLE_URI; + } + +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/SubjectTypeAttribute.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/SubjectTypeAttribute.java new file mode 100644 index 0000000000..26edd027dd --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/SubjectTypeAttribute.java @@ -0,0 +1,35 @@ +package edu.cornell.mannlib.vitro.webapp.auth.attributes; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsRootUser; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; + +public class SubjectTypeAttribute extends AbstractAttribute { + + private static final Log log = LogFactory.getLog(SubjectTypeAttribute.class); + + public SubjectTypeAttribute(String uri, String subjectTypeValue) { + super(uri, subjectTypeValue); + } + + @Override + public boolean match(AuthorizationRequest ar) { + IdentifierBundle ac_subject = ar.getIds(); + String inputValue = IsRootUser.isRootUser(ac_subject) ? "ROOT_USER" : ""; + if (AttributeValueTester.test(this, ar, inputValue)) { + log.debug("Attribute subject type match requested object type '"); + return true; + } else { + log.debug("Attribute subject type don't match requested object type '"); + return false; + } + } + + @Override + public AttributeType getAttributeType() { + return AttributeType.OBJECT_TYPE; + } +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/TestType.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/TestType.java new file mode 100644 index 0000000000..4f8dcae11f --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/attributes/TestType.java @@ -0,0 +1,10 @@ +package edu.cornell.mannlib.vitro.webapp.auth.attributes; + +public enum TestType { + EQUALS, + NOT_EQUALS, + ONE_OF, + NOT_ONE_OF, + STARTS_WITH, + SPARQL_SELECT_QUERY_CONTAINS +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/ActiveIdentifierBundleFactories.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/ActiveIdentifierBundleFactories.java index 1c88ee07cc..85ee992303 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/ActiveIdentifierBundleFactories.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/ActiveIdentifierBundleFactories.java @@ -5,8 +5,6 @@ import java.util.ArrayList; import java.util.List; -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; import javax.servlet.http.HttpServletRequest; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; @@ -15,9 +13,19 @@ * Keep a list of the active IdentifierBundleFactories in the context. */ public class ActiveIdentifierBundleFactories { - private static final String ATTRIBUTE_ACTIVE_FACTORIES = ActiveIdentifierBundleFactories.class - .getName(); - + + private static ActiveIdentifierBundleFactories INSTANCE = new ActiveIdentifierBundleFactories(); + + private final List factories = new ArrayList(); + + private ActiveIdentifierBundleFactories() { + INSTANCE = this; + } + + public static ActiveIdentifierBundleFactories getInstance() { + return INSTANCE; + } + // ---------------------------------------------------------------------- // static methods // ---------------------------------------------------------------------- @@ -25,40 +33,20 @@ public class ActiveIdentifierBundleFactories { /** * Add a new IdentifierBundleFactory to the list. */ - public static void addFactory(ServletContextEvent sce, - IdentifierBundleFactory factory) { - if (sce == null) { - throw new NullPointerException("sce may not be null."); - } - if (factory == null) { - throw new NullPointerException("factory may not be null."); - } - - addFactory(sce.getServletContext(), factory); - } - - /** - * Add a new IdentifierBundleFactory to the list. - */ - public static void addFactory(ServletContext ctx, - IdentifierBundleFactory factory) { - if (ctx == null) { - throw new NullPointerException("ctx may not be null."); - } + public static void addFactory(IdentifierBundleFactory factory) { if (factory == null) { throw new NullPointerException("factory may not be null."); } - - getActiveFactories(ctx).addFactory(factory); + INSTANCE.factories.add(factory); } /** * Just for diagnostics. Don't expose the factories themselves, only their * names. */ - public static List getFactoryNames(ServletContext ctx) { + public static List getFactoryNames() { List names = new ArrayList(); - ActiveIdentifierBundleFactories actFact = getActiveFactories(ctx); + ActiveIdentifierBundleFactories actFact = ActiveIdentifierBundleFactories.getInstance(); for (IdentifierBundleFactory factory : actFact.factories) { names.add(factory.toString()); } @@ -74,66 +62,20 @@ public static List getFactoryNames(ServletContext ctx) { * request. */ static IdentifierBundle getIdentifierBundle(HttpServletRequest request) { - return getActiveFactories(request).getBundleForRequest(request); + return ActiveIdentifierBundleFactories.getInstance().getBundleForRequest(request); } /** * Get the Identifiers that would be created if this user were to log in. */ - public static IdentifierBundle getUserIdentifierBundle( - HttpServletRequest request, UserAccount userAccount) { - return getActiveFactories(request).getBundleForUser(userAccount); - } - - /** - * Get the singleton instance from the servlet context. If there isn't one, - * create one. This never returns null. - */ - private static ActiveIdentifierBundleFactories getActiveFactories( - HttpServletRequest req) { - if (req == null) { - throw new NullPointerException("req may not be null."); - } - - return getActiveFactories(req.getSession().getServletContext()); - } - - /** - * Get the singleton instance from the servlet context. If there isn't one, - * create one. This never returns null. - */ - private static ActiveIdentifierBundleFactories getActiveFactories( - ServletContext ctx) { - if (ctx == null) { - throw new NullPointerException("ctx may not be null."); - } - - Object obj = ctx.getAttribute(ATTRIBUTE_ACTIVE_FACTORIES); - if (obj == null) { - obj = new ActiveIdentifierBundleFactories(); - ctx.setAttribute(ATTRIBUTE_ACTIVE_FACTORIES, obj); - } - - if (!(obj instanceof ActiveIdentifierBundleFactories)) { - throw new IllegalStateException("Expected to find an instance of " - + ActiveIdentifierBundleFactories.class.getName() - + " in the context, but found an instance of " - + obj.getClass().getName() + " instead."); - } - - return (ActiveIdentifierBundleFactories) obj; + public static IdentifierBundle getUserIdentifierBundle(UserAccount userAccount) { + return ActiveIdentifierBundleFactories.getInstance().getBundleForUser(userAccount); } // ---------------------------------------------------------------------- // the instance // ---------------------------------------------------------------------- - private final List factories = new ArrayList(); - - private void addFactory(IdentifierBundleFactory factory) { - factories.add(factory); - } - /** * Run through the active factories and get all Identifiers for this * request. diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/HasPermission.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/HasPermission.java deleted file mode 100644 index 3aa9aeff12..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/HasPermission.java +++ /dev/null @@ -1,72 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.identifier.common; - -import java.util.Collection; -import java.util.HashSet; -import java.util.Set; - -import edu.cornell.mannlib.vitro.webapp.auth.identifier.Identifier; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; -import edu.cornell.mannlib.vitro.webapp.auth.permissions.Permission; - -/** - * The current user has this Permission, through one or more PermissionSets. - */ -public class HasPermission extends AbstractCommonIdentifier implements - Identifier, Comparable { - public static Collection getIdentifiers(IdentifierBundle ids) { - return getIdentifiersForClass(ids, HasPermission.class); - } - - public static Collection getPermissions(IdentifierBundle ids) { - Set set = new HashSet(); - for (HasPermission id : getIdentifiers(ids)) { - set.add(id.getPermission()); - } - return set; - } - - private final Permission permission; // never null - - public HasPermission(Permission permission) { - if (permission == null) { - throw new NullPointerException("permission may not be null."); - } - this.permission = permission; - } - - public Permission getPermission() { - return permission; - } - - @Override - public String toString() { - return "HasPermission[" + permission + "]"; - } - - @Override - public int hashCode() { - return permission.hashCode(); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (obj == null) { - return false; - } - if (!(obj instanceof HasPermission)) { - return false; - } - HasPermission that = (HasPermission) obj; - return this.permission.equals(that.permission); - } - - @Override - public int compareTo(HasPermission that) { - return this.permission.compareTo(that.permission); - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/HasPermissionSet.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/IdentifierPermissionSetProvider.java similarity index 69% rename from api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/HasPermissionSet.java rename to api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/IdentifierPermissionSetProvider.java index cf94e1437c..c537ece27e 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/HasPermissionSet.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/IdentifierPermissionSetProvider.java @@ -13,15 +13,15 @@ /** * The current user has this Permission, through one or more PermissionSets. */ -public class HasPermissionSet extends AbstractCommonIdentifier implements - Identifier, Comparable { - public static Collection getIdentifiers(IdentifierBundle ids) { - return getIdentifiersForClass(ids, HasPermissionSet.class); +public class IdentifierPermissionSetProvider extends AbstractCommonIdentifier implements + Identifier, Comparable { + public static Collection getIdentifiers(IdentifierBundle ids) { + return getIdentifiersForClass(ids, IdentifierPermissionSetProvider.class); } public static Collection getPermissionSets(IdentifierBundle ids) { Set set = new HashSet<>(); - for (HasPermissionSet id : getIdentifiers(ids)) { + for (IdentifierPermissionSetProvider id : getIdentifiers(ids)) { set.add(id.getPermissionSet()); } return set; @@ -29,7 +29,7 @@ public static Collection getPermissionSets(IdentifierBundle ids) public static Collection getPermissionSetUris(IdentifierBundle ids) { Set set = new HashSet<>(); - for (HasPermissionSet id : getIdentifiers(ids)) { + for (IdentifierPermissionSetProvider id : getIdentifiers(ids)) { set.add(id.getPermissionSet().getUri()); } return set; @@ -37,7 +37,7 @@ public static Collection getPermissionSetUris(IdentifierBundle ids) { private final PermissionSet permissionSet; // never null - public HasPermissionSet(PermissionSet permissionSet) { + public IdentifierPermissionSetProvider(PermissionSet permissionSet) { if (permissionSet == null) { throw new NullPointerException("permissionSet may not be null."); } @@ -66,15 +66,15 @@ public boolean equals(Object obj) { if (obj == null) { return false; } - if (!(obj instanceof HasPermissionSet)) { + if (!(obj instanceof IdentifierPermissionSetProvider)) { return false; } - HasPermissionSet that = (HasPermissionSet) obj; + IdentifierPermissionSetProvider that = (IdentifierPermissionSetProvider) obj; return this.permissionSet.getUri().equals(that.permissionSet.getUri()); } @Override - public int compareTo(HasPermissionSet that) { + public int compareTo(IdentifierPermissionSetProvider that) { return this.permissionSet.getUri().compareTo( that.permissionSet.getUri()); } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/IsBlacklisted.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/IsBlacklisted.java index 36275f37bb..dd9a5b411e 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/IsBlacklisted.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/common/IsBlacklisted.java @@ -2,42 +2,20 @@ package edu.cornell.mannlib.vitro.webapp.auth.identifier.common; -import java.io.File; -import java.io.FileFilter; -import java.io.FileInputStream; -import java.io.IOException; import java.util.Collection; import java.util.HashSet; import java.util.Set; -import javax.servlet.ServletContext; - -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.apache.jena.ontology.OntModel; -import org.apache.jena.query.Query; -import org.apache.jena.query.QueryExecution; -import org.apache.jena.query.QueryExecutionFactory; -import org.apache.jena.query.QueryFactory; -import org.apache.jena.query.QuerySolution; -import org.apache.jena.query.ResultSet; -import org.apache.jena.rdf.model.RDFNode; - import edu.cornell.mannlib.vitro.webapp.auth.identifier.Identifier; import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; import edu.cornell.mannlib.vitro.webapp.beans.Individual; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; /** * The current user is blacklisted for this reason. */ public class IsBlacklisted extends AbstractCommonIdentifier implements Identifier { - private static final Log log = LogFactory.getLog(IsBlacklisted.class); - private final static String BLACKLIST_SPARQL_DIR = "/admin/selfEditBlacklist"; private static final String NOT_BLACKLISTED = null; // ---------------------------------------------------------------------- @@ -48,16 +26,12 @@ public class IsBlacklisted extends AbstractCommonIdentifier implements * If this individual is blacklisted, return an appropriate Identifier. * Otherwise, return null. */ - public static IsBlacklisted getInstance(Individual individual, - ServletContext context) { + public static IsBlacklisted getInstance(Individual individual) { if (individual == null) { throw new NullPointerException("individual may not be null."); } - if (context == null) { - throw new NullPointerException("context may not be null."); - } - String reasonForBlacklisting = checkForBlacklisted(individual, context); + String reasonForBlacklisting = NOT_BLACKLISTED; IsBlacklisted id = new IsBlacklisted(individual.getURI(), reasonForBlacklisting); if (id.isBlacklisted()) { @@ -67,123 +41,6 @@ public static IsBlacklisted getInstance(Individual individual, } } - /** - * Runs through .sparql files in the BLACKLIST_SPARQL_DIR. - * - * The first that returns one or more rows will be cause the user to be - * blacklisted. - * - * The first variable from the first solution set will be returned. - */ - private static String checkForBlacklisted(Individual ind, - ServletContext context) { - String realPath = context.getRealPath(BLACKLIST_SPARQL_DIR); - File blacklistDir = new File(realPath); - if (!blacklistDir.isDirectory() || !blacklistDir.canRead()) { - log.debug("cannot read blacklist directory " + realPath); - return NOT_BLACKLISTED; - } - - log.debug("checking directlry " + realPath - + " for blacklisting sparql query files"); - File[] files = blacklistDir.listFiles(new FileFilter() { - @Override - public boolean accept(File pathname) { - return pathname.getName().endsWith(".sparql"); - } - }); - - String reasonForBlacklist = NOT_BLACKLISTED; - for (File file : files) { - try { - reasonForBlacklist = runSparqlFileForBlacklist(file, ind, - context); - if (reasonForBlacklist != NOT_BLACKLISTED) - break; - } catch (RuntimeException ex) { - log.error( - "Could not run blacklist check query for file " - + file.getAbsolutePath() + File.separatorChar - + file.getName(), ex); - } - } - return reasonForBlacklist; - } - - /** - * Runs the SPARQL query in the file with the uri of the individual - * substituted in. - * - * The URI of ind will be substituted into the query where ever the token - * "?individualURI" is found. - * - * If there are any solution sets, then the URI of the variable named - * "cause" will be returned. Make sure that it is a resource with a URI. - * Otherwise null will be returned. - */ - private static String runSparqlFileForBlacklist(File file, Individual ind, - ServletContext context) { - if (!file.canRead()) { - log.debug("cannot read blacklisting SPARQL file " + file.getName()); - return NOT_BLACKLISTED; - } - - String queryString = null; - FileInputStream fis = null; - try { - fis = new FileInputStream(file); - byte b[] = new byte[fis.available()]; - fis.read(b); - queryString = new String(b); - } catch (IOException ioe) { - log.debug(ioe); - return NOT_BLACKLISTED; - } finally { - if (fis != null) { - try { - fis.close(); - } catch (IOException e) { - log.warn("could not close file", e); - } - } - } - - if (StringUtils.isEmpty(queryString)) { - log.debug(file.getName() + " is empty"); - return NOT_BLACKLISTED; - } - - OntModel model = ModelAccess.on(context).getOntModel(); - - queryString = queryString.replaceAll("\\?individualURI", - "<" + ind.getURI() + ">"); - log.debug(queryString); - - Query query = QueryFactory.create(queryString); - QueryExecution qexec = QueryExecutionFactory.create(query, model); - try { - ResultSet results = qexec.execSelect(); - while (results.hasNext()) { - QuerySolution solution = results.nextSolution(); - if (solution.contains("cause")) { - RDFNode node = solution.get("cause"); - if (node.isResource()) { - return node.asResource().getURI(); - } else if (node.isLiteral()) { - return node.asLiteral().getString(); - } - } else { - log.error("Query solution must contain a variable " - + "\"cause\" of type Resource or Literal."); - return NOT_BLACKLISTED; - } - } - } finally { - qexec.close(); - } - return NOT_BLACKLISTED; - } - public static Collection getIdentifiers(IdentifierBundle ids) { return getIdentifiersForClass(ids, IsBlacklisted.class); } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/BaseIdentifierBundleFactory.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/BaseIdentifierBundleFactory.java index 75bd8c119a..be0909d1ce 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/BaseIdentifierBundleFactory.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/BaseIdentifierBundleFactory.java @@ -2,8 +2,6 @@ package edu.cornell.mannlib.vitro.webapp.auth.identifier.factory; -import javax.servlet.ServletContext; - import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundleFactory; import edu.cornell.mannlib.vitro.webapp.dao.IndividualDao; import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; @@ -15,17 +13,12 @@ */ public abstract class BaseIdentifierBundleFactory implements IdentifierBundleFactory { - protected final ServletContext ctx; protected final WebappDaoFactory wdf; protected final UserAccountsDao uaDao; protected final IndividualDao indDao; - public BaseIdentifierBundleFactory(ServletContext ctx) { - if (ctx == null) { - throw new NullPointerException("ctx may not be null."); - } - this.ctx = ctx; - this.wdf = ModelAccess.on(ctx).getWebappDaoFactory(); + public BaseIdentifierBundleFactory() { + this.wdf = ModelAccess.getInstance().getWebappDaoFactory(); this.uaDao = wdf.getUserAccountsDao(); this.indDao = wdf.getIndividualDao(); } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/BaseUserBasedIdentifierBundleFactory.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/BaseUserBasedIdentifierBundleFactory.java index 93aa965036..3aed5afec7 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/BaseUserBasedIdentifierBundleFactory.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/BaseUserBasedIdentifierBundleFactory.java @@ -2,7 +2,6 @@ package edu.cornell.mannlib.vitro.webapp.auth.identifier.factory; -import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; import edu.cornell.mannlib.vedit.beans.LoginStatusBean; @@ -16,10 +15,6 @@ public abstract class BaseUserBasedIdentifierBundleFactory extends BaseIdentifierBundleFactory implements UserBasedIdentifierBundleFactory { - public BaseUserBasedIdentifierBundleFactory(ServletContext ctx) { - super(ctx); - } - @Override public final IdentifierBundle getIdentifierBundle(HttpServletRequest request) { return getIdentifierBundleForUser(LoginStatusBean diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionFactory.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionFactory.java deleted file mode 100644 index 44d0689d46..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionFactory.java +++ /dev/null @@ -1,90 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.identifier.factory; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashSet; -import java.util.List; -import java.util.Set; - -import javax.servlet.ServletContext; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasPermission; -import edu.cornell.mannlib.vitro.webapp.auth.permissions.Permission; -import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionRegistry; -import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet; -import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; - -/** - * Figure out what Permissions the user is entitled to have. - */ -public class HasPermissionFactory extends BaseUserBasedIdentifierBundleFactory { - private static final Log log = LogFactory - .getLog(HasPermissionFactory.class); - - public HasPermissionFactory(ServletContext ctx) { - super(ctx); - } - - @Override - public IdentifierBundle getIdentifierBundleForUser(UserAccount user) { - if (user == null) { - return createPublicPermissions(); - } else { - return createUserPermissions(user); - } - } - - private IdentifierBundle createPublicPermissions() { - Set permissionUris = new HashSet(); - for (PermissionSet ps : uaDao.getAllPermissionSets()) { - if (ps.isForPublic()) { - permissionUris.addAll(ps.getPermissionUris()); - } - } - log.debug("Permission URIs: " + permissionUris); - - return new ArrayIdentifierBundle( - getIdentifiersFromPermissions(getPermissionsForUris(permissionUris))); - } - - private IdentifierBundle createUserPermissions(UserAccount user) { - Set permissionUris = new HashSet(); - for (String psUri : user.getPermissionSetUris()) { - PermissionSet ps = uaDao.getPermissionSetByUri(psUri); - if (ps != null) { - permissionUris.addAll(ps.getPermissionUris()); - } - } - log.debug("user permission sets: " + user.getPermissionSetUris()); - log.debug("Permission URIs: " + permissionUris); - - return new ArrayIdentifierBundle( - getIdentifiersFromPermissions(getPermissionsForUris(permissionUris))); - } - - private Collection getPermissionsForUris( - Collection permissionUris) { - List permissions = new ArrayList(); - PermissionRegistry registry = PermissionRegistry.getRegistry(ctx); - for (String uri : permissionUris) { - permissions.add(registry.getPermission(uri)); - } - return permissions; - } - - private List getIdentifiersFromPermissions( - Collection permissions) { - List ids = new ArrayList(); - for (Permission permission : permissions) { - ids.add(new HasPermission(permission)); - } - return ids; - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionSetFactory.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionSetFactory.java index e132251cff..fbcd90783f 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionSetFactory.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasPermissionSetFactory.java @@ -2,28 +2,20 @@ package edu.cornell.mannlib.vitro.webapp.auth.identifier.factory; -import javax.servlet.ServletContext; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle; import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasPermissionSet; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IdentifierPermissionSetProvider; import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; /** * Figure out what PermissionSets the user is entitled to have. */ -public class HasPermissionSetFactory extends - BaseUserBasedIdentifierBundleFactory { - private static final Log log = LogFactory - .getLog(HasPermissionFactory.class); - - public HasPermissionSetFactory(ServletContext ctx) { - super(ctx); - } +public class HasPermissionSetFactory extends BaseUserBasedIdentifierBundleFactory { + private static final Log log = LogFactory.getLog(HasPermissionSetFactory.class); @Override public IdentifierBundle getIdentifierBundleForUser(UserAccount user) { @@ -32,7 +24,7 @@ public IdentifierBundle getIdentifierBundleForUser(UserAccount user) { for (String psUri : user.getPermissionSetUris()) { PermissionSet ps = uaDao.getPermissionSetByUri(psUri); if (ps != null) { - ids.add(new HasPermissionSet(ps)); + ids.add(new IdentifierPermissionSetProvider(ps)); } } } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasProfileOrIsBlacklistedFactory.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasProfileOrIsBlacklistedFactory.java index 674c795627..3801839312 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasProfileOrIsBlacklistedFactory.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasProfileOrIsBlacklistedFactory.java @@ -28,17 +28,13 @@ public class HasProfileOrIsBlacklistedFactory extends private static final Log log = LogFactory .getLog(HasProfileOrIsBlacklistedFactory.class); - public HasProfileOrIsBlacklistedFactory(ServletContext ctx) { - super(ctx); - } - @Override public IdentifierBundle getIdentifierBundleForUser(UserAccount user) { ArrayIdentifierBundle ids = new ArrayIdentifierBundle(); for (Individual ind : getAssociatedIndividuals(user)) { // If they are blacklisted, this factory will return an identifier - Identifier id = IsBlacklisted.getInstance(ind, ctx); + Identifier id = IsBlacklisted.getInstance(ind); if (id != null) { ids.add(id); } else { @@ -60,7 +56,7 @@ private Collection getAssociatedIndividuals(UserAccount user) { return individuals; } - SelfEditingConfiguration sec = SelfEditingConfiguration.getBean(ctx); + SelfEditingConfiguration sec = SelfEditingConfiguration.getInstance(); individuals.addAll(sec.getAssociatedIndividuals(indDao, user)); return individuals; diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasProxyEditingRightsFactory.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasProxyEditingRightsFactory.java index c126bcb91e..718f9cbb64 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasProxyEditingRightsFactory.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/HasProxyEditingRightsFactory.java @@ -2,8 +2,6 @@ package edu.cornell.mannlib.vitro.webapp.auth.identifier.factory; -import javax.servlet.ServletContext; - import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle; import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasProxyEditingRights; @@ -15,10 +13,6 @@ public class HasProxyEditingRightsFactory extends BaseUserBasedIdentifierBundleFactory { - public HasProxyEditingRightsFactory(ServletContext ctx) { - super(ctx); - } - @Override public IdentifierBundle getIdentifierBundleForUser(UserAccount user) { ArrayIdentifierBundle ids = new ArrayIdentifierBundle(); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsRootUserFactory.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsRootUserFactory.java index 9767b2f2ea..fa8df2fe74 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsRootUserFactory.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsRootUserFactory.java @@ -2,8 +2,6 @@ package edu.cornell.mannlib.vitro.webapp.auth.identifier.factory; -import javax.servlet.ServletContext; - import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle; import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsRootUser; @@ -14,10 +12,6 @@ */ public class IsRootUserFactory extends BaseUserBasedIdentifierBundleFactory { - public IsRootUserFactory(ServletContext ctx) { - super(ctx); - } - @Override public IdentifierBundle getIdentifierBundleForUser(UserAccount user) { if ((user != null) && user.isRootUser()) { diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsUserFactory.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsUserFactory.java index d1d60ea9e5..67b935a1dd 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsUserFactory.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/identifier/factory/IsUserFactory.java @@ -2,8 +2,6 @@ package edu.cornell.mannlib.vitro.webapp.auth.identifier.factory; -import javax.servlet.ServletContext; - import edu.cornell.mannlib.vitro.webapp.auth.identifier.ArrayIdentifierBundle; import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsUser; @@ -14,10 +12,6 @@ */ public class IsUserFactory extends BaseUserBasedIdentifierBundleFactory { - public IsUserFactory(ServletContext ctx) { - super(ctx); - } - @Override public IdentifierBundle getIdentifierBundleForUser(UserAccount user) { if (user == null) { diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/AccessObject.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/AccessObject.java new file mode 100644 index 0000000000..57077a54fa --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/AccessObject.java @@ -0,0 +1,109 @@ +/* $This file is distributed under the terms of the license in LICENSE$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.objects; + +import org.apache.jena.rdf.model.Model; + +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType; +import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; +import edu.cornell.mannlib.vitro.webapp.beans.Property; + +public abstract class AccessObject { + + public static String SOME_URI = "?SOME_URI"; + public static Property SOME_PREDICATE = new Property(SOME_URI); + public static String SOME_LITERAL = "?SOME_LITERAL"; + + private AccessObjectStatement statement; + private DataProperty dataProperty; + private ObjectProperty objectProperty; + + public ObjectProperty getObjectProperty() { + return objectProperty; + } + + public void setObjectProperty(ObjectProperty objectProperty) { + this.objectProperty = objectProperty; + } + + public String getUri() { + return null; + } + + public AccessObjectType getType() { + return AccessObjectType.ANY; + }; + + public AccessObjectStatement getStatement() { + return statement; + }; + + protected void initializeStatement() { + if (statement == null) { + statement = new AccessObjectStatement(); + } + } + + public void setStatementOntModel(Model ontModel) { + initializeStatement(); + getStatement().setModel(ontModel); + } + + public Model getStatementOntModel() { + initializeStatement(); + return getStatement().getModel(); + } + + public void setStatementSubject(String subject) { + initializeStatement(); + getStatement().setSubject(subject); + } + + public String getStatementSubject() { + initializeStatement(); + return getStatement().getSubject(); + } + + public void setStatementPredicate(Property predicate) { + initializeStatement(); + getStatement().setPredicate(predicate); + } + + private Property getPredicate() { + initializeStatement(); + return getStatement().getPredicate(); + } + + public String getStatementPredicateUri() { + if (statement == null || statement.getPredicate() == null) { + return null; + } + Property predicate = getPredicate(); + return predicate.getURI(); + } + + public void setStatementObject(String objectUri) { + initializeStatement(); + this.getStatement().setObject(objectUri); + } + + public String getStatementObject() { + initializeStatement(); + return getStatement().getObject(); + } + + public DataProperty getDataProperty() { + return dataProperty; + } + + public void setDataProperty(DataProperty dataProperty) { + this.dataProperty = dataProperty; + } + + public String[] getResourceUris() { + initializeStatement(); + return getStatement().getResourceUris(getType()); + } + +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/AccessObjectImpl.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/AccessObjectImpl.java new file mode 100644 index 0000000000..a4e1bb84d8 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/AccessObjectImpl.java @@ -0,0 +1,62 @@ +/* $This file is distributed under the terms of the license in LICENSE$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.objects; + +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType; + +/** + * A RequestedAction that can be recognized by a SimplePermission. + */ +public class AccessObjectImpl extends AccessObject { + private final String uri; + private AccessObjectType type; + + public AccessObjectImpl() { + this.uri = ""; + this.type = AccessObjectType.NAMED_OBJECT; + } + + public AccessObjectImpl(String uri, AccessObjectType type) { + this.uri = uri; + this.type = type; + } + + public AccessObjectImpl(String uri) { + this.uri = uri; + this.type = AccessObjectType.NAMED_OBJECT; + } + + @Override + public String getUri() { + return uri; + } + + @Override + public int hashCode() { + return uri.hashCode(); + } + + @Override + public boolean equals(Object o) { + if (o instanceof AccessObjectImpl) { + AccessObjectImpl that = (AccessObjectImpl) o; + return equivalent(this.uri, that.uri); + } + return false; + } + + private boolean equivalent(Object o1, Object o2) { + return (o1 == null) ? (o2 == null) : o1.equals(o2); + } + + @Override + public String toString() { + return "SimpleRequestedAction['" + uri + "']"; + } + + @Override + public AccessObjectType getType() { + return type; + } + +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/AccessObjectStatement.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/AccessObjectStatement.java new file mode 100644 index 0000000000..f9c15a5bb3 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/AccessObjectStatement.java @@ -0,0 +1,56 @@ +package edu.cornell.mannlib.vitro.webapp.auth.objects; + +import org.apache.jena.rdf.model.Model; + +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType; +import edu.cornell.mannlib.vitro.webapp.beans.Property; + +public class AccessObjectStatement { + + private Model model = null; + private String subject = null; + private Property predicate = null; + private String object = null; + + public Model getModel() { + return model; + } + + public void setModel(Model model) { + this.model = model; + } + + public String getSubject() { + return subject; + } + + public void setSubject(String subject) { + this.subject = subject; + } + + public Property getPredicate() { + return predicate; + } + + public void setPredicate(Property predicate) { + this.predicate = predicate; + } + + public String getObject() { + return object; + } + + public void setObject(String object) { + this.object = object; + } + + + public String[] getResourceUris(AccessObjectType type) { + if (AccessObjectType.DATA_PROPERTY_STATEMENT.equals(type)) { + return new String[] { getSubject() }; + } else if (AccessObjectType.OBJECT_PROPERTY_STATEMENT.equals(type)) { + return new String[] { getSubject(), getObject() }; + } + return new String[0]; + } +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/DataPropertyAccessObject.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/DataPropertyAccessObject.java new file mode 100644 index 0000000000..680e033750 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/DataPropertyAccessObject.java @@ -0,0 +1,16 @@ +package edu.cornell.mannlib.vitro.webapp.auth.objects; + +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType; +import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; + +public class DataPropertyAccessObject extends AccessObject { + + public DataPropertyAccessObject(DataProperty dataProperty) { + setDataProperty(dataProperty); + } + + @Override + public AccessObjectType getType() { + return AccessObjectType.DATA_PROPERTY; + } +} \ No newline at end of file diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/DataPropertyStatementAccessObject.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/DataPropertyStatementAccessObject.java new file mode 100644 index 0000000000..b41271b4af --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/DataPropertyStatementAccessObject.java @@ -0,0 +1,41 @@ +/* $This file is distributed under the terms of the license in LICENSE$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.objects; + +import org.apache.jena.ontology.OntModel; + +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType; +import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.beans.Property; + +/** + * A base class for requested actions that involve adding, editing, or dropping + * data property statements from a model. + */ +public class DataPropertyStatementAccessObject extends AccessObject { + + public DataPropertyStatementAccessObject(OntModel ontModel, String subjectUri, String predicateUri, String dataValue) { + setStatementOntModel(ontModel); + setStatementSubject(subjectUri); + setStatementPredicate(new Property(predicateUri)); + setStatementObject(dataValue); + + } + + public DataPropertyStatementAccessObject(OntModel ontModel, DataPropertyStatement dps) { + setStatementOntModel(ontModel); + setStatementSubject((dps.getIndividual() == null) ? dps.getIndividualURI() : dps.getIndividual().getURI()); + setStatementPredicate(new Property(dps.getDatapropURI())); + setStatementObject(dps.getData()); + } + + @Override + public String toString() { + return getClass().getSimpleName() + ": <" + getStatementSubject() + "> <" + getStatementPredicateUri() + ">"; + } + + @Override + public AccessObjectType getType() { + return AccessObjectType.DATA_PROPERTY_STATEMENT; + } +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/ObjectPropertyAccessObject.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/ObjectPropertyAccessObject.java new file mode 100644 index 0000000000..68115cf2f3 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/ObjectPropertyAccessObject.java @@ -0,0 +1,16 @@ +package edu.cornell.mannlib.vitro.webapp.auth.objects; + +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType; +import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; + +public class ObjectPropertyAccessObject extends AccessObject { + + public ObjectPropertyAccessObject(ObjectProperty objectProperty) { + setObjectProperty(objectProperty); + } + + @Override + public AccessObjectType getType() { + return AccessObjectType.OBJECT_PROPERTY; + } +} \ No newline at end of file diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/ObjectPropertyStatementAccessObject.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/ObjectPropertyStatementAccessObject.java new file mode 100644 index 0000000000..aed71b9533 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/ObjectPropertyStatementAccessObject.java @@ -0,0 +1,32 @@ +/* $This file is distributed under the terms of the license in LICENSE$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.objects; + +import org.apache.jena.rdf.model.Model; + +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType; +import edu.cornell.mannlib.vitro.webapp.beans.Property; + +/** + * A base class for requested access objects that involve adding, editing, or deleting + * object property statements from a model. + */ +public class ObjectPropertyStatementAccessObject extends AccessObject { + + public ObjectPropertyStatementAccessObject(Model ontModel, String subjectUri, Property predicate, String objectUri) { + setStatementOntModel(ontModel); + setStatementSubject(subjectUri); + setStatementPredicate(predicate); + setStatementObject(objectUri); + } + + @Override + public AccessObjectType getType() { + return AccessObjectType.OBJECT_PROPERTY_STATEMENT; + } + + @Override + public String toString() { + return getClass().getSimpleName() + ": <" + getStatementSubject() + "> <" + getStatementPredicateUri() + ">"; + } +} \ No newline at end of file diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/RootAccessObject.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/RootAccessObject.java new file mode 100644 index 0000000000..e45ce6a45a --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/objects/RootAccessObject.java @@ -0,0 +1,16 @@ +/* $This file is distributed under the terms of the license in LICENSE$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.objects; + +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType; + +/** + * Should we allow the user to edit or delete the root account? + */ +public class RootAccessObject extends AccessObjectImpl { + + @Override + public AccessObjectType getType() { + return AccessObjectType.ROOT_USER; + } +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/BrokenPermission.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/BrokenPermission.java deleted file mode 100644 index e28d8a3b73..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/BrokenPermission.java +++ /dev/null @@ -1,26 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.permissions; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; - -/** - * This is what the PermissionRegistry hands out if you ask for a Permission - * that it doesn't know about. Nothing is authorized by this Permission. - */ -public class BrokenPermission extends Permission { - public BrokenPermission(String uri) { - super(uri); - } - - @Override - public boolean isAuthorized(RequestedAction whatToAuth) { - return false; - } - - @Override - public String toString() { - return "BrokenPermission[" + uri + "]"; - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/DisplayByRolePermission.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/DisplayByRolePermission.java deleted file mode 100644 index 99cab19d38..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/DisplayByRolePermission.java +++ /dev/null @@ -1,127 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.permissions; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBean; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataProperty; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataPropertyStatement; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayObjectProperty; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayObjectPropertyStatement; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; -import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; -import edu.cornell.mannlib.vitro.webapp.beans.Property; - -/** - * Is the user authorized to display properties that are marked as restricted to - * a certain "Role Level"? - */ -public class DisplayByRolePermission extends Permission { - private static final Log log = LogFactory - .getLog(DisplayByRolePermission.class); - - public static final String NAMESPACE = "java:" - + DisplayByRolePermission.class.getName() + "#"; - - private final String roleName; - private final RoleLevel roleLevel; - - public DisplayByRolePermission(String roleName, RoleLevel roleLevel) { - super(NAMESPACE + roleName); - - if (roleName == null) { - throw new NullPointerException("role may not be null."); - } - if (roleLevel == null) { - throw new NullPointerException("roleLevel may not be null."); - } - - this.roleName = roleName; - this.roleLevel = roleLevel; - } - - @Override - public boolean isAuthorized(RequestedAction whatToAuth) { - boolean result; - - if (whatToAuth instanceof DisplayDataProperty) { - result = isAuthorized((DisplayDataProperty) whatToAuth); - } else if (whatToAuth instanceof DisplayObjectProperty) { - result = isAuthorized((DisplayObjectProperty) whatToAuth); - } else if (whatToAuth instanceof DisplayDataPropertyStatement) { - result = isAuthorized((DisplayDataPropertyStatement) whatToAuth); - } else if (whatToAuth instanceof DisplayObjectPropertyStatement) { - result = isAuthorized((DisplayObjectPropertyStatement) whatToAuth); - } else { - result = false; - } - - if (result) { - log.debug(this + " authorizes " + whatToAuth); - } else { - log.debug(this + " does not authorize " + whatToAuth); - } - - return result; - } - - /** - * The user may see this data property if they are allowed to see its - * predicate. - */ - private boolean isAuthorized(DisplayDataProperty action) { - String predicateUri = action.getDataProperty().getURI(); - return canDisplayPredicate(new Property(predicateUri)); - } - - /** - * The user may see this object property if they are allowed to see its - * predicate. - */ - private boolean isAuthorized(DisplayObjectProperty action) { - return canDisplayPredicate(action.getObjectProperty()); - } - - /** - * The user may see this data property if they are allowed to see its - * subject and its predicate. - */ - private boolean isAuthorized(DisplayDataPropertyStatement action) { - DataPropertyStatement stmt = action.getDataPropertyStatement(); - String subjectUri = stmt.getIndividualURI(); - String predicateUri = stmt.getDatapropURI(); - return canDisplayResource(subjectUri) - && canDisplayPredicate(new Property(predicateUri)); - } - - /** - * The user may see this data property if they are allowed to see its - * subject, its predicate, and its object. - */ - private boolean isAuthorized(DisplayObjectPropertyStatement action) { - String subjectUri = action.getSubjectUri(); - String objectUri = action.getObjectUri(); - Property op = action.getProperty(); - return canDisplayResource(subjectUri) && canDisplayPredicate(op) - && canDisplayResource(objectUri); - } - - private boolean canDisplayResource(String resourceUri) { - return PropertyRestrictionBean.getBean().canDisplayResource( - resourceUri, this.roleLevel); - } - - private boolean canDisplayPredicate(Property predicate) { - return PropertyRestrictionBean.getBean().canDisplayPredicate(predicate, - this.roleLevel); - } - - @Override - public String toString() { - return "DisplayByRolePermission['" + roleName + "']"; - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/EditByRolePermission.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/EditByRolePermission.java deleted file mode 100644 index e276f9ace2..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/EditByRolePermission.java +++ /dev/null @@ -1,105 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.permissions; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBean; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDataPropertyStatementAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyStatementAction; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; -import edu.cornell.mannlib.vitro.webapp.beans.Property; - -/** - * Is the user authorized to edit properties that are marked as restricted to a - * certain "Role Level"? - */ -public class EditByRolePermission extends Permission { - private static final Log log = LogFactory - .getLog(EditByRolePermission.class); - - public static final String NAMESPACE = "java:" - + EditByRolePermission.class.getName() + "#"; - - private final String roleName; - private final RoleLevel roleLevel; - - public EditByRolePermission(String roleName, RoleLevel roleLevel) { - super(NAMESPACE + roleName); - - if (roleName == null) { - throw new NullPointerException("role may not be null."); - } - if (roleLevel == null) { - throw new NullPointerException("roleLevel may not be null."); - } - - this.roleName = roleName; - this.roleLevel = roleLevel; - } - - /** - * If the requested action is to edit a property statement, we might - * authorize it based on their role level. - */ - @Override - public boolean isAuthorized(RequestedAction whatToAuth) { - boolean result; - - if (whatToAuth instanceof AbstractDataPropertyStatementAction) { - result = isAuthorized((AbstractDataPropertyStatementAction) whatToAuth); - } else if (whatToAuth instanceof AbstractObjectPropertyStatementAction) { - result = isAuthorized((AbstractObjectPropertyStatementAction) whatToAuth); - } else { - result = false; - } - - if (result) { - log.debug(this + " authorizes " + whatToAuth); - } else { - log.debug(this + " does not authorize " + whatToAuth); - } - - return result; - } - - /** - * The user may add, edit, or delete this data property if they are allowed - * to modify its subject and its predicate. - */ - private boolean isAuthorized(AbstractDataPropertyStatementAction action) { - String subjectUri = action.getSubjectUri(); - Property predicate = action.getPredicate(); - return canModifyResource(subjectUri) && canModifyPredicate(predicate); - } - - /** - * The user may add, edit, or delete this data property if they are allowed - * to modify its subject, its predicate, and its object. - */ - private boolean isAuthorized(AbstractObjectPropertyStatementAction action) { - String subjectUri = action.getSubjectUri(); - Property predicate = action.getPredicate(); - String objectUri = action.getObjectUri(); - return canModifyResource(subjectUri) && canModifyPredicate(predicate) - && canModifyResource(objectUri); - } - - private boolean canModifyResource(String resourceUri) { - return PropertyRestrictionBean.getBean().canModifyResource(resourceUri, - roleLevel); - } - - private boolean canModifyPredicate(Property predicate) { - return PropertyRestrictionBean.getBean().canModifyPredicate(predicate, - roleLevel); - } - - @Override - public String toString() { - return "EditByRolePermission['" + roleName + "']"; - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/Permission.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/Permission.java deleted file mode 100644 index fda203fc22..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/Permission.java +++ /dev/null @@ -1,76 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.permissions; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; - -/** - * Interface that describes a unit of authorization, or permission to perform - * requested actions. - */ -public abstract class Permission implements Comparable { - protected final String uri; - - protected Permission(String uri) { - if (uri == null) { - throw new NullPointerException("uri may not be null."); - } - this.uri = uri; - } - - /** - * Get the URI that identifies this Permission object. - */ - public String getUri() { - return uri; - } - - /** - * Is a user with this Permission authorized to perform this - * RequestedAction? - */ - public abstract boolean isAuthorized(RequestedAction whatToAuth); - - @Override - public int compareTo(Permission that) { - return this.uri.compareTo(that.uri); - } - - @Override - public boolean equals(Object obj) { - if (obj == this) { - return true; - } - if (obj == null) { - return false; - } - if (!obj.getClass().equals(this.getClass())) { - return false; - } - Permission that = (Permission) obj; - return this.uri.equals(that.uri); - } - - @Override - public int hashCode() { - return uri.hashCode(); - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + "['" + uri + "']"; - } - - /** - * A concrete Permission instance that authorizes nothing. - */ - static Permission NOT_AUTHORIZED = new Permission("java:" - + Permission.class.getName() + "#NOT_AUTHORIZED") { - - @Override - public boolean isAuthorized(RequestedAction whatToAuth) { - return false; - } - - }; -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionRegistry.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionRegistry.java deleted file mode 100644 index fab6cfff62..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionRegistry.java +++ /dev/null @@ -1,216 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.permissions; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; -import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; - -/** - * A collection of Permission objects, keyed by URI. Resides in the - * ServletContext. - * - * This is not thread-safe, so Permissions should be added only during context - * initialization. - */ -public class PermissionRegistry { - private static final Log log = LogFactory.getLog(PermissionRegistry.class); - - // ---------------------------------------------------------------------- - // The factory - // ---------------------------------------------------------------------- - - private static final String ATTRIBUTE_NAME = PermissionRegistry.class - .getName(); - - /** - * Has the registry been created yet? - */ - public static boolean isRegistryCreated(ServletContext ctx) { - return ctx.getAttribute(ATTRIBUTE_NAME) instanceof PermissionRegistry; - } - - /** - * Create the registry and store it in the context. - */ - public static void createRegistry(ServletContext ctx, - Collection permissions) { - if (ctx == null) { - throw new NullPointerException("ctx may not be null."); - } - if (permissions == null) { - throw new NullPointerException("permissions may not be null."); - } - if (ctx.getAttribute(ATTRIBUTE_NAME) != null) { - throw new IllegalStateException( - "PermissionRegistry has already been set."); - } - - PermissionRegistry registry = new PermissionRegistry(); - registry.addPermissions(permissions); - ctx.setAttribute(ATTRIBUTE_NAME, registry); - } - - /** - * Get the registry from the context. If there isn't one, throw an - * exception. - */ - public static PermissionRegistry getRegistry(ServletContext ctx) { - if (ctx == null) { - throw new NullPointerException("ctx may not be null."); - } - - Object o = ctx.getAttribute(ATTRIBUTE_NAME); - if (o == null) { - throw new IllegalStateException( - "PermissionRegistry has not been set."); - } else if (!(o instanceof PermissionRegistry)) { - throw new IllegalStateException("PermissionRegistry was set to an " - + "invalid object: " + o); - } - - return (PermissionRegistry) o; - } - - // ---------------------------------------------------------------------- - // The instance - // ---------------------------------------------------------------------- - - private final Map map = new HashMap<>(); - - /** - * This class is not thread-safe, so permissions should be added only during - * context initialization. - */ - public void addPermissions(Collection permissions) { - for (Permission p : permissions) { - addPermission(p); - } - } - - /** - * This class is not thread-safe, so permissions should be added only during - * context initialization. - */ - public void addPermission(Permission p) { - String uri = p.getUri(); - if (map.containsKey(uri)) { - throw new IllegalStateException("A Permission is already " - + "registered with this URI: '" + uri + "'."); - } - map.put(uri, p); - } - - /** - * Is there a Permission registered with this URI? - */ - public boolean isPermission(String uri) { - return map.containsKey(uri); - } - - /** - * Get the permission that is registered with this URI. If there is no such - * Permission, return a BrokenPermission that always denies authorization. - * - * If you want to know whether an actual Permission has been registered at - * this URI, call isPermission() instead. - */ - public Permission getPermission(String uri) { - Permission p = map.get(uri); - if (p == null) { - log.warn("No Permission is registered for '" + uri + "'"); - return new BrokenPermission(uri); - } - - return p; - } - - // ---------------------------------------------------------------------- - // Setup class - // ---------------------------------------------------------------------- - - public static class Setup implements ServletContextListener { - @Override - public void contextInitialized(ServletContextEvent sce) { - ServletContext ctx = sce.getServletContext(); - StartupStatus ss = StartupStatus.getBean(ctx); - try { - List permissions = new ArrayList(); - - permissions.addAll(SimplePermission.getAllInstances()); - permissions.addAll(createDisplayByRolePermissions()); - permissions.addAll(createEditByRolePermissions()); - permissions.addAll(createPublishByRolePermissions()); - - PermissionRegistry.createRegistry(ctx, permissions); - - ss.info(this, "Created the PermissionRegistry with " - + permissions.size() + " permissions."); - } catch (Exception e) { - ss.fatal(this, "Failed to initialize the PermissionRegistry.", - e); - } - } - - /** - * There is no DisplayByRolePermission for self-editors. They get the - * same rights as PUBLIC. Other permissions give them their self-editing - * privileges. - */ - private Collection createDisplayByRolePermissions() { - List list = new ArrayList(); - list.add(new DisplayByRolePermission("Admin", RoleLevel.DB_ADMIN)); - list.add(new DisplayByRolePermission("Curator", RoleLevel.CURATOR)); - list.add(new DisplayByRolePermission("Editor", RoleLevel.EDITOR)); - list.add(new DisplayByRolePermission("Public", RoleLevel.PUBLIC)); - return list; - } - - /** - * There is no EditByRolePermission for PUBLIC or for self-editors. A - * property may be given an edit-level of "PUBLIC", but that may also - * simply be the default assigned to it when editing, and we don't want - * to recognize that. - * - * Other permissions give self-editors their editing privileges. - */ - private Collection createEditByRolePermissions() { - List list = new ArrayList(); - list.add(new EditByRolePermission("Admin", RoleLevel.DB_ADMIN)); - list.add(new EditByRolePermission("Curator", RoleLevel.CURATOR)); - list.add(new EditByRolePermission("Editor", RoleLevel.EDITOR)); - return list; - } - - @Override - public void contextDestroyed(ServletContextEvent sce) { - sce.getServletContext().removeAttribute(ATTRIBUTE_NAME); - } - - /** - * There is no PublishByRolePermission for self-editors. They get the - * same rights as PUBLIC. Other permissions give them their self-editing - * privileges. - */ - private Collection createPublishByRolePermissions() { - List list = new ArrayList(); - list.add(new PublishByRolePermission("Admin", RoleLevel.DB_ADMIN)); - list.add(new PublishByRolePermission("Curator", RoleLevel.CURATOR)); - list.add(new PublishByRolePermission("Editor", RoleLevel.EDITOR)); - list.add(new PublishByRolePermission("Public", RoleLevel.PUBLIC)); - return list; - } - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionSetsSmokeTest.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionSetsSmokeTest.java index 766f4c136d..b8c68f993a 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionSetsSmokeTest.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/PermissionSetsSmokeTest.java @@ -69,7 +69,6 @@ public SmokeTester(ServletContextListener listener, ServletContext ctx, public void test() { checkForPermissionSetsWithoutLabels(); checkForReferencesToNonexistentPermissionSets(); - checkForReferencesToNonexistentPermissions(); warnIfNoPermissionSetsForNewUsers(); } @@ -95,21 +94,6 @@ private void checkForReferencesToNonexistentPermissionSets() { } } - private void checkForReferencesToNonexistentPermissions() { - PermissionRegistry registry = PermissionRegistry.getRegistry(ctx); - for (PermissionSet ps : uaDao.getAllPermissionSets()) { - for (String pUri : ps.getPermissionUris()) { - if (!registry.isPermission(pUri)) { - ss.warning(listener, - "The PermissionSet '" + ps.getLabel() - + "' has the Permission '" + pUri - + "', but the Permission " - + "is not found in the registry."); - } - } - } - } - private void warnIfNoPermissionSetsForNewUsers() { for (PermissionSet ps : uaDao.getAllPermissionSets()) { if (ps.isForNewUsers()) { diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/PublishByRolePermission.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/PublishByRolePermission.java deleted file mode 100644 index b1e63aa4bb..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/PublishByRolePermission.java +++ /dev/null @@ -1,125 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.permissions; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBean; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish.PublishDataProperty; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish.PublishDataPropertyStatement; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish.PublishObjectProperty; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish.PublishObjectPropertyStatement; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; -import edu.cornell.mannlib.vitro.webapp.beans.Property; - -/** - * Is the user authorized to publish properties that are marked as restricted to - * a certain "Role Level"? - */ -public class PublishByRolePermission extends Permission { - private static final Log log = LogFactory - .getLog(PublishByRolePermission.class); - - public static final String NAMESPACE = "java:" - + PublishByRolePermission.class.getName() + "#"; - - private final String roleName; - private final RoleLevel roleLevel; - - public PublishByRolePermission(String roleName, RoleLevel roleLevel) { - super(NAMESPACE + roleName); - - if (roleName == null) { - throw new NullPointerException("role may not be null."); - } - if (roleLevel == null) { - throw new NullPointerException("roleLevel may not be null."); - } - - this.roleName = roleName; - this.roleLevel = roleLevel; - } - - @Override - public boolean isAuthorized(RequestedAction whatToAuth) { - boolean result; - - if (whatToAuth instanceof PublishDataProperty) { - result = isAuthorized((PublishDataProperty) whatToAuth); - } else if (whatToAuth instanceof PublishObjectProperty) { - result = isAuthorized((PublishObjectProperty) whatToAuth); - } else if (whatToAuth instanceof PublishDataPropertyStatement) { - result = isAuthorized((PublishDataPropertyStatement) whatToAuth); - } else if (whatToAuth instanceof PublishObjectPropertyStatement) { - result = isAuthorized((PublishObjectPropertyStatement) whatToAuth); - } else { - result = false; - } - - if (result) { - log.debug(this + " authorizes " + whatToAuth); - } else { - log.debug(this + " does not authorize " + whatToAuth); - } - - return result; - } - - /** - * The user may publish this data property if they are allowed to publish - * its predicate. - */ - private boolean isAuthorized(PublishDataProperty action) { - String predicateUri = action.getDataProperty().getURI(); - return canPublishPredicate(new Property(predicateUri)); - } - - /** - * The user may publish this object property if they are allowed to publish - * its predicate. - */ - private boolean isAuthorized(PublishObjectProperty action) { - return canPublishPredicate(action.getObjectProperty()); - } - - /** - * The user may publish this data property if they are allowed to publish - * its subject and its predicate. - */ - private boolean isAuthorized(PublishDataPropertyStatement action) { - String subjectUri = action.getSubjectUri(); - String predicateUri = action.getPredicateUri(); - return canPublishResource(subjectUri) - && canPublishPredicate(new Property(predicateUri)); - } - - /** - * The user may publish this data property if they are allowed to publish - * its subject, its predicate, and its object. - */ - private boolean isAuthorized(PublishObjectPropertyStatement action) { - String subjectUri = action.getSubjectUri(); - Property predicate = action.getPredicate(); - String objectUri = action.getObjectUri(); - return canPublishResource(subjectUri) && canPublishPredicate(predicate) - && canPublishResource(objectUri); - } - - private boolean canPublishResource(String resourceUri) { - return PropertyRestrictionBean.getBean().canPublishResource( - resourceUri, this.roleLevel); - } - - private boolean canPublishPredicate(Property predicate) { - return PropertyRestrictionBean.getBean().canPublishPredicate(predicate, - this.roleLevel); - } - - @Override - public String toString() { - return "PublishByRolePermission['" + roleName + "']"; - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/SimplePermission.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/SimplePermission.java index 82ee603fa7..9c5571d499 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/SimplePermission.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/permissions/SimplePermission.java @@ -1,154 +1,73 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - package edu.cornell.mannlib.vitro.webapp.auth.permissions; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.SimpleRequestedAction; - -/** - * A class of simple permissions. Each instance holds a RequestedAction, and - * will only authorize that RequestedAction (or one with the same URI). - */ -public class SimplePermission extends Permission { - private static final Log log = LogFactory.getLog(SimplePermission.class); - - private static final String NAMESPACE = "java:" - + SimplePermission.class.getName() + "#"; - - private static final Map allInstances = new HashMap(); - - public static final SimplePermission ACCESS_SPECIAL_DATA_MODELS = new SimplePermission( - NAMESPACE + "AccessSpecialDataModels"); - public static final SimplePermission DO_BACK_END_EDITING = new SimplePermission( - NAMESPACE + "DoBackEndEditing"); - public static final SimplePermission DO_FRONT_END_EDITING = new SimplePermission( - NAMESPACE + "DoFrontEndEditing"); - public static final SimplePermission EDIT_ONTOLOGY = new SimplePermission( - NAMESPACE + "EditOntology"); - public static final SimplePermission EDIT_OWN_ACCOUNT = new SimplePermission( - NAMESPACE + "EditOwnAccount"); - public static final SimplePermission EDIT_SITE_INFORMATION = new SimplePermission( - NAMESPACE + "EditSiteInformation"); - public static final SimplePermission ENABLE_DEVELOPER_PANEL = new SimplePermission( - NAMESPACE + "EnableDeveloperPanel"); - public static final SimplePermission LOGIN_DURING_MAINTENANCE = new SimplePermission( - NAMESPACE + "LoginDuringMaintenance"); - public static final SimplePermission MANAGE_MENUS = new SimplePermission( - NAMESPACE + "ManageMenus"); - public static final SimplePermission MANAGE_OWN_PROXIES = new SimplePermission( - NAMESPACE + "ManageOwnProxies"); - public static final SimplePermission MANAGE_PROXIES = new SimplePermission( - NAMESPACE + "ManageProxies"); - public static final SimplePermission MANAGE_SEARCH_INDEX = new SimplePermission( - NAMESPACE + "ManageSearchIndex"); - public static final SimplePermission MANAGE_USER_ACCOUNTS = new SimplePermission( - NAMESPACE + "ManageUserAccounts"); - public static final SimplePermission QUERY_FULL_MODEL = new SimplePermission( - NAMESPACE + "QueryFullModel"); - public static final SimplePermission QUERY_USER_ACCOUNTS_MODEL = new SimplePermission( - NAMESPACE + "QueryUserAccountsModel"); - public static final SimplePermission REFRESH_VISUALIZATION_CACHE = new SimplePermission( - NAMESPACE + "RefreshVisualizationCache"); - public static final SimplePermission SEE_CONFIGURATION = new SimplePermission( - NAMESPACE + "SeeConfiguration"); - public static final SimplePermission SEE_INDVIDUAL_EDITING_PANEL = new SimplePermission( - NAMESPACE + "SeeIndividualEditingPanel"); - public static final SimplePermission SEE_REVISION_INFO = new SimplePermission( - NAMESPACE + "SeeRevisionInfo"); - public static final SimplePermission SEE_SITE_ADMIN_PAGE = new SimplePermission( - NAMESPACE + "SeeSiteAdminPage"); - public static final SimplePermission SEE_STARTUP_STATUS = new SimplePermission( - NAMESPACE + "SeeStartupStatus"); - public static final SimplePermission SEE_VERBOSE_PROPERTY_INFORMATION = new SimplePermission( - NAMESPACE + "SeeVerbosePropertyInformation"); - public static final SimplePermission USE_ADVANCED_DATA_TOOLS_PAGES = new SimplePermission( - NAMESPACE + "UseAdvancedDataToolsPages"); - public static final SimplePermission USE_INDIVIDUAL_CONTROL_PANEL = new SimplePermission( - NAMESPACE + "UseIndividualControlPanel"); - public static final SimplePermission USE_SPARQL_QUERY_PAGE = new SimplePermission( - NAMESPACE + "UseSparqlQueryPage"); - public static final SimplePermission USE_SPARQL_QUERY_API = new SimplePermission( - NAMESPACE + "UseSparqlQueryApi"); - public static final SimplePermission USE_SPARQL_UPDATE_API = new SimplePermission( - NAMESPACE + "UseSparqlUpdateApi"); - - // ---------------------------------------------------------------------- - // These instances are "catch all" permissions to cover poorly defined - // groups of actions until better definitions were found. Don't add usages - // of these, and remove existing usages where possible. - // ---------------------------------------------------------------------- - - public static final SimplePermission USE_BASIC_AJAX_CONTROLLERS = new SimplePermission( - NAMESPACE + "UseBasicAjaxControllers"); - public static final SimplePermission USE_MISCELLANEOUS_ADMIN_PAGES = new SimplePermission( - NAMESPACE + "UseMiscellaneousAdminPages"); - public static final SimplePermission USE_MISCELLANEOUS_CURATOR_PAGES = new SimplePermission( - NAMESPACE + "UseMiscellaneousCuratorPages"); - public static final SimplePermission USE_MISCELLANEOUS_PAGES = new SimplePermission( - NAMESPACE + "UseMiscellaneousPages"); - - // ---------------------------------------------------------------------- - // These instances are permissions that can be specified for a given page created/managed through page management, - // e.g. this page is viewable only by admins, this page is viewable to anyone who is logged in, etc. - // ---------------------------------------------------------------------- - public static final SimplePermission PAGE_VIEWABLE_ADMIN = new SimplePermission( - NAMESPACE + "PageViewableAdmin"); - public static final SimplePermission PAGE_VIEWABLE_CURATOR = new SimplePermission( - NAMESPACE + "PageViewableCurator"); - public static final SimplePermission PAGE_VIEWABLE_LOGGEDIN = new SimplePermission( - NAMESPACE + "PageViewableLoggedIn"); - public static final SimplePermission PAGE_VIEWABLE_EDITOR = new SimplePermission( - NAMESPACE + "PageViewableEditor"); - public static final SimplePermission PAGE_VIEWABLE_PUBLIC = new SimplePermission( - NAMESPACE + "PageViewablePublic"); - - - public static List getAllInstances() { - return new ArrayList(allInstances.values()); - } - - //private final String localName; - public final RequestedAction ACTION; - - public SimplePermission(String uri) { - super(uri); - - if (uri == null) { - throw new NullPointerException("uri may not be null."); - } - - this.ACTION = new SimpleRequestedAction(uri); - - if (allInstances.containsKey(this.uri)) { - throw new IllegalStateException("A SimplePermission named '" - + this.uri + "' already exists."); - } - allInstances.put(uri, this); - } - - @Override - public boolean isAuthorized(RequestedAction whatToAuth) { - if (whatToAuth != null) { - if (ACTION.getURI().equals(whatToAuth.getURI())) { - log.debug(this + " authorizes " + whatToAuth); - return true; - } - } - log.debug(this + " does not authorize " + whatToAuth); - return false; - } - - @Override - public String toString() { - return "SimplePermission['" + uri+ "']"; - } - +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessOperation; +import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObjectImpl; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.SimpleAuthorizationRequest; + +public class SimplePermission { + + //Access rules stored here for compatibility reasons + + public static final SimplePermission ACCESS_SPECIAL_DATA_MODELS = new SimplePermission("AccessSpecialDataModels"); + public static final SimplePermission DO_BACK_END_EDITING = new SimplePermission("DoBackEndEditing"); + public static final SimplePermission DO_FRONT_END_EDITING = new SimplePermission("DoFrontEndEditing"); + public static final SimplePermission EDIT_ONTOLOGY = new SimplePermission("EditOntology"); + public static final SimplePermission EDIT_OWN_ACCOUNT = new SimplePermission("EditOwnAccount"); + public static final SimplePermission EDIT_SITE_INFORMATION = new SimplePermission("EditSiteInformation"); + public static final SimplePermission ENABLE_DEVELOPER_PANEL = new SimplePermission("EnableDeveloperPanel"); + public static final SimplePermission LOGIN_DURING_MAINTENANCE = new SimplePermission("LoginDuringMaintenance"); + public static final SimplePermission MANAGE_MENUS = new SimplePermission("ManageMenus"); + public static final SimplePermission MANAGE_OWN_PROXIES = new SimplePermission("ManageOwnProxies"); + public static final SimplePermission MANAGE_PROXIES = new SimplePermission("ManageProxies"); + public static final SimplePermission MANAGE_SEARCH_INDEX = new SimplePermission("ManageSearchIndex"); + public static final SimplePermission MANAGE_USER_ACCOUNTS = new SimplePermission("ManageUserAccounts"); + public static final SimplePermission QUERY_FULL_MODEL = new SimplePermission("QueryFullModel"); + public static final SimplePermission QUERY_USER_ACCOUNTS_MODEL = new SimplePermission("QueryUserAccountsModel"); + public static final SimplePermission REFRESH_VISUALIZATION_CACHE = new SimplePermission("RefreshVisualizationCache"); + public static final SimplePermission SEE_CONFIGURATION = new SimplePermission("SeeConfiguration"); + public static final SimplePermission SEE_INDVIDUAL_EDITING_PANEL = new SimplePermission("SeeIndividualEditingPanel"); + public static final SimplePermission SEE_REVISION_INFO = new SimplePermission("SeeRevisionInfo"); + public static final SimplePermission SEE_SITE_ADMIN_PAGE = new SimplePermission("SeeSiteAdminPage"); + public static final SimplePermission SEE_STARTUP_STATUS = new SimplePermission("SeeStartupStatus"); + public static final SimplePermission SEE_VERBOSE_PROPERTY_INFORMATION = new SimplePermission("SeeVerbosePropertyInformation"); + public static final SimplePermission USE_ADVANCED_DATA_TOOLS_PAGES = new SimplePermission("UseAdvancedDataToolsPages"); + public static final SimplePermission USE_INDIVIDUAL_CONTROL_PANEL = new SimplePermission("UseIndividualControlPanel"); + public static final SimplePermission USE_SPARQL_QUERY_PAGE = new SimplePermission("UseSparqlQueryPage"); + public static final SimplePermission USE_SPARQL_QUERY_API = new SimplePermission("UseSparqlQueryApi"); + public static final SimplePermission USE_SPARQL_UPDATE_API = new SimplePermission("UseSparqlUpdateApi"); + + // ---------------------------------------------------------------------- + // These instances are "catch all" permissions to cover poorly defined + // groups of actions until better definitions were found. Don't add usages + // of these, and remove existing usages where possible. + // ---------------------------------------------------------------------- + + public static final SimplePermission USE_BASIC_AJAX_CONTROLLERS = new SimplePermission("UseBasicAjaxControllers"); + public static final SimplePermission USE_MISCELLANEOUS_ADMIN_PAGES = new SimplePermission("UseMiscellaneousAdminPages"); + public static final SimplePermission USE_MISCELLANEOUS_CURATOR_PAGES = new SimplePermission("UseMiscellaneousCuratorPages"); + public static final SimplePermission USE_MISCELLANEOUS_PAGES = new SimplePermission("UseMiscellaneousPages"); + + // ---------------------------------------------------------------------- + // These instances are permissions that can be specified for a given page + // created/managed through page management, + // e.g. this page is viewable only by admins, this page is viewable to anyone + // who is logged in, etc. + // ---------------------------------------------------------------------- + + public static final SimplePermission PAGE_VIEWABLE_ADMIN = new SimplePermission("PageViewableAdmin"); + public static final SimplePermission PAGE_VIEWABLE_CURATOR = new SimplePermission("PageViewableCurator"); + public static final SimplePermission PAGE_VIEWABLE_LOGGEDIN = new SimplePermission("PageViewableLoggedIn"); + public static final SimplePermission PAGE_VIEWABLE_EDITOR = new SimplePermission("PageViewableEditor"); + public static final SimplePermission PAGE_VIEWABLE_PUBLIC = new SimplePermission("PageViewablePublic"); + + + public SimpleAuthorizationRequest ACTION; + public static final String NS = "java:edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission#"; + + private SimplePermission(String uri) { + uri = SimplePermission.NS + uri; + AccessObjectImpl ao = new AccessObjectImpl(uri, AccessObjectType.NAMED_OBJECT); + this.ACTION = new SimpleAuthorizationRequest(ao, AccessOperation.EXECUTE); + } } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/BaseSelfEditingPolicy.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/BaseSelfEditingPolicy.java deleted file mode 100644 index 1541cfc8eb..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/BaseSelfEditingPolicy.java +++ /dev/null @@ -1,61 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.policy; - -import javax.servlet.ServletContext; - -import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBean; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; -import edu.cornell.mannlib.vitro.webapp.beans.Property; - -/** - * A base class with utility methods for policies involving self-editing. - */ -public abstract class BaseSelfEditingPolicy { - protected final ServletContext ctx; - protected final RoleLevel roleLevel; - - public BaseSelfEditingPolicy(ServletContext ctx, RoleLevel roleLevel) { - this.ctx = ctx; - this.roleLevel = roleLevel; - } - - protected boolean canModifyResource(String uri) { - return PropertyRestrictionBean.getBean().canModifyResource(uri, - roleLevel); - } - - protected boolean canModifyPredicate(Property predicate) { - return PropertyRestrictionBean.getBean().canModifyPredicate(predicate, - roleLevel); - } - - protected PolicyDecision cantModifyResource(String uri) { - return inconclusiveDecision("No access to admin resources; cannot modify " - + uri); - } - - protected PolicyDecision cantModifyPredicate(Property predicate) { - return inconclusiveDecision("No access to admin predicates; cannot modify " - + predicate.getURI()); - } - - protected PolicyDecision userNotAuthorizedToStatement() { - return inconclusiveDecision("User has no access to this statement."); - } - - /** An INCONCLUSIVE decision with a message like "PolicyClass: message". */ - protected PolicyDecision inconclusiveDecision(String message) { - return new BasicPolicyDecision(Authorization.INCONCLUSIVE, getClass() - .getSimpleName() + ": " + message); - } - - /** An AUTHORIZED decision with a message like "PolicyClass: message". */ - protected PolicyDecision authorizedDecision(String message) { - return new BasicPolicyDecision(Authorization.AUTHORIZED, getClass() - .getSimpleName() + ": " + message); - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/BasicPolicyDecision.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/BasicPolicyDecision.java index b831be9ddb..2f44ff48dc 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/BasicPolicyDecision.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/BasicPolicyDecision.java @@ -2,7 +2,7 @@ package edu.cornell.mannlib.vitro.webapp.auth.policy; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization; +import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.DecisionResult; import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; /** @@ -14,21 +14,19 @@ public class BasicPolicyDecision implements PolicyDecision{ String debuggingInfo; String message; String StackTrace; - Authorization authorized; + DecisionResult decisionResult; - - - public BasicPolicyDecision( Authorization authorized, String message) { + public BasicPolicyDecision( DecisionResult authorized, String message) { super(); this.message = message; - this.authorized = authorized; + this.decisionResult = authorized; } - public Authorization getAuthorized() { - return authorized; + public DecisionResult getDecisionResult() { + return decisionResult; } - public BasicPolicyDecision setAuthorized(Authorization auth) { - this.authorized = auth; + public BasicPolicyDecision setDecisionResult(DecisionResult decisionResult) { + this.decisionResult = decisionResult; return this; } public String getDebuggingInfo() { @@ -53,6 +51,6 @@ public void setStackTrace(String stackTrace) { } public String toString(){ - return authorized + ": " + message; + return decisionResult + ": " + message; } } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/CompositPolicyDecision.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/CompositPolicyDecision.java deleted file mode 100644 index 22d568f2ff..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/CompositPolicyDecision.java +++ /dev/null @@ -1,23 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.policy; - -import java.util.List; - -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; - -/** - * Policy decision that is made from some analysis of a set of decisions. - * @author bdc34 - * - */ -public class CompositPolicyDecision extends BasicPolicyDecision implements PolicyDecision { - List subDecisions; - - public CompositPolicyDecision(Authorization auth, String message, List subDecisions){ - super( auth, message); - this.subDecisions = subDecisions; - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/DisplayRestrictedDataToSelfPolicy.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/DisplayRestrictedDataToSelfPolicy.java deleted file mode 100644 index 2c536813c7..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/DisplayRestrictedDataToSelfPolicy.java +++ /dev/null @@ -1,179 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.policy; - -import java.util.Collection; - -import javax.servlet.ServletContext; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasAssociatedIndividual; -import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBean; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataProperty; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayDataPropertyStatement; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayObjectProperty; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display.DisplayObjectPropertyStatement; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; -import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; -import edu.cornell.mannlib.vitro.webapp.beans.Property; - -/** - * Permit display of various data if it relates to the user's associated - * individual. - * - * This policy is only to handle the case where a user would not be able to see - * data except for their self-editing status. If the data would be visible - * without that status, we assume that some other policy will grant access. - */ -public class DisplayRestrictedDataToSelfPolicy implements PolicyIface { - private static final Log log = LogFactory - .getLog(DisplayRestrictedDataToSelfPolicy.class); - - private final ServletContext ctx; - - public DisplayRestrictedDataToSelfPolicy(ServletContext ctx) { - this.ctx = ctx; - } - - /** - * If the requested action is to display a property or a property statement, - * we might authorize it based on their role level. - */ - @Override - public PolicyDecision isAuthorized(IdentifierBundle whoToAuth, - RequestedAction whatToAuth) { - if (whoToAuth == null) { - return defaultDecision("whomToAuth was null"); - } - if (whatToAuth == null) { - return defaultDecision("whatToAuth was null"); - } - - Collection associated = HasAssociatedIndividual - .getIndividualUris(whoToAuth); - if (associated.isEmpty()) { - return defaultDecision("not self-editing for anyone"); - } - - if (whatToAuth instanceof DisplayDataProperty) { - return defaultDecision("DataProperties have no associated 'self'"); - } else if (whatToAuth instanceof DisplayObjectProperty) { - return defaultDecision("ObjectProperties have no associated 'self'"); - } - - PolicyDecision result; - if (whatToAuth instanceof DisplayDataPropertyStatement) { - result = isAuthorized((DisplayDataPropertyStatement) whatToAuth, - associated); - } else if (whatToAuth instanceof DisplayObjectPropertyStatement) { - result = isAuthorized((DisplayObjectPropertyStatement) whatToAuth, - associated); - } else { - result = defaultDecision("Unrecognized action"); - } - - log.debug("decision for '" + whatToAuth + "' is " + result); - return result; - } - - /** - * The user may see this data property statement if the subject and the - * predicate are both viewable by self-editors, and the subject is one of - * the associated individuals (the "selves"). - */ - private PolicyDecision isAuthorized(DisplayDataPropertyStatement action, - Collection individuals) { - DataPropertyStatement stmt = action.getDataPropertyStatement(); - String subjectUri = stmt.getIndividualURI(); - Property predicate = new Property(stmt.getDatapropURI()); - if (canDisplayResource(subjectUri) && canDisplayPredicate(predicate) - && isAboutAssociatedIndividual(individuals, subjectUri)) { - return authorized("user may view DataPropertyStatement " - + subjectUri + " ==> " + predicate.getURI()); - } else { - return defaultDecision("user may not view DataPropertyStatement " - + subjectUri + " ==> " + predicate.getURI()); - } - } - - /** - * The user may see this data property statement if the subject, the - * predicate, and the object are all viewable by self-editors, and either - * the subject or the object is one of the associated individuals (the - * "selves"). - */ - private PolicyDecision isAuthorized(DisplayObjectPropertyStatement action, - Collection individuals) { - String subjectUri = action.getSubjectUri(); - Property predicate = action.getProperty(); - String objectUri = action.getObjectUri(); - if (canDisplayResource(subjectUri) - && canDisplayPredicate(predicate) - && canDisplayResource(objectUri) - && isAboutAssociatedIndividual(individuals, subjectUri, - objectUri)) { - return authorized("user may view ObjectPropertyStatement " - + subjectUri + " ==> " + predicate.getURI() + " ==> " - + objectUri); - } else { - return defaultDecision("user may not view ObjectPropertyStatement " - + subjectUri + " ==> " + predicate.getURI() + " ==> " - + objectUri); - } - } - - /** If the user is explicitly authorized, return this. */ - private PolicyDecision authorized(String message) { - String className = this.getClass().getSimpleName(); - return new BasicPolicyDecision(Authorization.AUTHORIZED, className - + ": " + message); - } - - /** If the user isn't explicitly authorized, return this. */ - private PolicyDecision defaultDecision(String message) { - return new BasicPolicyDecision(Authorization.INCONCLUSIVE, message); - } - - private boolean canDisplayResource(String uri) { - return PropertyRestrictionBean.getBean().canDisplayResource(uri, - RoleLevel.SELF); - } - - private boolean canDisplayPredicate(Property predicate) { - return PropertyRestrictionBean.getBean().canDisplayPredicate(predicate, - RoleLevel.SELF); - } - - private boolean isAboutAssociatedIndividual(Collection selves, - String subjectUri) { - for (String self : selves) { - if (self.equals(subjectUri)) { - return true; - } - } - return false; - } - - private boolean isAboutAssociatedIndividual(Collection selves, - String subjectUri, String objectUri) { - for (String self : selves) { - if (self.equals(subjectUri) || self.equals(objectUri)) { - return true; - } - } - return false; - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + " - " + hashCode(); - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/DynamicPolicy.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/DynamicPolicy.java new file mode 100644 index 0000000000..7658f07e17 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/DynamicPolicy.java @@ -0,0 +1,80 @@ +package edu.cornell.mannlib.vitro.webapp.auth.policy; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject; +import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.DecisionResult; +import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; +import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Policy; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; +import edu.cornell.mannlib.vitro.webapp.auth.rules.AccessRule; + +public class DynamicPolicy implements Policy { + private static final Log log = LogFactory.getLog(DynamicPolicy.class); + private String uri; + + @Override + public String getUri() { + return uri; + } + + private long priority; + public long getPriority() { + return priority; + } + + private Set rules = Collections.synchronizedSet(new HashSet<>()); + + public Set getRules() { + return rules; + } + + public void addRules(Set addition) { + rules.addAll(addition); + } + + public DynamicPolicy(String uri, long priority) { + this.uri = uri; + this.priority = priority; + } + + @Override + public PolicyDecision decide(AuthorizationRequest ar) { + //IdentifierBundle ac_subject = ar.getIds(); + AccessObject whatToAuth = ar.getAccessObject(); + //if (ac_subject == null) { + // return defaultDecision("whomToAuth was null"); + //} + if (whatToAuth == null) { + return defaultDecision("whatToAuth was null"); + } + for (AccessRule rule : getFilteredRules(ar)) { + if (rule.match(ar)) { + if(rule.isAllowMatched()) { + log.debug("Access rule " + rule + " approves request " + whatToAuth); + return new BasicPolicyDecision(DecisionResult.AUTHORIZED, "Dynamic policy '" + uri + "' rule '" + rule + "' approved " + ar); + } else { + log.debug("Access rule " + rule + " rejects request " + whatToAuth); + return new BasicPolicyDecision(DecisionResult.UNAUTHORIZED, "Dynamic policy '" + uri + "' rule '" + rule + "' rejected " + ar); + } + } else { + log.trace("Dynamic policy '" + uri + "' rule '" + rule + "' doesn't match the request " + ar); + } + } + + return defaultDecision("no permission will approve " + whatToAuth); + } + + public Set getFilteredRules(AuthorizationRequest ar) { + return rules; + } + + private PolicyDecision defaultDecision(String message) { + return new BasicPolicyDecision(DecisionResult.INCONCLUSIVE, message); + } +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/EntityPolicyController.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/EntityPolicyController.java new file mode 100644 index 0000000000..b3c985bdc0 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/EntityPolicyController.java @@ -0,0 +1,79 @@ +package edu.cornell.mannlib.vitro.webapp.auth.policy; + +import java.util.Collections; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.OperationGroup; +import edu.cornell.mannlib.vitro.webapp.beans.Property; + +public class EntityPolicyController { + + private static final Log log = LogFactory.getLog(EntityPolicyController.class); + + public static void updateEntityPolicy(String entityUri, AccessObjectType aot, OperationGroup og, + List selectedRoles, List allRoles) { + if (StringUtils.isBlank(entityUri)) { + return; + } + Set selectedSet = new HashSet<>(selectedRoles); + for (String role : allRoles) { + boolean isInDataSet = isUriInTestDataset(entityUri, og, aot, role); + boolean isSelected = selectedSet.contains(role); + final PolicyLoader loader = PolicyLoader.getInstance(); + final String policyUri = loader.getPolicyUriByKey(og, aot, role); + if (policyUri == null) { + log.debug(String.format("Policy wasn't found by key:\n%s\n%s\n%s", og.toString(), aot.toString(), role)); + continue; + } + if (isSelected && !isInDataSet) { + loader.addEntityToPolicyDataSet(entityUri, aot, og, role); + DynamicPolicy policy = loader.loadPolicy(policyUri); + PolicyStore.getInstance().add(policy); + } else if (!isSelected && isInDataSet) { + loader.removeEntityFromPolicyDataSet(entityUri, aot, og, role); + DynamicPolicy policy = loader.loadPolicy(policyUri); + PolicyStore.getInstance().add(policy); + } + } + } + + public static List getGrantedRoles(String entityUri, OperationGroup og, AccessObjectType aot, List allRoles) { + if (StringUtils.isBlank(entityUri)) { + return Collections.emptyList(); + } + List grantedRoles = new LinkedList<>(); + for (String role : allRoles) { + if (isUriInTestDataset(entityUri, og, aot, role)) { + grantedRoles.add(role); + } + } + return grantedRoles; + } + + private static boolean isUriInTestDataset(String entityUri, OperationGroup og, AccessObjectType aot, String role) { + Set values = PolicyLoader.getInstance().getPolicyDataSetValues(og, aot, role); + return values.contains(entityUri); + } + + public static void deletedEntityEvent(Property oldObj) { + log.debug("Don't delete access rule if property has been deleted " + oldObj ); + } + + public static void updatedEntityEvent(Object oldObj, Object newObj) { + if (oldObj instanceof Property || newObj instanceof Property) { + log.error("update entity event old " + oldObj + " new object " + newObj ); + } + } + + public static void insertedEntityEvent(Property newObj) { + log.debug("Nothing to do " + newObj ); + } +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PermissionsPolicy.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PermissionsPolicy.java deleted file mode 100644 index 0a66bdeffc..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PermissionsPolicy.java +++ /dev/null @@ -1,56 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.policy; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasPermission; -import edu.cornell.mannlib.vitro.webapp.auth.permissions.Permission; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; - -/** - * The user is authorized to perform the RequestedAction if one of his - * Permissions will authorize it. - */ -public class PermissionsPolicy implements PolicyIface { - private static final Log log = LogFactory.getLog(PermissionsPolicy.class); - - @Override - public PolicyDecision isAuthorized(IdentifierBundle whoToAuth, - RequestedAction whatToAuth) { - if (whoToAuth == null) { - return defaultDecision("whomToAuth was null"); - } - if (whatToAuth == null) { - return defaultDecision("whatToAuth was null"); - } - - for (Permission p : HasPermission.getPermissions(whoToAuth)) { - if (p.isAuthorized(whatToAuth)) { - log.debug("Permission " + p + " approves request " + whatToAuth); - return new BasicPolicyDecision(Authorization.AUTHORIZED, - "PermissionsPolicy: approved by " + p); - } else { - log.trace("Permission " + p + " denies request " + whatToAuth); - } - } - log.debug("No permission will approve " + whatToAuth); - return defaultDecision("no permission will approve " + whatToAuth); - } - - /** If the user isn't explicitly authorized, return this. */ - private PolicyDecision defaultDecision(String message) { - return new BasicPolicyDecision(Authorization.INCONCLUSIVE, message); - } - - @Override - public String toString() { - return "PermissionsPolicy - " + hashCode(); - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/Policies.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/Policies.java new file mode 100644 index 0000000000..0766a98489 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/Policies.java @@ -0,0 +1,18 @@ +package edu.cornell.mannlib.vitro.webapp.auth.policy; + +import java.util.List; + +import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Policy; + +public interface Policies { + + public List getList(); + + public boolean contains(Policy policy); + + public void add(Policy policy); + + public long size(); + + public void clear(); +} \ No newline at end of file diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyDecisionLogger.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyDecisionLogger.java index 1880c76939..a5e48bb6d7 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyDecisionLogger.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyDecisionLogger.java @@ -2,7 +2,7 @@ package edu.cornell.mannlib.vitro.webapp.auth.policy; -import static edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization.INCONCLUSIVE; +import static edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.DecisionResult.INCONCLUSIVE; import java.util.regex.Pattern; @@ -10,9 +10,9 @@ import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject; import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; +import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Policy; import edu.cornell.mannlib.vitro.webapp.utils.developer.DeveloperSettings; import edu.cornell.mannlib.vitro.webapp.utils.developer.Key; @@ -33,7 +33,7 @@ public class PolicyDecisionLogger { INCONCLUSIVE, "The decision was null."); private final DeveloperSettings settings; - private final RequestedAction whatToAuth; + private final AccessObject whatToAuth; private final IdentifierBundle whoToAuth; private final boolean enabled; @@ -43,7 +43,7 @@ public class PolicyDecisionLogger { private final boolean includeIdentifiers; public PolicyDecisionLogger(IdentifierBundle whoToAuth, - RequestedAction whatToAuth) { + AccessObject whatToAuth) { this.settings = DeveloperSettings.getInstance(); this.whoToAuth = whoToAuth; this.whatToAuth = whatToAuth; @@ -130,7 +130,7 @@ private Pattern compilePatternFromSetting(Key key) { * If the logger and the policy and the decision all pass the restrictions, * write to the log. A null decision is treated as inconclusive. */ - public void log(PolicyIface policy, PolicyDecision pd) { + public void log(Policy policy, PolicyDecision pd) { if (passesRestrictions(String.valueOf(policy), pd)) { if (this.includeIdentifiers) { log.info(String.format( @@ -161,7 +161,7 @@ private boolean passesConclusiveRestriction(PolicyDecision pd) { } private boolean isInconclusive(PolicyDecision pd) { - return pd == null || pd.getAuthorized() == INCONCLUSIVE; + return pd == null || pd.getDecisionResult() == INCONCLUSIVE; } public void logNoDecision(PolicyDecision pd) { diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyDecisionPoint.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyDecisionPoint.java new file mode 100644 index 0000000000..366fd7a852 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyDecisionPoint.java @@ -0,0 +1,43 @@ +package edu.cornell.mannlib.vitro.webapp.auth.policy; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.DecisionResult; +import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Policy; +import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; + +public class PolicyDecisionPoint { + + private static final Log log = LogFactory.getLog(PolicyDecisionPoint.class.getName()); + + public static PolicyDecision decide(AuthorizationRequest ar) { + PolicyDecision pd = null; + PolicyDecisionLogger logger = new PolicyDecisionLogger(ar.getIds(), ar.getAccessObject()); + PolicyStore store = PolicyStore.getInstance(); + for(Policy policy : store.getList()){ + try{ + pd = policy.decide(ar); + logger.log(policy, pd); + if( pd != null ){ + if( pd.getDecisionResult() == DecisionResult.AUTHORIZED ) + return pd; + if( pd.getDecisionResult() == DecisionResult.UNAUTHORIZED ) + return pd; + if( pd.getDecisionResult() == DecisionResult.INCONCLUSIVE ) + continue; + } else{ + log.debug("policy " + policy.toString() + " returned a null PolicyDecision"); + } + }catch(Throwable th){ + log.error("ignoring exception in policy " + policy.toString(), th ); + } + } + + pd = new BasicPolicyDecision(DecisionResult.INCONCLUSIVE, + "No policy returned a conclusive decision on " + ar.getAccessObject()); + logger.logNoDecision(pd); + return pd; + } +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyHelper.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyHelper.java index 67f61897cb..e6b41374c3 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyHelper.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyHelper.java @@ -2,7 +2,11 @@ package edu.cornell.mannlib.vitro.webapp.auth.policy; -import static edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction.SOME_URI; +import static edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject.SOME_URI; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; import javax.servlet.http.HttpServletRequest; @@ -18,16 +22,19 @@ import org.apache.jena.rdf.model.Statement; import org.apache.jena.rdf.model.StmtIterator; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessOperation; import edu.cornell.mannlib.vitro.webapp.auth.identifier.ActiveIdentifierBundleFactories; import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasAssociatedIndividual; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IdentifierPermissionSetProvider; +import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject; +import edu.cornell.mannlib.vitro.webapp.auth.objects.DataPropertyStatementAccessObject; +import edu.cornell.mannlib.vitro.webapp.auth.objects.ObjectPropertyStatementAccessObject; +import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.DecisionResult; +import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddDataPropertyStatement; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AddObjectPropertyStatement; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropDataPropertyStatement; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObjectPropertyStatement; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.SimpleAuthorizationRequest; import edu.cornell.mannlib.vitro.webapp.beans.Property; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator; @@ -39,44 +46,80 @@ public class PolicyHelper { private static final Log log = LogFactory.getLog(PolicyHelper.class); - /** - * Are these actions authorized for the current user by the current - * policies? - */ - public static boolean isAuthorizedForActions(HttpServletRequest req, - AuthorizationRequest... actions) { - return isAuthorizedForActions(req, AuthorizationRequest.andAll(actions)); - } - - /** - * Are these actions authorized for the current user by the current - * policies? - */ - public static boolean isAuthorizedForActions(HttpServletRequest req, - Iterable actions) { - return isAuthorizedForActions(req, AuthorizationRequest.andAll(actions)); - } - - /** - * Are these actions authorized for the current user by the current - * policies? - */ - private static boolean isAuthorizedForActions(HttpServletRequest req, - AuthorizationRequest ar) { - PolicyIface policy = ServletPolicyList.getPolicies(req); + public static boolean isAuthorizedForActions(HttpServletRequest req, AccessObject ar, AccessOperation operation) { IdentifierBundle ids = RequestIdentifiers.getIdBundleForRequest(req); - return ar.isAuthorized(ids, policy); + return actionRequestIsAuthorized(ids, ar, operation); } - - /** - * Are these actions authorized for these identifiers by these policies? - */ - public static boolean isAuthorizedForActions(IdentifierBundle ids, - PolicyIface policy, AuthorizationRequest ar) { - return ar.isAuthorized(ids, policy); + + public static boolean isAuthorizedForActions(IdentifierBundle ids, AccessObject ar, AccessOperation op) { + return actionRequestIsAuthorized(ids, ar, op); + } + + public static boolean isAuthorizedForActions(IdentifierBundle ids, AuthorizationRequest ar) { + if (ar == null) { + log.error("AuthorizationRequest is null"); + return false; + } + if (ar.getPredefinedDecision() != DecisionResult.INCONCLUSIVE){ + return ar.getPredefinedDecision() == DecisionResult.AUTHORIZED; + } + if (ar.isContainer()) { + List items = ar.getItems(); + boolean result = false; + for (AuthorizationRequest item : items ) { + result = result || isAuthorizedForActions(ids, item); + } + return result; + } + return actionRequestIsAuthorized(ids, ar.getAccessObject(), ar.getAccessOperation()); + } + + public static boolean isAuthorizedForActions(HttpServletRequest req, AuthorizationRequest ar) { + if (ar == null) { + log.error("AuthorizationRequest is null"); + return false; + } + if (ar.getPredefinedDecision() != DecisionResult.INCONCLUSIVE){ + return ar.getPredefinedDecision() == DecisionResult.AUTHORIZED; + } + if (ar.isContainer()) { + List items = ar.getItems(); + boolean result = false; + for (AuthorizationRequest item : items ) { + result = result || isAuthorizedForActions(req, item); + } + return result; + } + IdentifierBundle ids = RequestIdentifiers.getIdBundleForRequest(req); + return actionRequestIsAuthorized(ids, ar.getAccessObject(), ar.getAccessOperation()); + } + + private static boolean actionRequestIsAuthorized(IdentifierBundle ids, AccessObject ao, AccessOperation operation) { + if (operation == null) { + log.error("Opeartion is null, accessObject " + ao ); + return false; + } + if (ao == null) { + log.error("Access object is null, operation " + operation); + return false; + } + AuthorizationRequest ar = new SimpleAuthorizationRequest(ao, operation); + Collection uris = IdentifierPermissionSetProvider.getPermissionSetUris(ids); + ar.setRoleUris(new ArrayList(uris)); + ar.setIds(ids); + ar.setEditorUris(new ArrayList(HasAssociatedIndividual.getIndividualUris(ids))); + PolicyDecision decision = PolicyDecisionPoint.decide(ar); + debug(ar, decision); + return decision.getDecisionResult() == DecisionResult.AUTHORIZED; } - /** + private static void debug(AuthorizationRequest ar, PolicyDecision decision) { + if (true) {//log.isDebugEnabled() + log.error(String.format("Request for %s on object %s resulted in decision %s", ar.getAccessOperation(), ar.getAccessObject(), decision.getDecisionResult())); + } + } + + /** * Is the email/password authorized for these actions? This should be used * when a controller or something needs allow actions if the user passes in * their email and password. @@ -84,8 +127,7 @@ public static boolean isAuthorizedForActions(IdentifierBundle ids, * It may be better to check this as part of a servlet Filter and add an * identifier bundle. */ - public static boolean isAuthorizedForActions(HttpServletRequest req, - String email, String password, AuthorizationRequest ar) { + public static boolean isAuthorizedForActions(HttpServletRequest req, String email, String password, AuthorizationRequest ar) { if (password == null || email == null || password.isEmpty() || email.isEmpty()) { return false; @@ -111,10 +153,8 @@ public static boolean isAuthorizedForActions(HttpServletRequest req, + "account URI: %s", email, uri)); // figure out if that account can do the actions - IdentifierBundle ids = ActiveIdentifierBundleFactories - .getUserIdentifierBundle(req, user); - PolicyIface policy = ServletPolicyList.getPolicies(req); - return ar.isAuthorized(ids, policy); + IdentifierBundle ids = ActiveIdentifierBundleFactories.getUserIdentifierBundle(user); + return isAuthorizedForActions(ids, ar); } catch (Exception ex) { log.error("Error while attempting to authorize actions " + ar, ex); return false; @@ -127,8 +167,7 @@ public static boolean isAuthorizedForActions(HttpServletRequest req, * * The statement is expected to be fully-populated, with no null fields. */ - public static boolean isAuthorizedToAdd(HttpServletRequest req, - Statement stmt, OntModel modelToBeModified) { + public static boolean isAuthorizedToAdd(HttpServletRequest req, Statement stmt, OntModel modelToBeModified) { if ((req == null) || (stmt == null) || (modelToBeModified == null)) { return false; } @@ -140,20 +179,20 @@ public static boolean isAuthorizedToAdd(HttpServletRequest req, return false; } - RequestedAction action; + AccessObject action; if (objectNode.isResource()) { Property property = new Property(predicate.getURI()); property.setDomainVClassURI(SOME_URI); property.setRangeVClassURI(SOME_URI); - action = new AddObjectPropertyStatement(modelToBeModified, + action = new ObjectPropertyStatementAccessObject(modelToBeModified, subject.getURI(), property, objectNode.asResource() .getURI()); } else { - action = new AddDataPropertyStatement(modelToBeModified, + action = new DataPropertyStatementAccessObject(modelToBeModified, subject.getURI(), predicate.getURI(), objectNode .asLiteral().getString()); } - return isAuthorizedForActions(req, action); + return isAuthorizedForActions(req, action, AccessOperation.ADD); } /** @@ -162,8 +201,7 @@ public static boolean isAuthorizedToAdd(HttpServletRequest req, * * The statement is expected to be fully-populated, with no null fields. */ - public static boolean isAuthorizedToDrop(HttpServletRequest req, - Statement stmt, OntModel modelToBeModified) { + public static boolean isAuthorizedToDrop(HttpServletRequest req, Statement stmt, OntModel modelToBeModified) { if ((req == null) || (stmt == null) || (modelToBeModified == null)) { return false; } @@ -175,20 +213,20 @@ public static boolean isAuthorizedToDrop(HttpServletRequest req, return false; } - RequestedAction action; + AccessObject action; if (objectNode.isResource()) { Property property = new Property(predicate.getURI()); property.setDomainVClassURI(SOME_URI); property.setRangeVClassURI(SOME_URI); - action = new DropObjectPropertyStatement(modelToBeModified, + action = new ObjectPropertyStatementAccessObject(modelToBeModified, subject.getURI(), property, objectNode.asResource() .getURI()); } else { - action = new DropDataPropertyStatement(modelToBeModified, + action = new DataPropertyStatementAccessObject(modelToBeModified, subject.getURI(), predicate.getURI(), objectNode .asLiteral().getString()); } - return isAuthorizedForActions(req, action); + return isAuthorizedForActions(req, action, AccessOperation.DROP); } /** @@ -204,8 +242,7 @@ public static boolean isAuthorizedToDrop(HttpServletRequest req, * log will contain a full record of all failures. This is no more expensive * than if all statements succeeded. */ - public static boolean isAuthorizedAsExpected(HttpServletRequest req, - Model additions, Model retractions, OntModel modelBeingModified) { + public static boolean isAuthorizedAsExpected(HttpServletRequest req, Model additions, Model retractions, OntModel modelBeingModified) { if (req == null) { log.warn("Can't evaluate authorization if req is null"); return false; @@ -334,4 +371,5 @@ private PolicyHelper() { // nothing to do. } + } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyList.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyList.java deleted file mode 100644 index 8baf48889a..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyList.java +++ /dev/null @@ -1,66 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.policy; - -import java.util.ArrayList; -import java.util.Collection; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; - -/** - * This is a List of Policy Objects that implements PolciyIface. The intent - * is to make it easy to query a list of policies for a PolicyDecision. - * - * The Policy objects in the PolicyList are queried for authorization in order - * and return the first AUTHORIZED or UNAUTHROIZED decision. INCONCLUSIVE - * or null decisions will be ignored and the next policy on the list will - * be queried. - */ -public class PolicyList extends ArrayList implements PolicyIface{ - private static final Log log = LogFactory.getLog(PolicyList.class.getName()); - - public PolicyList(){ - super(); - } - - public PolicyList(Collection policies) { - super(policies); - } - - @Override - public PolicyDecision isAuthorized(IdentifierBundle whoToAuth, RequestedAction whatToAuth) { - PolicyDecision pd = null; - PolicyDecisionLogger logger = new PolicyDecisionLogger(whoToAuth, whatToAuth); - for(PolicyIface policy : this){ - try{ - pd = policy.isAuthorized(whoToAuth, whatToAuth); - logger.log(policy, pd); - if( pd != null ){ - if( pd.getAuthorized() == Authorization.AUTHORIZED ) - return pd; - if( pd.getAuthorized() == Authorization.UNAUTHORIZED ) - return pd; - if( pd.getAuthorized() == Authorization.INCONCLUSIVE ) - continue; - } else{ - log.debug("policy " + policy.toString() + " returned a null PolicyDecision"); - } - }catch(Throwable th){ - log.error("ignoring exception in policy " + policy.toString(), th ); - } - } - - pd = new BasicPolicyDecision(Authorization.INCONCLUSIVE, - "No policy returned a conclusive decision on " + whatToAuth); - logger.logNoDecision(pd); - return pd; - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyLoader.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyLoader.java new file mode 100644 index 0000000000..1835cdfa83 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyLoader.java @@ -0,0 +1,641 @@ +package edu.cornell.mannlib.vitro.webapp.auth.policy; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.jena.query.ParameterizedSparqlString; +import org.apache.jena.query.Query; +import org.apache.jena.query.QueryExecution; +import org.apache.jena.query.QueryExecutionFactory; +import org.apache.jena.query.QueryFactory; +import org.apache.jena.query.QuerySolution; +import org.apache.jena.query.ResultSet; +import org.apache.jena.query.ResultSetFormatter; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.RDFNode; + +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AttributeFactory; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.OperationGroup; +import edu.cornell.mannlib.vitro.webapp.auth.rules.AccessRule; +import edu.cornell.mannlib.vitro.webapp.auth.rules.AccessRuleFactory; +import edu.cornell.mannlib.vitro.webapp.dao.jena.event.BulkUpdateEvent; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; +import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ModelSerializationFormat; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.model.RDFServiceModel; + +public class PolicyLoader { + + private static final String PRIORITY = "priority"; + public static final String POLICY = "policy"; + private static final Log log = LogFactory.getLog(PolicyLoader.class); + private static final String POLICY_QUERY = + "prefix rdfs: \n" + + "prefix owl: \n" + + "prefix rdf: \n" + + "prefix xsd: \n" + + "prefix auth: \n" + + "prefix ai: \n" + + "prefix ao: \n" + + "SELECT DISTINCT ?" + POLICY + " ?" + PRIORITY + " \n" + + "WHERE {\n" + + "?" + POLICY + " rdf:type ao:Policy .\n" + + "OPTIONAL {?" + POLICY + " ao:priority ?set_priority" + " . }\n" + + "BIND(COALESCE(?set_priority, 0 ) as ?" + PRIORITY + " ) .\n" + + "} ORDER BY ?" + PRIORITY; + + private static final String PRIORITY_QUERY = + "prefix rdfs: \n" + + "prefix owl: \n" + + "prefix rdf: \n" + + "prefix xsd: \n" + + "prefix auth: \n" + + "prefix ai: \n" + + "prefix ao: \n" + + "SELECT DISTINCT ?" + PRIORITY + " \n" + + "WHERE {\n" + + "?" + POLICY + " rdf:type ao:Policy .\n" + + "OPTIONAL {?" + POLICY + " ao:priority ?set_priority" + " . }\n" + + "BIND(COALESCE(?set_priority, 0 ) as ?" + PRIORITY + " ) .\n" + + "} ORDER BY ?" + PRIORITY; + + private static final String DATASET_QUERY = + "prefix rdfs: \n" + + "prefix owl: \n" + + "prefix rdf: \n" + + "prefix xsd: \n" + + "prefix auth: \n" + + "prefix ai: \n" + + "prefix ao: \n" + + "SELECT DISTINCT ?dataSet \n" + + "WHERE {\n" + + " ?policy ao:testDatasets ?dataSets .\n" + + " ?policy rdf:type ao:Policy .\n" + + " ?dataSets ao:testDataset ?dataSet .\n" + + "} ORDER BY ?dataSet"; + + private static final String NO_DATASET_RULES_QUERY = + "prefix rdfs: \n" + + "prefix owl: \n" + + "prefix rdf: \n" + + "prefix xsd: \n" + + "prefix auth: \n" + + "prefix ai: \n" + + "prefix ao: \n" + + "SELECT DISTINCT ?rules ?rule ?attribute ?testId ?typeId ?value ?lit_value ?decision_id \n" + + "WHERE {\n" + + "?policy rdf:type ao:Policy .\n" + + "?policy ao:rules ?rules . \n" + + "?rules ao:rule ?rule . \n" + + "?rule ao:attribute ?attribute .\n" + + "OPTIONAL {\n" + + " ?attribute ao:test ?attributeTest .\n" + + " OPTIONAL {\n" + + " ?attributeTest ao:id ?testId . \n" + + " }\n" + + "}" + + "OPTIONAL {\n" + + " ?attribute ao:type ?attributeType . \n" + + " OPTIONAL {\n" + + " ?attributeType ao:id ?typeId . \n" + + " }\n" + + "}\n" + + "OPTIONAL {\n" + + " ?rule ao:decision ?decision . \n" + + " ?decision ao:id ?decision_id . \n" + + "}\n" + + "?attribute ao:value ?value . \n" + + "OPTIONAL {?value ao:id ?lit_value . }\n" + + "} ORDER BY ?rule ?attribute"; + + private static final String DATASET_RULES_QUERY = + "prefix rdfs: \n" + + "prefix owl: \n" + + "prefix rdf: \n" + + "prefix xsd: \n" + + "prefix auth: \n" + + "prefix ai: \n" + + "prefix ao: \n" + + "SELECT DISTINCT ?rules ?rule ?attribute ?testId ?typeId ?value ?lit_value ?decision_id ?dataSetUri \n" + + "WHERE {\n" + + "?policy rdf:type ao:Policy .\n" + + "?policy ao:rules ?rules . \n" + + "?rules rdf:type ao:Rules . \n" + + "?rules ao:rule ?rule . \n" + + "?rule ao:attribute ?attribute . \n" + + "?attribute rdf:type ao:Attribute .\n" + + "OPTIONAL {\n" + + " ?attribute ao:test ?attributeTest .\n" + + " OPTIONAL {\n" + + " ?attributeTest ao:id ?testId . \n" + + " }\n" + + "}" + + "OPTIONAL {\n" + + " ?attribute ao:type ?attributeType . \n" + + " OPTIONAL {\n" + + " ?attributeType ao:id ?typeId . \n" + + " }\n" + + "}\n" + + "OPTIONAL {\n" + + " ?rule ao:decision ?decision . \n" + + " ?decision ao:id ?decision_id . \n" + + "}\n" + + "OPTIONAL {\n" + + " ?attribute ao:setValue ?testData . \n" + + " ?dataSet ao:testData ?testData . \n" + + " ?testData ao:dataValue ?value . \n" + + " OPTIONAL {?value ao:id ?lit_value . }\n" + + "}\n" + + "OPTIONAL {\n" + + " ?attribute ao:value ?value . \n" + + " OPTIONAL {?value ao:id ?lit_value . }\n" + + "}\n" + + "BIND(?dataSet as ?dataSetUri)\n" + + "} ORDER BY ?rule ?attribute"; + + + private static final String policyKeyTemplatePrefix = + "prefix rdfs: \n" + + "prefix owl: \n" + + "prefix rdf: \n" + + "prefix xsd: \n" + + "prefix auth: \n" + + "prefix ai: \n" + + "prefix ao: \n" + + "SELECT DISTINCT ?" + POLICY + " ?value ?valueId ( COUNT(?key) AS ?keySize ) \n" + + "WHERE {\n" + + " ?" + POLICY + " ao:policyKey ?policyKeyUri .\n" + + " ?" + POLICY + " ao:testDatasets ?testDataSets .\n" + + " ?testDataSets ao:testDataset ?dataSet . \n" + + " ?dataSet ao:testData ?testData . \n" + + " OPTIONAL { ?testData ao:dataValue ?value . \n" + + " OPTIONAL { ?value ao:id ?valueId . } \n" + + " }" + + " ?policyKeyUri ao:keyComponent ?key .\n"; + + private static final String policyKeyTemplateSuffix = "} GROUP BY ?" + POLICY + " ?value ?valueId"; + + private static final String policyStatementByKeyTemplatePrefix = + "prefix rdfs: \n" + + "prefix owl: \n" + + "prefix rdf: \n" + + "prefix xsd: \n" + + "prefix auth: \n" + + "prefix ai: \n" + + "prefix ao: \n" + + "CONSTRUCT { \n" + + " ?testData ao:dataValue <%s> .\n" + + "}\n" + + "WHERE {\n" + + " ?" + POLICY + " ao:policyKey ?policyKeyUri .\n" + + " ?" + POLICY + " ao:testDatasets ?testDataSets .\n" + + " ?testDataSets ao:testDataset ?dataSet . \n" + + " ?dataSet ao:testData ?testData . \n"; + + private static final String policyStatementByKeyTemplateSuffix = "}"; + + private Model userAccountsModel; + private RDFService rdfService; + private static PolicyLoader INSTANCE; + + public static PolicyLoader getInstance() { + return INSTANCE; + } + + private PolicyLoader(Model model) { + if (model != null) { + this.userAccountsModel = model; + this.rdfService = new RDFServiceModel(userAccountsModel); + } else { + this.userAccountsModel = ModelAccess.getInstance().getOntModelSelector().getUserAccountsModel(); + //this.rdfService = ModelAccess.getInstance().getRDFService(WhichService.CONFIGURATION); + this.rdfService = new RDFServiceModel(userAccountsModel); + loadPolicies(); + } + } + + private Model getUserAccountsModel() { + return userAccountsModel; + } + + public static void initialize(Model model) { + INSTANCE = new PolicyLoader(model); + } + + private void loadPolicies() { + List policyUris = getPolicyUris(); + for (String uri : policyUris) { + debug("Loading policy %s", uri); + DynamicPolicy policy = loadPolicy(uri); + if (policy != null) { + debug("Loaded policy %s", uri); + //take policy priority into account + PolicyStore.getInstance().add(policy); + } + } + } + + public List getPolicyUris() { + debug("SPARQL Query to get policy uris from the graph:\n %s", POLICY_QUERY); + Query query = QueryFactory.create(POLICY_QUERY); + QueryExecution qexec = QueryExecutionFactory.create(query, getUserAccountsModel()); + List policyUris = new LinkedList(); + try { + ResultSet rs = qexec.execSelect(); + while (rs.hasNext()) { + QuerySolution qs = rs.next(); + if (!qs.contains(POLICY) || !qs.get(POLICY).isResource()) { + //debug("Policy solution doesn't contain policy resource"); + continue; + } + policyUris.add(qs.getResource(POLICY).getURI()); + } + } catch (Exception e) { + log.error(e, e); + } finally { + qexec.close(); + } + return policyUris; + } + + public DynamicPolicy loadPolicy(String uri) { + List dataSetNames = getDataSetNames(uri); + Set rules = new HashSet<>(); + long priority = getPriority(uri); + try { + if (dataSetNames.isEmpty()) { + loadRulesWithoutDataSet(uri, rules); + } else { + for (String dataSetName : dataSetNames) { + loadRulesForDataSet(uri, rules, dataSetName); + } + } + } catch (Exception e) { + return null; + } + if (rules.isEmpty()) { + return null; + } + DynamicPolicy policy = new DynamicPolicy(uri, priority); + policy.addRules(rules); + return policy; + } + + public Set getPolicyDataSetValues(OperationGroup og, AccessObjectType aot, String role) { + Set values = new HashSet<>(); + long expectedSize = 3; + final String queryText = getPolicyTestValuesByKeyQuery(new String[]{role}, new String[]{og.toString(), aot.toString()}); + debug("SPARQL Query to get policy data set values:\n %s", queryText); + Query query = QueryFactory.create(queryText); + QueryExecution qexec = QueryExecutionFactory.create(query, getUserAccountsModel()); + try { + ResultSet rs = qexec.execSelect(); + while (rs.hasNext()) { + QuerySolution qs = rs.next(); + if (!qs.contains(POLICY) || + !qs.contains("keySize") || + !qs.get("keySize").isLiteral()) { + continue; + } + long keySize = qs.getLiteral("keySize").getLong(); + if (expectedSize != keySize) { + continue; + } + if (qs.contains("valueId") && qs.get("valueId").isLiteral()) { + values.add(qs.getLiteral("valueId").getString()); + } else if (qs.contains("value")) { + RDFNode node = qs.get("value"); + if (node.isLiteral()) { + values.add(node.asLiteral().toString()); + } else if (node.isResource()){ + values.add(node.asResource().getURI()); + } + } + } + } catch (Exception e) { + log.error(e, e); + } finally { + qexec.close(); + } + return values; + } + + public String getPolicyUriByKey(OperationGroup og, AccessObjectType aot, String role) { + String uri = null; + long expectedSize = 3; + final String queryText = getPolicyTestValuesByKeyQuery(new String[]{role}, new String[]{og.toString(), aot.toString()}); + debug("SPARQL Query to get policy data set values:\n %s", queryText); + Query query = QueryFactory.create(queryText); + QueryExecution qexec = QueryExecutionFactory.create(query, getUserAccountsModel()); + try { + ResultSet rs = qexec.execSelect(); + while (rs.hasNext()) { + QuerySolution qs = rs.next(); + if (!qs.contains(POLICY) || + !qs.get(POLICY).isResource() || + !qs.contains("keySize") || + !qs.get("keySize").isLiteral()) { + continue; + } + long keySize = qs.getLiteral("keySize").getLong(); + if (expectedSize != keySize) { + continue; + } + return qs.getResource(POLICY).getURI(); + } + } catch (Exception e) { + log.error(e, e); + } finally { + qexec.close(); + } + return uri; + } + + public void modifyPolicyDataSetValue(String entityUri, OperationGroup og, AccessObjectType aot, String role, boolean isAdd) { + final String queryText = getPolicyDataSetValueStatementByKeyQuery(entityUri, new String[]{role}, new String[]{og.toString(), aot.toString()}); + debug("SPARQL Query to get policy data set values:\n %s", queryText); + Query query = QueryFactory.create(queryText); + QueryExecution qexec = QueryExecutionFactory.create(query, getUserAccountsModel()); + try { + Model model = qexec.execConstruct(); + if (model.isEmpty()) { + log.error("statements to add/delete are empty"); + return; + } + updateUserAccountsModel(model, isAdd); + } catch (Exception e) { + log.error(e, e); + } finally { + qexec.close(); + } + } + + private void updateUserAccountsModel(Model data, boolean isAdd) { + try { + ChangeSet changeSet = makeChangeSet(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + data.write(baos, "TTL"); + InputStream in = new ByteArrayInputStream(baos.toByteArray()); + debug(modelToString(data, isAdd)); + if (isAdd) { + changeSet.addAddition(in, ModelSerializationFormat.N3, ModelNames.USER_ACCOUNTS); + } else { + changeSet.addRemoval(in, ModelSerializationFormat.N3, ModelNames.USER_ACCOUNTS); + } + rdfService.changeSetUpdate(changeSet); + } catch (RDFServiceException e) { + String message = modelToString(data, isAdd); + log.error(message); + log.error(e,e); + } + } + + private String modelToString(Model ruleData, boolean isAdd) { + StringWriter sw = new StringWriter(); + ruleData.write(sw, "TTL"); + String message = (isAdd ? "Adding to" : "Removing from") + " user accounts model \n" + sw.toString(); + return message; + } + + private static String getPolicyDataSetValueStatementByKeyQuery(String entityUri, String[] uris, String[] ids) { + StringBuilder query = new StringBuilder(); + query.append(String.format(policyStatementByKeyTemplatePrefix, entityUri)); + for (String uri : uris) { + query.append(String.format(" ?policyKeyUri ao:keyComponent <%s> . \n", uri)); + } + int i = 0; + for (String id : ids) { + query.append(String.format(" ?policyKeyUri ao:keyComponent ?uri%d . ?uri%d ao:id \"%s\" . \n", i, i, id)); + i++; + } + query.append(policyStatementByKeyTemplateSuffix); + return query.toString(); + } + + private static String getPolicyTestValuesByKeyQuery(String[] uris, String[] ids) { + StringBuilder query = new StringBuilder(policyKeyTemplatePrefix); + for (String uri : uris) { + query.append(String.format(" ?policyKeyUri ao:keyComponent <%s> . \n", uri)); + } + int i = 0; + for (String id : ids) { + query.append(String.format(" ?policyKeyUri ao:keyComponent ?uri%d . ?uri%d ao:id \"%s\" . \n", i, i, id)); + i++; + } + query.append(policyKeyTemplateSuffix); + return query.toString(); + } + + private long getPriority(String uri) { + //debug("SPARQL Query to get policy uris from the graph:\n %s", POLICY_URIS_QUERY); + ParameterizedSparqlString pss = new ParameterizedSparqlString(PRIORITY_QUERY); + pss.setIri(POLICY, uri); + //debug("Get priority query:\n %s", pss.toString()); + Query query = QueryFactory.create(pss.toString()); + QueryExecution qexec = QueryExecutionFactory.create(query, getUserAccountsModel()); + try { + ResultSet rs = qexec.execSelect(); + while (rs.hasNext()) { + QuerySolution qs = rs.next(); + if (!qs.contains(PRIORITY) || !qs.get(PRIORITY).isLiteral()) { + return 0; + } + return qs.getLiteral(PRIORITY).getLong(); + } + } catch (Exception e) { + log.error(e, e); + } finally { + qexec.close(); + } + return 0; + } + + private void loadRulesWithoutDataSet(String policyUri, Set rules) throws Exception { + ParameterizedSparqlString pss = new ParameterizedSparqlString(NO_DATASET_RULES_QUERY); + pss.setIri(POLICY, policyUri); + debug(pss.toString()); + Query query = QueryFactory.create(pss.toString()); + QueryExecution qexec = QueryExecutionFactory.create(query, getUserAccountsModel()); + try { + ResultSet rs = qexec.execSelect(); + AccessRule rule = null; + //debugSelectQueryResults(rs); + while (rs.hasNext()) { + QuerySolution qs = rs.next(); + if (isInvalidPolicySolution(policyUri, qs)) { + throw new Exception(); + } + if (isRuleContinues(rule, qs)){ + populateRule(rule, qs); + } else { + if (rule != null) { + rules.add(rule); + } + rule = AccessRuleFactory.createRule(qs); + } + } + if (rule != null) { + rules.add(rule); + debug("\nLoaded %s rules for %s policy", rules.size(), policyUri); + } else { + debug("\nNo rules loaded from the user accounts model for %s policy.", policyUri); + } + } finally { + qexec.close(); + } + } + + private void loadRulesForDataSet(String policyUri, Set rules, String dataSetName) throws Exception { + ParameterizedSparqlString pss = new ParameterizedSparqlString(DATASET_RULES_QUERY); + pss.setIri(POLICY, policyUri); + pss.setIri("dataSet", dataSetName); + debug(pss.toString()); + Query query = QueryFactory.create(pss.toString()); + QueryExecution qexec = QueryExecutionFactory.create(query, getUserAccountsModel()); + try { + ResultSet rs = qexec.execSelect(); + AccessRule rule = null; + //debugSelectQueryResults(rs); + while (rs.hasNext()) { + QuerySolution qs = rs.next(); + if (isInvalidPolicySolution(policyUri, qs)) { + throw new Exception(); + } + if (isRuleContinues(rule, qs)){ + populateRule(rule, qs); + } else { + if (rule != null) { + rules.add(rule); + } + rule = AccessRuleFactory.createRule(qs); + } + } + if (rule != null) { + rules.add(rule); + debug("\nLoaded %s rules for %s policy", rules.size(), policyUri); + } else { + debug("\nNo rules loaded from the user accounts model for %s policy.", policyUri); + } + } finally { + qexec.close(); + } + } + + private List getDataSetNames(String policyUri) { + List result = new ArrayList<>(); + ParameterizedSparqlString pss = new ParameterizedSparqlString(DATASET_QUERY); + pss.setIri(POLICY, policyUri); + Query query = QueryFactory.create(pss.toString()); + QueryExecution qexec = QueryExecutionFactory.create(query, getUserAccountsModel()); + try { + ResultSet rs = qexec.execSelect(); + while (rs.hasNext()) { + QuerySolution qs = rs.next(); + if (qs.contains("dataSet")) { + RDFNode dataSet = qs.get("dataSet"); + if (dataSet.isResource()) { + result.add(dataSet.asResource().getURI()); + } + } + } + } catch (Exception e) { + log.error(e, e); + } finally { + qexec.close(); + } + return result; + } + + + private void debugSelectQueryResults(ResultSet rs) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ResultSetFormatter.outputAsJSON(baos, rs); + String json = new String(baos.toByteArray()); + debug(json); + } + + private static boolean isRuleContinues(AccessRule rule, QuerySolution qs) { + if (rule == null) { + return false; + } + String ruleUri = qs.getResource("rule").getURI(); + if (qs.contains("dataSetUri")) { + ruleUri += "." + qs.getResource("dataSetUri").getURI(); + } + return rule.getRuleUri().equals(ruleUri); + } + + private static void populateRule(AccessRule ar, QuerySolution qs) throws Exception { + if (ar == null) { + return; + } + String attributeUri = qs.getResource("attribute").getURI(); + if (ar.containsAttributeUri(attributeUri)) { + AttributeFactory.extendAttribute(ar.getAttribute(attributeUri), qs); + return; + } + try { + ar.addAttribute(AttributeFactory.createAttribute(qs)); + } catch (Exception e) { + log.error(e, e); + } + } + + private static boolean isInvalidPolicySolution(String uri, QuerySolution qs) { + if (!qs.contains("rules") || !qs.get("rules").isResource()) { + debug("Policy <%s> solution doesn't contain rules uri", uri); + return true; + } + if (!qs.contains("rule") || !qs.get("rule").isResource()) { + debug("Policy <%s> solution doesn't contain rule uri", uri); + return true; + } + if (!qs.contains("value")) { + debug("Policy <%s> solution doesn't contain value", uri); + return true; + } + if (!qs.contains("typeId") || !qs.get("typeId").isLiteral()) { + debug("Policy <%s> solution doesn't contain attribute type id", uri); + return true; + } + if (!qs.contains("testId") || !qs.get("testId").isLiteral()) { + debug("Policy <%s> solution doesn't contain attribute test id", uri); + return true; + } + return false; + } + + private static void debug(String template, Object... objects) { + if (log.isDebugEnabled()) { + log.error(String.format(template, objects )); + } + } + + public void addEntityToPolicyDataSet(String entityUri, AccessObjectType aot, OperationGroup og, String role) { + modifyPolicyDataSetValue(entityUri, og, aot, role, true); + } + + public void removeEntityFromPolicyDataSet(String entityUri, AccessObjectType aot, OperationGroup og, String role) { + modifyPolicyDataSetValue(entityUri, og, aot, role, false); + } + + private ChangeSet makeChangeSet() { + ChangeSet cs = rdfService.manufactureChangeSet(); + cs.addPreChangeEvent(new BulkUpdateEvent(null, true)); + cs.addPostChangeEvent(new BulkUpdateEvent(null, false)); + return cs; + } +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyStore.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyStore.java new file mode 100644 index 0000000000..7702ef0086 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/PolicyStore.java @@ -0,0 +1,91 @@ +/* $This file is distributed under the terms of the license in LICENSE$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.policy; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Policy; + +public class PolicyStore implements Policies { + + private static final Comparator comparator = getPolicyComparator(); + private static PolicyStore INSTANCE = new PolicyStore(); + private static final Log log = LogFactory.getLog(PolicyStore.class); + + private PolicyStore() { + INSTANCE = this; + } + + public static PolicyStore getInstance() { + return INSTANCE; + } + protected List policyList = Collections.synchronizedList(new ArrayList()); + protected Map policyMap = Collections.synchronizedMap(new LinkedHashMap()); + + @Override + public boolean contains(Policy policy) { + return policyList.contains(policy); + } + + @Override + public synchronized void add(Policy policy) { + if (policy == null) { + log.error("Policy to add is null"); + return; + } + Policy oldPolicy = policyMap.put(policy.getUri(), policy); + if (oldPolicy != null) { + policyList.remove(oldPolicy); + } + policyList.add(policy); + Collections.sort(policyList, comparator); + } + + @Override + public synchronized void clear() { + policyList.clear(); + policyMap.clear(); + } + + public List getUris() { + List uris = new LinkedList<>(); + for (Policy policy : policyList) { + uris.add(policy.getUri()); + } + return uris; + } + + private static Comparator getPolicyComparator() { + return new Comparator() { + @Override + public int compare(Policy lps, Policy rps) { + if ( lps.getPriority() > rps.getPriority() ) { + return -1; + } else + if (lps.getPriority() > rps.getPriority()) { + return 1; + } + return lps.getUri().compareTo(lps.getUri()); + } + }; + } + + @Override + public List getList() { + return new ArrayList<>(policyList); + } + + @Override + public long size() { + return policyList.size(); + } +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/RequestPolicyList.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/RequestPolicyList.java deleted file mode 100644 index c077daac50..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/RequestPolicyList.java +++ /dev/null @@ -1,71 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.policy; - -import javax.servlet.ServletContext; -import javax.servlet.ServletRequest; -import javax.servlet.http.HttpServletRequest; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface; - -/** - * Allow us to store policies in a Request, in addition to those in the - * ServletContext - */ -public class RequestPolicyList extends PolicyList { - private static final String ATTRIBUTE_POLICY_ADDITIONS = RequestPolicyList.class - .getName(); - private static final Log log = LogFactory.getLog(RequestPolicyList.class); - - /** - * Get a copy of the current list of policies. This includes the policies in - * the ServletContext, followed by any stored in the request. This method may - * return an empty list, but it never returns null. - */ - public static PolicyList getPolicies(HttpServletRequest request) { - ServletContext ctx = request.getSession().getServletContext(); - - PolicyList list = ServletPolicyList.getPolicies(ctx); - list.addAll(getPoliciesFromRequest(request)); - return list; - } - - public static void addPolicy(ServletRequest request, PolicyIface policy) { - PolicyList policies = getPoliciesFromRequest(request); - if (!policies.contains(policy)) { - policies.add(policy); - log.debug("Added policy: " + policy.toString()); - } else { - log.warn("Ignored attempt to add redundent policy."); - } - } - - /** - * Get the current list of policy additions from the request, or create one - * if there is none. This method may return an empty list, but it never - * returns null. - */ - private static PolicyList getPoliciesFromRequest(ServletRequest request) { - if (request == null) { - throw new NullPointerException("request may not be null."); - } - - Object obj = request.getAttribute(ATTRIBUTE_POLICY_ADDITIONS); - if (obj == null) { - obj = new PolicyList(); - request.setAttribute(ATTRIBUTE_POLICY_ADDITIONS, obj); - } - - if (!(obj instanceof PolicyList)) { - throw new IllegalStateException("Expected to find an instance of " - + PolicyList.class.getName() - + " in the context, but found an instance of " - + obj.getClass().getName() + " instead."); - } - - return (PolicyList) obj; - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/RestrictHomeMenuItemEditingPolicy.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/RestrictHomeMenuItemEditingPolicy.java deleted file mode 100644 index 3b43577548..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/RestrictHomeMenuItemEditingPolicy.java +++ /dev/null @@ -1,70 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.policy; - -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyStatementAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.DropObjectPropertyStatement; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjectPropertyStatement; -import edu.cornell.mannlib.vitro.webapp.dao.DisplayVocabulary; - -/** - * Don't allow user to edit or drop the HomeMenuItem statement. - */ -public class RestrictHomeMenuItemEditingPolicy implements PolicyIface { - - @Override - public PolicyDecision isAuthorized(IdentifierBundle whoToAuth, - RequestedAction whatToAuth) { - if (whatToAuth instanceof EditObjectPropertyStatement) { - return isAuthorized((EditObjectPropertyStatement) whatToAuth); - } else if (whatToAuth instanceof DropObjectPropertyStatement) { - return isAuthorized((DropObjectPropertyStatement) whatToAuth); - } else { - return notHandled(); - } - } - - private PolicyDecision isAuthorized( - AbstractObjectPropertyStatementAction whatToAuth) { - if (whatToAuth.getPredicateUri() - .equals(DisplayVocabulary.HAS_ELEMENT) - && whatToAuth.getObjectUri().equals( - DisplayVocabulary.HOME_MENU_ITEM)) { - return notAuthorized(); - } else { - return notHandled(); - } - } - - private BasicPolicyDecision notHandled() { - return new BasicPolicyDecision(Authorization.INCONCLUSIVE, - "Doesn't handle this type of request"); - } - - private BasicPolicyDecision notAuthorized() { - return new BasicPolicyDecision(Authorization.UNAUTHORIZED, - "Can't edit home menu item."); - } - - public static class Setup implements ServletContextListener { - @Override - public void contextInitialized(ServletContextEvent sce) { - ServletPolicyList.addPolicyAtFront(sce.getServletContext(), - new RestrictHomeMenuItemEditingPolicy()); - } - - @Override - public void contextDestroyed(ServletContextEvent ctx) { - // Nothing to do here. - } - - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/RootUserPolicy.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/RootUserPolicy.java deleted file mode 100644 index 816bf7d515..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/RootUserPolicy.java +++ /dev/null @@ -1,233 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.policy; - -import java.util.TreeSet; - -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsRootUser; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; -import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status; -import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; -import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; -import edu.cornell.mannlib.vitro.webapp.dao.UserAccountsDao; -import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; - -/** - * If the user has an IsRootUser identifier, they can do anything! - * - * On setup, check to see that the specified root user exists. If not, create - * it. If we can't create it, abort. - * - * If any other root users exist, warn about them. - */ -public class RootUserPolicy implements PolicyIface { - private static final Log log = LogFactory.getLog(RootUserPolicy.class); - - private static final String PROPERTY_ROOT_USER_EMAIL = "rootUser.emailAddress"; - /* - * UQAM Add-Feature For parameterization of rootUser - */ - private static final String PROPERTY_ROOT_USER_PASSWORD = "rootUser.password"; - private static final String PROPERTY_ROOT_USER_PASSWORD_CHANGE_REQUIRED = "rootUser.passwordChangeRequired"; - - private static final String ROOT_USER_INITIAL_PASSWORD = "rootPassword"; - private static final String ROOT_USER_INITIAL_PASSWORD_CHANGE_REQUIRED = "true"; - - /** - * This is the entire policy. If you are a root user, you are authorized. - */ - @Override - public PolicyDecision isAuthorized(IdentifierBundle whoToAuth, - RequestedAction whatToAuth) { - if (IsRootUser.isRootUser(whoToAuth)) { - return new BasicPolicyDecision(Authorization.AUTHORIZED, - "RootUserPolicy: approved"); - } else { - return new BasicPolicyDecision(Authorization.INCONCLUSIVE, - "not root user"); - } - } - - @Override - public String toString() { - return "RootUserPolicy - " + hashCode(); - } - - // ---------------------------------------------------------------------- - // Setup class - // ---------------------------------------------------------------------- - - public static class Setup implements ServletContextListener { - private ServletContext ctx; - private StartupStatus ss; - private UserAccountsDao uaDao; - private ConfigurationProperties cp; - private String configuredRootUser; - private boolean configuredRootUserExists; - private TreeSet otherRootUsers; - - @Override - public void contextInitialized(ServletContextEvent sce) { - ctx = sce.getServletContext(); - ss = StartupStatus.getBean(ctx); - cp = ConfigurationProperties.getBean(ctx); - - try { - uaDao = ModelAccess.on(ctx).getWebappDaoFactory() - .getUserAccountsDao(); - configuredRootUser = getRootEmailFromConfig(); - - otherRootUsers = getEmailsOfAllRootUsers(); - configuredRootUserExists = otherRootUsers - .remove(configuredRootUser); - - if (configuredRootUserExists) { - if (otherRootUsers.isEmpty()) { - informThatRootUserExists(); - } else { - complainAboutMultipleRootUsers(); - } - } else { - createRootUser(); - if (!otherRootUsers.isEmpty()) { - complainAboutWrongRootUsers(); - } - } - - ServletPolicyList.addPolicy(ctx, new RootUserPolicy()); - } catch (Exception e) { - ss.fatal(this, "Failed to set up the RootUserPolicy", e); - } - } - - private String getRootEmailFromConfig() { - String email = ConfigurationProperties.getBean(ctx).getProperty( - PROPERTY_ROOT_USER_EMAIL); - if (email == null) { - throw new IllegalStateException( - "runtime.properties must contain a value for '" - + PROPERTY_ROOT_USER_EMAIL + "'"); - } else { - return email; - } - } - - private TreeSet getEmailsOfAllRootUsers() { - TreeSet rootUsers = new TreeSet(); - for (UserAccount ua : uaDao.getAllUserAccounts()) { - if (ua.isRootUser()) { - rootUsers.add(ua.getEmailAddress()); - } - } - return rootUsers; - } - - /** - * TODO The first and last name should be left blank, so the user will - * be forced to edit them. However, that's not in place yet. - */ - private void createRootUser() { - if (!Authenticator.isValidEmailAddress(configuredRootUser)) { - throw new IllegalStateException("Value for '" - + PROPERTY_ROOT_USER_EMAIL - + "' is not a valid email address: '" - + configuredRootUser + "'"); - } - - if (null != uaDao.getUserAccountByEmail(configuredRootUser)) { - throw new IllegalStateException("Can't create root user - " - + "an account already exists with email address '" - + configuredRootUser + "'"); - } - - UserAccount ua = new UserAccount(); - ua.setEmailAddress(configuredRootUser); - ua.setFirstName("root"); - ua.setLastName("user"); - // UQAM Add-Feature using getRootPasswordFromConfig() - ua.setArgon2Password(Authenticator.applyArgon2iEncoding( - getRootPasswordFromConfig())); - ua.setMd5Password(""); - // UQAM Add-Feature using getRootPasswdChangeRequiredFromConfig() - ua.setPasswordChangeRequired(getRootPasswdChangeRequiredFromConfig().booleanValue()); - ua.setStatus(Status.ACTIVE); - ua.setRootUser(true); - - uaDao.insertUserAccount(ua); - - StartupStatus.getBean(ctx).info(this, - "Created root user '" + configuredRootUser + "'"); - } - - private void informThatRootUserExists() { - ss.info(this, "Root user is " + configuredRootUser); - } - - private void complainAboutMultipleRootUsers() { - for (String other : otherRootUsers) { - ss.warning(this, "runtime.properties specifies '" - + configuredRootUser + "' as the value for '" - + PROPERTY_ROOT_USER_EMAIL - + "', but the system also contains this root user: " - + other); - } - ss.warning(this, "For security, " - + "it is best to delete unneeded root user accounts."); - } - - private void complainAboutWrongRootUsers() { - for (String other : otherRootUsers) { - ss.warning(this, "runtime.properties specifies '" - + configuredRootUser + "' as the value for '" - + PROPERTY_ROOT_USER_EMAIL - + "', but the system contains this root user instead: " - + other); - } - ss.warning(this, "Creating root user '" + configuredRootUser + "'"); - ss.warning(this, "For security, " - + "it is best to delete unneeded root user accounts."); - } - /* - * UQAM Add-Feature - * Add for getting rootUser.password property value from runtime.properties - */ - private String getRootPasswordFromConfig() { - String passwd = ConfigurationProperties.getBean(ctx).getProperty( - PROPERTY_ROOT_USER_PASSWORD); - if (passwd == null) { - passwd = ROOT_USER_INITIAL_PASSWORD; - } - return passwd; - } - - /* - * UQAM Add-Feature - * Add for getting rootUser.passwordChangeRequired property value from runtime.properties - */ - private Boolean getRootPasswdChangeRequiredFromConfig() { - String passwdCR = ConfigurationProperties.getBean(ctx).getProperty( - PROPERTY_ROOT_USER_PASSWORD_CHANGE_REQUIRED); - if (passwdCR == null) { - passwdCR = ROOT_USER_INITIAL_PASSWORD_CHANGE_REQUIRED; - } - return new Boolean(passwdCR); - } - @Override - public void contextDestroyed(ServletContextEvent sce) { - // Nothing to destroy - } - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicy.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicy.java deleted file mode 100644 index ab43736a74..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/SelfEditingPolicy.java +++ /dev/null @@ -1,161 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.policy; - -import java.util.ArrayList; -import java.util.List; - -import javax.servlet.ServletContext; - -import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasAssociatedIndividual; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDataPropertyStatementAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyStatementAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.resource.AbstractResourceAction; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; -import edu.cornell.mannlib.vitro.webapp.beans.Property; - -/** - * Policy to use for Vivo Self-Editing based on NetId for use at Cornell. All - * methods in this class should be thread safe and side effect free. - */ -public class SelfEditingPolicy extends BaseSelfEditingPolicy implements - PolicyIface { - public SelfEditingPolicy(ServletContext ctx) { - super(ctx, RoleLevel.SELF); - } - - @Override - public PolicyDecision isAuthorized(IdentifierBundle whoToAuth, - RequestedAction whatToAuth) { - if (whoToAuth == null) { - return inconclusiveDecision("whoToAuth was null"); - } - if (whatToAuth == null) { - return inconclusiveDecision("whatToAuth was null"); - } - - List userUris = new ArrayList( - HasAssociatedIndividual.getIndividualUris(whoToAuth)); - - if (userUris.isEmpty()) { - return inconclusiveDecision("Not self-editing."); - } - - if (whatToAuth instanceof AbstractObjectPropertyStatementAction) { - return isAuthorizedForObjectPropertyAction(userUris, - (AbstractObjectPropertyStatementAction) whatToAuth); - } - - if (whatToAuth instanceof AbstractDataPropertyStatementAction) { - return isAuthorizedForDataPropertyAction(userUris, - (AbstractDataPropertyStatementAction) whatToAuth); - } - - if (whatToAuth instanceof AbstractResourceAction) { - return isAuthorizedForResourceAction((AbstractResourceAction) whatToAuth); - } - - return inconclusiveDecision("Does not authorize " - + whatToAuth.getClass().getSimpleName() + " actions"); - } - - /** - * The user can edit a object property if it is not restricted and if it is - * about him. - */ - private PolicyDecision isAuthorizedForObjectPropertyAction( - List userUris, AbstractObjectPropertyStatementAction action) { - String subject = action.getSubjectUri(); - Property predicate = action.getPredicate(); - String object = action.getObjectUri(); - - if (!canModifyResource(subject)) { - return cantModifyResource(subject); - } - if (!canModifyPredicate(predicate)) { - return cantModifyPredicate(predicate); - } - if (!canModifyResource(object)) { - return cantModifyResource(object); - } - - if (userCanEditAsSubjectOrObjectOfStmt(userUris, subject, object)) { - return authorizedDecision("User is subject or object of statement."); - } else { - return userNotAuthorizedToStatement(); - } - } - - /** - * The user can edit a data property if it is not restricted and if it is - * about him. - */ - private PolicyDecision isAuthorizedForDataPropertyAction( - List userUris, AbstractDataPropertyStatementAction action) { - String subject = action.getSubjectUri(); - Property predicate = action.getPredicate(); - - if (!canModifyResource(subject)) { - return cantModifyResource(subject); - } - if (!canModifyPredicate(predicate)) { - return cantModifyPredicate(predicate); - } - - if (userCanEditAsSubjectOfStmt(userUris, subject)) { - return authorizedDecision("User is subject of statement."); - } else { - return userNotAuthorizedToStatement(); - } - } - - /** - * The user can add or remove resources if they are not restricted. - */ - private PolicyDecision isAuthorizedForResourceAction( - AbstractResourceAction action) { - String uri = action.getSubjectUri(); - if (!canModifyResource(uri)) { - return cantModifyResource(uri); - } else { - return authorizedDecision("May add/remove resource."); - } - } - - // ---------------------------------------------------------------------- - // Helper methods - // ---------------------------------------------------------------------- - - private boolean userCanEditAsSubjectOfStmt(List userUris, - String subject) { - for (String userUri : userUris) { - if (userUri.equals(subject)) { - return true; - } - } - return false; - } - - private boolean userCanEditAsSubjectOrObjectOfStmt(List userUris, - String subject, String object) { - for (String userUri : userUris) { - if (userUri.equals(subject)) { - return true; - } - if (userUri.equals(object)) { - return true; - } - } - return false; - } - - @Override - public String toString() { - return "SelfEditingPolicy - " + hashCode(); - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/ServletPolicyList.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/ServletPolicyList.java deleted file mode 100644 index f724a50390..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/ServletPolicyList.java +++ /dev/null @@ -1,122 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.policy; - -import java.util.ListIterator; - -import javax.servlet.ServletContext; -import javax.servlet.http.HttpServletRequest; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface; - -/** - * This maintains a PolicyList in the ServletContext. As a rule, however, this - * is only used as the basis for the RequestPolicyList. Client code that wants - * to access the current list of policies should look there. - */ -public class ServletPolicyList { - private static final String ATTRIBUTE_POLICY_LIST = ServletPolicyList.class.getName(); - private static final Log log = LogFactory.getLog(ServletPolicyList.class); - - /** - * Get a copy of the current list of policies. This method may return an - * empty list, but it never returns null. - */ - public static PolicyIface getPolicies(HttpServletRequest hreq) { - return getPolicies(hreq.getSession().getServletContext()); - } - - /** - * Get a copy of the current list of policies. This method may return an - * empty list, but it never returns null. - */ - public static PolicyList getPolicies(ServletContext sc) { - return new PolicyList(getPolicyList(sc)); - } - - /** - * Add the policy to the end of the list. - */ - public static void addPolicy(ServletContext sc, PolicyIface policy) { - if (policy == null) { - return; - } - - PolicyList policies = getPolicyList(sc); - if (!policies.contains(policy)) { - policies.add(policy); - log.debug("Added policy: " + policy.toString()); - } else { - log.warn("Ignored attempt to add redundant policy."); - } - } - - /** - * Add the policy to the front of the list. It may be moved further down the - * list by other policies that are later added using this method. - */ - public static void addPolicyAtFront(ServletContext sc, PolicyIface policy) { - if (policy == null) { - return; - } - - PolicyList policies = getPolicyList(sc); - if (!policies.contains(policy)) { - policies.add(0, policy); - log.debug("Added policy at front: " + policy.toString()); - } else { - log.warn("Ignored attempt to add redundant policy."); - } - } - - /** - * Replace the first instance of this class of policy in the list. If no - * instance is found, add the policy to the end of the list. - */ - public static void replacePolicy(ServletContext sc, PolicyIface policy) { - if (policy == null) { - return; - } - - Class clzz = policy.getClass(); - PolicyList policies = getPolicyList(sc); - ListIterator it = policies.listIterator(); - while (it.hasNext()) { - if (clzz.isAssignableFrom(it.next().getClass())) { - it.set(policy); - return; - } - } - - addPolicy(sc, policy); - } - - /** - * Get the current PolicyList from the context, or create one if there is - * none. This method may return an empty list, but it never returns null. - */ - private static PolicyList getPolicyList(ServletContext ctx) { - if (ctx == null) { - throw new NullPointerException("ctx may not be null."); - } - - Object obj = ctx.getAttribute(ATTRIBUTE_POLICY_LIST); - if (obj == null) { - obj = new PolicyList(); - ctx.setAttribute(ATTRIBUTE_POLICY_LIST, obj); - } - - if (!(obj instanceof PolicyList)) { - throw new IllegalStateException("Expected to find an instance of " - + PolicyList.class.getName() - + " in the context, but found an instance of " - + obj.getClass().getName() + " instead."); - } - - return (PolicyList) obj; - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionBean.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionBean.java deleted file mode 100644 index 51c113ee5d..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionBean.java +++ /dev/null @@ -1,207 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.policy.bean; - -import java.util.Arrays; -import java.util.Collection; - -import javax.servlet.ServletContext; -import javax.servlet.ServletContextEvent; -import javax.servlet.ServletContextListener; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; -import edu.cornell.mannlib.vitro.webapp.beans.Property; -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; -import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; - -/** - * Assists the role-based policies in determining whether a property or resource - * may be displayed, modified, or published in linked open data. - * - * There is a singleton bean that holds the current threshold role levels for - * displaying, modifying, or publishing restricted properties. - * - * Create this bean after the context models are in place. - * - * Add PropertyRestrictionListener to your EditProcessObject if you are editing - * a property, to ensure that the bean stays current. - */ -public abstract class PropertyRestrictionBean { - private static final Log log = LogFactory - .getLog(PropertyRestrictionBean.class); - - private static final PropertyRestrictionBean NULL = new PropertyRestrictionBeanNull(); - - protected static volatile PropertyRestrictionBean instance = NULL; - - protected static final Collection PROHIBITED_NAMESPACES = Arrays - .asList(new String[] { VitroVocabulary.vitroURI, "" }); - - protected static final Collection PERMITTED_EXCEPTIONS = Arrays - .asList(new String[] { VitroVocabulary.MONIKER, - VitroVocabulary.MODTIME, VitroVocabulary.IND_MAIN_IMAGE, - VitroVocabulary.LINK, VitroVocabulary.PRIMARY_LINK, - VitroVocabulary.ADDITIONAL_LINK, - VitroVocabulary.LINK_ANCHOR, VitroVocabulary.LINK_URL }); - - // ---------------------------------------------------------------------- - // static methods - // ---------------------------------------------------------------------- - - public static PropertyRestrictionBean getBean() { - return instance; - } - - // ---------------------------------------------------------------------- - // instance methods - // ---------------------------------------------------------------------- - - /** - * Any resource can be displayed. - * - * (Someday we may want to implement display restrictions based on VClass.) - */ - public abstract boolean canDisplayResource(String resourceUri, - RoleLevel userRole); - - /** - * A resource cannot be modified if its namespace is in the prohibited list - * (but some exceptions are allowed). - * - * (Someday we may want to implement modify restrictions based on VClass.) - */ - public abstract boolean canModifyResource(String resourceUri, - RoleLevel userRole); - - /** - * Any resource can be published. - * - * (Someday we may want to implement publish restrictions based on VClass.) - */ - public abstract boolean canPublishResource(String resourceUri, - RoleLevel userRole); - - /** - * If display of a predicate is restricted, the user's role must be at least - * as high as the restriction level. - */ - public abstract boolean canDisplayPredicate(Property predicate, - RoleLevel userRole); - - /** - * A predicate cannot be modified if its namespace is in the prohibited list - * (some exceptions are allowed). - * - * If modification of a predicate is restricted, the user's role must be at - * least as high as the restriction level. - */ - public abstract boolean canModifyPredicate(Property predicate, - RoleLevel userRole); - - /** - * If publishing of a predicate is restricted, the user's role must be at - * least as high as the restriction level. - */ - public abstract boolean canPublishPredicate(Property predicate, - RoleLevel userRole); - - /** - * The threshold values for this property may have changed. - */ - public abstract void updateProperty(PropertyRestrictionLevels levels); - - // ---------------------------------------------------------------------- - // The null implementation - // ---------------------------------------------------------------------- - - /** - * A placeholder for when the bean instance is not set. - */ - private static class PropertyRestrictionBeanNull extends - PropertyRestrictionBean { - @Override - public boolean canDisplayResource(String resourceUri, RoleLevel userRole) { - warn(); - return false; - } - - @Override - public boolean canModifyResource(String resourceUri, RoleLevel userRole) { - warn(); - return false; - } - - @Override - public boolean canPublishResource(String resourceUri, RoleLevel userRole) { - warn(); - return false; - } - - @Override - public boolean canDisplayPredicate(Property predicate, - RoleLevel userRole) { - warn(); - return false; - } - - @Override - public boolean canModifyPredicate(Property predicate, RoleLevel userRole) { - warn(); - return false; - } - - @Override - public boolean canPublishPredicate(Property predicate, - RoleLevel userRole) { - warn(); - return false; - } - - @Override - public void updateProperty(PropertyRestrictionLevels levels) { - warn(); - } - - private void warn() { - try { - throw new IllegalStateException(); - } catch (IllegalStateException e) { - log.warn("No PropertyRestrictionBean in place.", e); - } - } - } - - // ---------------------------------------------------------------------- - // Setup class - // ---------------------------------------------------------------------- - - /** - * Create the bean at startup and remove it at shutdown. - */ - public static class Setup implements ServletContextListener { - @Override - public void contextInitialized(ServletContextEvent sce) { - ServletContext ctx = sce.getServletContext(); - StartupStatus ss = StartupStatus.getBean(ctx); - - try { - instance = new PropertyRestrictionBeanImpl( - PROHIBITED_NAMESPACES, PERMITTED_EXCEPTIONS, - ModelAccess.on(ctx)); - } catch (Exception e) { - ss.fatal(this, - "could not set up PropertyRestrictionBean", e); - } - } - - @Override - public void contextDestroyed(ServletContextEvent sce) { - instance = NULL; - } - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionBeanImpl.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionBeanImpl.java deleted file mode 100644 index 7676396dcd..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionBeanImpl.java +++ /dev/null @@ -1,247 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.policy.bean; - -import static edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionLevels.Which.DISPLAY; -import static edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionLevels.Which.MODIFY; -import static edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionLevels.Which.PUBLISH; - -import java.util.Collection; -import java.util.Collections; -import java.util.Comparator; -import java.util.Map; -import java.util.Objects; -import java.util.Set; -import java.util.SortedSet; -import java.util.TreeSet; -import java.util.concurrent.ConcurrentHashMap; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.apache.jena.rdf.model.impl.Util; - -import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionLevels.Which; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; -import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; -import edu.cornell.mannlib.vitro.webapp.beans.FauxProperty; -import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; -import edu.cornell.mannlib.vitro.webapp.beans.Property; -import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey; -import edu.cornell.mannlib.vitro.webapp.dao.WebappDaoFactory; -import edu.cornell.mannlib.vitro.webapp.modelaccess.ContextModelAccess; - -/** - * On creation, populate a map of PropertyRestrictionLevels. - * - * When a change is detected, update the map accordingly. - * - * ------------------------------ - * - * How is authorization determined? - * - * Resources are easy. If they aren't in a prohibited namespace, or are an - * exception to the prohibition, they are accessible. - * - * Properties are harder. The prohibited namespace and exceptions still apply, - * but if we pass that test, then we check the threshold map. - * - * When a test is made, we look for thresholds in the map. First we look for the - * full key of domain-base-range, in case we are testing a faux property. Faux - * properties are recorded in the map with the full key. - * - * If we don't find the full key, then perhaps we are testing a faux property - * that has no settings, or perhaps we are testing an object property. We look - * for the partial key of null-base-null, which covers both of these cases, - * since object properties (and data properties) are recorded the map with a - * partial key. - * - * Similarly, if we find a null threshold value in the full key, we look back to - * the partial key for a threshold. - * - * If we find no non-null threshold value then the property is unrestricted for - * that feature. - * - * ----------------------------- - * - * It would perhaps be a silly optimization, but if we find a key with 3 null - * thresholds, we could remove it from the map without changing the behavior. - */ -public class PropertyRestrictionBeanImpl extends PropertyRestrictionBean { - private static final Log log = LogFactory - .getLog(PropertyRestrictionBeanImpl.class); - - private final Set prohibitedNamespaces; - private final Set permittedExceptions; - - private final Map thresholdMap = new ConcurrentHashMap<>(); - - public PropertyRestrictionBeanImpl(Collection prohibitedNamespaces, - Collection permittedExceptions, ContextModelAccess models) { - Objects.requireNonNull(prohibitedNamespaces, - "prohibitedNamespaces may not be null."); - this.prohibitedNamespaces = Collections.unmodifiableSet(new TreeSet<>( - prohibitedNamespaces)); - - Objects.requireNonNull(permittedExceptions, - "permittedExceptions may not be null."); - this.permittedExceptions = Collections.unmodifiableSet(new TreeSet<>( - permittedExceptions)); - - Objects.requireNonNull(models, "models may not be null."); - populateThresholdMap(models.getWebappDaoFactory()); - } - - private void populateThresholdMap(WebappDaoFactory wadf) { - for (ObjectProperty oProp : wadf.getObjectPropertyDao() - .getAllObjectProperties()) { - addObjectPropertyToMap(oProp); - for (FauxProperty fProp : wadf.getFauxPropertyDao() - .getFauxPropertiesForBaseUri(oProp.getURI())) { - addFauxPropertyToMap(fProp); - } - } - for (DataProperty dProp : wadf.getDataPropertyDao() - .getAllDataProperties()) { - addDataPropertyToMap(dProp); - } - } - - private void addObjectPropertyToMap(ObjectProperty oProp) { - FullPropertyKey key = new FullPropertyKey(oProp.getURI()); - PropertyRestrictionLevels levels = new PropertyRestrictionLevels(key, - oProp.getHiddenFromDisplayBelowRoleLevel(), - oProp.getProhibitedFromUpdateBelowRoleLevel(), - oProp.getHiddenFromPublishBelowRoleLevel()); - thresholdMap.put(key, levels); - } - - private void addFauxPropertyToMap(FauxProperty fProp) { - FullPropertyKey key = new FullPropertyKey(fProp.getDomainURI(), - fProp.getBaseURI(), fProp.getRangeURI()); - PropertyRestrictionLevels levels = new PropertyRestrictionLevels(key, - fProp.getHiddenFromDisplayBelowRoleLevel(), - fProp.getProhibitedFromUpdateBelowRoleLevel(), - fProp.getHiddenFromPublishBelowRoleLevel()); - thresholdMap.put(key, levels); - } - - private void addDataPropertyToMap(DataProperty dProp) { - FullPropertyKey key = new FullPropertyKey(dProp.getURI()); - PropertyRestrictionLevels levels = new PropertyRestrictionLevels(key, - dProp.getHiddenFromDisplayBelowRoleLevel(), - dProp.getProhibitedFromUpdateBelowRoleLevel(), - dProp.getHiddenFromPublishBelowRoleLevel()); - thresholdMap.put(key, levels); - } - - @Override - public boolean canDisplayResource(String resourceUri, RoleLevel userRole) { - return (resourceUri != null) && (userRole != null); - } - - @Override - public boolean canModifyResource(String resourceUri, RoleLevel userRole) { - if (resourceUri == null || userRole == null) { - return false; - } - return !prohibitedNamespaces.contains(namespace(resourceUri)) - || permittedExceptions.contains(resourceUri); - } - - @Override - public boolean canPublishResource(String resourceUri, RoleLevel userRole) { - return (resourceUri != null) && (userRole != null); - } - - @Override - public boolean canDisplayPredicate(Property predicate, RoleLevel userRole) { - if (predicate == null || predicate.getURI() == null) { - return false; - } - return isAuthorized(userRole, getThreshold(predicate, DISPLAY)); - } - - @Override - public boolean canModifyPredicate(Property predicate, RoleLevel userRole) { - if (predicate == null || predicate.getURI() == null) { - return false; - } - return isAuthorized(userRole, getPropertyModifyThreshold(predicate)); - } - - @Override - public boolean canPublishPredicate(Property predicate, RoleLevel userRole) { - if (predicate == null || predicate.getURI() == null) { - return false; - } - return isAuthorized(userRole, getThreshold(predicate, PUBLISH)); - } - - @Override - public void updateProperty(PropertyRestrictionLevels levels) { - thresholdMap.put(levels.getKey(), levels); - } - - private boolean isAuthorized(RoleLevel userRole, RoleLevel thresholdRole) { - if (userRole == null) { - return false; - } - if (thresholdRole == null) { - return true; - } - return userRole.compareTo(thresholdRole) >= 0; - } - - private RoleLevel getPropertyModifyThreshold(Property p) { - if (prohibitedNamespaces.contains(namespace(p.getURI())) - && !permittedExceptions.contains(p.getURI())) { - return RoleLevel.NOBODY; - } - return getThreshold(p, MODIFY); - } - - private RoleLevel getThreshold(Property p, Which which) { - RoleLevel qualifiedLevel = getThreshold(new FullPropertyKey(p), which); - if (qualifiedLevel != null) { - return qualifiedLevel; - } - - RoleLevel bareLevel = getThreshold(new FullPropertyKey(p.getURI()), - which); - return bareLevel; - } - - private RoleLevel getThreshold(FullPropertyKey key, Which which) { - PropertyRestrictionLevels levels = thresholdMap.get(key); - if (levels == null) { - return null; - } else { - return levels.getLevel(which); - } - } - - private String namespace(String uri) { - return uri.substring(0, Util.splitNamespaceXML(uri)); - } - - @Override - public String toString() { - SortedSet keys = new TreeSet<>( - new Comparator() { - @Override - public int compare(FullPropertyKey o1, FullPropertyKey o2) { - return o1.toString().compareTo(o2.toString()); - } - }); - keys.addAll(thresholdMap.keySet()); - - StringBuilder buffer = new StringBuilder(); - for (FullPropertyKey key : keys) { - buffer.append(key).append(" ").append(thresholdMap.get(key).getLevel(DISPLAY)).append(" ").append(thresholdMap.get(key).getLevel(MODIFY)).append(" ").append(thresholdMap.get(key).getLevel(PUBLISH)).append("\n"); - } - return buffer.toString(); - - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionLevels.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionLevels.java deleted file mode 100644 index 369c074705..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionLevels.java +++ /dev/null @@ -1,68 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.policy.bean; - -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; -import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey; - -/** - * The threshold levels for operations on a given property. - * - * This is based on the assumption that the FullPropertyKey is sufficient to - * distinguish all properties. An object property and a data property may not - * share the same key. A faux property must have a different key from any object - * property. - */ -public class PropertyRestrictionLevels { - private final FullPropertyKey key; - private final RoleLevel displayThreshold; - private final RoleLevel modifyThreshold; - private final RoleLevel publishThreshold; - - public enum Which { - DISPLAY, MODIFY, PUBLISH - } - - public PropertyRestrictionLevels(FullPropertyKey key, - RoleRestrictedProperty p) { - this(key, p.getHiddenFromDisplayBelowRoleLevel(), p - .getProhibitedFromUpdateBelowRoleLevel(), p - .getHiddenFromPublishBelowRoleLevel()); - } - - public PropertyRestrictionLevels(FullPropertyKey key, - RoleLevel displayThreshold, RoleLevel modifyThreshold, - RoleLevel publishThreshold) { - this.key = key; - this.displayThreshold = displayThreshold; - this.modifyThreshold = modifyThreshold; - this.publishThreshold = publishThreshold; - } - - public FullPropertyKey getKey() { - return key; - } - - public RoleLevel getLevel(Which which) { - if (which == null) { - return null; - } else { - switch (which) { - case DISPLAY: - return displayThreshold; - case MODIFY: - return modifyThreshold; - default: - return publishThreshold; - } - } - } - - @Override - public String toString() { - return "PropertyRestrictionLevels[key=" + key + ", display=" - + displayThreshold + ", modify=" + modifyThreshold - + ", publish=" + publishThreshold + "]"; - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionListener.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionListener.java index d632703fac..19862e2cd4 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionListener.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/PropertyRestrictionListener.java @@ -2,12 +2,13 @@ package edu.cornell.mannlib.vitro.webapp.auth.policy.bean; +import edu.cornell.mannlib.vitro.webapp.auth.policy.EntityPolicyController; +import edu.cornell.mannlib.vitro.webapp.beans.Property; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vedit.beans.EditProcessObject; import edu.cornell.mannlib.vedit.listener.ChangeListener; -import edu.cornell.mannlib.vitro.webapp.dao.PropertyDao.FullPropertyKey; /** * Add this ChangeListener to your EditProcessObject when modifying the @@ -15,20 +16,17 @@ * appropriate. */ public class PropertyRestrictionListener implements ChangeListener { - private static final Log log = LogFactory - .getLog(PropertyRestrictionListener.class); + private static final Log log = LogFactory.getLog(PropertyRestrictionListener.class); /** * If the deleted property had a non-null restriction, rebuild the bean. */ @Override public void doDeleted(Object oldObj, EditProcessObject epo) { - if (oldObj instanceof RoleRestrictedProperty) { - RoleRestrictedProperty p = (RoleRestrictedProperty) oldObj; - FullPropertyKey key = new FullPropertyKey(p); - updateLevels(new PropertyRestrictionLevels(key, p)); + if (oldObj instanceof Property) { + EntityPolicyController.deletedEntityEvent((Property)oldObj); } else { - log.warn("Not an instance of RoleRestrictedProperty: " + oldObj); + log.warn("Not an instance of Property: " + oldObj); } } @@ -37,12 +35,10 @@ public void doDeleted(Object oldObj, EditProcessObject epo) { */ @Override public void doInserted(Object newObj, EditProcessObject epo) { - if (newObj instanceof RoleRestrictedProperty) { - RoleRestrictedProperty p = (RoleRestrictedProperty) newObj; - FullPropertyKey key = new FullPropertyKey(p); - updateLevels(new PropertyRestrictionLevels(key, p)); + if (newObj instanceof Property) { + EntityPolicyController.insertedEntityEvent((Property)newObj); } else { - log.warn("Not an instance of RoleRestrictedProperty: " + newObj); + log.warn("Not an instance of Property: " + newObj); } } @@ -51,17 +47,12 @@ public void doInserted(Object newObj, EditProcessObject epo) { */ @Override public void doUpdated(Object oldObj, Object newObj, EditProcessObject epo) { - if (newObj instanceof RoleRestrictedProperty) { - RoleRestrictedProperty newP = (RoleRestrictedProperty) newObj; - FullPropertyKey key = new FullPropertyKey(newP); - updateLevels(new PropertyRestrictionLevels(key, newP)); + if (newObj instanceof Property) { + EntityPolicyController.updatedEntityEvent(oldObj, newObj); + } else { - log.warn("Not instances of RoleRestrictedProperty: " + oldObj + log.warn("Not instances of Property: " + oldObj + ", " + newObj); } } - - private void updateLevels(PropertyRestrictionLevels levels) { - PropertyRestrictionBean.getBean().updateProperty(levels); - } } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/RoleRestrictedProperty.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/RoleRestrictedProperty.java deleted file mode 100644 index 7219bbf4bd..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/bean/RoleRestrictedProperty.java +++ /dev/null @@ -1,23 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.policy.bean; - -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; - -/** - * A property or faux property whose usage can be restricted according to the - * user's role level. - */ -public interface RoleRestrictedProperty { - String getDomainVClassURI(); - - String getRangeVClassURI(); - - String getURI(); - - RoleLevel getHiddenFromDisplayBelowRoleLevel(); - - RoleLevel getProhibitedFromUpdateBelowRoleLevel(); - - RoleLevel getHiddenFromPublishBelowRoleLevel(); -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/ifaces/Authorization.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/ifaces/DecisionResult.java similarity index 89% rename from api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/ifaces/Authorization.java rename to api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/ifaces/DecisionResult.java index 367a5a2acb..b5eaae3875 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/ifaces/Authorization.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/ifaces/DecisionResult.java @@ -2,7 +2,7 @@ package edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces; -public enum Authorization { +public enum DecisionResult { AUTHORIZED, //explicitly authorized UNAUTHORIZED, //explicitly not authorized INCONCLUSIVE; diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/ifaces/PolicyIface.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/ifaces/Policy.java similarity index 55% rename from api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/ifaces/PolicyIface.java rename to api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/ifaces/Policy.java index 11a19a4ede..1a55dd048d 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/ifaces/PolicyIface.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/ifaces/Policy.java @@ -2,8 +2,7 @@ package edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; /** * Represents the process of mapping an identifier that represents a user or @@ -13,7 +12,14 @@ * @author bdc34 * */ -public interface PolicyIface { - public PolicyDecision isAuthorized(IdentifierBundle whoToAuth, RequestedAction whatToAuth); +public interface Policy { + public PolicyDecision decide(AuthorizationRequest ar); + public default String getUri() { + return ""; + } + + public default long getPriority() { + return 0; + } } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/ifaces/PolicyDecision.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/ifaces/PolicyDecision.java index c174776c1b..93ad098963 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/ifaces/PolicyDecision.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/ifaces/PolicyDecision.java @@ -8,7 +8,7 @@ * they are not authorized for some action. */ public interface PolicyDecision { - public Authorization getAuthorized(); + public DecisionResult getDecisionResult(); public String getStackTrace(); public String getMessage(); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java index 7a57232677..444c48b496 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/setup/CommonPolicyFamilySetup.java @@ -8,17 +8,12 @@ import edu.cornell.mannlib.vitro.webapp.auth.identifier.ActiveIdentifierBundleFactories; import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundleFactory; -import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasPermissionFactory; import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasPermissionSetFactory; import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasProfileOrIsBlacklistedFactory; import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.HasProxyEditingRightsFactory; import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.IsRootUserFactory; import edu.cornell.mannlib.vitro.webapp.auth.identifier.factory.IsUserFactory; -import edu.cornell.mannlib.vitro.webapp.auth.policy.DisplayRestrictedDataToSelfPolicy; -import edu.cornell.mannlib.vitro.webapp.auth.policy.PermissionsPolicy; -import edu.cornell.mannlib.vitro.webapp.auth.policy.SelfEditingPolicy; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface; +import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyLoader; import edu.cornell.mannlib.vitro.webapp.startup.StartupStatus; /** @@ -32,27 +27,19 @@ public void contextInitialized(ServletContextEvent sce) { StartupStatus ss = StartupStatus.getBean(ctx); try { - policy(ctx, new PermissionsPolicy()); - policy(ctx, new DisplayRestrictedDataToSelfPolicy(ctx)); - policy(ctx, new SelfEditingPolicy(ctx)); - - factory(ctx, new IsUserFactory(ctx)); - factory(ctx, new IsRootUserFactory(ctx)); - factory(ctx, new HasProfileOrIsBlacklistedFactory(ctx)); - factory(ctx, new HasPermissionSetFactory(ctx)); - factory(ctx, new HasPermissionFactory(ctx)); - factory(ctx, new HasProxyEditingRightsFactory(ctx)); + PolicyLoader.initialize(null); + factory(new IsUserFactory()); + factory(new IsRootUserFactory()); + factory(new HasProfileOrIsBlacklistedFactory()); + factory(new HasPermissionSetFactory()); + factory(new HasProxyEditingRightsFactory()); } catch (Exception e) { ss.fatal(this, "could not run CommonPolicyFamilySetup", e); } } - private void policy(ServletContext ctx, PolicyIface policy) { - ServletPolicyList.addPolicy(ctx, policy); - } - - private void factory(ServletContext ctx, IdentifierBundleFactory factory) { - ActiveIdentifierBundleFactories.addFactory(ctx, factory); + private void factory(IdentifierBundleFactory factory) { + ActiveIdentifierBundleFactories.addFactory(factory); } @Override diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/specialrelationships/AbstractRelationshipPolicy.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/specialrelationships/AbstractRelationshipPolicy.java deleted file mode 100644 index ddf88ed179..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/specialrelationships/AbstractRelationshipPolicy.java +++ /dev/null @@ -1,63 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.policy.specialrelationships; - -import javax.servlet.ServletContext; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import edu.cornell.mannlib.vitro.webapp.auth.policy.BasicPolicyDecision; -import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionBean; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; -import edu.cornell.mannlib.vitro.webapp.beans.Property; - -/** - * A collection of building-block methods so we can code a policy based on the - * relationship of the object being edited to the identity of the user doing the - * editing. - */ -public abstract class AbstractRelationshipPolicy implements PolicyIface { - private static final Log log = LogFactory - .getLog(AbstractRelationshipPolicy.class); - - protected final ServletContext ctx; - - public AbstractRelationshipPolicy(ServletContext ctx) { - this.ctx = ctx; - } - - protected boolean canModifyResource(String uri) { - return PropertyRestrictionBean.getBean().canModifyResource(uri, - RoleLevel.SELF); - } - - protected boolean canModifyPredicate(Property predicate) { - return PropertyRestrictionBean.getBean().canModifyPredicate(predicate, - RoleLevel.SELF); - } - - protected PolicyDecision cantModifyResource(String uri) { - return inconclusiveDecision("No access to admin resources; cannot modify " - + uri); - } - - protected PolicyDecision cantModifyPredicate(String uri) { - return inconclusiveDecision("No access to admin predicates; cannot modify " - + uri); - } - - protected PolicyDecision userNotAuthorizedToStatement() { - return inconclusiveDecision("User has no access to this statement."); - } - - /** An INCONCLUSIVE decision with a message like "PolicyClass: message". */ - protected PolicyDecision inconclusiveDecision(String message) { - return new BasicPolicyDecision(Authorization.INCONCLUSIVE, getClass() - .getSimpleName() + ": " + message); - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/specialrelationships/RelationshipChecker.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/specialrelationships/RelationshipChecker.java deleted file mode 100644 index 31625f912a..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/policy/specialrelationships/RelationshipChecker.java +++ /dev/null @@ -1,205 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.policy.specialrelationships; - -import java.util.ArrayList; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.apache.jena.ontology.OntModel; -import org.apache.jena.rdf.model.Property; -import org.apache.jena.rdf.model.RDFNode; -import org.apache.jena.rdf.model.Resource; -import org.apache.jena.rdf.model.Selector; -import org.apache.jena.rdf.model.SimpleSelector; -import org.apache.jena.rdf.model.StmtIterator; -import org.apache.jena.shared.Lock; - -import edu.cornell.mannlib.vitro.webapp.auth.policy.BasicPolicyDecision; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; -import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; - -/** - * Look for relationships within an OntModel. Types of resources, links between - * resources, and links between resources via a context node. - * - * Also provides some convenience methods for test lists of URIs and for - * creating PolicyDecisions. - */ -public class RelationshipChecker { - private static final Log log = LogFactory.getLog(RelationshipChecker.class); - - protected static final String NS_CORE = "http://vivoweb.org/ontology/core#"; - protected static final String NS_OBO = "http://purl.obolibrary.org/obo/"; - protected static final String URI_RELATES = NS_CORE + "relates"; - protected static final String URI_RELATED_BY = NS_CORE + "relatedBy"; - protected static final String URI_INHERES_IN = NS_OBO + "RO_0000052"; - protected static final String URI_REALIZES = NS_OBO + "BFO_0000055"; - - private final OntModel ontModel; - - public RelationshipChecker(OntModel ontModel) { - this.ontModel = ontModel; - } - - /** - * Are there any URIs that appear in both of these lists? - */ - public boolean anyUrisInCommon(List list1, List list2) { - List urisInCommon = new ArrayList(list1); - urisInCommon.retainAll(list2); - return !urisInCommon.isEmpty(); - } - - /** - * Is this resource a member of this type? That is, is there an statement of - * the form: {@code rdfs:type } - */ - public boolean isResourceOfType(String resourceUri, String typeUri) { - Selector selector = createSelector(resourceUri, - VitroVocabulary.RDF_TYPE, typeUri); - - StmtIterator stmts = null; - ontModel.enterCriticalSection(Lock.READ); - try { - stmts = ontModel.listStatements(selector); - if (stmts.hasNext()) { - log.debug("resource '" + resourceUri + "' is of type '" - + typeUri + "'"); - return true; - } else { - log.debug("resource '" + resourceUri + "' is not of type '" - + typeUri + "'"); - return false; - } - } finally { - if (stmts != null) { - stmts.close(); - } - ontModel.leaveCriticalSection(); - } - } - - /** - * Get a list of the object URIs that satisfy this statement: - * - * {@code } - * - * May return an empty list, but never returns null. - */ - public List getObjectsOfProperty(String resourceUri, - String propertyUri) { - List list = new ArrayList(); - - Selector selector = createSelector(resourceUri, propertyUri, null); - - StmtIterator stmts = null; - ontModel.enterCriticalSection(Lock.READ); - try { - stmts = ontModel.listStatements(selector); - while (stmts.hasNext()) { - list.add(stmts.next().getObject().toString()); - } - log.debug("Objects of property '" + propertyUri + "' on resource '" - + resourceUri + "': " + list); - return list; - } finally { - if (stmts != null) { - stmts.close(); - } - ontModel.leaveCriticalSection(); - } - } - - /** - * Get a list of the object URIs that satisfy these statements: - * - * {@code } - * - * {@code } - * - * May return an empty list, but never returns null. - */ - public List getObjectsOfLinkedProperty(String resourceUri, - String linkUri, String propertyUri) { - List list = new ArrayList(); - - Selector selector = createSelector(resourceUri, linkUri, null); - - StmtIterator stmts = null; - - ontModel.enterCriticalSection(Lock.READ); - try { - stmts = ontModel.listStatements(selector); - while (stmts.hasNext()) { - RDFNode contextNode = stmts.next().getObject(); - if (contextNode.isResource()) { - log.debug("found context node for '" + resourceUri + "': " - + contextNode); - list.addAll(getObjectsOfProperty(contextNode.asResource() - .getURI(), propertyUri)); - } - } - log.debug("Objects of linked properties '" + linkUri + "' ==> '" - + propertyUri + "' on '" + resourceUri + "': " + list); - return list; - } finally { - if (stmts != null) { - stmts.close(); - } - ontModel.leaveCriticalSection(); - } - } - - /** - * Get a list of URIs for object that link to the specified resource, by - * means of the specified properties, through a linking node of the - * specified type. - * - * So we're looking for object URIs that statisfy these statements: - * - * {@code } - * - * {@code rdfs:type } - * - * {@code } - */ - public List getObjectsThroughLinkingNode(String resourceUri, - String property1Uri, String linkNodeTypeUri, String property2Uri) { - List list = new ArrayList(); - - for (String linkNodeUri : getObjectsOfProperty(resourceUri, property1Uri)) { - if (isResourceOfType(linkNodeUri, linkNodeTypeUri)) { - list.addAll(getObjectsOfProperty(linkNodeUri, property2Uri)); - } - } - - return list; - } - - public Selector createSelector(String subjectUri, String predicateUri, - String objectUri) { - Resource subject = (subjectUri == null) ? null : ontModel - .getResource(subjectUri); - return createSelector(subject, predicateUri, objectUri); - } - - public Selector createSelector(Resource subject, String predicateUri, - String objectUri) { - Property predicate = (predicateUri == null) ? null : ontModel - .getProperty(predicateUri); - RDFNode object = (objectUri == null) ? null : ontModel - .getResource(objectUri); - return new SimpleSelector(subject, predicate, object); - } - - /** An AUTHORIZED decision with a message like "PolicyClass: message". */ - protected PolicyDecision authorizedDecision(String message) { - return new BasicPolicyDecision(Authorization.AUTHORIZED, getClass() - .getSimpleName() + ": " + message); - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/AllowedAuthorizationRequest.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/AllowedAuthorizationRequest.java new file mode 100644 index 0000000000..fdb99f9fc4 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/AllowedAuthorizationRequest.java @@ -0,0 +1,30 @@ +package edu.cornell.mannlib.vitro.webapp.auth.requestedAction; + +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessOperation; +import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject; +import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.DecisionResult; + +public class AllowedAuthorizationRequest extends AuthorizationRequest{ + + private DecisionResult decision; + + public AllowedAuthorizationRequest() { + decision = DecisionResult.AUTHORIZED; + } + + @Override + public DecisionResult getPredefinedDecision() { + return decision; + } + + @Override + public AccessObject getAccessObject() { + return null; + } + + @Override + public AccessOperation getAccessOperation() { + return null; + } + +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/AuthHelper.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/AuthHelper.java new file mode 100644 index 0000000000..cd23112a29 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/AuthHelper.java @@ -0,0 +1,61 @@ +package edu.cornell.mannlib.vitro.webapp.auth.requestedAction; + +import java.util.Arrays; +import java.util.List; + +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessOperation; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject; + +public class AuthHelper { + + static class OrAuthorizationRequest extends AuthorizationRequest { + private final AuthorizationRequest ar1; + private final AuthorizationRequest ar2; + + private OrAuthorizationRequest(AuthorizationRequest ar1, AuthorizationRequest ar2) { + this.ar1 = ar1; + this.ar2 = ar2; + } + @Override + public boolean isContainer() { + return true; + } + + public List getItems(){ + return Arrays.asList(ar1, ar2); + }; + + + @Override + public String toString() { + return "(" + ar1 + " || " + ar2 + ")"; + } + @Override + public AccessObject getAccessObject() { + // TODO Auto-generated method stub + return null; + } + @Override + public AccessOperation getAccessOperation() { + // TODO Auto-generated method stub + return null; + } + @Override + public IdentifierBundle getIds() { + // TODO Auto-generated method stub + return null; + } + } + + public static AuthorizationRequest logicOr(AuthorizationRequest fist, AuthorizationRequest second) { + if (fist == null) { + return second; + } else if (second == null) { + return fist; + } else { + return new AuthHelper.OrAuthorizationRequest(fist, second); + } + } + +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/AuthorizationRequest.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/AuthorizationRequest.java index 80e3f32cf5..4672bee4ad 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/AuthorizationRequest.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/AuthorizationRequest.java @@ -1,125 +1,61 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - package edu.cornell.mannlib.vitro.webapp.auth.requestedAction; -import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessOperation; import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface; +import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject; +import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.DecisionResult; -/** - * A base class for RequestedAction that permits boolean operations on them. - * - * A null request is ignored, so in "and" it is equivalent to true, while in - * "or" it is equivalent to false. - */ public abstract class AuthorizationRequest { - // ---------------------------------------------------------------------- - // Constants - // ---------------------------------------------------------------------- - - public static final AuthorizationRequest AUTHORIZED = new AuthorizationRequest() { - @Override - public boolean isAuthorized(IdentifierBundle ids, PolicyIface policy) { - return true; - } - }; - - public static final AuthorizationRequest UNAUTHORIZED = new AuthorizationRequest() { - @Override - public boolean isAuthorized(IdentifierBundle ids, PolicyIface policy) { - return false; - } - }; - - // ---------------------------------------------------------------------- - // Static convenience methods - // ---------------------------------------------------------------------- - - public static AuthorizationRequest andAll(AuthorizationRequest... ars) { - return andAll(Arrays.asList(ars)); - } - - public static AuthorizationRequest andAll( - Iterable ars) { - AuthorizationRequest result = AUTHORIZED; - for (AuthorizationRequest ar : ars) { - result = result.and(ar); - } - return result; - } - - // ---------------------------------------------------------------------- - // The abstract class - // ---------------------------------------------------------------------- - - public AuthorizationRequest and(AuthorizationRequest that) { - if (that == null) { - return this; - } else { - return new AndAuthorizationRequest(this, that); - } - } - - public AuthorizationRequest or(AuthorizationRequest that) { - if (that == null) { - return this; - } else { - return new OrAuthorizationRequest(this, that); - } - } - - public abstract boolean isAuthorized(IdentifierBundle ids, - PolicyIface policy); - - // ---------------------------------------------------------------------- - // Subclasses for boolean operations - // ---------------------------------------------------------------------- - - private static class AndAuthorizationRequest extends AuthorizationRequest { - private final AuthorizationRequest ar1; - private final AuthorizationRequest ar2; - - private AndAuthorizationRequest(AuthorizationRequest ar1, - AuthorizationRequest ar2) { - this.ar1 = ar1; - this.ar2 = ar2; - } - - @Override - public boolean isAuthorized(IdentifierBundle ids, PolicyIface policy) { - return ar1.isAuthorized(ids, policy) - && ar2.isAuthorized(ids, policy); - } - - @Override - public String toString() { - return "(" + ar1 + " && " + ar2 + ")"; - } - - } - - private static class OrAuthorizationRequest extends AuthorizationRequest { - private final AuthorizationRequest ar1; - private final AuthorizationRequest ar2; - - private OrAuthorizationRequest(AuthorizationRequest ar1, - AuthorizationRequest ar2) { - this.ar1 = ar1; - this.ar2 = ar2; - } - - @Override - public boolean isAuthorized(IdentifierBundle ids, PolicyIface policy) { - return ar1.isAuthorized(ids, policy) - || ar2.isAuthorized(ids, policy); - } - - @Override - public String toString() { - return "(" + ar1 + " || " + ar2 + ")"; - } - - } -} + public static final AuthorizationRequest UNAUTHORIZED = new ForbiddenAuthorizationRequest(); + public static final AuthorizationRequest AUTHORIZED = new AllowedAuthorizationRequest(); + + IdentifierBundle ids; + private List editorUris = Collections.emptyList(); + List roleUris = Collections.emptyList(); + + + public void setRoleUris(List roleUris) { + this.roleUris = roleUris; + } + + public boolean isContainer() { + return false; + } + + public DecisionResult getPredefinedDecision(){ + return DecisionResult.INCONCLUSIVE; + } + + public List getItems() { + return Collections.emptyList(); + } + + public abstract AccessObject getAccessObject(); + + public abstract AccessOperation getAccessOperation(); + + public IdentifierBundle getIds() { + return ids; + } + + public List getRoleUris() { + return roleUris; + } + + public void setIds(IdentifierBundle ids) { + this.ids = ids; + } + + public void setEditorUris(List list) { + editorUris = list; + } + + public List getEditorUris(){ + return editorUris; + }; + +} \ No newline at end of file diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ForbiddenAuthorizationRequest.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ForbiddenAuthorizationRequest.java new file mode 100644 index 0000000000..43222c3ff2 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ForbiddenAuthorizationRequest.java @@ -0,0 +1,36 @@ +package edu.cornell.mannlib.vitro.webapp.auth.requestedAction; + +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessOperation; +import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; +import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject; +import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.DecisionResult; + +public class ForbiddenAuthorizationRequest extends AuthorizationRequest { + + private DecisionResult predefinedDecision; + + public ForbiddenAuthorizationRequest() { + predefinedDecision = DecisionResult.UNAUTHORIZED; + } + + @Override + public DecisionResult getPredefinedDecision() { + return predefinedDecision; + } + + @Override + public AccessObject getAccessObject() { + return null; + } + + @Override + public AccessOperation getAccessOperation() { + return null; + } + + @Override + public IdentifierBundle getIds() { + // TODO Auto-generated method stub + return null; + } +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/RequestedAction.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/RequestedAction.java deleted file mode 100644 index e326674659..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/RequestedAction.java +++ /dev/null @@ -1,41 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction; - -import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.Authorization; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyDecision; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.PolicyIface; -import edu.cornell.mannlib.vitro.webapp.beans.Property; - -/* Represents a request to perform an action. */ -public abstract class RequestedAction extends AuthorizationRequest { - public static String ACTION_NAMESPACE = "java:"; - - public static String SOME_URI = "?SOME_URI"; - public static Property SOME_PREDICATE = new Property(SOME_URI); - public static String SOME_LITERAL = "?SOME_LITERAL"; - - /** - * In its most basic form, a RequestAction needs to have an identifier. - * Sometimes this will be enough. - */ - public String getURI() { - return ACTION_NAMESPACE + this.getClass().getName(); - } - - /** - * For authorization, just ask the Policy. INCONCLUSIVE is not good enough. - */ - @Override - public final boolean isAuthorized(IdentifierBundle ids, PolicyIface policy) { - PolicyDecision decision = policy.isAuthorized(ids, this); - return decision.getAuthorized() == Authorization.AUTHORIZED; - } - - @Override - public String toString() { - return this.getClass().getSimpleName(); - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/SimpleAuthorizationRequest.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/SimpleAuthorizationRequest.java new file mode 100644 index 0000000000..c7139f2cda --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/SimpleAuthorizationRequest.java @@ -0,0 +1,47 @@ +package edu.cornell.mannlib.vitro.webapp.auth.requestedAction; + +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessOperation; +import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject; +import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObjectImpl; +import edu.cornell.mannlib.vitro.webapp.auth.policy.ifaces.DecisionResult; + +public class SimpleAuthorizationRequest extends AuthorizationRequest { + + private AccessObject object; + + public AccessObject getObject() { + return object; + } + + public AccessOperation getOperation() { + return operation; + } + + private AccessOperation operation; + + public SimpleAuthorizationRequest(AccessObject object, AccessOperation operation) { + this.object = object; + this.operation = operation; + } + + public SimpleAuthorizationRequest(String namedAccessObject) { + this.object = new AccessObjectImpl(namedAccessObject); + this.operation = AccessOperation.EXECUTE; + } + + @Override + public DecisionResult getPredefinedDecision() { + return DecisionResult.INCONCLUSIVE; + } + + @Override + public AccessObject getAccessObject() { + return object; + } + + @Override + public AccessOperation getAccessOperation() { + return operation; + } + +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/SimpleRequestedAction.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/SimpleRequestedAction.java deleted file mode 100644 index 28ff5ba770..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/SimpleRequestedAction.java +++ /dev/null @@ -1,48 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction; - - -/** - * A RequestedAction that can be recognized by a SimplePermission. - */ -public class SimpleRequestedAction extends RequestedAction { - private final String uri; - - public SimpleRequestedAction(String uri) { - if (uri == null) { - throw new NullPointerException("uri may not be null."); - } - - this.uri = uri; - } - - @Override - public String getURI() { - return uri; - } - - @Override - public int hashCode() { - return uri.hashCode(); - } - - @Override - public boolean equals(Object o) { - if (o instanceof SimpleRequestedAction) { - SimpleRequestedAction that = (SimpleRequestedAction) o; - return equivalent(this.uri, that.uri); - } - return false; - } - - private boolean equivalent(Object o1, Object o2) { - return (o1 == null) ? (o2 == null) : o1.equals(o2); - } - - @Override - public String toString() { - return "SimpleRequestedAction['" + uri + "']"; - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/AddNewUser.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/AddNewUser.java deleted file mode 100644 index 0c57618a98..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/AddNewUser.java +++ /dev/null @@ -1,11 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.admin; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.AdminRequestedAction; - -/** Should we allow the user to create a user account? */ -public class AddNewUser extends RequestedAction implements AdminRequestedAction{ - // no members -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/LoadOntology.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/LoadOntology.java deleted file mode 100644 index ea7027a735..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/LoadOntology.java +++ /dev/null @@ -1,19 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.admin; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.AdminRequestedAction; - -/** Should we allow the user to load an ontology? */ -public class LoadOntology extends RequestedAction implements AdminRequestedAction{ - protected String ontologyUrl; - - public String getOntologyUrl() { - return ontologyUrl; - } - - public void setOntologyUrl(String ontologyUrl) { - this.ontologyUrl = ontologyUrl; - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/RebuildTextIndex.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/RebuildTextIndex.java deleted file mode 100644 index e0261e4504..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/RebuildTextIndex.java +++ /dev/null @@ -1,10 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.admin; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.AdminRequestedAction; - -public class RebuildTextIndex extends RequestedAction implements AdminRequestedAction{ - // no members -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/RemoveUser.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/RemoveUser.java deleted file mode 100644 index 28fd602ad0..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/RemoveUser.java +++ /dev/null @@ -1,19 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.admin; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.AdminRequestedAction; - -/** Should we allow the user to remove a user account */ -public class RemoveUser extends RequestedAction implements AdminRequestedAction{ - protected String userUri; - - public String getUserUri() { - return userUri; - } - - public void setUserUri(String userUri) { - this.userUri = userUri; - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/ServerStatus.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/ServerStatus.java deleted file mode 100644 index 8e2ff80ddd..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/ServerStatus.java +++ /dev/null @@ -1,11 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.admin; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.AdminRequestedAction; - -/** Should we allow the user to view information about the server status? */ -public class ServerStatus extends RequestedAction implements AdminRequestedAction { - // no members -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/UpdateTextIndex.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/UpdateTextIndex.java deleted file mode 100644 index 2331078236..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/UpdateTextIndex.java +++ /dev/null @@ -1,10 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.admin; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.AdminRequestedAction; - -public class UpdateTextIndex extends RequestedAction implements AdminRequestedAction{ - // no fields -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/UploadFile.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/UploadFile.java deleted file mode 100644 index 2327ecc4ff..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/admin/UploadFile.java +++ /dev/null @@ -1,18 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.admin; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.AdminRequestedAction; - -/** Should we allow the user to upload a file? */ -public class UploadFile extends RequestedAction implements AdminRequestedAction{ - protected String subjectUri; - protected String predicateUri; - - public UploadFile(String subjectUri, String predicateUri) { - super(); - this.subjectUri = subjectUri; - this.predicateUri = predicateUri; - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayDataProperty.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayDataProperty.java deleted file mode 100644 index a452d40fba..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayDataProperty.java +++ /dev/null @@ -1,24 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; - -/** Should we allow the user to see this DataProperty? */ -public class DisplayDataProperty extends RequestedAction { - private final DataProperty dataProperty; - - public DisplayDataProperty(DataProperty dataProperty) { - this.dataProperty = dataProperty; - } - - public DataProperty getDataProperty() { - return dataProperty; - } - - @Override - public String toString() { - return "DisplayDataProperty[" + dataProperty + "]"; - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayDataPropertyStatement.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayDataPropertyStatement.java deleted file mode 100644 index dfa25f1ab2..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayDataPropertyStatement.java +++ /dev/null @@ -1,29 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; - -/** Should we let the user see this DataPropertyStatement? */ -public class DisplayDataPropertyStatement extends RequestedAction { - private final DataPropertyStatement dataPropertyStatement; - - public DisplayDataPropertyStatement( - DataPropertyStatement dataPropertyStatement) { - this.dataPropertyStatement = dataPropertyStatement; - } - - public DataPropertyStatement getDataPropertyStatement() { - return dataPropertyStatement; - } - - @Override - public String toString() { - return "DisplayDataPropertyStatement[" - + dataPropertyStatement.getIndividualURI() + "==>" - + dataPropertyStatement.getDatapropURI() + "==>" - + dataPropertyStatement.getData() + "]"; - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayObjectProperty.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayObjectProperty.java deleted file mode 100644 index 19b5655641..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayObjectProperty.java +++ /dev/null @@ -1,25 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; - -/** Should we allow the user to see this ObjectProperty? */ -public class DisplayObjectProperty extends RequestedAction { - private final ObjectProperty objectProperty; - - public DisplayObjectProperty(ObjectProperty objectProperty) { - this.objectProperty = objectProperty; - } - - public ObjectProperty getObjectProperty() { - return objectProperty; - } - - @Override - public String toString() { - return "DisplayObjectProperty[" + objectProperty + "]"; - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayObjectPropertyStatement.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayObjectPropertyStatement.java deleted file mode 100644 index 1decb1196a..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/display/DisplayObjectPropertyStatement.java +++ /dev/null @@ -1,39 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.display; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; - -/** Should we let the user see this ObjectPropertyStatement? */ -public class DisplayObjectPropertyStatement extends RequestedAction { - private final String subjectUri; - private final ObjectProperty property; - private final String objectUri; - - public DisplayObjectPropertyStatement(String subjectUri, - ObjectProperty property, String objectUri) { - this.subjectUri = subjectUri; - this.property = property; - this.objectUri = objectUri; - } - - public String getSubjectUri() { - return subjectUri; - } - - public ObjectProperty getProperty() { - return property; - } - - public String getObjectUri() { - return objectUri; - } - - @Override - public String toString() { - return "DisplayObjectPropertyStatement[" + subjectUri + "==>" - + property.getURI() + "==>" + objectUri + "]"; - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/AdminRequestedAction.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/AdminRequestedAction.java deleted file mode 100644 index 25e73019c0..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/AdminRequestedAction.java +++ /dev/null @@ -1,8 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces; - -/** Denotes an action that is administrative, like adding users, etc. */ -public interface AdminRequestedAction { - /** marker interface */ -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/OntoRequestedAction.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/OntoRequestedAction.java deleted file mode 100644 index cc2382901b..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/OntoRequestedAction.java +++ /dev/null @@ -1,8 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces; - -/** Denotes an action that relates to manipulating the ontology. */ -public interface OntoRequestedAction { - /** marker interface */ -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/RequiresActions.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/RequiresActions.java deleted file mode 100644 index 7199b0f9f6..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/RequiresActions.java +++ /dev/null @@ -1,36 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; -import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; - -/** - * Interface to objects that provide a list of Actions that are - * required for the object to be used. - * - * This is intended to provide a way to setup DataGetter - * objects to be used with the FreemarkerHttpServlet.requiredActions() - * method. - * - * @author bdc34 - */ -public interface RequiresActions { - - /** - * Returns Actions that are required to be authorized for - * the object to be used. - * - * The code that is calling this method - * could use methods from PolicyHelper to check if the - * request has authorization to do these Actions. The code - * calling this method would then have the ability to - * deny the action if it is not authorized. - * - * @param vreq Vitro request - * @return Should not be null. Return Actions.AUTHORIZED - * if no authorization is required to do use the object. - */ - public AuthorizationRequest requiredActions(VitroRequest vreq) ; - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/SingleParameterAction.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/SingleParameterAction.java deleted file mode 100644 index f460e4feb9..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ifaces/SingleParameterAction.java +++ /dev/null @@ -1,25 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; - -/** - * A base class for actions that involve a single URI. - */ -public abstract class SingleParameterAction extends RequestedAction { - protected String subjectUri; - - public String getSubjectUri() { - return subjectUri; - } - - public void setSubjectUri(String subjectUri) { - this.subjectUri = subjectUri; - } - - @Override - public String toString(){ - return this.getClass().getName() + " <"+subjectUri+">"; - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ontology/CreateOwlClass.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ontology/CreateOwlClass.java deleted file mode 100644 index 36b7f732c4..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ontology/CreateOwlClass.java +++ /dev/null @@ -1,11 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ontology; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.OntoRequestedAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.SingleParameterAction; - -/** Should we allow the user to create a new class in the ontology? */ -public class CreateOwlClass extends SingleParameterAction implements OntoRequestedAction { - // no fields -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ontology/DefineDataProperty.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ontology/DefineDataProperty.java deleted file mode 100644 index f7667d5f91..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ontology/DefineDataProperty.java +++ /dev/null @@ -1,11 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ontology; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.OntoRequestedAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.SingleParameterAction; - -/** Should we allow the user to define a data property in the ontology? */ -public class DefineDataProperty extends SingleParameterAction implements OntoRequestedAction{ - // no fields -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ontology/DefineObjectProperty.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ontology/DefineObjectProperty.java deleted file mode 100644 index 63d1898837..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ontology/DefineObjectProperty.java +++ /dev/null @@ -1,11 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ontology; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.OntoRequestedAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.SingleParameterAction; - -/** Should we allow the user to define a new object property in the ontology? */ -public class DefineObjectProperty extends SingleParameterAction implements OntoRequestedAction{ - // no fields -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ontology/RemoveOwlClass.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ontology/RemoveOwlClass.java deleted file mode 100644 index 495116aaeb..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/ontology/RemoveOwlClass.java +++ /dev/null @@ -1,11 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ontology; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.OntoRequestedAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.ifaces.SingleParameterAction; - -/** Should we allow the user to remove a class from the ontology? */ -public class RemoveOwlClass extends SingleParameterAction implements OntoRequestedAction{ - // no fields -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractDataPropertyStatementAction.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractDataPropertyStatementAction.java deleted file mode 100644 index 2d9a17338b..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractDataPropertyStatementAction.java +++ /dev/null @@ -1,72 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt; - -import org.apache.jena.ontology.OntModel; - -import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; -import edu.cornell.mannlib.vitro.webapp.beans.Property; - -/** - * A base class for requested actions that involve adding, editing, or dropping - * data property statements from a model. - */ -public abstract class AbstractDataPropertyStatementAction extends - AbstractPropertyStatementAction { - private final String subjectUri; - private final String predicateUri; - private final Property predicate; - private final String dataValue; - - public AbstractDataPropertyStatementAction(OntModel ontModel, - String subjectUri, String predicateUri, String dataValue) { - super(ontModel); - this.subjectUri = subjectUri; - this.predicateUri = predicateUri; - Property dataProperty = new Property(); - dataProperty.setURI(predicateUri); - this.predicate = dataProperty; - this.dataValue = dataValue; - } - - public AbstractDataPropertyStatementAction(OntModel ontModel, - DataPropertyStatement dps) { - super(ontModel); - this.subjectUri = (dps.getIndividual() == null) ? dps - .getIndividualURI() : dps.getIndividual().getURI(); - this.predicateUri = dps.getDatapropURI(); - Property dataProperty = new Property(); - dataProperty.setURI(predicateUri); - this.predicate = dataProperty; - this.dataValue = dps.getData(); - } - - public String getSubjectUri() { - return subjectUri; - } - - @Override - public Property getPredicate() { - return predicate; - } - - @Override - public String getPredicateUri() { - return predicateUri; - } - - @Override - public String[] getResourceUris() { - return new String[] {subjectUri}; - } - - public String dataValue() { - return dataValue; - } - - @Override - public String toString() { - return getClass().getSimpleName() + ": <" + subjectUri + "> <" - + predicateUri + ">"; - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractObjectPropertyStatementAction.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractObjectPropertyStatementAction.java deleted file mode 100644 index 2e70191e10..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractObjectPropertyStatementAction.java +++ /dev/null @@ -1,55 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt; - -import org.apache.jena.ontology.OntModel; - -import edu.cornell.mannlib.vitro.webapp.beans.Property; - -/** - * A base class for requested actions that involve adding, editing, or deleting - * object property statements from a model. - */ -public abstract class AbstractObjectPropertyStatementAction extends - AbstractPropertyStatementAction { - private final String subjectUri; - private final Property predicate; - private final String objectUri; - - public AbstractObjectPropertyStatementAction(OntModel ontModel, - String subjectUri, Property predicate, String objectUri) { - super(ontModel); - this.subjectUri = subjectUri; - this.predicate = predicate; - this.objectUri = objectUri; - } - - public String getSubjectUri() { - return subjectUri; - } - - public String getObjectUri() { - return objectUri; - } - - @Override - public Property getPredicate() { - return predicate; - } - - @Override - public String getPredicateUri() { - return predicate.getURI(); - } - - @Override - public String[] getResourceUris() { - return new String[] { subjectUri, objectUri }; - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + ": <" + subjectUri + "> <" - + predicate.getURI() + "> <" + objectUri + ">"; - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractPropertyStatementAction.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractPropertyStatementAction.java deleted file mode 100644 index b0351a9d45..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AbstractPropertyStatementAction.java +++ /dev/null @@ -1,34 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt; - -import org.apache.jena.ontology.OntModel; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.beans.Property; - -/** - * A base class for requested actions that involve adding, editing, or deleting - * statements from a model. - */ -public abstract class AbstractPropertyStatementAction extends RequestedAction { - private final OntModel ontModel; - - public AbstractPropertyStatementAction(OntModel ontModel) { - this.ontModel = ontModel; - } - - public OntModel getOntModel() { - return ontModel; - } - - /** - * Get the URI of the Resources that are involved in this statement. Those - * are the Subject, and the Object if this is an ObjectProperty request. - */ - public abstract String[] getResourceUris(); - - public abstract Property getPredicate(); - - public abstract String getPredicateUri(); -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AddDataPropertyStatement.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AddDataPropertyStatement.java deleted file mode 100644 index 8b49ddc6b9..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AddDataPropertyStatement.java +++ /dev/null @@ -1,24 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt; - -import org.apache.jena.ontology.OntModel; - -import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; - -/** - * Should we allow the user to add this DataPropertyStatement to this model? - */ -public class AddDataPropertyStatement extends - AbstractDataPropertyStatementAction { - - public AddDataPropertyStatement(OntModel ontModel, String subjectUri, - String predicateUri, String dataValue) { - super(ontModel, subjectUri, predicateUri, dataValue); - } - - public AddDataPropertyStatement(OntModel ontModel, DataPropertyStatement dps) { - super(ontModel, dps); - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AddObjectPropertyStatement.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AddObjectPropertyStatement.java deleted file mode 100644 index cc3f53dc65..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/AddObjectPropertyStatement.java +++ /dev/null @@ -1,19 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt; - -import org.apache.jena.ontology.OntModel; - -import edu.cornell.mannlib.vitro.webapp.beans.Property; - -/** - * Should we allow the user to add this ObjectPropertyStatement to this model? - */ -public class AddObjectPropertyStatement extends - AbstractObjectPropertyStatementAction { - public AddObjectPropertyStatement(OntModel ontModel, String uriOfSub, - Property predicate, String uriOfObj) { - super(ontModel, uriOfSub, predicate, uriOfObj); - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/DropDataPropertyStatement.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/DropDataPropertyStatement.java deleted file mode 100644 index e801837dc1..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/DropDataPropertyStatement.java +++ /dev/null @@ -1,25 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt; - -import org.apache.jena.ontology.OntModel; - -import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; - -/** - * Should we allow the user to delete this DataPropertyStatement from this - * model? - */ -public class DropDataPropertyStatement extends - AbstractDataPropertyStatementAction { - - public DropDataPropertyStatement(OntModel ontModel, String subjectUri, - String predicateUri, String dataValue) { - super(ontModel, subjectUri, predicateUri, dataValue); - } - - public DropDataPropertyStatement(OntModel ontModel, - DataPropertyStatement dps) { - super(ontModel, dps); - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/DropObjectPropertyStatement.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/DropObjectPropertyStatement.java deleted file mode 100644 index 36549b8b8f..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/DropObjectPropertyStatement.java +++ /dev/null @@ -1,19 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt; - -import org.apache.jena.ontology.OntModel; - -import edu.cornell.mannlib.vitro.webapp.beans.Property; - -/** - * Should we allow the user to delete this ObjectPropertyStatement from this - * model? - */ -public class DropObjectPropertyStatement extends - AbstractObjectPropertyStatementAction { - public DropObjectPropertyStatement(OntModel ontModel, String sub, - Property pred, String obj) { - super(ontModel, sub, pred, obj); - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/EditDataPropertyStatement.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/EditDataPropertyStatement.java deleted file mode 100644 index 8fe4939d68..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/EditDataPropertyStatement.java +++ /dev/null @@ -1,23 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt; - -import org.apache.jena.ontology.OntModel; - -import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; - -/** - * Should we allow the user to edit this DataPropertyStatement in this model? - */ -public class EditDataPropertyStatement extends - AbstractDataPropertyStatementAction { - public EditDataPropertyStatement(OntModel ontModel, String subjectUri, - String predicateUri, String dataValue) { - super(ontModel, subjectUri, predicateUri, dataValue); - } - - public EditDataPropertyStatement(OntModel ontModel, - DataPropertyStatement dps) { - super(ontModel, dps); - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/EditObjectPropertyStatement.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/EditObjectPropertyStatement.java deleted file mode 100644 index d85bfe7842..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/propstmt/EditObjectPropertyStatement.java +++ /dev/null @@ -1,18 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt; - -import org.apache.jena.ontology.OntModel; - -import edu.cornell.mannlib.vitro.webapp.beans.Property; - -/** - * Should we allow the user to edit this ObjectPropertyStatement in this model? - */ -public class EditObjectPropertyStatement extends - AbstractObjectPropertyStatementAction { - public EditObjectPropertyStatement(OntModel ontModel, String subjectUri, - Property keywordPred, String objectUri) { - super(ontModel, subjectUri, keywordPred, objectUri); - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/publish/PublishDataProperty.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/publish/PublishDataProperty.java deleted file mode 100644 index e3d36a3e36..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/publish/PublishDataProperty.java +++ /dev/null @@ -1,24 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; - -/** Should we allow the user to publish this DataProperty in Linked Open Data? */ -public class PublishDataProperty extends RequestedAction { - private final DataProperty dataProperty; - - public PublishDataProperty(DataProperty dataProperty) { - this.dataProperty = dataProperty; - } - - public DataProperty getDataProperty() { - return dataProperty; - } - - @Override - public String toString() { - return "PublishDataProperty[" + dataProperty + "]"; - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/publish/PublishDataPropertyStatement.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/publish/PublishDataPropertyStatement.java deleted file mode 100644 index 03c019a80d..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/publish/PublishDataPropertyStatement.java +++ /dev/null @@ -1,26 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish; - -import org.apache.jena.ontology.OntModel; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractDataPropertyStatementAction; -import edu.cornell.mannlib.vitro.webapp.beans.DataPropertyStatement; - -/** - * Should we publish this DataPropertyStatement in a Linked Open Data request - * from the current user? - */ -public class PublishDataPropertyStatement extends - AbstractDataPropertyStatementAction { - public PublishDataPropertyStatement(OntModel ontModel, String subjectUri, - String predicateUri, String dataValue) { - super(ontModel, subjectUri, predicateUri, dataValue); - } - - public PublishDataPropertyStatement(OntModel ontModel, - DataPropertyStatement dps) { - super(ontModel, dps); - } - -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/publish/PublishObjectProperty.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/publish/PublishObjectProperty.java deleted file mode 100644 index 5120a04cf0..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/publish/PublishObjectProperty.java +++ /dev/null @@ -1,24 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; - -/** Should we allow the user to publish this ObjectProperty in Linked Open Data? */ -public class PublishObjectProperty extends RequestedAction { - private final ObjectProperty objectProperty; - - public PublishObjectProperty(ObjectProperty objectProperty) { - this.objectProperty = objectProperty; - } - - public ObjectProperty getObjectProperty() { - return objectProperty; - } - - @Override - public String toString() { - return "PublishObjectProperty[" + objectProperty.getLocalName() + "]"; - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/publish/PublishObjectPropertyStatement.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/publish/PublishObjectPropertyStatement.java deleted file mode 100644 index cf593284fa..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/publish/PublishObjectPropertyStatement.java +++ /dev/null @@ -1,40 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish; - -import static edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction.SOME_URI; - -import org.apache.jena.ontology.OntModel; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.AbstractObjectPropertyStatementAction; -import edu.cornell.mannlib.vitro.webapp.beans.Property; - -/** - * Should we publish this ObjectPropertyStatement in a Linked Open Data request - * from the current user? - */ - -public class PublishObjectPropertyStatement extends - AbstractObjectPropertyStatementAction { - public PublishObjectPropertyStatement(OntModel ontModel, String subjectUri, - Property keywordPred, String objectUri) { - super(ontModel, subjectUri, keywordPred, objectUri); - } - - /** - * We don't need to know range and domain because publishing never involves - * faux properties. - */ - public PublishObjectPropertyStatement(OntModel ontModel, - String subjectUri, - String predicateUri, String objectUri) { - this(ontModel, subjectUri, populateProperty(predicateUri), objectUri); - } - - private static Property populateProperty(String predicateUri) { - Property prop = new Property(predicateUri); - prop.setDomainVClassURI(SOME_URI); - prop.setRangeVClassURI(SOME_URI); - return prop; - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/resource/AbstractResourceAction.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/resource/AbstractResourceAction.java deleted file mode 100644 index a3354af9d6..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/resource/AbstractResourceAction.java +++ /dev/null @@ -1,33 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.resource; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; - -/** - * A common base class for resource-related actions. - */ -public abstract class AbstractResourceAction extends RequestedAction { - private final String typeUri; - private final String subjectUri; - - public AbstractResourceAction(String typeUri, String subjectUri) { - this.typeUri = typeUri; - this.subjectUri = subjectUri; - } - - // This should return a list of type URIs since an Indiviudal can be - // multiple types. - public String getTypeUri() { - return typeUri; - } - - public String getSubjectUri() { - return subjectUri; - } - - @Override - public String toString() { - return this.getClass().getSimpleName() + " <" + subjectUri + ">"; - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/resource/AddResource.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/resource/AddResource.java deleted file mode 100644 index 6f748975b6..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/resource/AddResource.java +++ /dev/null @@ -1,11 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.resource; - -/** Should we allow the user to add a Resource to the model? */ -public class AddResource extends AbstractResourceAction { - - public AddResource(String typeUri, String subjectUri) { - super(typeUri, subjectUri); - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/resource/DropResource.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/resource/DropResource.java deleted file mode 100644 index 7dadddc433..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/resource/DropResource.java +++ /dev/null @@ -1,11 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.resource; - -/** Should we allow the user to delete a Resource from the model? */ -public class DropResource extends AbstractResourceAction { - - public DropResource(String typeUri, String subjectUri) { - super(typeUri, subjectUri); - } -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/usepages/ManageRootAccount.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/usepages/ManageRootAccount.java deleted file mode 100644 index f2603b34aa..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/usepages/ManageRootAccount.java +++ /dev/null @@ -1,12 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages; - -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; - -/** - * Should we allow the user to edit or delete the root account? - */ -public class ManageRootAccount extends RequestedAction { - // no fields -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/usepages/UsePagesRequestedAction.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/usepages/UsePagesRequestedAction.java deleted file mode 100644 index 7910825dd7..0000000000 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/requestedAction/usepages/UsePagesRequestedAction.java +++ /dev/null @@ -1,8 +0,0 @@ -/* $This file is distributed under the terms of the license in LICENSE$ */ - -package edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages; - -/** Denotes a request to use a particular page or group of pages. */ -public interface UsePagesRequestedAction { - /** marker interface */ -} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/rules/AccessRule.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/rules/AccessRule.java new file mode 100644 index 0000000000..caa191cf8f --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/rules/AccessRule.java @@ -0,0 +1,156 @@ +/* $This file is distributed under the terms of the license in LICENSE$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.rules; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import org.apache.commons.lang3.builder.EqualsBuilder; +import org.apache.commons.lang3.builder.HashCodeBuilder; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import edu.cornell.mannlib.vitro.webapp.auth.attributes.Attribute; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AttributeType; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessOperation; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; + +public abstract class AccessRule { + private static final Log log = LogFactory.getLog(AccessRule.class); + private AccessOperation operation = AccessOperation.ANY; + private AccessObjectType objectType = AccessObjectType.ANY; + private Set> ruleSets = new HashSet<>(); + protected Map attributes = new HashMap<>(); + private boolean allowMatched = true; + private String objectUri = ""; + private String ruleUri; + + public boolean isAllowMatched() { + return allowMatched; + } + + public void setAllowMatched(boolean allowMatched) { + this.allowMatched = allowMatched; + } + + public String getRuleUri() { + return ruleUri; + } + + public void setRuleUri(String ruleUri) { + this.ruleUri = ruleUri; + } + + public void addToSet(Set set) { + ruleSets.add(set); + set.add(this); + } + + public void removeFromSets() { + for (Set set : ruleSets) { + set.remove(this); + } + ruleSets.clear(); + } + + public Map getAttributes() { + return attributes; + } + + public boolean match(AuthorizationRequest ar) { + for (Attribute a : attributes.values()) { + if (!a.match(ar)) { + return false; + } + } + return true; + } + + public String getObjectUri() { + return objectUri; + }; + + public void setObjectUri(String uri) { + this.objectUri = uri; + }; + + public void addAttribute(Attribute attr) { + if (attributes.containsKey(attr.getUri())) { + log.error(String.format("attribute %s already exists in the rule",attr.getUri())); + } + attributes.put(attr.getUri(), attr); + if (attr.getAttributeType().equals(AttributeType.OPERATION)) { + operation = AccessOperation.valueOf(attr.getValues().iterator().next()); + } + if (attr.getAttributeType().equals(AttributeType.OBJECT_TYPE)) { + objectType = AccessObjectType.valueOf(attr.getValues().iterator().next()); + } + if (attr.getAttributeType().equals(AttributeType.OBJECT_URI)) { + objectUri = attr.getValues().iterator().next(); + } + } + + public AccessOperation getOperation() { + return operation; + } + + public void setObjectType(AccessObjectType objectType) { + this.objectType = objectType; + } + + public AccessObjectType getObjectType() { + return objectType; + } + + @Override + public boolean equals(Object object) { + if (!(object instanceof AccessRule)) { + return false; + } + if (object == this) { + return true; + } + AccessRule compared = (AccessRule) object; + + return new EqualsBuilder() + .append(getRuleUri(), compared.getRuleUri()) + .append(getObjectUri(), compared.getObjectUri()) + .append(getAttributes(), compared.getAttributes()) + .append(getOperation(), compared.getOperation()) + .isEquals(); + } + + @Override + public int hashCode() { + return new HashCodeBuilder(15, 101) + .append(getAttributes()) + .append(getObjectUri()) + .append(getRuleUri()) + .append(getOperation()) + .toHashCode(); + } + + public Set getAttributeUris() { + return attributes.keySet(); + } + + public boolean containsAttributeUri(String uri) { + return attributes.containsKey(uri); + } + + protected Set getAttributesByType(AttributeType type){ + return getAttributes().values().stream().filter(a -> a.getAttributeType().equals(type)).collect(Collectors.toSet()); + } + + public long getAttributesCount() { + return attributes.size(); + } + + public Attribute getAttribute(String uri) { + return attributes.get(uri); + } +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/rules/AccessRuleFactory.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/rules/AccessRuleFactory.java new file mode 100644 index 0000000000..1893fe7bec --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/rules/AccessRuleFactory.java @@ -0,0 +1,30 @@ +package edu.cornell.mannlib.vitro.webapp.auth.rules; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.jena.query.QuerySolution; + +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AttributeFactory; + +public class AccessRuleFactory { + + private static final Log log = LogFactory.getLog(AccessRuleFactory.class); + + public static AccessRule createRule(QuerySolution qs) { + AccessRule ar = new SimpleAccessRule(); + String ruleUri = qs.getResource(AccessRuleStore.RULE).getURI(); + if (qs.contains("dataSetUri")) { + ruleUri += "." + qs.getResource("dataSetUri").getURI(); + } + + ar.setRuleUri(ruleUri); + ar.addAttribute(AttributeFactory.createAttribute(qs)); + if (qs.contains("decision_id") && qs.get("decision_id").isLiteral()) { + String decisionId = qs.getLiteral("decision_id").getString(); + if (decisionId.equals("DENY")) { + ar.setAllowMatched(false); + } + } + return ar; + } +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/rules/AccessRuleStore.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/rules/AccessRuleStore.java new file mode 100644 index 0000000000..23b801374f --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/rules/AccessRuleStore.java @@ -0,0 +1,694 @@ +package edu.cornell.mannlib.vitro.webapp.auth.rules; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringWriter; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.UUID; + +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.jena.query.ParameterizedSparqlString; +import org.apache.jena.query.Query; +import org.apache.jena.query.QueryExecution; +import org.apache.jena.query.QueryExecutionFactory; +import org.apache.jena.query.QueryFactory; +import org.apache.jena.query.QuerySolution; +import org.apache.jena.query.ResultSet; +import org.apache.jena.rdf.model.Model; +import org.apache.jena.rdf.model.ModelFactory; +import org.apache.jena.rdf.model.RDFNode; + +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessOperation; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.Attribute; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AttributeFactory; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AttributeType; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.TestType; +import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject; +import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObjectImpl; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.SimpleAuthorizationRequest; +import edu.cornell.mannlib.vitro.webapp.dao.jena.event.BulkUpdateEvent; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess; +import edu.cornell.mannlib.vitro.webapp.modelaccess.ModelNames; +import edu.cornell.mannlib.vitro.webapp.rdfservice.ChangeSet; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFService.ModelSerializationFormat; +import edu.cornell.mannlib.vitro.webapp.rdfservice.RDFServiceException; +import edu.cornell.mannlib.vitro.webapp.rdfservice.impl.jena.model.RDFServiceModel; + +public class AccessRuleStore { + private static final String NO_URI_VALUE = ""; + public static final String ATTR_VALUE = "value"; + public static final String LITERAL_VALUE = "lit_value"; + public static final String TYPE_ID = "typeId"; + public static final String TEST_ID = "testId"; + public static final String ID = "id"; + public static final String URI = "uri"; + public static final String OBJECT_TYPE_ID = "objectTypeId"; + public static final String OBJECT_URI = "objectUri"; + public static final String OPERATION_ID = "operationId"; + public static final String ATTRIBUTE = "attribute"; + public static final String RULE = "rule"; + + private static final String RULES_QUERY = + "prefix rdfs: \n" + + "prefix owl: \n" + + "prefix rdf: \n" + + "prefix xsd: \n" + + "prefix auth: \n" + + "prefix ai: \n" + + "prefix ao: \n" + + "SELECT ?" + RULE + " ?" + ATTRIBUTE + " ?" + TEST_ID + " ?" + TYPE_ID + " ?" + ATTR_VALUE + " ?" + LITERAL_VALUE + " \n" + + "WHERE {\n" + + "?" + RULE + " rdf:type ao:Rule .\n" + + "?" + RULE + " ao:attribute ?" + ATTRIBUTE + " .\n" + + "?" + ATTRIBUTE + " ao:test ?test .\n" + + "?test ao:id ?" + TEST_ID + " .\n" + + "?" + ATTRIBUTE + " ao:type ?type .\n" + + "?type ao:id ?" + TYPE_ID + " .\n" + + "?" + ATTRIBUTE + " ao:value ?" + ATTR_VALUE + " .\n" + + "OPTIONAL {?" + ATTR_VALUE + " ao:id ?" + LITERAL_VALUE + " . }\n" + + "} ORDER BY ?rule ?attribute"; + + private static final String RULE_QUERY = + "prefix rdfs: \n" + + "prefix owl: \n" + + "prefix rdf: \n" + + "prefix xsd: \n" + + "prefix auth: \n" + + "prefix ai: \n" + + "prefix ao: \n" + + "SELECT ?" + RULE + " ?" + ATTRIBUTE + " ?" + TEST_ID + " ?" + TYPE_ID + " ?" + ATTR_VALUE + " ?" + LITERAL_VALUE + " \n" + + "WHERE {\n" + + "?" + RULE + " rdf:type ao:Rule .\n" + + "?" + RULE + " ao:attribute ?" + ATTRIBUTE + " .\n" + + "?" + ATTRIBUTE + " ao:test ?test .\n" + + "?test ao:id ?" + TEST_ID + " .\n" + + "?" + ATTRIBUTE + " ao:type ?type .\n" + + "?type ao:id ?" + TYPE_ID + " .\n" + + "?" + ATTRIBUTE + " ao:value ?" + ATTR_VALUE + " .\n" + + "OPTIONAL {?" + ATTR_VALUE + " ao:id ?" + LITERAL_VALUE + " . }\n" + + "FILTER (?" + RULE + " = IRI(?rule_filter) )\n" + + "} ORDER BY ?rule ?attribute"; + + private static final String DELETE_QUERY = + "prefix rdfs: \n" + + "prefix owl: \n" + + "prefix rdf: \n" + + "prefix xsd: \n" + + "prefix auth: \n" + + "prefix ai: \n" + + "prefix ao: \n" + + "CONSTRUCT { \n" + + " ?" + RULE + " rdf:type ao:Rule .\n" + + " ?" + RULE + " ao:attribute ?" + ATTRIBUTE + " .\n" + + " ?" + ATTRIBUTE + " rdf:type ?rdfType . \n" + + " ?" + ATTRIBUTE + " ao:test ?test .\n" + + " ?" + ATTRIBUTE + " ao:type ?type .\n" + + " ?" + ATTRIBUTE + " ao:value ?" + ATTR_VALUE + " .\n" + + " ?" + ATTR_VALUE + " ao:id ?" + LITERAL_VALUE + " . \n" + + "}" + + "WHERE {\n" + + " ?" + RULE + " rdf:type ao:Rule .\n" + + " ?" + RULE + " ao:attribute ?" + ATTRIBUTE + " .\n" + + " OPTIONAL {\n" + + " FILTER NOT EXISTS {" + + " ?rule2 ao:attribute ?" + ATTRIBUTE + " .\n" + + " FILTER (?" + RULE + " != ?rule2)" + + " }" + + " ?" + ATTRIBUTE + " rdf:type ?rdfType . \n" + + " ?" + ATTRIBUTE + " ao:test ?test . \n" + + " ?" + ATTRIBUTE + " ao:type ?type . \n" + + " ?" + ATTRIBUTE + " ao:value ?" + ATTR_VALUE + " .\n" + + " }" + + "}"; + + private static final String getAttributeUriQuery(boolean hasLiteralValue) { + return + "prefix rdfs: \n" + + "prefix owl: \n" + + "prefix rdf: \n" + + "prefix xsd: \n" + + "prefix auth: \n" + + "prefix ai: \n" + + "prefix ao: \n" + + "SELECT ?" + ATTRIBUTE + " \n" + + "WHERE {\n" + + "?" + ATTRIBUTE + " rdf:type ao:Attribute .\n" + + "?" + ATTRIBUTE + " ao:test ?test .\n" + + "?test ao:id ?" + TEST_ID + " .\n" + + "?" + ATTRIBUTE + " ao:type ?type .\n" + + "?type ao:id ?" + TYPE_ID + " .\n" + + "?" + ATTRIBUTE + " ao:value ?" + ATTR_VALUE + " .\n" + + (hasLiteralValue ? "?" + ATTR_VALUE + " ao:id ?" + LITERAL_VALUE + " . \n" : NO_URI_VALUE) + + "}"; + } + + private static final String URI_BY_ID_QUERY = NO_URI_VALUE + + "prefix ao: \n" + + "SELECT ?" + URI + " \n" + + "WHERE {\n" + + "?" + URI + " ao:id ?" + ID + " .\n" + + "}"; + + private static final Log log = LogFactory.getLog(AccessRuleStore.class); + + + private static AccessRuleStore INSTANCE; + + public static AccessRuleStore getInstance() { + return INSTANCE; + } + + private Set allRules = Collections.synchronizedSet(new HashSet<>()); + private Map> ruleSetsByOperation; + private Map> ruleSetsByObjectType; + private Map> ruleSetsByObjectUri; + + private Model userAccountsModel; + private Model getUserAccountsModel() { + return userAccountsModel; + } + + private RDFService rdfService; + + + private AccessRuleStore(Model model){ + if (model != null) { + this.userAccountsModel = model; + } else { + this.userAccountsModel = ModelAccess.getInstance().getOntModelSelector().getUserAccountsModel(); + //this.rdfService = ModelAccess.getInstance().getRDFService(WhichService.CONFIGURATION); + } + this.rdfService = new RDFServiceModel(userAccountsModel); + initilizeRuleSetsByOperation(); + initilizeRuleSetsByObjectType(); + initilizeRuleSetsByObjectUri(); + loadRules(); + } + + private void initilizeRuleSetsByObjectUri() { + ruleSetsByObjectUri = Collections.synchronizedMap(new HashMap<>()); + Set set = Collections.synchronizedSet(new HashSet<>()); + ruleSetsByObjectUri.put(NO_URI_VALUE, set); + } + + private void initilizeRuleSetsByObjectType() { + ruleSetsByObjectType = Collections.synchronizedMap(new HashMap<>()); + for (AccessObjectType aot : AccessObjectType.values()) { + Set set = Collections.synchronizedSet(new HashSet<>()); + ruleSetsByObjectType.put(aot, set); + } + } + + private void initilizeRuleSetsByOperation() { + ruleSetsByOperation = Collections.synchronizedMap(new HashMap<>()); + for (AccessOperation ao : AccessOperation.values()) { + Set set = Collections.synchronizedSet(new HashSet<>()); + ruleSetsByOperation.put(ao, set); + } + } + + public static void initialize(Model model) { + INSTANCE = new AccessRuleStore(model); + } + + private void loadRules() { + loadRulesFromModel(RULES_QUERY); + } + + private void loadRule(String uri) { + ParameterizedSparqlString pss = new ParameterizedSparqlString(RULE_QUERY); + pss.setLiteral("rule_filter", uri); + loadRulesFromModel(pss.toString()); + } + + private void loadRulesFromModel(String sparqlQuery) { + debug("SPARQL Query to get rule from the model:\n %s", sparqlQuery); + Query query = QueryFactory.create(sparqlQuery); + QueryExecution qexec = QueryExecutionFactory.create(query, getUserAccountsModel()); + try { + ResultSet rs = qexec.execSelect(); + AccessRule rule = null; + while (rs.hasNext()) { + QuerySolution qs = rs.next(); + if (isInvalidRulesData(qs)) { + return; + } + if (isRuleContinues(rule, qs)){ + populateRule(rule, qs); + } else { + if (rule != null) { + addRule(rule); + } + rule = AccessRuleFactory.createRule(qs); + } + } + if (rule != null) { + addRule(rule); + } { + debug("Rule wasn't loaded from the user accounts model."); + } + } catch (Exception e) { + log.error(e, e); + } finally { + qexec.close(); + } + } + + private String getAttributeUri(String testId, String typeId, String value, boolean valueIsLiteral) throws Exception { + String uri = getAttributeUriFromModel(testId, typeId, value, valueIsLiteral); + if (StringUtils.isBlank(uri)) { + uri = createNewAttribute(testId, typeId, value); + } + return uri; + } + + private String createNewAttribute(String testId, String typeId, String value) throws Exception { + final String attributeUri = generateAttributeUri(testId, typeId); + String ttl = NO_URI_VALUE + + "@prefix rdf: .\n" + + "@prefix ai: .\n" + + "@prefix ao: .\n" + + "<" + attributeUri + "> rdf:type ao:Attribute . \n" + + "<" + attributeUri + "> ao:test <" + getUriById(testId) + "> .\n" + + "<" + attributeUri + "> ao:type <" + getUriById(typeId) + "> .\n" + + NO_URI_VALUE; + if (AttributeType.OBJECT_URI.toString().equals(typeId) || + AttributeType.SUBJECT_ROLE_URI.toString().equals(typeId)) { + ttl += "<" + attributeUri + "> ao:value <" + value + "> . \n"; + } else { + System.out.println(typeId); + ttl += "<" + attributeUri + "> ao:value <" + getUriById(value) + "> . \n"; + } + try { + Model attributeData = ModelFactory.createDefaultModel(); + attributeData.read(IOUtils.toInputStream(ttl, "UTF-8"), null, "TTL"); + updateUserAccountsModel(attributeData, false); + } catch (IOException e) { + log.error(e, e); + } + return attributeUri; + } + + private String getUriById(String id) throws Exception { + ParameterizedSparqlString pss = new ParameterizedSparqlString(URI_BY_ID_QUERY); + pss.setLiteral(ID, id); + Query query = QueryFactory.create(pss.toString()); + QueryExecution qexec = QueryExecutionFactory.create(query, getUserAccountsModel()); + try { + ResultSet rs = qexec.execSelect(); + while (rs.hasNext()) { + QuerySolution qs = rs.next(); + RDFNode uri = qs.get(URI); + if (uri.isResource()) { + return uri.asResource().toString(); + } + } + } catch (Exception e) { + log.error(e, e); + } finally { + qexec.close(); + } + throw new Exception(String.format("Uri by id '%s' not found.", id )); + } + + private String generateUUID() { + return UUID.randomUUID().toString(); + } + + protected String getAttributeUriFromModel(String testId, String typeId, String value, boolean valueIsLiteral) { + ParameterizedSparqlString pss = new ParameterizedSparqlString(getAttributeUriQuery(valueIsLiteral)); + if (testId != null) { + pss.setLiteral(TEST_ID,testId); + } + if (typeId != null) { + pss.setLiteral(TYPE_ID, typeId); + } + if (value != null) { + if (valueIsLiteral) { + pss.setLiteral(LITERAL_VALUE, value); + } else { + pss.setIri(ATTR_VALUE, value); + } + } + Query query = QueryFactory.create(pss.toString()); + QueryExecution qexec = QueryExecutionFactory.create(query, getUserAccountsModel()); + try { + ResultSet rs = qexec.execSelect(); + while (rs.hasNext()) { + QuerySolution qs = rs.next(); + RDFNode uri = qs.get(ATTRIBUTE); + if (uri.isResource()) { + return uri.asResource().toString(); + } + } + } catch (Exception e) { + log.error(e, e); + } finally { + qexec.close(); + } + return NO_URI_VALUE; + } + + private void removeRuleFromModel(String ruleUri) { + ParameterizedSparqlString pss = new ParameterizedSparqlString(DELETE_QUERY); + pss.setIri(RULE, ruleUri); + Query query = QueryFactory.create(pss.toString()); + QueryExecution qexec = QueryExecutionFactory.create(query, getUserAccountsModel()); + Model ruleData = null; + try { + ruleData = qexec.execConstruct(); + } catch (Exception e) { + log.error(e, e); + } finally { + qexec.close(); + } + if (ruleData != null) { + updateUserAccountsModel(ruleData, true); + } + } + + private void updateUserAccountsModel(Model ruleData, boolean isRemove) { + try { + ChangeSet changeSet = makeChangeSet(); + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ruleData.write(baos, "TTL"); + InputStream in = new ByteArrayInputStream(baos.toByteArray()); + debug(modelToString(ruleData, isRemove)); + if (isRemove) { + changeSet.addRemoval(in, ModelSerializationFormat.N3, ModelNames.USER_ACCOUNTS); + } else { + changeSet.addAddition(in, ModelSerializationFormat.N3, ModelNames.USER_ACCOUNTS); + } + rdfService.changeSetUpdate(changeSet); + } catch (RDFServiceException e) { + String message = modelToString(ruleData, isRemove); + log.error(message); + log.error(e,e); + } + } + + private String modelToString(Model ruleData, boolean isRemove) { + StringWriter sw = new StringWriter(); + ruleData.write(sw, "TTL"); + String message = (isRemove ? "Removing from" : "Adding to") + " user accounts model \n" + sw.toString(); + return message; + } + + private void addRule(AccessRule rule) { + rule.addToSet(allRules); + addRuleToOperationSets(rule); + addRuleToObjectTypeSets(rule); + addRuleToObjectUriSets(rule); + debug("Added rule %s with %s attributes to store sets ", rule.getRuleUri(), rule.attributes.size()); + } + + private synchronized void addRuleToObjectUriSets(AccessRule rule) { + String uri = rule.getObjectUri(); + Set set; + if (ruleSetsByObjectUri.containsKey(uri)) { + set = ruleSetsByObjectUri.get(uri); + } else { + set = Collections.synchronizedSet(new HashSet<>()); + ruleSetsByObjectUri.put(uri, set); + } + rule.addToSet(set); + } + + private void addRuleToObjectTypeSets(AccessRule rule) { + AccessObjectType aot = rule.getObjectType(); + Set set = ruleSetsByObjectType.get(aot); + rule.addToSet(set); + } + + private void addRuleToOperationSets(AccessRule rule) { + AccessOperation operation = rule.getOperation(); + Set set = ruleSetsByOperation.get(operation); + rule.addToSet(set); + } + + private static void populateRule(AccessRule ar, QuerySolution qs) { + if (ar == null) { + return; + } + String attributeUri = qs.getResource(ATTRIBUTE).getURI(); + if (ar.getAttributeUris().contains(attributeUri)) { + log.error("Attribute has already been processed. Shouldn't be here."); + return; + } + try { + ar.addAttribute(AttributeFactory.createAttribute(qs)); + } catch (Exception e) { + log.error(e, e); + } + } + + private static boolean isRuleContinues(AccessRule rule, QuerySolution qs) { + if (rule == null) { + return false; + } + return rule.getRuleUri().equals(qs.getResource(RULE).getURI()); + } + + private static boolean isInvalidRulesData(QuerySolution qs) { + if (!qs.contains(RULE) || !qs.get(RULE).isResource()) { + log.error("Rules data doesn't contain rule resource"); + return true; + } + if (!qs.contains(ATTRIBUTE) || !qs.get(ATTRIBUTE).isResource()) { + log.error("Rules data doesn't contain attribute resource"); + return true; + } + return false; + } + + public Set getFilteredRules(AuthorizationRequest ar) { + Set> ruleSets = new HashSet<>(); + getFilteredByOperation(ar.getAccessOperation(), ruleSets); + AccessObject accessObject = ar.getAccessObject(); + if (accessObject != null) { + getFilteredByObjectType(accessObject.getType(), ruleSets); + getFilteredByObjectUri(accessObject.getUri(), ruleSets); + } + return getIntersection(ruleSets); + } + + + private Set getGrantedRoleRulesForEntityUri(String entityURI, AccessOperation operation) { + Set> ruleSets = new HashSet<>(); + Set filteredByObjectUri = ruleSetsByObjectUri.get(entityURI); + if (filteredByObjectUri == null) { + filteredByObjectUri = new HashSet<>(); + } + filteredByObjectUri.addAll(ruleSetsByObjectUri.get(NO_URI_VALUE)); + ruleSets.add(filteredByObjectUri); + + Set filteredByOperation = ruleSetsByOperation.get(operation); + if (filteredByOperation == null) { + filteredByOperation = new HashSet<>(); + } + filteredByObjectUri.addAll(ruleSetsByOperation.get(AccessOperation.ANY)); + ruleSets.add(filteredByOperation); + + Set ruleset = getIntersection(ruleSets); + return ruleset; + } + + private void getFilteredByObjectUri(String uri, Set> ruleSets) { + if (uri == null) { + return; + } + Set filteredByObjectUri = ruleSetsByObjectUri.get(uri); + if (filteredByObjectUri != null) { + ruleSets.add(filteredByObjectUri); + } + } + + private void getFilteredByObjectType(AccessObjectType aot, Set> ruleSets) { + if (aot == AccessObjectType.ANY) { + return; + } + Set filteredByObjectType = ruleSetsByObjectType.get(aot); + if (filteredByObjectType != null) { + ruleSets.add(filteredByObjectType); + } + } + + private void getFilteredByOperation(AccessOperation aop, Set> ruleSets) { + if (aop == null) { + log.error("Access operation is null in request " + aop); + return; + } + Set filteredByOperation = ruleSetsByOperation.get(aop); + if (filteredByOperation != null) { + ruleSets.add(filteredByOperation); + } + } + + private Set getIntersection(Set> ruleSets) { + if (ruleSets.isEmpty()) { + return Collections.emptySet(); + } + Set intersection = new HashSet<>(findMinimalSet(ruleSets)); + if (intersection.isEmpty()) { + return intersection; + } + for (Set set : ruleSets) { + intersection.retainAll(set); + if (intersection.isEmpty()) { + return intersection; + } + } + return intersection; + } + + private Set findMinimalSet(Set> ruleSets) { + Set min = ruleSets.iterator().next(); + for (Set set : ruleSets) { + if (set.size() < min.size()) { + min = set; + } + } + return min; + } + + public void updateEntityRules(String entityUri, AccessObjectType aot, AccessOperation operation, Set newRoleUris) { + debug("Update entity rules uri: %s object type %s operation %s roleUris %s", entityUri, aot, operation, newRoleUris); + Set currentRoleUris = new HashSet<>(getGrantedRoleUris(entityUri, operation)); + //remove already existing roles, now list contains roles to allow access. + Set roleUrisToCreate = new HashSet(newRoleUris); + roleUrisToCreate.removeAll(currentRoleUris); + debug("Going to create rules for objectUri: %s objectType: %s operation %s roles %s", entityUri, aot, operation, roleUrisToCreate); + for (String roleUri : roleUrisToCreate) { + createEntityRule(entityUri, aot, operation, roleUri); + } + Set rolesUrisToRemove = new HashSet(currentRoleUris); + rolesUrisToRemove.removeAll(newRoleUris); + debug("Going to remove rules for objectUri: %s objectType: %s operation %s roles %s", entityUri, aot, operation, rolesUrisToRemove); + for (String roleUri : rolesUrisToRemove) { + removeEntityRule(entityUri, aot, operation, roleUri); + } + } + + protected void removeEntityRule(String entityUri, AccessObjectType aot, AccessOperation operation, String roleUri) { + AccessObjectImpl ao = new AccessObjectImpl(entityUri, aot); + AuthorizationRequest ar = new SimpleAuthorizationRequest(ao, operation); + ar.setRoleUris(Collections.singletonList(roleUri)); + Set rules = getFilteredRules(ar); + for (AccessRule rule : rules) { + //Check number of attributes to avoid removing custom rules + if (rule.match(ar) && rule.getAttributesCount() == 4) { + rule.removeFromSets(); + removeRuleFromModel(rule.getRuleUri()); + debug("Removed rule for objectUri: %s objectType: %s operation %s role %s", entityUri, aot, operation, roleUri); + } + + } + } + + protected void createEntityRule(String objectUri, AccessObjectType aot, AccessOperation operation, String roleUri) { + //create 4 attribute uris or get uris + String equals = TestType.EQUALS.toString(); + String ruleUri = generateRuleUri(); + try { + String subjectRoleAtt = getAttributeUri(equals, AttributeType.SUBJECT_ROLE_URI.toString(), roleUri, false); + String operationAtt = getAttributeUri(equals, AttributeType.OPERATION.toString(), operation.toString(), true); + String objectUriAtt = getAttributeUri(equals, AttributeType.OBJECT_URI.toString(), objectUri, true); + String objectTypeAtt = getAttributeUri(equals, AttributeType.OBJECT_TYPE.toString(), aot.toString(), true); + String ttl = generateEntityRuleData(ruleUri, subjectRoleAtt, operationAtt, objectUriAtt, objectTypeAtt); + debug("Going to load new rule for objectUri: %s objectType: %s operation %s role. TTL: %s \n %s", objectUri, aot, operation, roleUri, ttl); + Model ruleData = ModelFactory.createDefaultModel(); + ruleData.read(IOUtils.toInputStream(ttl, "UTF-8"), null, "TTL"); + updateUserAccountsModel(ruleData, false); + loadRule(ruleUri); + } catch (Exception e) { + log.error(e, e); + } + } + + private String generateRuleUri() { + return "https://vivoweb.org/ontology/vitro-application/auth/individual/rule/" + generateUUID(); + } + + private String generateAttributeUri(String testId, String typeId) { + return "https://vivoweb.org/ontology/vitro-application/auth/individual/attribute/"+ typeId + "/" + testId + "/" + generateUUID(); + } + + private String generateEntityRuleData(String ruleUri, String subjectRoleAttribute, String operationAttribute, + String objectUriAttribute, String objectTypeAttribute) { + String ttl = NO_URI_VALUE + + "@prefix rdf: .\n" + + "@prefix ai: .\n" + + "@prefix ao: .\n" + + "<" + ruleUri + "> rdf:type ao:Rule . \n" + + "<" + ruleUri + "> ao:attribute <" + subjectRoleAttribute + "> .\n" + + "<" + ruleUri + "> ao:attribute <" + operationAttribute + "> .\n" + + "<" + ruleUri + "> ao:attribute <" + objectUriAttribute + "> .\n" + + "<" + ruleUri + "> ao:attribute <" + objectTypeAttribute + "> ."; + return ttl; + } + + public List getGrantedRoleUris(String entityUri, AccessOperation operation) { + if (StringUtils.isBlank(entityUri)) { + return Collections.emptyList(); + } + Set rulesWithGrantedRoles = getGrantedRoleRulesForEntityUri(entityUri, operation); + List grantedUrisFromRules = getGrantedUrisFromRules(rulesWithGrantedRoles); + debug("Execute action %s on entity with uri %s found to be allowed to %s", entityUri, operation, grantedUrisFromRules); + return grantedUrisFromRules; + } + + + private void debug(String template, Object... objects) { + if (true) { + log.error(String.format(template, objects )); + } + } + + private List getGrantedUrisFromRules(Set ruleset) { + List roleUris = Collections.emptyList(); + for (AccessRule ar : ruleset) { + Set atts = ar.getAttributesByType(AttributeType.SUBJECT_ROLE_URI); + if (!atts.isEmpty()) { + String uri = atts.iterator().next().getValues().iterator().next(); + if (uri != null) { + if(roleUris.isEmpty()) { + roleUris = new LinkedList<>(); + } + roleUris.add(uri); + } + } + } + return roleUris; + } + + + public long getRulesCount() { + return allRules.size(); + } + + public long getModelSize() { + return getUserAccountsModel().size(); + } + + private ChangeSet makeChangeSet() { + ChangeSet cs = rdfService.manufactureChangeSet(); + cs.addPreChangeEvent(new BulkUpdateEvent(null, true)); + cs.addPostChangeEvent(new BulkUpdateEvent(null, false)); + return cs; + } + +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/rules/SimpleAccessRule.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/rules/SimpleAccessRule.java new file mode 100644 index 0000000000..c0ad23f594 --- /dev/null +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/auth/rules/SimpleAccessRule.java @@ -0,0 +1,10 @@ +/* $This file is distributed under the terms of the license in LICENSE$ */ + +package edu.cornell.mannlib.vitro.webapp.auth.rules; + +/** + * A class of simple access rules. + */ +public class SimpleAccessRule extends AccessRule { + +} diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/BaseResourceBean.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/BaseResourceBean.java index 9633414c3a..802a206cfb 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/BaseResourceBean.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/BaseResourceBean.java @@ -2,18 +2,12 @@ package edu.cornell.mannlib.vitro.webapp.beans; -import java.util.Set; - -import javax.servlet.http.HttpServletRequest; - import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.jena.rdf.model.Resource; import org.apache.jena.rdf.model.ResourceFactory; -import edu.cornell.mannlib.vedit.beans.LoginStatusBean; -import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionSets; import edu.cornell.mannlib.vitro.webapp.dao.VitroVocabulary; public class BaseResourceBean implements ResourceBean { @@ -25,94 +19,6 @@ public class BaseResourceBean implements ResourceBean { protected String localNameWithPrefix = null; protected String pickListName = null; - protected RoleLevel hiddenFromDisplayBelowRoleLevel = null; - protected RoleLevel prohibitedFromUpdateBelowRoleLevel = null; - protected RoleLevel hiddenFromPublishBelowRoleLevel = null; - - public enum RoleLevel { - PUBLIC("http://vitro.mannlib.cornell.edu/ns/vitro/role#public", - "all users, including public", "all users who can log in", - "public"), - - SELF("http://vitro.mannlib.cornell.edu/ns/vitro/role#selfEditor", - "self-editor and above", "self-editor and above", "self"), - - EDITOR("http://vitro.mannlib.cornell.edu/ns/vitro/role#editor", - "editor and above", "editor and above", "editor"), - - CURATOR("http://vitro.mannlib.cornell.edu/ns/vitro/role#curator", - "curator and above", "curator and above", "curator"), - - DB_ADMIN("http://vitro.mannlib.cornell.edu/ns/vitro/role#dbAdmin", - "site admin and root user", "site admin and root user", - "siteAdmin"), - - NOBODY("http://vitro.mannlib.cornell.edu/ns/vitro/role#nobody", - "root user", "root user", "root"); - - private final String uri; - private final String displayLabel; - private final String updateLabel; - private final String shorthand; - - private RoleLevel(String uri, String displayLabel, String updateLabel, - String shorthand) { - this.uri = uri; - this.displayLabel = displayLabel; - this.updateLabel = updateLabel; - this.shorthand = shorthand; - } - - public String getURI() { - return uri; - } - - public String getDisplayLabel() { - return displayLabel; - } - - public String getUpdateLabel() { - return updateLabel; - } - - public String getShorthand() { - return shorthand; - } - - // Never returns null. - public static RoleLevel getRoleByUri(String uri2) { - if (uri2 == null) - return RoleLevel.values()[0]; - - for (RoleLevel role : RoleLevel.values()) { - if (role.uri.equals(uri2)) - return role; - } - return RoleLevel.values()[0]; - } - - public static RoleLevel getRoleFromLoginStatus(HttpServletRequest req) { - UserAccount u = LoginStatusBean.getCurrentUser(req); - if (u == null) { - return PUBLIC; - } - - Set roles = u.getPermissionSetUris(); - if (roles.contains(PermissionSets.URI_DBA)) { - return DB_ADMIN; - } else if (roles.contains(PermissionSets.URI_CURATOR)) { - return CURATOR; - } else if (roles.contains(PermissionSets.URI_EDITOR)) { - return EDITOR; - } else if (roles.contains(PermissionSets.URI_SELF_EDITOR)) { - return SELF; - } else { - // Logged in but with no recognized role? Make them SELF - return SELF; - } - } - } - public BaseResourceBean() { // default constructor } @@ -203,51 +109,6 @@ public void setPickListName(String pickListName) { this.pickListName = pickListName; } - @Override - public RoleLevel getHiddenFromDisplayBelowRoleLevel() { - return hiddenFromDisplayBelowRoleLevel; - } - - @Override - public void setHiddenFromDisplayBelowRoleLevel(RoleLevel level) { - hiddenFromDisplayBelowRoleLevel = level; - } - - @Override - public void setHiddenFromDisplayBelowRoleLevelUsingRoleUri(String roleUri) { - hiddenFromDisplayBelowRoleLevel = RoleLevel.getRoleByUri(roleUri); - } - - @Override - public RoleLevel getProhibitedFromUpdateBelowRoleLevel() { - return prohibitedFromUpdateBelowRoleLevel; - } - - @Override - public void setProhibitedFromUpdateBelowRoleLevel(RoleLevel level) { - prohibitedFromUpdateBelowRoleLevel = level; - } - - @Override - public void setProhibitedFromUpdateBelowRoleLevelUsingRoleUri(String roleUri) { - prohibitedFromUpdateBelowRoleLevel = RoleLevel.getRoleByUri(roleUri); - } - - @Override - public RoleLevel getHiddenFromPublishBelowRoleLevel() { - return hiddenFromPublishBelowRoleLevel; - } - - @Override - public void setHiddenFromPublishBelowRoleLevel(RoleLevel level) { - hiddenFromPublishBelowRoleLevel = level; - } - - @Override - public void setHiddenFromPublishBelowRoleLevelUsingRoleUri(String roleUri) { - hiddenFromPublishBelowRoleLevel = BaseResourceBean.RoleLevel.getRoleByUri(roleUri); - } - @Override public boolean equals(Object obj) { if(obj == null ) diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/DataProperty.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/DataProperty.java index 05bc0396ac..4a39698beb 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/DataProperty.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/DataProperty.java @@ -6,15 +6,13 @@ import java.util.List; import java.util.LinkedList; -import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.RoleRestrictedProperty; - /** * class representing a property that relates an entity (object) * to a data literal * @author bjl23 * */ -public class DataProperty extends Property implements Comparable, ResourceBean, RoleRestrictedProperty { +public class DataProperty extends Property implements Comparable, ResourceBean { private String name = null; private String publicName = null; diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/FauxProperty.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/FauxProperty.java index cebc1d68b5..baa76aab5e 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/FauxProperty.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/FauxProperty.java @@ -8,14 +8,11 @@ import org.apache.commons.lang3.StringUtils; -import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.RoleRestrictedProperty; - /** * Represents a specialization on an ObjectProperty, only meaningful for * display. */ -public class FauxProperty extends BaseResourceBean implements ResourceBean, - RoleRestrictedProperty { +public class FauxProperty extends Property implements ResourceBean { // Must be null on insert. Must not be null on update. Ignored on delete. private String contextUri; // Must be null on insert. Must not be null on update. Ignored on delete. diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/ObjectProperty.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/ObjectProperty.java index 87cf27dfb4..b409494574 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/ObjectProperty.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/ObjectProperty.java @@ -16,13 +16,11 @@ import org.apache.jena.datatypes.xsd.XSDDatatype; -import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.RoleRestrictedProperty; - /** * a class representing an object property * */ -public class ObjectProperty extends Property implements Comparable, ResourceBean, Cloneable, RoleRestrictedProperty +public class ObjectProperty extends Property implements Comparable, ResourceBean, Cloneable { private static final Log log = LogFactory.getLog(ObjectProperty.class.getName()); @@ -631,8 +629,6 @@ public ObjectProperty clone() clone.setExample(this.getExample()); clone.setFunctional(this.getFunctional()); clone.setGroupURI(this.getGroupURI()); - clone.setHiddenFromDisplayBelowRoleLevel(this.getHiddenFromDisplayBelowRoleLevel()); - clone.setHiddenFromPublishBelowRoleLevel(this.getHiddenFromPublishBelowRoleLevel()); clone.setInverseFunctional(this.getInverseFunctional()); clone.setLabel(this.getLabel()); clone.setLocalName(this.getLocalName()); @@ -644,7 +640,6 @@ public ObjectProperty clone() clone.setOfferCreateNewOption(this.getOfferCreateNewOption()); clone.setParentURI(this.getParentURI()); clone.setPickListName(this.getPickListName()); - clone.setProhibitedFromUpdateBelowRoleLevel(this.getProhibitedFromUpdateBelowRoleLevel()); clone.setPublicDescription(this.getPublicDescription()); clone.setRangeDisplayLimit(this.getRangeDisplayLimit()); clone.setRangeDisplayTier(this.getRangeDisplayTier()); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/ResourceBean.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/ResourceBean.java index 1e8a2cdfbd..716cdfe55e 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/ResourceBean.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/ResourceBean.java @@ -2,8 +2,6 @@ package edu.cornell.mannlib.vitro.webapp.beans; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; - /** * User: bdc34 * Date: Oct 18, 2007 @@ -27,24 +25,6 @@ public interface ResourceBean { String getLabel(); - public RoleLevel getHiddenFromDisplayBelowRoleLevel() ; - - public void setHiddenFromDisplayBelowRoleLevel(RoleLevel eR) ; - - public void setHiddenFromDisplayBelowRoleLevelUsingRoleUri(String roleUri) ; - - public RoleLevel getProhibitedFromUpdateBelowRoleLevel() ; - - public void setProhibitedFromUpdateBelowRoleLevel(RoleLevel eR) ; - - public void setProhibitedFromUpdateBelowRoleLevelUsingRoleUri(String roleUri) ; - - public RoleLevel getHiddenFromPublishBelowRoleLevel() ; - - public void setHiddenFromPublishBelowRoleLevel(RoleLevel eR) ; - - public void setHiddenFromPublishBelowRoleLevelUsingRoleUri(String roleUri) ; - public String getPickListName(); } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/SelfEditingConfiguration.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/SelfEditingConfiguration.java index 06eab4472b..b9d8795c02 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/SelfEditingConfiguration.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/beans/SelfEditingConfiguration.java @@ -21,13 +21,22 @@ * used methods on those properties. */ public class SelfEditingConfiguration { - private static final Log log = LogFactory - .getLog(SelfEditingConfiguration.class); + private static final Log log = LogFactory.getLog(SelfEditingConfiguration.class); - private static final String BEAN_ATTRIBUTE = SelfEditingConfiguration.class - .getName(); + private static SelfEditingConfiguration INSTANCE; - /** + public static SelfEditingConfiguration getInstance() { + if (INSTANCE != null) { + return INSTANCE; + } + + SelfEditingConfiguration bean = buildBean(); + log.debug("Created a bean: " + bean); + INSTANCE = bean; + return bean; + } + + /** * This configuration property tells us which data property on the * Individual is used to associate it with a net ID. */ @@ -65,20 +74,11 @@ public static SelfEditingConfiguration getBean(ServletRequest request) { * Never returns null. */ public static SelfEditingConfiguration getBean(ServletContext ctx) { - Object attr = ctx.getAttribute(BEAN_ATTRIBUTE); - if (attr instanceof SelfEditingConfiguration) { - log.debug("Found a bean: " + attr); - return (SelfEditingConfiguration) attr; - } - - SelfEditingConfiguration bean = buildBean(ctx); - log.debug("Created a bean: " + bean); - ctx.setAttribute(BEAN_ATTRIBUTE, bean); - return bean; + return getInstance(); } - private static SelfEditingConfiguration buildBean(ServletContext ctx) { - ConfigurationProperties config = ConfigurationProperties.getBean(ctx); + private static SelfEditingConfiguration buildBean() { + ConfigurationProperties config = ConfigurationProperties.getInstance(); String selfEditingIdMatchingProperty = config .getProperty(PROPERTY_SELF_EDITING_ID_MATCHING_PROPERTY); return new SelfEditingConfiguration(selfEditingIdMatchingProperty); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/config/ConfigurationProperties.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/config/ConfigurationProperties.java index ee27feef38..e8e6f950a8 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/config/ConfigurationProperties.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/config/ConfigurationProperties.java @@ -9,7 +9,6 @@ import javax.servlet.ServletContextEvent; import javax.servlet.ServletRequest; import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; @@ -26,98 +25,69 @@ public abstract class ConfigurationProperties { private static final Log log = LogFactory .getLog(ConfigurationProperties.class); - - /** The bean is attached to the session by this name. */ - private static final String ATTRIBUTE_NAME = ConfigurationProperties.class - .getName(); - + /** If they ask for a bean before one has been set, they get this. */ private static final ConfigurationProperties DUMMY_PROPERTIES = new DummyConfigurationProperties(); + private static ConfigurationProperties INSTANCE = DUMMY_PROPERTIES; + + public static ConfigurationProperties getInstance() { + if (INSTANCE == DUMMY_PROPERTIES) { + log.error("ConfigurationProperties bean has not been set."); + } + return INSTANCE; + } + + public static void setInstance(ConfigurationProperties props) { + INSTANCE = props; + } // ---------------------------------------------------------------------- // static methods // ---------------------------------------------------------------------- + @Deprecated public static ConfigurationProperties getBean(ServletRequest request) { - if (request == null) { - throw new NullPointerException("request may not be null."); - } - if (!(request instanceof HttpServletRequest)) { - throw new IllegalArgumentException( - "request must be an HttpServletRequest"); - } - HttpServletRequest httpRequest = (HttpServletRequest) request; - return getBean(httpRequest.getSession()); - } + return getInstance(); - public static ConfigurationProperties getBean(HttpSession session) { - if (session == null) { - throw new NullPointerException("session may not be null."); - } - return getBean(session.getServletContext()); } + @Deprecated + public static ConfigurationProperties getBean(HttpSession session) { + return getInstance(); - public static ConfigurationProperties getBean(HttpServlet servlet) { - if (servlet == null) { - throw new NullPointerException("servlet may not be null."); - } - return getBean(servlet.getServletContext()); } + @Deprecated + public static ConfigurationProperties getBean(HttpServlet servlet) { + return getInstance(); - public static ConfigurationProperties getBean(ServletContextEvent sce) { - if (sce == null) { - throw new NullPointerException("sce may not be null."); - } - return getBean(sce.getServletContext()); } + @Deprecated + public static ConfigurationProperties getBean(ServletContextEvent sce) { + return getInstance(); - public static ConfigurationProperties getBean(ServletConfig servletConfig) { - if (servletConfig == null) { - throw new NullPointerException("servletConfig may not be null."); - } - return getBean(servletConfig.getServletContext()); } + @Deprecated + public static ConfigurationProperties getBean(ServletConfig servletConfig) { + return getInstance(); + } + @Deprecated public static ConfigurationProperties getBean(ServletContext context) { - if (context == null) { - throw new NullPointerException("context may not be null."); - } - - Object o = context.getAttribute(ATTRIBUTE_NAME); - if (o == null) { - log.error("ConfigurationProperties bean has not been set."); - return DUMMY_PROPERTIES; - } else if (!(o instanceof ConfigurationProperties)) { - log.error("Error: ConfigurationProperties was set to an " - + "invalid object: " + o); - return DUMMY_PROPERTIES; - } - - return (ConfigurationProperties) o; + return getInstance(); } /** * Protected access, so the Stub class can call it for unit tests. * Otherwise, this should only be called by ConfigurationPropertiesSetup. */ - protected static void setBean(ServletContext context, - ConfigurationProperties bean) { - if (context == null) { - throw new NullPointerException("context may not be null."); - } - if (bean == null) { - throw new NullPointerException("bean may not be null."); - } - context.setAttribute(ATTRIBUTE_NAME, bean); - log.debug(bean); + @Deprecated + protected static void setBean(ConfigurationProperties bean) { + setInstance(bean); } + @Deprecated /** Package access, so unit tests can call it. */ static void removeBean(ServletContext context) { - if (context == null) { - throw new NullPointerException("context may not be null."); - } - context.removeAttribute(ATTRIBUTE_NAME); + INSTANCE = DUMMY_PROPERTIES; } // ---------------------------------------------------------------------- diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/config/ConfigurationPropertiesSetup.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/config/ConfigurationPropertiesSetup.java index 54d0ac90d0..8f420cf244 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/config/ConfigurationPropertiesSetup.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/config/ConfigurationPropertiesSetup.java @@ -82,7 +82,7 @@ public void contextInitialized(ServletContextEvent sce) { ConfigurationPropertiesImpl bean = new ConfigurationPropertiesImpl( stream, preempts, new BuildProperties(ctx).getMap()); - ConfigurationProperties.setBean(ctx, bean); + ConfigurationProperties.setBean(bean); ss.info(this, "Loaded " + bean.getPropertyMap().size() + " properties."); } finally { diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/IndividualListRdfController.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/IndividualListRdfController.java index 06ce8c50e4..5f99497d95 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/IndividualListRdfController.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/IndividualListRdfController.java @@ -23,9 +23,10 @@ import org.apache.jena.rdf.model.Model; import org.apache.jena.rdf.model.ModelFactory; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessOperation; +import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject; +import edu.cornell.mannlib.vitro.webapp.auth.objects.ObjectPropertyStatementAccessObject; import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.publish.PublishObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.beans.ObjectProperty; import edu.cornell.mannlib.vitro.webapp.controller.api.VitroApiServlet; import edu.cornell.mannlib.vitro.webapp.controller.api.sparqlquery.InvalidQueryTypeException; @@ -96,10 +97,10 @@ private RdfResultMediaType parseAcceptHeader(HttpServletRequest req) private boolean isVclassRestricted(String vclassUri, HttpServletRequest req) { ObjectProperty property = new ObjectProperty(); property.setURI(RDF_TYPE); - RequestedAction dops = new PublishObjectPropertyStatement(ModelAccess - .on(req).getOntModel(FULL_ASSERTIONS), RequestedAction.SOME_URI, property, + AccessObject dops = new ObjectPropertyStatementAccessObject(ModelAccess + .on(req).getOntModel(FULL_ASSERTIONS), AccessObject.SOME_URI, property, vclassUri); - return !PolicyHelper.isAuthorizedForActions(req, dops); + return !PolicyHelper.isAuthorizedForActions(req, dops, AccessOperation.PUBLISH); } private void sendEmptyModel(RdfResultMediaType mediaType, diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/SparqlQueryBuilderServlet.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/SparqlQueryBuilderServlet.java index 2879af9dd0..f5e761ae96 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/SparqlQueryBuilderServlet.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/SparqlQueryBuilderServlet.java @@ -11,6 +11,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.utils.JSPPageHandler; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -20,7 +21,6 @@ import org.apache.jena.sparql.resultset.ResultsFormat; import edu.cornell.mannlib.vedit.controller.BaseEditController; -import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; /** * This servlet works as a RequestDispatcher to direct to the sparl query builder page. diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/VitroHttpServlet.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/VitroHttpServlet.java index 0d0c3453e4..90205db49d 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/VitroHttpServlet.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/VitroHttpServlet.java @@ -2,8 +2,6 @@ package edu.cornell.mannlib.vitro.webapp.controller; -import static edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest.AUTHORIZED; - import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; @@ -12,7 +10,6 @@ import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; -import java.util.Collections; import java.util.Comparator; import java.util.Enumeration; import java.util.List; @@ -120,7 +117,7 @@ protected void doPost(HttpServletRequest request, protected boolean isAuthorizedToDisplayPage(HttpServletRequest request, HttpServletResponse response, AuthorizationRequest actions) { // Record restricted pages so we won't return to them on logout - if (actions != AUTHORIZED) { + if (actions != AuthorizationRequest.AUTHORIZED) { LogoutRedirector.recordRestrictedPageUri(request); } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsDeleter.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsDeleter.java index 70d52bead2..9fbe7001a6 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsDeleter.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsDeleter.java @@ -12,8 +12,9 @@ import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vedit.beans.LoginStatusBean; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessOperation; +import edu.cornell.mannlib.vitro.webapp.auth.objects.RootAccessObject; import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageRootAccount; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.accounts.UserAccountsPage; @@ -75,7 +76,7 @@ private void validateInputUris() { if (u.isRootUser() && (!PolicyHelper.isAuthorizedForActions(vreq, - new ManageRootAccount()))) { + new RootAccessObject(), AccessOperation.DROP))) { log.warn("Attempting to delete the root account, " + "but not authorized. Logged in as " + LoginStatusBean.getCurrentUser(vreq)); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java index 13e1ab0dd4..e93f211519 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsEditPage.java @@ -15,8 +15,9 @@ import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vedit.beans.LoginStatusBean; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessOperation; +import edu.cornell.mannlib.vitro.webapp.auth.objects.RootAccessObject; import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageRootAccount; import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.SelfEditingConfiguration; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; @@ -122,7 +123,7 @@ private void validateUserAccountInfo() { } if (userAccount.isRootUser()) { if (!PolicyHelper.isAuthorizedForActions(vreq, - new ManageRootAccount())) { + new RootAccessObject(), AccessOperation.EDIT)) { log.warn("User is attempting to edit the root account, " + "but is not authorized to do so. Logged in as: " + LoginStatusBean.getCurrentUser(vreq)); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsListPage.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsListPage.java index f02e17b8e4..1347e1eb55 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsListPage.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/admin/UserAccountsListPage.java @@ -19,8 +19,9 @@ import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vedit.beans.LoginStatusBean; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessOperation; +import edu.cornell.mannlib.vitro.webapp.auth.objects.RootAccessObject; import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageRootAccount; import edu.cornell.mannlib.vitro.webapp.beans.PermissionSet; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount.Status; @@ -198,7 +199,7 @@ private boolean permittedToEdit(UserAccount account) { if (!account.isRootUser()) { return true; } - if (PolicyHelper.isAuthorizedForActions(vreq, new ManageRootAccount())) { + if (PolicyHelper.isAuthorizedForActions(vreq, new RootAccessObject(), AccessOperation.EDIT)) { return true; } return false; diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/manageproxies/ajax/ManageProxiesAjaxController.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/manageproxies/ajax/ManageProxiesAjaxController.java index 97d2e1ce2b..40b27ddc85 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/manageproxies/ajax/ManageProxiesAjaxController.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/manageproxies/ajax/ManageProxiesAjaxController.java @@ -12,6 +12,7 @@ import org.apache.commons.logging.LogFactory; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthHelper; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.ajax.VitroAjaxController; @@ -28,8 +29,9 @@ public class ManageProxiesAjaxController extends VitroAjaxController { @Override protected AuthorizationRequest requiredActions(VitroRequest vreq) { - return SimplePermission.MANAGE_OWN_PROXIES.ACTION - .or(SimplePermission.MANAGE_PROXIES.ACTION); + return AuthHelper.logicOr( + SimplePermission.MANAGE_OWN_PROXIES.ACTION + ,SimplePermission.MANAGE_PROXIES.ACTION); } @Override diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsUserController.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsUserController.java index 45be8f5531..9abe5f2698 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsUserController.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/accounts/user/UserAccountsUserController.java @@ -3,7 +3,6 @@ package edu.cornell.mannlib.vitro.webapp.controller.accounts.user; import static edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource.EXTERNAL; -import static edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest.AUTHORIZED; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServletRequest; @@ -11,8 +10,8 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; +import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.beans.DisplayMessage; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; @@ -44,7 +43,7 @@ protected AuthorizationRequest requiredActions(VitroRequest vreq) { if (ACTION_MY_ACCOUNT.equals(action)) { return SimplePermission.EDIT_OWN_ACCOUNT.ACTION; } else { - return AUTHORIZED; + return AuthorizationRequest.AUTHORIZED; } } diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/admin/ShowAuthController.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/admin/ShowAuthController.java index b3ee6af2d4..876477be54 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/admin/ShowAuthController.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/admin/ShowAuthController.java @@ -2,9 +2,8 @@ package edu.cornell.mannlib.vitro.webapp.controller.admin; -import static edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest.AUTHORIZED; -import static edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction.SOME_PREDICATE; -import static edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction.SOME_URI; +import static edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject.SOME_PREDICATE; +import static edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject.SOME_URI; import java.util.ArrayList; import java.util.HashMap; @@ -12,20 +11,20 @@ import java.util.Map; import java.util.TreeMap; -import javax.servlet.ServletContext; import javax.servlet.annotation.WebServlet; import edu.cornell.mannlib.vedit.beans.LoginStatusBean; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessOperation; import edu.cornell.mannlib.vitro.webapp.auth.identifier.ActiveIdentifierBundleFactories; import edu.cornell.mannlib.vitro.webapp.auth.identifier.Identifier; import edu.cornell.mannlib.vitro.webapp.auth.identifier.IdentifierBundle; import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers; import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.HasAssociatedIndividual; +import edu.cornell.mannlib.vitro.webapp.auth.objects.AccessObject; +import edu.cornell.mannlib.vitro.webapp.auth.objects.ObjectPropertyStatementAccessObject; import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList; +import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyStore; import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.propstmt.EditObjectPropertyStatement; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.authenticate.Authenticator; @@ -42,7 +41,7 @@ public class ShowAuthController extends FreemarkerHttpServlet { @Override protected AuthorizationRequest requiredActions(VitroRequest vreq) { - return AUTHORIZED; + return AuthorizationRequest.AUTHORIZED; } @Override @@ -53,8 +52,8 @@ protected ResponseValues processRequest(VitroRequest vreq) { body.put("identifiers", getSortedIdentifiers(vreq)); body.put("currentUser", LoginStatusBean.getCurrentUser(vreq)); body.put("associatedIndividuals", getAssociatedIndividuals(vreq)); - body.put("factories", getIdentifierFactoryNames(vreq)); - body.put("policies", ServletPolicyList.getPolicies(vreq)); + body.put("factories", ActiveIdentifierBundleFactories.getFactoryNames()); + body.put("policies", PolicyStore.getInstance().getUris()); body.put("matchingProperty", getMatchingProperty(vreq)); body.put("authenticator", Authenticator.getInstance(vreq)); @@ -69,11 +68,6 @@ private List getSortedIdentifiers(VitroRequest vreq) { return new ArrayList(idMap.values()); } - private List getIdentifierFactoryNames(VitroRequest vreq) { - ServletContext ctx = vreq.getSession().getServletContext(); - return ActiveIdentifierBundleFactories.getFactoryNames(ctx); - } - private String getMatchingProperty(VitroRequest vreq) { return ConfigurationProperties.getBean(vreq).getProperty( "selfEditing.idMatchingProperty", ""); @@ -94,10 +88,10 @@ private List getAssociatedIndividuals( * this individual? */ private boolean mayEditIndividual(VitroRequest vreq, String individualUri) { - RequestedAction action = new EditObjectPropertyStatement( + AccessObject action = new ObjectPropertyStatementAccessObject( vreq.getJenaOntModel(), individualUri, SOME_PREDICATE, SOME_URI); - return PolicyHelper.isAuthorizedForActions(vreq, action); + return PolicyHelper.isAuthorizedForActions(vreq, action, AccessOperation.EDIT); } public class AssociatedIndividual { diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/admin/ShowSourcesController.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/admin/ShowSourcesController.java index c0d5e3fc3a..bf235be28c 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/admin/ShowSourcesController.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/admin/ShowSourcesController.java @@ -2,7 +2,6 @@ package edu.cornell.mannlib.vitro.webapp.controller.admin; -import static edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest.AUTHORIZED; import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.LanguageOption.LANGUAGE_NEUTRAL; import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONFIGURATION; import static edu.cornell.mannlib.vitro.webapp.modelaccess.ModelAccess.WhichService.CONTENT; @@ -112,7 +111,7 @@ public class ShowSourcesController extends FreemarkerHttpServlet { @Override protected AuthorizationRequest requiredActions(VitroRequest vreq) { - return AUTHORIZED; + return AuthorizationRequest.AUTHORIZED; } @Override diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/ajax/VitroAjaxController.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/ajax/VitroAjaxController.java index 51a68e602a..3c0daf4e76 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/ajax/VitroAjaxController.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/ajax/VitroAjaxController.java @@ -2,8 +2,6 @@ package edu.cornell.mannlib.vitro.webapp.controller.ajax; -import static edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest.AUTHORIZED; - import java.io.IOException; import java.io.PrintWriter; import java.util.Map; @@ -68,7 +66,7 @@ protected final void doPost(HttpServletRequest req, HttpServletResponse resp) */ @SuppressWarnings("unused") protected AuthorizationRequest requiredActions(VitroRequest vreq) { - return AUTHORIZED; + return AuthorizationRequest.AUTHORIZED; } /** diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/VitroApiServlet.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/VitroApiServlet.java index 47bcdfd21a..52951a8a92 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/VitroApiServlet.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/api/VitroApiServlet.java @@ -41,7 +41,7 @@ public class VitroApiServlet extends HttpServlet { * them for this action, throw an AuthException. */ protected void confirmAuthorization(HttpServletRequest req, - AuthorizationRequest requiredActions) throws AuthException { + AuthorizationRequest requiredActions) throws AuthException { String email = req.getParameter("email"); String password = req.getParameter("password"); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/AdminLoginController.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/AdminLoginController.java index 36a7601b23..da13d5867e 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/AdminLoginController.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/AdminLoginController.java @@ -3,7 +3,6 @@ package edu.cornell.mannlib.vitro.webapp.controller.authenticate; import static edu.cornell.mannlib.vedit.beans.LoginStatusBean.AuthenticationSource.INTERNAL; -import static edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest.AUTHORIZED; import static edu.cornell.mannlib.vitro.webapp.beans.UserAccount.MAX_PASSWORD_LENGTH; import static edu.cornell.mannlib.vitro.webapp.beans.UserAccount.MIN_PASSWORD_LENGTH; @@ -58,7 +57,7 @@ public class AdminLoginController extends FreemarkerHttpServlet { @Override protected AuthorizationRequest requiredActions(VitroRequest vreq) { - return AUTHORIZED; // No requirements to use this page. + return AuthorizationRequest.AUTHORIZED; // No requirements to use this page. } @Override diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/Authenticator.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/Authenticator.java index e8bbec5167..ec1230313b 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/Authenticator.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/Authenticator.java @@ -266,10 +266,8 @@ public static boolean isValidEmailAddress(String emailAddress) { * Get the IDs that would be created for this userAccount, if this user were * to log in. */ - public static IdentifierBundle getIdsForUserAccount(HttpServletRequest req, - UserAccount userAccount) { - return ActiveIdentifierBundleFactories.getUserIdentifierBundle(req, - userAccount); + public static IdentifierBundle getIdsForUserAccount(UserAccount userAccount) { + return ActiveIdentifierBundleFactories.getUserIdentifierBundle(userAccount); } // ---------------------------------------------------------------------- diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/BasicAuthenticator.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/BasicAuthenticator.java index 34fc6a01d6..19795a9fcc 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/BasicAuthenticator.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/BasicAuthenticator.java @@ -2,14 +2,10 @@ package edu.cornell.mannlib.vitro.webapp.controller.authenticate; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.Map; - import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; +import edu.cornell.mannlib.vitro.webapp.auth.permissions.PermissionSets; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -18,7 +14,6 @@ import edu.cornell.mannlib.vitro.webapp.application.ApplicationUtils; import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers; import edu.cornell.mannlib.vitro.webapp.auth.identifier.common.IsRootUser; -import edu.cornell.mannlib.vitro.webapp.beans.BaseResourceBean.RoleLevel; import edu.cornell.mannlib.vitro.webapp.beans.Individual; import edu.cornell.mannlib.vitro.webapp.beans.SelfEditingConfiguration; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; @@ -33,6 +28,12 @@ import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngine; import edu.cornell.mannlib.vitro.webapp.modules.searchEngine.SearchEngineException; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.Set; + /** * The "standard" implementation of Authenticator. */ @@ -228,17 +229,20 @@ private void createLoginStatusBean(String userUri, /** * Editors and other privileged users get a longer timeout interval. */ - private void setSessionTimeoutLimit(UserAccount userAccount, - HttpSession session) { - RoleLevel role = RoleLevel.getRoleFromLoginStatus(request); - if (role == RoleLevel.EDITOR || role == RoleLevel.CURATOR - || role == RoleLevel.DB_ADMIN) { - session.setMaxInactiveInterval(PRIVILEGED_TIMEOUT_INTERVAL); - } else if (userAccount.isRootUser()) { - session.setMaxInactiveInterval(PRIVILEGED_TIMEOUT_INTERVAL); + private void setSessionTimeoutLimit(UserAccount userAccount, HttpSession session) { + int interval = LOGGED_IN_TIMEOUT_INTERVAL; + if (userAccount.isRootUser()) { + interval = PRIVILEGED_TIMEOUT_INTERVAL; } else { - session.setMaxInactiveInterval(LOGGED_IN_TIMEOUT_INTERVAL); + Set permissions = userAccount.getPermissionSetUris(); + for (String uri : permissions) { + if (!uri.equals(PermissionSets.URI_SELF_EDITOR)) { + interval = PRIVILEGED_TIMEOUT_INTERVAL; + } + } } + + session.setMaxInactiveInterval(interval); } /** diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/LoginRedirector.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/LoginRedirector.java index 65b8a2310f..ca4ba5056e 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/LoginRedirector.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/LoginRedirector.java @@ -74,15 +74,17 @@ public String getRedirectionUriForLoggedInUser() { return getAssociatedIndividualHomePage(); } - if (!canSeeSiteAdminPage()) { - log.debug("User not recognized. Going to application home."); - return getApplicationHomePageUrl(); - } + if (null != afterLoginPage) { + if (isLoginPage(afterLoginPage)) { + if (canSeeSiteAdminPage()) { + log.debug("Coming from /login. Going to site admin page."); + return getSiteAdminPageUrl(); + } else { + log.debug("User not recognized. Going to application home."); + return getApplicationHomePageUrl(); + } + } - if (isLoginPage(afterLoginPage)) { - log.debug("Coming from /login. Going to site admin page."); - return getSiteAdminPageUrl(); - } else if (null != afterLoginPage) { log.debug("Returning to requested page: " + afterLoginPage); return afterLoginPage; } else { diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/RestrictedAuthenticator.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/RestrictedAuthenticator.java index bb4fb6322f..783acd1405 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/RestrictedAuthenticator.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/authenticate/RestrictedAuthenticator.java @@ -11,7 +11,6 @@ import edu.cornell.mannlib.vitro.webapp.auth.identifier.RequestIdentifiers; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper; -import edu.cornell.mannlib.vitro.webapp.auth.policy.ServletPolicyList; import edu.cornell.mannlib.vitro.webapp.beans.UserAccount; /** @@ -49,12 +48,10 @@ public boolean isUserPermittedToLogin(UserAccount userAccount) { } ArrayIdentifierBundle ids = new ArrayIdentifierBundle(); - ids.addAll(getIdsForUserAccount(req, userAccount)); + ids.addAll(getIdsForUserAccount(userAccount)); ids.addAll(RequestIdentifiers.getIdBundleForRequest(req)); - return PolicyHelper.isAuthorizedForActions(ids, - ServletPolicyList.getPolicies(req), - SimplePermission.LOGIN_DURING_MAINTENANCE.ACTION); + return PolicyHelper.isAuthorizedForActions(ids, SimplePermission.LOGIN_DURING_MAINTENANCE.ACTION); } @Override diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/datatools/dumprestore/DumpRestoreController.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/datatools/dumprestore/DumpRestoreController.java index 77f22b3755..0f5e427854 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/datatools/dumprestore/DumpRestoreController.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/datatools/dumprestore/DumpRestoreController.java @@ -15,7 +15,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.auth.policy.PolicyHelper; -import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.RequestedAction; +import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.AuthorizationRequest; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet; import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder; @@ -37,7 +37,7 @@ @WebServlet(name = "DumpRestoreController", urlPatterns = {"/dumpRestore/*"} ) public class DumpRestoreController extends FreemarkerHttpServlet { - private static final RequestedAction REQUIRED_ACTION = SimplePermission.USE_ADVANCED_DATA_TOOLS_PAGES.ACTION; + private static final AuthorizationRequest REQUIRED_ACTION = SimplePermission.USE_ADVANCED_DATA_TOOLS_PAGES.ACTION; static final String ACTION_DUMP = "/dump"; static final String ACTION_RESTORE = "/restore"; diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/edit/DatapropEditController.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/edit/DatapropEditController.java index 4028c0aec3..9e1d36b43d 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/edit/DatapropEditController.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/edit/DatapropEditController.java @@ -43,7 +43,7 @@ public void doPost (HttpServletRequest request, HttpServletResponse response) { VitroRequest vreq = new VitroRequest(request); - final int NUM_COLS=19; + final int NUM_COLS=15; String datapropURI = request.getParameter("uri"); @@ -69,14 +69,10 @@ public void doPost (HttpServletRequest request, HttpServletResponse response) { results.add("public description"); // column 9 results.add("example"); // column 10 results.add("editor description"); // column 11 - results.add("display level"); // column 12 - results.add("update level"); // column 13 - results.add("display tier"); // column 14 - results.add("display limit"); // column 15 - results.add("custom entry form"); // column 16 - results.add("editing"); // column 17 - results.add("URI"); // column 18 - results.add("publish level"); // column 19 + results.add("display tier"); // column 12 + results.add("display limit"); // column 13 + results.add("custom entry form"); // column 14 + results.add("URI"); // column 15 results.add(dp.getPickListName()); // column 1 results.add(dp.getPublicName() == null ? "(no public label)" : dp.getPublicName()); // column 2 @@ -137,17 +133,10 @@ public void doPost (HttpServletRequest request, HttpServletResponse response) { String descriptionStr = (dp.getDescription() == null) ? "" : dp.getDescription(); // column 11 results.add(descriptionStr); - results.add(dp.getHiddenFromDisplayBelowRoleLevel() == null ? "(unspecified)" - : dp.getHiddenFromDisplayBelowRoleLevel().getDisplayLabel()); // column 12 - results.add(dp.getProhibitedFromUpdateBelowRoleLevel() == null ? "(unspecified)" - : dp.getProhibitedFromUpdateBelowRoleLevel().getUpdateLabel()); // column 13 - results.add(String.valueOf(dp.getDisplayTier())); // column 14 - results.add(String.valueOf(dp.getDisplayLimit())); // column 15 - results.add(dp.getCustomEntryForm() == null ? "(unspecified)" : dp.getCustomEntryForm()); // column 16 - results.add(dp.getEditing() == null ? "" : dp.getEditing()); // column 17 - results.add(dp.getURI() == null ? "" : dp.getURI()); // column 18 - results.add(dp.getHiddenFromPublishBelowRoleLevel() == null ? "(unspecified)" - : dp.getHiddenFromPublishBelowRoleLevel().getDisplayLabel()); // column 19 + results.add(String.valueOf(dp.getDisplayTier())); // column 12 + results.add(String.valueOf(dp.getDisplayLimit())); // column 13 + results.add(dp.getCustomEntryForm() == null ? "(unspecified)" : dp.getCustomEntryForm()); // column 14 + results.add(dp.getURI() == null ? "" : dp.getURI()); // column 15 request.setAttribute("results",results); request.setAttribute("columncount",NUM_COLS); request.setAttribute("suppressquery","true"); diff --git a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/edit/DatapropRetryController.java b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/edit/DatapropRetryController.java index 70d47a80a7..3fd3fda43e 100644 --- a/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/edit/DatapropRetryController.java +++ b/api/src/main/java/edu/cornell/mannlib/vitro/webapp/controller/edit/DatapropRetryController.java @@ -25,12 +25,12 @@ import edu.cornell.mannlib.vedit.util.FormUtils; import edu.cornell.mannlib.vedit.validator.impl.IntValidator; import edu.cornell.mannlib.vedit.validator.impl.XMLNameValidator; +import edu.cornell.mannlib.vitro.webapp.auth.attributes.AccessObjectType; import edu.cornell.mannlib.vitro.webapp.auth.permissions.SimplePermission; import edu.cornell.mannlib.vitro.webapp.auth.policy.bean.PropertyRestrictionListener; import edu.cornell.mannlib.vitro.webapp.beans.DataProperty; import edu.cornell.mannlib.vitro.webapp.beans.VClass; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; -import edu.cornell.mannlib.vitro.webapp.controller.edit.utils.RoleLevelOptionsSetup; import edu.cornell.mannlib.vitro.webapp.dao.DataPropertyDao; import edu.cornell.mannlib.vitro.webapp.dao.DatatypeDao; import edu.cornell.mannlib.vitro.webapp.dao.OntologyDao; @@ -165,23 +165,6 @@ public void doPost (HttpServletRequest request, HttpServletResponse response) { groupOptList.add(0,new Option("","none")); optionMap.put("GroupURI", groupOptList); - optionMap.put("HiddenFromDisplayBelowRoleLevelUsingRoleUri",RoleLevelOptionsSetup.getDisplayOptionsList(objectForEditing)); - optionMap.put("ProhibitedFromUpdateBelowRoleLevelUsingRoleUri",RoleLevelOptionsSetup.getUpdateOptionsList(objectForEditing)); - optionMap.put("HiddenFromPublishBelowRoleLevelUsingRoleUri",RoleLevelOptionsSetup.getPublishOptionsList(objectForEditing)); - - // Set the value of the editing parameter (as defined in VitroVocabulary.java). - // Use value to control form types as in defaultDataPropertyForm.ftl - String editingVal = objectForEditing.getEditing(); - List