mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-09-10 14:11:58 +00:00
Compare commits
39 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
7db550cee1 | ||
|
937d80327f | ||
|
8abff868cc | ||
|
ffae8a62a1 | ||
|
0350c966df | ||
|
833a7675bc | ||
|
8aa263f377 | ||
|
73f30b7ef2 | ||
|
4bf58cc99c | ||
|
d53881d87f | ||
|
937601020d | ||
|
429b389b08 | ||
|
c944f3560c | ||
|
40ff2558f5 | ||
|
4f69f28586 | ||
|
aa66dd748f | ||
|
bf9c8ab870 | ||
|
959cf8f13f | ||
|
8b4285afbd | ||
|
7143f5975f | ||
|
31944bfc0f | ||
|
c874fa4e51 | ||
|
5780871f0c | ||
|
85ef347dc3 | ||
|
0a76858778 | ||
|
6db6245e53 | ||
|
7b572a3e02 | ||
|
b1cbebacc3 | ||
|
0bbe73aee1 | ||
|
9135fdae8b | ||
|
0cb0cfa8f6 | ||
|
5a96cce5bb | ||
|
c999fb25b9 | ||
|
3c2643dbf2 | ||
|
106e398393 | ||
|
1c45748f9a | ||
|
2b7ff213a9 | ||
|
f693c49e87 | ||
|
0f156ba259 |
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-amps</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-automation-community-repo</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
@@ -50,6 +50,7 @@ import org.apache.http.HttpResponse;
|
||||
import org.apache.http.HttpStatus;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
import org.json.JSONObject;
|
||||
import org.junit.Ignore;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.testng.AssertJUnit;
|
||||
import org.testng.annotations.BeforeClass;
|
||||
@@ -135,192 +136,195 @@ public class DispositionScheduleLinkedRecordsTest extends BaseRMRestTest {
|
||||
* <p>
|
||||
* <p/> TestRail Test C775<p/>
|
||||
**/
|
||||
@Test
|
||||
@AlfrescoTest(jira = "RM-1622")
|
||||
public void dispositionScheduleLinkedRecords() throws UnsupportedEncodingException {
|
||||
STEP("Create record category");
|
||||
Category1 = createRootCategory(categoryRM3077);
|
||||
// @Ignore("ACS-5020")
|
||||
// @Test
|
||||
// @AlfrescoTest(jira = "RM-1622")
|
||||
// public void dispositionScheduleLinkedRecords() throws UnsupportedEncodingException {
|
||||
// STEP("Create record category");
|
||||
// Category1 = createRootCategory(categoryRM3077);
|
||||
//
|
||||
// //create retention schedule
|
||||
// dispositionScheduleService.createCategoryRetentionSchedule(Category1.getName(), false);
|
||||
//
|
||||
// // add cut off step
|
||||
// dispositionScheduleService.addCutOffAfterPeriodStep(Category1.getName(), "day|2", CREATED_DATE);
|
||||
//
|
||||
// //create a copy of the category recordsCategory
|
||||
// String CopyCategoryId = copyCategory(getAdminUser(),Category1.getId(), copyCategoryRM3077);
|
||||
//
|
||||
// // create folders in both categories
|
||||
// CatFolder = createRecordFolder(Category1.getId(), folderRM3077);
|
||||
// CopyCatFolder = createRecordFolder(CopyCategoryId, copyFolderRM3077);
|
||||
//
|
||||
// // create record files
|
||||
// String electronicRecord = "RM-2801 electronic record";
|
||||
// Record elRecord = createElectronicRecord(CatFolder.getId(), electronicRecord);
|
||||
// String elRecordFullName = recordsAPI.getRecordFullName(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
// getDataUser().usingAdmin().getAdminUser().getPassword(), CatFolder.getName(), electronicRecord);
|
||||
//
|
||||
// String nonElectronicRecord = "RM-2801 non-electronic record";
|
||||
// Record nonElRecord = createNonElectronicRecord(CatFolder.getId(), nonElectronicRecord);
|
||||
// String nonElRecordFullName = recordsAPI.getRecordFullName(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
// getDataUser().usingAdmin().getAdminUser().getPassword(), CatFolder.getName(), nonElectronicRecord);
|
||||
//
|
||||
// // link the records to copy folder, then complete them
|
||||
// List<String> recordLists = new ArrayList<>();
|
||||
// recordLists.add(NODE_REF_WORKSPACE_SPACES_STORE + elRecord.getId());
|
||||
// recordLists.add(NODE_REF_WORKSPACE_SPACES_STORE + nonElRecord.getId());
|
||||
//
|
||||
// linksAPI.linkRecord(getDataUser().getAdminUser().getUsername(),
|
||||
// getDataUser().getAdminUser().getPassword(), HttpStatus.SC_OK,copyCategoryRM3077 + "/" +
|
||||
// copyFolderRM3077, recordLists);
|
||||
// recordsAPI.completeRecord(rmAdmin.getUsername(), rmAdmin.getPassword(), elRecordFullName);
|
||||
// recordsAPI.completeRecord(rmAdmin.getUsername(), rmAdmin.getPassword(), nonElRecordFullName);
|
||||
//
|
||||
// // edit disposition date
|
||||
// recordFoldersAPI.postFolderAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),editDispositionDateJson(),CatFolder.getName());
|
||||
//
|
||||
// // cut off the Folder
|
||||
// recordFoldersAPI.postFolderAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),new JSONObject().put("name","cutoff"),CatFolder.getName());
|
||||
//
|
||||
// // Verify the Content
|
||||
// Node electronicNode = getNode(elRecord.getId());
|
||||
// assertTrue("The content of " + electronicRecord + " is available",
|
||||
// StringUtils.isEmpty(electronicNode.getNodeContent().getResponse().getBody().asString()));
|
||||
//
|
||||
// // verify the Properties
|
||||
// AssertJUnit.assertNull("The properties are present even after cutting off the record.", elRecord.getProperties().getTitle());
|
||||
//
|
||||
// // delete precondition
|
||||
// deleteRecordCategory(Category1.getId());
|
||||
// deleteRecordCategory(CopyCategoryId);
|
||||
// }
|
||||
// /**
|
||||
// * Test covering RM-3060
|
||||
// * Check the disposition steps for a record can be executed
|
||||
// * When the record is linked to a folder with the same disposition schedule
|
||||
// * */
|
||||
// @Ignore("ACS-5020")
|
||||
//// @Test
|
||||
// @AlfrescoTest (jira = "RM-3060")
|
||||
// public void sameDispositionScheduleLinkedRecords() throws UnsupportedEncodingException {
|
||||
//
|
||||
// // create a category with retention applied on records level
|
||||
// RecordCategory recordCategory = getRestAPIFactory().getFilePlansAPI(rmAdmin)
|
||||
// .createRootRecordCategory(RecordCategory.builder().name(firstCategoryRM3060).build(),
|
||||
// RecordCategory.DEFAULT_FILE_PLAN_ALIAS);
|
||||
// dispositionScheduleService.createCategoryRetentionSchedule(firstCategoryRM3060, true);
|
||||
// dispositionScheduleService.addCutOffAfterPeriodStep(firstCategoryRM3060, "week|1", DATE_FILED);
|
||||
// dispositionScheduleService.addTransferAfterEventStep(firstCategoryRM3060, TRANSFER_LOCATION, RMEvents.CASE_CLOSED.getEventName());
|
||||
// dispositionScheduleService.addDestroyWithoutGhostingAfterPeriodStep(firstCategoryRM3060, "week|1", CUT_OFF_DATE);
|
||||
//
|
||||
// // make a copy of the category created
|
||||
// String categorySecondId = copyCategory(getAdminUser(), recordCategory.getId(), secondCategoryRM3060);
|
||||
//
|
||||
// // create a folder on the category firstCategoryRM3060 with a complete electronic record
|
||||
// RecordCategoryChild firstFolderRecordCategoryChild = createRecordFolder(recordCategory.getId(),firstFolderRM3060);
|
||||
// Record firstElectronicRecord = createElectronicRecord(firstFolderRecordCategoryChild.getId(),electronicRecordRM3060);
|
||||
//
|
||||
// String elRecordFullName = recordsAPI.getRecordFullName(getDataUser().getAdminUser().getUsername(),
|
||||
// getDataUser().getAdminUser().getPassword(),firstFolderRM3060, electronicRecordRM3060);
|
||||
// String elRecordNameNodeRef = recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
// getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordFullName, "/" + firstCategoryRM3060 + "/" + firstFolderRM3060);
|
||||
//
|
||||
// recordsAPI.completeRecord(getDataUser().getAdminUser().getUsername(),
|
||||
// getDataUser().getAdminUser().getPassword(), elRecordFullName);
|
||||
//
|
||||
// // create a folder on the category secondCategoryRM3060 with a non electronic record
|
||||
// RecordCategoryChild secondFolderRecordCategoryChild = createRecordFolder(categorySecondId,secondFolderRM3060);
|
||||
// Record secondNonElectronicRecord = createNonElectronicRecord(secondFolderRecordCategoryChild.getId(),nonElectronicRecordRM3060);
|
||||
//
|
||||
// // link the nonElectronicRecordRM3060 to firstFolderRM3060
|
||||
// List<String> recordLists = new ArrayList<>();
|
||||
// recordLists.add(NODE_REF_WORKSPACE_SPACES_STORE + secondNonElectronicRecord.getId());
|
||||
//
|
||||
// linksAPI.linkRecord(getDataUser().getAdminUser().getUsername(),
|
||||
// getDataUser().getAdminUser().getPassword(), HttpStatus.SC_OK,secondCategoryRM3060 + "/" +
|
||||
// secondFolderRM3060, recordLists);
|
||||
// String nonElRecordFullName = recordsAPI.getRecordFullName(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
// getDataUser().usingAdmin().getAdminUser().getPassword(), secondFolderRM3060, secondNonElectronicRecord.getName());
|
||||
// String nonElRecordNameNodeRef = recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
// getDataUser().usingAdmin().getAdminUser().getPassword(), nonElRecordFullName, "/" + secondCategoryRM3060 + "/" + secondFolderRM3060);
|
||||
//
|
||||
// // complete records and cut them off
|
||||
// recordsAPI.completeRecord(getDataUser().getAdminUser().getUsername(),
|
||||
// getDataUser().getAdminUser().getPassword(), nonElRecordFullName);
|
||||
//
|
||||
// // edit the disposition date
|
||||
// recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),editDispositionDateJson(),nonElRecordNameNodeRef);
|
||||
//
|
||||
// // cut off the record
|
||||
// recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),new JSONObject().put("name","cutoff"),nonElRecordNameNodeRef);
|
||||
//
|
||||
// //check the record is cut off
|
||||
// AssertJUnit.assertTrue("The file " + nonElectronicRecordRM3060 + " has not been successfully cut off.", getRestAPIFactory().getRecordsAPI().getRecord(secondNonElectronicRecord.getId()).getAspectNames().contains(CUT_OFF_ASPECT));
|
||||
//
|
||||
// // link the electronic record to secondFolderRM3060
|
||||
// recordLists.clear();
|
||||
// recordLists.add(NODE_REF_WORKSPACE_SPACES_STORE + secondNonElectronicRecord.getId());
|
||||
// linksAPI.linkRecord(getDataUser().getAdminUser().getUsername(),
|
||||
// getDataUser().getAdminUser().getPassword(), HttpStatus.SC_OK,secondCategoryRM3060 + "/" +
|
||||
// secondFolderRM3060, recordLists);
|
||||
//
|
||||
// // edit the disposition date and cut off the record
|
||||
// recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),editDispositionDateJson(),elRecordNameNodeRef);
|
||||
// recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),new JSONObject().put("name","cutoff"),elRecordNameNodeRef);
|
||||
//
|
||||
// AssertJUnit.assertTrue("The file " + electronicRecordRM3060 + " has not been successfully cut off.", getRestAPIFactory().getRecordsAPI().getRecord(firstElectronicRecord.getId()).getAspectNames().contains(CUT_OFF_ASPECT));
|
||||
//
|
||||
// // open the record and complete the disposition schedule event
|
||||
// rmRolesAndActionsAPI.completeEvent(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(), elRecordFullName, RMEvents.CASE_CLOSED, Instant.now());
|
||||
// rmRolesAndActionsAPI.completeEvent(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(), nonElRecordFullName, RMEvents.CASE_CLOSED, Instant.now());
|
||||
//
|
||||
// // transfer the files & complete transfers
|
||||
// HttpResponse nonElRecordNameHttpResponse = recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),new JSONObject().put("name","transfer"),recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
// getDataUser().usingAdmin().getAdminUser().getPassword(), nonElRecordFullName, "/" + secondCategoryRM3060 + "/" + secondFolderRM3060));
|
||||
//
|
||||
// String nonElRecordNameTransferId = getTransferId(nonElRecordNameHttpResponse,nonElRecordNameNodeRef);
|
||||
// recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),new JSONObject().put("name","transferComplete"),nonElRecordNameTransferId);
|
||||
//
|
||||
// HttpResponse elRecordNameHttpResponse = recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),new JSONObject().put("name","transfer"),recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
// getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordFullName, "/" + firstCategoryRM3060 + "/" + firstFolderRM3060));
|
||||
//
|
||||
// String elRecordNameTransferId = getTransferId(elRecordNameHttpResponse,elRecordNameNodeRef);
|
||||
// recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),new JSONObject().put("name","transferComplete"),elRecordNameTransferId);
|
||||
//
|
||||
// AssertJUnit.assertTrue("The file " + electronicRecordRM3060 + " has not been successfully transferred", getRestAPIFactory().getRecordsAPI().getRecord(firstElectronicRecord.getId()).getAspectNames().contains(TRANSFER_TYPE));
|
||||
// AssertJUnit.assertTrue("The file " + nonElectronicRecordRM3060 + " has not been successfully transferred.", getRestAPIFactory().getRecordsAPI().getRecord(secondNonElectronicRecord.getId()).getAspectNames().contains(TRANSFER_TYPE));
|
||||
//
|
||||
// // edit the disposition date for nonElectronicRecordRM3060 & electronicRecordRM3060
|
||||
// recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),editDispositionDateJson(),nonElRecordNameNodeRef);
|
||||
// recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),editDispositionDateJson(),elRecordNameNodeRef);
|
||||
//
|
||||
// // destroy nonElectronicRecordRM3060 & electronicRecordRM3060 records
|
||||
// recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),new JSONObject().put("name","destroy"),nonElRecordNameNodeRef);
|
||||
// recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
// getAdminUser().getPassword(),new JSONObject().put("name","destroy"),elRecordNameNodeRef);
|
||||
//
|
||||
// // check the file is not displayed
|
||||
// assertNull("The file " + nonElectronicRecordRM3060 + " has not been successfully destroyed.", secondNonElectronicRecord.getContent());
|
||||
// assertNull("The file " + electronicRecordRM3060 + " has not been successfully destroyed.", firstElectronicRecord.getContent());
|
||||
//
|
||||
// // delete precondition
|
||||
// deleteRecordCategory(recordCategory.getId());
|
||||
// deleteRecordCategory(categorySecondId);
|
||||
// }
|
||||
|
||||
//create retention schedule
|
||||
dispositionScheduleService.createCategoryRetentionSchedule(Category1.getName(), false);
|
||||
|
||||
// add cut off step
|
||||
dispositionScheduleService.addCutOffAfterPeriodStep(Category1.getName(), "day|2", CREATED_DATE);
|
||||
|
||||
//create a copy of the category recordsCategory
|
||||
String CopyCategoryId = copyCategory(getAdminUser(),Category1.getId(), copyCategoryRM3077);
|
||||
|
||||
// create folders in both categories
|
||||
CatFolder = createRecordFolder(Category1.getId(), folderRM3077);
|
||||
CopyCatFolder = createRecordFolder(CopyCategoryId, copyFolderRM3077);
|
||||
|
||||
// create record files
|
||||
String electronicRecord = "RM-2801 electronic record";
|
||||
Record elRecord = createElectronicRecord(CatFolder.getId(), electronicRecord);
|
||||
String elRecordFullName = recordsAPI.getRecordFullName(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
getDataUser().usingAdmin().getAdminUser().getPassword(), CatFolder.getName(), electronicRecord);
|
||||
|
||||
String nonElectronicRecord = "RM-2801 non-electronic record";
|
||||
Record nonElRecord = createNonElectronicRecord(CatFolder.getId(), nonElectronicRecord);
|
||||
String nonElRecordFullName = recordsAPI.getRecordFullName(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
getDataUser().usingAdmin().getAdminUser().getPassword(), CatFolder.getName(), nonElectronicRecord);
|
||||
|
||||
// link the records to copy folder, then complete them
|
||||
List<String> recordLists = new ArrayList<>();
|
||||
recordLists.add(NODE_REF_WORKSPACE_SPACES_STORE + elRecord.getId());
|
||||
recordLists.add(NODE_REF_WORKSPACE_SPACES_STORE + nonElRecord.getId());
|
||||
|
||||
linksAPI.linkRecord(getDataUser().getAdminUser().getUsername(),
|
||||
getDataUser().getAdminUser().getPassword(), HttpStatus.SC_OK,copyCategoryRM3077 + "/" +
|
||||
copyFolderRM3077, recordLists);
|
||||
recordsAPI.completeRecord(rmAdmin.getUsername(), rmAdmin.getPassword(), elRecordFullName);
|
||||
recordsAPI.completeRecord(rmAdmin.getUsername(), rmAdmin.getPassword(), nonElRecordFullName);
|
||||
|
||||
// edit disposition date
|
||||
recordFoldersAPI.postFolderAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),editDispositionDateJson(),CatFolder.getName());
|
||||
|
||||
// cut off the Folder
|
||||
recordFoldersAPI.postFolderAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),new JSONObject().put("name","cutoff"),CatFolder.getName());
|
||||
|
||||
// Verify the Content
|
||||
Node electronicNode = getNode(elRecord.getId());
|
||||
assertTrue("The content of " + electronicRecord + " is available",
|
||||
StringUtils.isEmpty(electronicNode.getNodeContent().getResponse().getBody().asString()));
|
||||
|
||||
// verify the Properties
|
||||
AssertJUnit.assertNull("The properties are present even after cutting off the record.", elRecord.getProperties().getTitle());
|
||||
|
||||
// delete precondition
|
||||
deleteRecordCategory(Category1.getId());
|
||||
deleteRecordCategory(CopyCategoryId);
|
||||
}
|
||||
/**
|
||||
* Test covering RM-3060
|
||||
* Check the disposition steps for a record can be executed
|
||||
* When the record is linked to a folder with the same disposition schedule
|
||||
* */
|
||||
@Test
|
||||
@AlfrescoTest (jira = "RM-3060")
|
||||
public void sameDispositionScheduleLinkedRecords() throws UnsupportedEncodingException {
|
||||
|
||||
// create a category with retention applied on records level
|
||||
RecordCategory recordCategory = getRestAPIFactory().getFilePlansAPI(rmAdmin)
|
||||
.createRootRecordCategory(RecordCategory.builder().name(firstCategoryRM3060).build(),
|
||||
RecordCategory.DEFAULT_FILE_PLAN_ALIAS);
|
||||
dispositionScheduleService.createCategoryRetentionSchedule(firstCategoryRM3060, true);
|
||||
dispositionScheduleService.addCutOffAfterPeriodStep(firstCategoryRM3060, "week|1", DATE_FILED);
|
||||
dispositionScheduleService.addTransferAfterEventStep(firstCategoryRM3060, TRANSFER_LOCATION, RMEvents.CASE_CLOSED.getEventName());
|
||||
dispositionScheduleService.addDestroyWithoutGhostingAfterPeriodStep(firstCategoryRM3060, "week|1", CUT_OFF_DATE);
|
||||
|
||||
// make a copy of the category created
|
||||
String categorySecondId = copyCategory(getAdminUser(), recordCategory.getId(), secondCategoryRM3060);
|
||||
|
||||
// create a folder on the category firstCategoryRM3060 with a complete electronic record
|
||||
RecordCategoryChild firstFolderRecordCategoryChild = createRecordFolder(recordCategory.getId(),firstFolderRM3060);
|
||||
Record firstElectronicRecord = createElectronicRecord(firstFolderRecordCategoryChild.getId(),electronicRecordRM3060);
|
||||
|
||||
String elRecordFullName = recordsAPI.getRecordFullName(getDataUser().getAdminUser().getUsername(),
|
||||
getDataUser().getAdminUser().getPassword(),firstFolderRM3060, electronicRecordRM3060);
|
||||
String elRecordNameNodeRef = recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordFullName, "/" + firstCategoryRM3060 + "/" + firstFolderRM3060);
|
||||
|
||||
recordsAPI.completeRecord(getDataUser().getAdminUser().getUsername(),
|
||||
getDataUser().getAdminUser().getPassword(), elRecordFullName);
|
||||
|
||||
// create a folder on the category secondCategoryRM3060 with a non electronic record
|
||||
RecordCategoryChild secondFolderRecordCategoryChild = createRecordFolder(categorySecondId,secondFolderRM3060);
|
||||
Record secondNonElectronicRecord = createNonElectronicRecord(secondFolderRecordCategoryChild.getId(),nonElectronicRecordRM3060);
|
||||
|
||||
// link the nonElectronicRecordRM3060 to firstFolderRM3060
|
||||
List<String> recordLists = new ArrayList<>();
|
||||
recordLists.add(NODE_REF_WORKSPACE_SPACES_STORE + secondNonElectronicRecord.getId());
|
||||
|
||||
linksAPI.linkRecord(getDataUser().getAdminUser().getUsername(),
|
||||
getDataUser().getAdminUser().getPassword(), HttpStatus.SC_OK,secondCategoryRM3060 + "/" +
|
||||
secondFolderRM3060, recordLists);
|
||||
String nonElRecordFullName = recordsAPI.getRecordFullName(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
getDataUser().usingAdmin().getAdminUser().getPassword(), secondFolderRM3060, secondNonElectronicRecord.getName());
|
||||
String nonElRecordNameNodeRef = recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
getDataUser().usingAdmin().getAdminUser().getPassword(), nonElRecordFullName, "/" + secondCategoryRM3060 + "/" + secondFolderRM3060);
|
||||
|
||||
// complete records and cut them off
|
||||
recordsAPI.completeRecord(getDataUser().getAdminUser().getUsername(),
|
||||
getDataUser().getAdminUser().getPassword(), nonElRecordFullName);
|
||||
|
||||
// edit the disposition date
|
||||
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),editDispositionDateJson(),nonElRecordNameNodeRef);
|
||||
|
||||
// cut off the record
|
||||
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),new JSONObject().put("name","cutoff"),nonElRecordNameNodeRef);
|
||||
|
||||
//check the record is cut off
|
||||
AssertJUnit.assertTrue("The file " + nonElectronicRecordRM3060 + " has not been successfully cut off.", getRestAPIFactory().getRecordsAPI().getRecord(secondNonElectronicRecord.getId()).getAspectNames().contains(CUT_OFF_ASPECT));
|
||||
|
||||
// link the electronic record to secondFolderRM3060
|
||||
recordLists.clear();
|
||||
recordLists.add(NODE_REF_WORKSPACE_SPACES_STORE + secondNonElectronicRecord.getId());
|
||||
linksAPI.linkRecord(getDataUser().getAdminUser().getUsername(),
|
||||
getDataUser().getAdminUser().getPassword(), HttpStatus.SC_OK,secondCategoryRM3060 + "/" +
|
||||
secondFolderRM3060, recordLists);
|
||||
|
||||
// edit the disposition date and cut off the record
|
||||
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),editDispositionDateJson(),elRecordNameNodeRef);
|
||||
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),new JSONObject().put("name","cutoff"),elRecordNameNodeRef);
|
||||
|
||||
AssertJUnit.assertTrue("The file " + electronicRecordRM3060 + " has not been successfully cut off.", getRestAPIFactory().getRecordsAPI().getRecord(firstElectronicRecord.getId()).getAspectNames().contains(CUT_OFF_ASPECT));
|
||||
|
||||
// open the record and complete the disposition schedule event
|
||||
rmRolesAndActionsAPI.completeEvent(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(), elRecordFullName, RMEvents.CASE_CLOSED, Instant.now());
|
||||
rmRolesAndActionsAPI.completeEvent(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(), nonElRecordFullName, RMEvents.CASE_CLOSED, Instant.now());
|
||||
|
||||
// transfer the files & complete transfers
|
||||
HttpResponse nonElRecordNameHttpResponse = recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),new JSONObject().put("name","transfer"),recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
getDataUser().usingAdmin().getAdminUser().getPassword(), nonElRecordFullName, "/" + secondCategoryRM3060 + "/" + secondFolderRM3060));
|
||||
|
||||
String nonElRecordNameTransferId = getTransferId(nonElRecordNameHttpResponse,nonElRecordNameNodeRef);
|
||||
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),new JSONObject().put("name","transferComplete"),nonElRecordNameTransferId);
|
||||
|
||||
HttpResponse elRecordNameHttpResponse = recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),new JSONObject().put("name","transfer"),recordsAPI.getRecordNodeRef(getDataUser().usingAdmin().getAdminUser().getUsername(),
|
||||
getDataUser().usingAdmin().getAdminUser().getPassword(), elRecordFullName, "/" + firstCategoryRM3060 + "/" + firstFolderRM3060));
|
||||
|
||||
String elRecordNameTransferId = getTransferId(elRecordNameHttpResponse,elRecordNameNodeRef);
|
||||
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),new JSONObject().put("name","transferComplete"),elRecordNameTransferId);
|
||||
|
||||
AssertJUnit.assertTrue("The file " + electronicRecordRM3060 + " has not been successfully transferred", getRestAPIFactory().getRecordsAPI().getRecord(firstElectronicRecord.getId()).getAspectNames().contains(TRANSFER_TYPE));
|
||||
AssertJUnit.assertTrue("The file " + nonElectronicRecordRM3060 + " has not been successfully transferred.", getRestAPIFactory().getRecordsAPI().getRecord(secondNonElectronicRecord.getId()).getAspectNames().contains(TRANSFER_TYPE));
|
||||
|
||||
// edit the disposition date for nonElectronicRecordRM3060 & electronicRecordRM3060
|
||||
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),editDispositionDateJson(),nonElRecordNameNodeRef);
|
||||
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),editDispositionDateJson(),elRecordNameNodeRef);
|
||||
|
||||
// destroy nonElectronicRecordRM3060 & electronicRecordRM3060 records
|
||||
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),new JSONObject().put("name","destroy"),nonElRecordNameNodeRef);
|
||||
recordFoldersAPI.postRecordAction(getAdminUser().getUsername(),
|
||||
getAdminUser().getPassword(),new JSONObject().put("name","destroy"),elRecordNameNodeRef);
|
||||
|
||||
// check the file is not displayed
|
||||
assertNull("The file " + nonElectronicRecordRM3060 + " has not been successfully destroyed.", secondNonElectronicRecord.getContent());
|
||||
assertNull("The file " + electronicRecordRM3060 + " has not been successfully destroyed.", firstElectronicRecord.getContent());
|
||||
|
||||
// delete precondition
|
||||
deleteRecordCategory(recordCategory.getId());
|
||||
deleteRecordCategory(categorySecondId);
|
||||
}
|
||||
private String copyCategory(UserModel user, String categoryId, String copyName) {
|
||||
RepoTestModel repoTestModel = new RepoTestModel() {};
|
||||
repoTestModel.setNodeRef(categoryId);
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-parent</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-governance-services-community-repo-parent</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
</parent>
|
||||
|
||||
<build>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-amps</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@@ -22,18 +22,21 @@ package org.alfresco.httpclient;
|
||||
import javax.net.ssl.KeyManager;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.TrustManager;
|
||||
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.apache.http.HttpHost;
|
||||
import org.apache.http.HttpRequestInterceptor;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.config.RegistryBuilder;
|
||||
import org.apache.http.conn.HttpClientConnectionManager;
|
||||
import org.apache.http.conn.socket.ConnectionSocketFactory;
|
||||
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
|
||||
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.impl.client.StandardHttpRequestRetryHandler;
|
||||
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
|
||||
|
||||
|
||||
public class HttpClient4Factory
|
||||
@@ -79,19 +82,19 @@ public class HttpClient4Factory
|
||||
throw new HttpClientException(msg);
|
||||
}
|
||||
});
|
||||
|
||||
SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(
|
||||
createSSLContext(config),
|
||||
new String[] { TLS_V_1_2, TLS_V_1_3 },
|
||||
null,
|
||||
config.isHostnameVerificationDisabled() ? new NoopHostnameVerifier() : SSLConnectionSocketFactory.getDefaultHostnameVerifier());
|
||||
clientBuilder.setSSLSocketFactory(sslConnectionSocketFactory);
|
||||
clientBuilder.setSSLSocketFactory(getSslConnectionSocketFactory(config));
|
||||
}
|
||||
|
||||
if(connectionManager != null)
|
||||
if (connectionManager != null)
|
||||
{
|
||||
clientBuilder.setConnectionManager(connectionManager);
|
||||
}
|
||||
else
|
||||
{
|
||||
//Setting a connectionManager overrides these properties
|
||||
clientBuilder.setMaxConnTotal(config.getMaxTotalConnections());
|
||||
clientBuilder.setMaxConnPerRoute(config.getMaxHostConnections());
|
||||
}
|
||||
|
||||
RequestConfig requestConfig = RequestConfig.custom()
|
||||
.setConnectTimeout(config.getConnectionTimeout())
|
||||
@@ -100,11 +103,41 @@ public class HttpClient4Factory
|
||||
.build();
|
||||
|
||||
clientBuilder.setDefaultRequestConfig(requestConfig);
|
||||
clientBuilder.setMaxConnTotal(config.getMaxTotalConnections());
|
||||
clientBuilder.setMaxConnPerRoute(config.getMaxHostConnections());
|
||||
|
||||
clientBuilder.setRetryHandler(new StandardHttpRequestRetryHandler(5, false));
|
||||
|
||||
return clientBuilder.build();
|
||||
}
|
||||
|
||||
private static SSLConnectionSocketFactory getSslConnectionSocketFactory(HttpClientConfig config)
|
||||
{
|
||||
return new SSLConnectionSocketFactory(
|
||||
createSSLContext(config),
|
||||
new String[] { TLS_V_1_2, TLS_V_1_3 },
|
||||
null,
|
||||
config.isHostnameVerificationDisabled() ? new NoopHostnameVerifier() : SSLConnectionSocketFactory.getDefaultHostnameVerifier());
|
||||
}
|
||||
|
||||
public static PoolingHttpClientConnectionManager createPoolingConnectionManager(HttpClientConfig config)
|
||||
{
|
||||
PoolingHttpClientConnectionManager poolingHttpClientConnectionManager;
|
||||
if(config.isMTLSEnabled())
|
||||
{
|
||||
poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(
|
||||
RegistryBuilder.<ConnectionSocketFactory>create()
|
||||
.register("https", getSslConnectionSocketFactory(config))
|
||||
.build());
|
||||
}
|
||||
else
|
||||
{
|
||||
poolingHttpClientConnectionManager = new PoolingHttpClientConnectionManager(
|
||||
RegistryBuilder.<ConnectionSocketFactory>create()
|
||||
.register("http", PlainConnectionSocketFactory.getSocketFactory())
|
||||
.build());
|
||||
}
|
||||
poolingHttpClientConnectionManager.setMaxTotal(config.getMaxTotalConnections());
|
||||
poolingHttpClientConnectionManager.setDefaultMaxPerRoute(config.getMaxHostConnections());
|
||||
|
||||
return poolingHttpClientConnectionManager;
|
||||
}
|
||||
}
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@@ -9,6 +9,6 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
</parent>
|
||||
</project>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
</parent>
|
||||
|
||||
<modules>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
</parent>
|
||||
|
||||
<organization>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
@@ -8,7 +8,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
@@ -680,17 +680,22 @@ public class RestWrapper extends DSLWrapper<RestWrapper>
|
||||
}
|
||||
else
|
||||
{
|
||||
if (returnedResponse.getContentType().contains("image/png"))
|
||||
{
|
||||
LOG.info("On {} {}, received the response with an image and headers: \n{}", restRequest.getHttpMethod(), restRequest.getPath(),
|
||||
returnedResponse.getHeaders().toString());
|
||||
}
|
||||
else if (returnedResponse.getContentType().contains("application/json") && !returnedResponse.asString().isEmpty())
|
||||
if (returnedResponse.asString().isEmpty())
|
||||
{
|
||||
LOG.info("On {} {}, received the following response \n{}", restRequest.getHttpMethod(), restRequest.getPath(),
|
||||
Utility.prettyPrintJsonString(returnedResponse.asString()));
|
||||
returnedResponse.getStatusCode());
|
||||
}
|
||||
else if (returnedResponse.getContentType().contains("application/xml") && !returnedResponse.asString().isEmpty())
|
||||
else if (returnedResponse.getContentType().contains("image/png"))
|
||||
{
|
||||
LOG.info("On {} {}, received the response with an image and headers: \n{}", restRequest.getHttpMethod(), restRequest.getPath(),
|
||||
returnedResponse.getHeaders().toString());
|
||||
}
|
||||
else if (returnedResponse.getContentType().contains("application/json"))
|
||||
{
|
||||
LOG.info("On {} {}, received the following response \n{}", restRequest.getHttpMethod(), restRequest.getPath(),
|
||||
Utility.prettyPrintJsonString(returnedResponse.asString()));
|
||||
}
|
||||
else if (returnedResponse.getContentType().contains("application/xml"))
|
||||
{
|
||||
String response = parseXML(returnedResponse);
|
||||
LOG.info("On {} {}, received the following response \n{}", restRequest.getHttpMethod(), restRequest.getPath(), response);
|
||||
@@ -698,7 +703,7 @@ public class RestWrapper extends DSLWrapper<RestWrapper>
|
||||
else
|
||||
{
|
||||
LOG.info("On {} {}, received the following response \n{}", restRequest.getHttpMethod(), restRequest.getPath(),
|
||||
ToStringBuilder.reflectionToString(returnedResponse.asString(), ToStringStyle.MULTI_LINE_STYLE));
|
||||
ToStringBuilder.reflectionToString(returnedResponse.asString(), ToStringStyle.MULTI_LINE_STYLE));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -60,7 +60,7 @@ public class RestErrorModel
|
||||
public static String INVALID_MAXITEMS = "Invalid paging parameter maxItems:%s";
|
||||
public static String INVALID_SKIPCOUNT = "Invalid paging parameter skipCount:%s";
|
||||
public static String INVALID_TAG = "Tag name must not contain %s char sequence";
|
||||
public static String EMPTY_TAG = "New tag cannot be null";
|
||||
public static String BLANK_TAG = "New tag cannot be blank";
|
||||
public static String UNKNOWN_ROLE = "Unknown role '%s'";
|
||||
public static String ALREADY_Site_MEMBER = "%s is already a member of site %s";
|
||||
public static String ALREADY_INVITED = "%s is already invited to site %s";
|
||||
|
@@ -32,8 +32,8 @@ public class GetTagsTests extends TagsDataPrep
|
||||
returnedCollection = restClient.withParams("maxItems=10000").withCoreAPI().getTags();
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
returnedCollection.assertThat().entriesListIsNotEmpty()
|
||||
.and().entriesListContains("tag", documentTagValue.toLowerCase())
|
||||
.and().entriesListContains("tag", documentTagValue2.toLowerCase());
|
||||
.and().entriesListContains("tag", documentTagValue)
|
||||
.and().entriesListContains("tag", documentTagValue2);
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, description = "Verify user with Collaborator role gets tags using REST API and status code is OK (200)")
|
||||
@@ -44,8 +44,8 @@ public class GetTagsTests extends TagsDataPrep
|
||||
returnedCollection = restClient.withParams("maxItems=10000").withCoreAPI().getTags();
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
returnedCollection.assertThat().entriesListIsNotEmpty()
|
||||
.and().entriesListContains("tag", documentTagValue.toLowerCase())
|
||||
.and().entriesListContains("tag", documentTagValue2.toLowerCase());
|
||||
.and().entriesListContains("tag", documentTagValue)
|
||||
.and().entriesListContains("tag", documentTagValue2);
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, description = "Verify user with Contributor role gets tags using REST API and status code is OK (200)")
|
||||
@@ -56,8 +56,8 @@ public class GetTagsTests extends TagsDataPrep
|
||||
returnedCollection = restClient.withParams("maxItems=10000").withCoreAPI().getTags();
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
returnedCollection.assertThat().entriesListIsNotEmpty()
|
||||
.and().entriesListContains("tag", documentTagValue.toLowerCase())
|
||||
.and().entriesListContains("tag", documentTagValue2.toLowerCase());
|
||||
.and().entriesListContains("tag", documentTagValue)
|
||||
.and().entriesListContains("tag", documentTagValue2);
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, description = "Verify user with Consumer role gets tags using REST API and status code is OK (200)")
|
||||
@@ -68,8 +68,8 @@ public class GetTagsTests extends TagsDataPrep
|
||||
returnedCollection = restClient.withParams("maxItems=10000").withCoreAPI().getTags();
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
returnedCollection.assertThat().entriesListIsNotEmpty()
|
||||
.and().entriesListContains("tag", documentTagValue.toLowerCase())
|
||||
.and().entriesListContains("tag", documentTagValue2.toLowerCase());
|
||||
.and().entriesListContains("tag", documentTagValue)
|
||||
.and().entriesListContains("tag", documentTagValue2);
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.SANITY, description = "Failed authentication get tags call returns status code 401 with Manager role")
|
||||
@@ -113,8 +113,8 @@ public class GetTagsTests extends TagsDataPrep
|
||||
returnedCollection = restClient.withParams("maxItems=10000").withCoreAPI().getTags();
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
returnedCollection.assertThat().entriesListIsNotEmpty()
|
||||
.and().entriesListContains("tag", documentTagValue.toLowerCase())
|
||||
.and().entriesListContains("tag", documentTagValue2.toLowerCase());
|
||||
.and().entriesListContains("tag", documentTagValue)
|
||||
.and().entriesListContains("tag", documentTagValue2);
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
@@ -126,7 +126,7 @@ public class GetTagsTests extends TagsDataPrep
|
||||
returnedCollection = restClient.withParams("maxItems=10000").withCoreAPI().getTags();
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
returnedCollection.assertThat().entriesListIsNotEmpty()
|
||||
.and().entriesListContains("tag", folderTagValue.toLowerCase());
|
||||
.and().entriesListContains("tag", folderTagValue);
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
@@ -139,8 +139,8 @@ public class GetTagsTests extends TagsDataPrep
|
||||
.withParams("maxItems=5000&properties=tag").withCoreAPI().getTags();
|
||||
restClient.assertStatusCodeIs(OK);
|
||||
returnedCollection.assertThat().entriesListIsNotEmpty()
|
||||
.and().entriesListContains("tag", documentTagValue.toLowerCase())
|
||||
.and().entriesListContains("tag", documentTagValue2.toLowerCase())
|
||||
.and().entriesListContains("tag", documentTagValue)
|
||||
.and().entriesListContains("tag", documentTagValue2)
|
||||
.and().entriesListDoesNotContain("id");
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ public class GetTagsTests extends TagsDataPrep
|
||||
|
||||
returnedCollection = restClient.withParams("maxItems=10000").withCoreAPI().getTags();
|
||||
returnedCollection.assertThat().entriesListIsNotEmpty()
|
||||
.and().entriesListDoesNotContain("tag", removedTag.toLowerCase());
|
||||
.and().entriesListDoesNotContain("tag", removedTag);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -243,7 +243,7 @@ public class GetTagsTests extends TagsDataPrep
|
||||
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedCollection.assertThat()
|
||||
.entrySetMatches("tag", Set.of(documentTagValue.toLowerCase()));
|
||||
.entrySetMatches("tag", Set.of(documentTagValue));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -260,7 +260,7 @@ public class GetTagsTests extends TagsDataPrep
|
||||
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedCollection.assertThat()
|
||||
.entrySetMatches("tag", Set.of(documentTagValue.toLowerCase(), folderTagValue.toLowerCase()));
|
||||
.entrySetMatches("tag", Set.of(documentTagValue, folderTagValue));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -271,13 +271,13 @@ public class GetTagsTests extends TagsDataPrep
|
||||
{
|
||||
STEP("Get tags with names filter using MATCHES and expect one item in result");
|
||||
returnedCollection = restClient.authenticateUser(adminUserModel)
|
||||
.withParams("where=(tag MATCHES ('orphan*'))")
|
||||
.withCoreAPI()
|
||||
.getTags();
|
||||
.withParams("where=(tag MATCHES ('orphan*'))", "maxItems=10000")
|
||||
.withCoreAPI()
|
||||
.getTags();
|
||||
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedCollection.assertThat()
|
||||
.entrySetContains("tag", orphanTag.getTag().toLowerCase());
|
||||
.entrySetContains("tag", orphanTag.getTag());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -288,13 +288,13 @@ public class GetTagsTests extends TagsDataPrep
|
||||
{
|
||||
STEP("Get tags with names filter using EQUALS and MATCHES and expect four items in result");
|
||||
returnedCollection = restClient.authenticateUser(adminUserModel)
|
||||
.withParams("where=(tag='" + orphanTag.getTag() + "' OR tag MATCHES ('*tag*'))")
|
||||
.withParams("where=(tag MATCHES ('*tag*'))", "maxItems=10000")
|
||||
.withCoreAPI()
|
||||
.getTags();
|
||||
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedCollection.assertThat()
|
||||
.entrySetContains("tag", documentTagValue.toLowerCase(), documentTagValue2.toLowerCase(), folderTagValue.toLowerCase(), orphanTag.getTag().toLowerCase());
|
||||
.entrySetContains("tag", documentTagValue, documentTagValue2, folderTagValue, orphanTag.getTag());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -305,17 +305,17 @@ public class GetTagsTests extends TagsDataPrep
|
||||
{
|
||||
STEP("Get tags applying names filter using MATCHES twice and expect four items in result");
|
||||
returnedCollection = restClient.authenticateUser(adminUserModel)
|
||||
.withParams("where=(tag MATCHES ('orphan*') OR tag MATCHES ('tag*'))")
|
||||
.withParams("where=(tag MATCHES ('orphan*') OR tag MATCHES ('tag*'))", "maxItems=10000")
|
||||
.withCoreAPI()
|
||||
.getTags();
|
||||
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedCollection.assertThat()
|
||||
.entrySetContains("tag", documentTagValue.toLowerCase(), documentTagValue2.toLowerCase(), folderTagValue.toLowerCase(), orphanTag.getTag().toLowerCase());
|
||||
.entrySetContains("tag", documentTagValue, documentTagValue2, folderTagValue, orphanTag.getTag());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify that providing incorrect field name in where query will result with 400 (Bad Request).
|
||||
* Verify that providing incorrect field name in where query will result with 400 (Bad Request).
|
||||
*/
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void testGetTags_withWrongWherePropertyNameAndExpect400()
|
||||
|
@@ -39,24 +39,25 @@ public class TagsDataPrep extends RestTest
|
||||
document = dataContent.usingUser(adminUserModel).usingSite(siteModel).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
||||
folder = dataContent.usingUser(adminUserModel).usingSite(siteModel).createFolder();
|
||||
|
||||
documentTagValue = RandomData.getRandomName("tag");
|
||||
documentTagValue2 = RandomData.getRandomName("tag");
|
||||
folderTagValue = RandomData.getRandomName("tag");
|
||||
documentTagValue = RandomData.getRandomName("tag").toLowerCase();
|
||||
documentTagValue2 = RandomData.getRandomName("tag").toLowerCase();
|
||||
folderTagValue = RandomData.getRandomName("tag").toLowerCase();
|
||||
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
documentTag = restClient.withCoreAPI().usingResource(document).addTag(documentTagValue);
|
||||
documentTag2 = restClient.withCoreAPI().usingResource(document).addTag(documentTagValue2);
|
||||
folderTag = restClient.withCoreAPI().usingResource(folder).addTag(folderTagValue);
|
||||
orphanTag = restClient.withCoreAPI().createSingleTag(RestTagModel.builder().tag(RandomData.getRandomName("orphan-tag")).create());
|
||||
orphanTag = restClient.withCoreAPI().createSingleTag(RestTagModel.builder().tag(RandomData.getRandomName("orphan-tag").toLowerCase()).create());
|
||||
|
||||
// Allow indexing to complete.
|
||||
Utility.sleep(500, 60000, () ->
|
||||
{
|
||||
returnedCollection = restClient.withParams("maxItems=10000", "where=(tag MATCHES ('*tag*'))")
|
||||
.withCoreAPI().getTags();
|
||||
returnedCollection.assertThat().entriesListContains("tag", documentTagValue.toLowerCase())
|
||||
.and().entriesListContains("tag", documentTagValue2.toLowerCase())
|
||||
.and().entriesListContains("tag", folderTagValue.toLowerCase());
|
||||
.withCoreAPI().getTags();
|
||||
returnedCollection.assertThat().entriesListContains("tag", documentTagValue)
|
||||
.and().entriesListContains("tag", documentTagValue2)
|
||||
.and().entriesListContains("tag", folderTagValue)
|
||||
.and().entriesListContains("tag", orphanTag.getTag());
|
||||
});
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package org.alfresco.rest.tags;
|
||||
|
||||
import static org.alfresco.utility.report.log.Step.STEP;
|
||||
import static org.testng.Assert.fail;
|
||||
|
||||
import org.alfresco.rest.model.RestErrorModel;
|
||||
import org.alfresco.rest.model.RestTagModel;
|
||||
@@ -15,6 +16,7 @@ import org.alfresco.utility.testrail.annotation.TestRail;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.testng.annotations.BeforeMethod;
|
||||
import org.testng.annotations.Ignore;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
@@ -27,17 +29,17 @@ public class UpdateTagTests extends TagsDataPrep
|
||||
private String randomTag = "";
|
||||
|
||||
@BeforeMethod(alwaysRun=true)
|
||||
public void addTagToDocument() throws Exception
|
||||
public void addTagToDocument()
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
oldTag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("old"));
|
||||
randomTag = RandomData.getRandomName("tag");
|
||||
oldTag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("old").toLowerCase());
|
||||
randomTag = RandomData.getRandomName("tag").toLowerCase();
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.SANITY, description = "Verify Admin user updates tags and status code is 200")
|
||||
@Bug(id="REPO-1828")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
|
||||
public void adminIsAbleToUpdateTags() throws Exception
|
||||
public void adminIsAbleToUpdateTags()
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
returnedModel = restClient.withCoreAPI().usingTag(oldTag).update(randomTag);
|
||||
@@ -49,7 +51,7 @@ public class UpdateTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API,
|
||||
TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, description = "Verify Manager user can't update tags with Rest API and status code is 403")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void managerIsNotAbleToUpdateTag() throws Exception
|
||||
public void managerIsNotAbleToUpdateTag()
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager));
|
||||
restClient.withCoreAPI().usingTag(oldTag).update(randomTag);
|
||||
@@ -59,7 +61,7 @@ public class UpdateTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS },
|
||||
executionType = ExecutionType.REGRESSION, description = "Verify Collaborator user can't update tags with Rest API and status code is 403")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void collaboratorIsNotAbleToUpdateTagCheckDefaultErrorModelSchema() throws Exception
|
||||
public void collaboratorIsNotAbleToUpdateTagCheckDefaultErrorModelSchema()
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator));
|
||||
restClient.withCoreAPI().usingTag(oldTag).update(randomTag);
|
||||
@@ -72,7 +74,7 @@ public class UpdateTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS },
|
||||
executionType = ExecutionType.REGRESSION, description = "Verify Contributor user can't update tags with Rest API and status code is 403")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void contributorIsNotAbleToUpdateTag() throws Exception
|
||||
public void contributorIsNotAbleToUpdateTag()
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor));
|
||||
restClient.withCoreAPI().usingTag(oldTag).update(randomTag);
|
||||
@@ -82,7 +84,7 @@ public class UpdateTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS },
|
||||
executionType = ExecutionType.SANITY, description = "Verify Consumer user can't update tags with Rest API and status code is 403")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void consumerIsNotAbleToUpdateTag() throws Exception
|
||||
public void consumerIsNotAbleToUpdateTag()
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer));
|
||||
restClient.withCoreAPI().usingTag(oldTag).update(randomTag);
|
||||
@@ -93,7 +95,7 @@ public class UpdateTagTests extends TagsDataPrep
|
||||
executionType = ExecutionType.SANITY, description = "Verify user gets status code 401 if authentication call fails")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
|
||||
// @Bug(id="MNT-16904", description = "It fails only on environment with tenants")
|
||||
public void userIsNotAbleToUpdateTagIfAuthenticationFails() throws Exception
|
||||
public void userIsNotAbleToUpdateTagIfAuthenticationFails()
|
||||
{
|
||||
UserModel siteManager = usersWithRoles.getOneUserWithRole(UserRole.SiteManager);
|
||||
String managerPassword = siteManager.getPassword();
|
||||
@@ -106,76 +108,93 @@ public class UpdateTagTests extends TagsDataPrep
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, description = "Verify admin is not able to update tag with invalid id")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void adminIsNotAbleToUpdateTagWithInvalidId() throws Exception
|
||||
public void adminIsNotAbleToUpdateTagWithInvalidId()
|
||||
{
|
||||
String invalidTagId = "invalid-id";
|
||||
RestTagModel tag = restClient.authenticateUser(adminUserModel).withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
RestTagModel tag = restClient.authenticateUser(adminUserModel).withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag").toLowerCase());
|
||||
tag.setId(invalidTagId);
|
||||
restClient.withCoreAPI().usingTag(tag).update(RandomData.getRandomName("tag"));
|
||||
restClient.withCoreAPI().usingTag(tag).update(RandomData.getRandomName("tag").toLowerCase());
|
||||
restClient.assertStatusCodeIs(HttpStatus.NOT_FOUND)
|
||||
.assertLastError().containsSummary(String.format(RestErrorModel.ENTITY_NOT_FOUND, invalidTagId));
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, description = "Verify admin is not able to update tag with empty id")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void adminIsNotAbleToUpdateTagWithEmptyId() throws Exception
|
||||
public void adminIsNotAbleToUpdateTagWithEmptyId()
|
||||
{
|
||||
RestTagModel tag = restClient.authenticateUser(adminUserModel).withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
RestTagModel tag = restClient.authenticateUser(adminUserModel).withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag").toLowerCase());
|
||||
tag.setId("");
|
||||
restClient.withCoreAPI().usingTag(tag).update(RandomData.getRandomName("tag"));
|
||||
restClient.withCoreAPI().usingTag(tag).update(RandomData.getRandomName("tag").toLowerCase());
|
||||
restClient.assertStatusCodeIs(HttpStatus.METHOD_NOT_ALLOWED)
|
||||
.assertLastError().containsSummary(RestErrorModel.PUT_EMPTY_ARGUMENT);
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, description = "Verify admin is not able to update tag with invalid body")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void adminIsNotAbleToUpdateTagWithEmptyBody() throws Exception
|
||||
public void adminIsNotAbleToUpdateTagWithEmptyBody()
|
||||
{
|
||||
RestTagModel tag = restClient.authenticateUser(adminUserModel).withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
RestTagModel tag = restClient.authenticateUser(adminUserModel).withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag").toLowerCase());
|
||||
restClient.withCoreAPI().usingTag(tag).update("");
|
||||
restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST)
|
||||
.assertLastError().containsSummary(RestErrorModel.EMPTY_TAG);
|
||||
.assertLastError().containsSummary(RestErrorModel.BLANK_TAG);
|
||||
}
|
||||
|
||||
@Bug(id="ACE-5629")
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify admin is not able to update tag with invalid body containing '|' symbol")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void adminIsNotAbleToUpdateTagWithInvalidBodyScenario1() throws Exception
|
||||
@Ignore
|
||||
public void adminIsNotAbleToUpdateTagWithInvalidBodyScenario1()
|
||||
{
|
||||
String invalidTagBody = "|.\"/<>*";
|
||||
RestTagModel tag = restClient.authenticateUser(adminUserModel).withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
Utility.sleep(500, 20000, () ->
|
||||
RestTagModel tag = restClient.authenticateUser(adminUserModel).withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag").toLowerCase());
|
||||
try
|
||||
{
|
||||
restClient.withCoreAPI().usingTag(tag).update(invalidTagBody);
|
||||
restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST)
|
||||
.assertLastError().containsSummary(String.format(RestErrorModel.INVALID_TAG, invalidTagBody));
|
||||
});
|
||||
Utility.sleep(500, 20000, () ->
|
||||
{
|
||||
restClient.withCoreAPI().usingTag(tag).update(invalidTagBody);
|
||||
restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST)
|
||||
.assertLastError().containsSummary(String.format(RestErrorModel.INVALID_TAG, invalidTagBody));
|
||||
});
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
fail("Test interrupted while waiting for error status code.");
|
||||
}
|
||||
}
|
||||
|
||||
@Bug(id="ACE-5629")
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify admin is not able to update tag with invalid body without '|' symbol")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void adminIsNotAbleToUpdateTagWithInvalidBodyScenario2() throws Exception
|
||||
@Ignore
|
||||
public void adminIsNotAbleToUpdateTagWithInvalidBodyScenario2()
|
||||
{
|
||||
String invalidTagBody = ".\"/<>*";
|
||||
RestTagModel tag = restClient.authenticateUser(adminUserModel).withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
Utility.sleep(500, 20000, () ->
|
||||
try
|
||||
{
|
||||
restClient.withCoreAPI().usingTag(tag).update(invalidTagBody);
|
||||
restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST)
|
||||
Utility.sleep(500, 20000, () ->
|
||||
{
|
||||
restClient.withCoreAPI().usingTag(tag).update(invalidTagBody);
|
||||
restClient.assertStatusCodeIs(HttpStatus.BAD_REQUEST)
|
||||
.assertLastError().containsSummary(String.format(RestErrorModel.INVALID_TAG, invalidTagBody));
|
||||
});
|
||||
});
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
fail("Test interrupted while waiting for error status code.");
|
||||
}
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify admin user can provide large string for new tag value.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
@Bug(id="REPO-1828")
|
||||
public void adminIsAbleToUpdateTagsProvideLargeStringTag() throws Exception
|
||||
@Ignore
|
||||
public void adminIsAbleToUpdateTagsProvideLargeStringTag()
|
||||
{
|
||||
String largeStringTag = RandomStringUtils.randomAlphanumeric(10000);
|
||||
String largeStringTag = RandomStringUtils.randomAlphanumeric(10000).toLowerCase();
|
||||
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
returnedModel = restClient.withCoreAPI().usingTag(oldTag).update(largeStringTag);
|
||||
@@ -188,9 +207,9 @@ public class UpdateTagTests extends TagsDataPrep
|
||||
description = "Verify admin user can provide short string for new tag value.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
@Bug(id="REPO-1828")
|
||||
public void adminIsAbleToUpdateTagsProvideShortStringTag() throws Exception
|
||||
public void adminIsAbleToUpdateTagsProvideShortStringTag()
|
||||
{
|
||||
String shortStringTag = RandomStringUtils.randomAlphanumeric(2);
|
||||
String shortStringTag = RandomStringUtils.randomAlphanumeric(2).toLowerCase();
|
||||
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
returnedModel = restClient.withCoreAPI().usingTag(oldTag).update(shortStringTag);
|
||||
@@ -203,9 +222,10 @@ public class UpdateTagTests extends TagsDataPrep
|
||||
description = "Verify admin user can provide string with special chars for new tag value.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
@Bug(id="REPO-1828")
|
||||
public void adminIsAbleToUpdateTagsProvideSpecialCharsStringTag() throws Exception
|
||||
@Ignore
|
||||
public void adminIsAbleToUpdateTagsProvideSpecialCharsStringTag()
|
||||
{
|
||||
String specialCharsString = "!@#$%^&*()'\".,<>-_+=|\\";
|
||||
String specialCharsString = RandomData.getRandomName("!@#$%^&*()'\".,<>-_+=|\\").toLowerCase();
|
||||
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
returnedModel = restClient.withCoreAPI().usingTag(oldTag).update(specialCharsString);
|
||||
@@ -218,9 +238,10 @@ public class UpdateTagTests extends TagsDataPrep
|
||||
description = "Verify Admin user can provide existing tag for new tag value.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
@Bug(id="REPO-1828")
|
||||
public void adminIsAbleToUpdateTagsProvideExistingTag() throws Exception
|
||||
@Ignore
|
||||
public void adminIsAbleToUpdateTagsProvideExistingTag()
|
||||
{
|
||||
String existingTag = "oldTag";
|
||||
String existingTag = RandomData.getRandomName("oldTag").toLowerCase();
|
||||
RestTagModel oldExistingTag = restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager))
|
||||
.withCoreAPI().usingResource(document).addTag(existingTag);
|
||||
restClient.assertStatusCodeIs(HttpStatus.CREATED);
|
||||
@@ -236,13 +257,14 @@ public class UpdateTagTests extends TagsDataPrep
|
||||
description = "Verify Admin user can delete a tag, add tag and update it.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
@Bug(id="REPO-1828")
|
||||
public void adminDeleteTagAddTagUpdateTag() throws Exception
|
||||
@Ignore
|
||||
public void adminDeleteTagAddTagUpdateTag()
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel)
|
||||
.withCoreAPI().usingResource(document).deleteTag(oldTag);
|
||||
restClient.assertStatusCodeIs(HttpStatus.NO_CONTENT);
|
||||
|
||||
String newTag = "addTag";
|
||||
String newTag = RandomData.getRandomName("addTag").toLowerCase();
|
||||
RestTagModel newTagModel = restClient.withCoreAPI().usingResource(document).addTag(newTag);
|
||||
restClient.assertStatusCodeIs(HttpStatus.CREATED);
|
||||
|
||||
@@ -256,9 +278,10 @@ public class UpdateTagTests extends TagsDataPrep
|
||||
description = "Verify Admin user can update a tag, delete tag and add it.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
@Bug(id="REPO-1828")
|
||||
public void adminUpdateTagDeleteTagAddTag() throws Exception
|
||||
@Ignore
|
||||
public void adminUpdateTagDeleteTagAddTag()
|
||||
{
|
||||
String newTag = "addTag";
|
||||
String newTag = RandomData.getRandomName("addTag").toLowerCase();
|
||||
|
||||
returnedModel = restClient.authenticateUser(adminUserModel).withCoreAPI().usingTag(oldTag).update(newTag);
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
@@ -278,11 +301,11 @@ public class UpdateTagTests extends TagsDataPrep
|
||||
public void adminIsAbleToUpdateOrphanTag()
|
||||
{
|
||||
STEP("Update orphan tag and expect 200");
|
||||
final String newTagName = RandomData.getRandomName("new");
|
||||
final String newTagName = RandomData.getRandomName("new").toLowerCase();
|
||||
returnedModel = restClient.authenticateUser(adminUserModel).withCoreAPI().usingTag(orphanTag).update(newTagName);
|
||||
|
||||
restClient.assertStatusCodeIs(HttpStatus.OK);
|
||||
returnedModel.assertThat().field("tag").is(newTagName);
|
||||
returnedModel.assertThat().field("id").isNotNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -33,13 +33,13 @@ public class AddTagTests extends TagsDataPrep
|
||||
@BeforeMethod(alwaysRun = true)
|
||||
public void generateRandomTag()
|
||||
{
|
||||
tagValue = RandomData.getRandomName("tag");
|
||||
tagValue = RandomData.getRandomName("tag").toLowerCase();
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify admin user adds tags with Rest API and status code is 201")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void adminIsAbleToAddTag() throws Exception
|
||||
public void adminIsAbleToAddTag()
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
returnedModel = restClient.withCoreAPI().usingResource(document).addTag(tagValue);
|
||||
@@ -51,7 +51,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.SANITY,
|
||||
description = "Verify Manager user adds tags with Rest API and status code is 201")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
|
||||
public void managerIsAbleToTagAFile() throws Exception
|
||||
public void managerIsAbleToTagAFile()
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager));
|
||||
returnedModel = restClient.withCoreAPI().usingResource(document).addTag(tagValue);
|
||||
@@ -63,7 +63,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Collaborator user adds tags with Rest API and status code is 201")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void collaboratorIsAbleToTagAFile() throws Exception
|
||||
public void collaboratorIsAbleToTagAFile()
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator));
|
||||
returnedModel = restClient.withCoreAPI().usingResource(document).addTag(tagValue);
|
||||
@@ -75,7 +75,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Contributor user doesn't have permission to add tags with Rest API and status code is 403")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void contributorIsNotAbleToAddTagToAnotherContent() throws Exception
|
||||
public void contributorIsNotAbleToAddTagToAnotherContent()
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor));
|
||||
restClient.withCoreAPI().usingResource(document).addTag(tagValue);
|
||||
@@ -85,7 +85,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Contributor user adds tags to his content with Rest API and status code is 201")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void contributorIsAbleToAddTagToHisContent() throws Exception
|
||||
public void contributorIsAbleToAddTagToHisContent()
|
||||
{
|
||||
userModel = usersWithRoles.getOneUserWithRole(UserRole.SiteContributor);
|
||||
restClient.authenticateUser(userModel);
|
||||
@@ -99,7 +99,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Consumer user doesn't have permission to add tags with Rest API and status code is 403")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void consumerIsNotAbleToTagAFile() throws Exception
|
||||
public void consumerIsNotAbleToTagAFile()
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer));
|
||||
restClient.withCoreAPI().usingResource(document).addTag(tagValue);
|
||||
@@ -110,7 +110,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
description = "Verify user gets status code 401 if authentication call fails")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
|
||||
// @Bug(id="MNT-16904", description = "It fails only on environment with tenants")
|
||||
public void userIsNotAbleToAddTagIfAuthenticationFails() throws Exception
|
||||
public void userIsNotAbleToAddTagIfAuthenticationFails()
|
||||
{
|
||||
UserModel siteManager = usersWithRoles.getOneUserWithRole(UserRole.SiteManager);
|
||||
String managerPassword = siteManager.getPassword();
|
||||
@@ -124,7 +124,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that adding empty tag returns status code 400")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void emptyTagTest() throws Exception
|
||||
public void emptyTagTest()
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
returnedModel = restClient.withCoreAPI().usingResource(document).addTag("");
|
||||
@@ -134,7 +134,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that adding tag with user that has no permissions returns status code 403")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void addTagWithUserThatDoesNotHavePermissions() throws Exception
|
||||
public void addTagWithUserThatDoesNotHavePermissions()
|
||||
{
|
||||
restClient.authenticateUser(dataUser.createRandomTestUser());
|
||||
returnedModel = restClient.withCoreAPI().usingResource(document).addTag(tagValue);
|
||||
@@ -144,7 +144,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that adding tag to a node that does not exist returns status code 404")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void addTagToInexistentNode() throws Exception
|
||||
public void addTagToInexistentNode()
|
||||
{
|
||||
String oldNodeRef = document.getNodeRef();
|
||||
String nodeRef = RandomStringUtils.randomAlphanumeric(10);
|
||||
@@ -159,7 +159,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.SANITY,
|
||||
description = "Verify that manager is able to tag a folder")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
|
||||
public void managerIsAbleToTagAFolder() throws Exception
|
||||
public void managerIsAbleToTagAFolder()
|
||||
{
|
||||
FolderModel folderModel = dataContent.usingUser(adminUserModel).usingSite(siteModel).createFolder();
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager));
|
||||
@@ -171,7 +171,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that tagged file can be tagged again")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void addTagToATaggedFile() throws Exception
|
||||
public void addTagToATaggedFile()
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
|
||||
@@ -195,7 +195,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that user cannot add invalid tag")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void addInvalidTag() throws Exception
|
||||
public void addInvalidTag()
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
returnedModel = restClient.withCoreAPI().usingResource(document).addTag("-1~!|@#$%^&*()_=");
|
||||
@@ -205,7 +205,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that contributor is able to tag a folder created by self")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void contributorIsAbleToTagAFolderCreatedBySelf() throws Exception
|
||||
public void contributorIsAbleToTagAFolderCreatedBySelf()
|
||||
{
|
||||
FolderModel folderModel = dataContent.usingUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor)).usingSite(siteModel).createFolder();
|
||||
|
||||
@@ -218,7 +218,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that collaborator is able to tag a folder")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void collaboratorIsAbleToTagAFolder() throws Exception
|
||||
public void collaboratorIsAbleToTagAFolder()
|
||||
{
|
||||
FolderModel folderModel = dataContent.usingUser(adminUserModel).usingSite(siteModel).createFolder();
|
||||
|
||||
@@ -231,7 +231,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that consumer is not able to tag a folder. Check default error model schema.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void consumerIsNotAbleToTagAFolder() throws Exception
|
||||
public void consumerIsNotAbleToTagAFolder()
|
||||
{
|
||||
FolderModel folderModel = dataContent.usingUser(adminUserModel).usingSite(siteModel).createFolder();
|
||||
|
||||
@@ -246,7 +246,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that tagged folder can be tagged again")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void addTagToATaggedFolder() throws Exception
|
||||
public void addTagToATaggedFolder()
|
||||
{
|
||||
FolderModel folderModel = dataContent.usingUser(adminUserModel).usingSite(siteModel).createFolder();
|
||||
|
||||
@@ -269,11 +269,11 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Using collaborator provide more than one tag element")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void provideMoreThanOneTagElement() throws Exception
|
||||
public void provideMoreThanOneTagElement()
|
||||
{
|
||||
FolderModel folderModel = dataContent.usingUser(adminUserModel).usingSite(siteModel).createFolder();
|
||||
String tagValue1 = RandomData.getRandomName("tag1");
|
||||
String tagValue2 = RandomData.getRandomName("tag2");
|
||||
String tagValue1 = RandomData.getRandomName("tag1").toLowerCase();
|
||||
String tagValue2 = RandomData.getRandomName("tag2").toLowerCase();
|
||||
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator));
|
||||
|
||||
@@ -288,7 +288,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that manager cannot add tag with special characters.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void addTagWithSpecialCharacters() throws Exception
|
||||
public void addTagWithSpecialCharacters()
|
||||
{
|
||||
FolderModel folderModel = dataContent.usingUser(adminUserModel).usingSite(siteModel).createFolder();
|
||||
String specialCharsTag = "!@#$%^&*()'\".,<>-_+=|\\";
|
||||
@@ -301,7 +301,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that you cannot tag a comment and it returns status code 405")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void addTagToAComment() throws Exception
|
||||
public void addTagToAComment()
|
||||
{
|
||||
FileModel file = dataContent.usingSite(siteModel).usingUser(adminUserModel).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
||||
String comment = "comment for a tag";
|
||||
@@ -316,7 +316,7 @@ public class AddTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that you cannot tag a tag and it returns status code 405")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void addTagToATag() throws Exception
|
||||
public void addTagToATag()
|
||||
{
|
||||
FileModel file = dataContent.usingSite(siteModel).usingUser(adminUserModel).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
||||
|
||||
@@ -326,4 +326,17 @@ public class AddTagTests extends TagsDataPrep
|
||||
restClient.withCoreAPI().usingResource(file).addTag(tagValue);
|
||||
restClient.assertStatusCodeIs(HttpStatus.METHOD_NOT_ALLOWED).assertLastError().containsSummary(RestErrorModel.CANNOT_TAG);
|
||||
}
|
||||
}
|
||||
|
||||
@TestRail (section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify the tag name is converted to lower case before being applied")
|
||||
@Test (groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void tagNameIsConvertedToLowerCase()
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
String tagName = RandomData.getRandomName("TaG-oNe");
|
||||
returnedModel = restClient.withCoreAPI().usingResource(document).addTag(tagName);
|
||||
restClient.assertStatusCodeIs(HttpStatus.CREATED);
|
||||
returnedModel.assertThat().field("tag").is(tagName.toLowerCase())
|
||||
.and().field("id").isNotEmpty();
|
||||
}
|
||||
}
|
||||
|
@@ -30,14 +30,14 @@ public class AddTagsTests extends TagsDataPrep
|
||||
@BeforeMethod(alwaysRun = true)
|
||||
public void generateRandomTagsList()
|
||||
{
|
||||
tag1 = RandomData.getRandomName("tag");
|
||||
tag2 = RandomData.getRandomName("tag");
|
||||
tag1 = RandomData.getRandomName("tag").toLowerCase();
|
||||
tag2 = RandomData.getRandomName("tag").toLowerCase();
|
||||
}
|
||||
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify admin user adds multiple tags with Rest API and status code is 201")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void adminIsAbleToAddTags() throws Exception
|
||||
public void adminIsAbleToAddTags()
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
returnedCollection = restClient.withCoreAPI().usingResource(document).addTags(tag1, tag2);
|
||||
@@ -49,7 +49,7 @@ public class AddTagsTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.SANITY,
|
||||
description = "Verify Manager user adds multiple tags with Rest API and status code is 201")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
|
||||
public void managerIsAbleToAddTags() throws Exception
|
||||
public void managerIsAbleToAddTags()
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteManager));
|
||||
returnedCollection = restClient.withCoreAPI().usingResource(document).addTags(tag1, tag2);
|
||||
@@ -61,7 +61,7 @@ public class AddTagsTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS },
|
||||
executionType = ExecutionType.SANITY, description = "Verify Collaborator user adds multiple tags with Rest API and status code is 201")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void collaboratorIsAbleToAddTags() throws Exception
|
||||
public void collaboratorIsAbleToAddTags()
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator));
|
||||
returnedCollection = restClient.withCoreAPI().usingResource(document).addTags(tag1, tag2);
|
||||
@@ -73,7 +73,7 @@ public class AddTagsTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Contributor user doesn't have permission to add multiple tags with Rest API and status code is 403")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void contributorIsNotAbleToAddTagsToAnotherContent() throws Exception
|
||||
public void contributorIsNotAbleToAddTagsToAnotherContent()
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteContributor));
|
||||
restClient.withCoreAPI().usingResource(document).addTags(tag1, tag2);
|
||||
@@ -83,7 +83,7 @@ public class AddTagsTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Contributor user adds multiple tags to his content with Rest API and status code is 201")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void contributorIsAbleToAddTagsToHisContent() throws Exception
|
||||
public void contributorIsAbleToAddTagsToHisContent()
|
||||
{
|
||||
userModel = usersWithRoles.getOneUserWithRole(UserRole.SiteContributor);
|
||||
restClient.authenticateUser(userModel);
|
||||
@@ -97,7 +97,7 @@ public class AddTagsTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Consumer user doesn't have permission to add multiple tags with Rest API and status code is 403")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void consumerIsNotAbleToAddTags() throws Exception
|
||||
public void consumerIsNotAbleToAddTags()
|
||||
{
|
||||
restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteConsumer)).withCoreAPI().usingResource(document).addTags(tag1, tag2);
|
||||
restClient.assertStatusCodeIs(HttpStatus.FORBIDDEN).assertLastError().containsSummary(RestErrorModel.PERMISSION_WAS_DENIED);
|
||||
@@ -107,7 +107,7 @@ public class AddTagsTests extends TagsDataPrep
|
||||
description = "Verify user gets status code 401 if authentication call fails")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
|
||||
// @Bug(id="MNT-16904", description = "It fails only on environment with tenants")
|
||||
public void userIsNotAbleToAddTagsIfAuthenticationFails() throws Exception
|
||||
public void userIsNotAbleToAddTagsIfAuthenticationFails()
|
||||
{
|
||||
UserModel siteManager = usersWithRoles.getOneUserWithRole(UserRole.SiteManager);
|
||||
String managerPassword = siteManager.getPassword();
|
||||
@@ -120,7 +120,7 @@ public class AddTagsTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API,
|
||||
TestGroup.TAGS }, executionType = ExecutionType.REGRESSION, description = "Verify include count parameter")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void getTagsUsingCountParam() throws Exception
|
||||
public void getTagsUsingCountParam()
|
||||
{
|
||||
FileModel file = dataContent.usingSite(siteModel).usingUser(adminUserModel).createContent(CMISUtil.DocumentType.TEXT_PLAIN);
|
||||
String tagName = RandomData.getRandomName("tag");
|
||||
@@ -139,4 +139,4 @@ public class AddTagsTests extends TagsDataPrep
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -15,6 +15,7 @@ import org.alfresco.utility.testrail.ExecutionType;
|
||||
import org.alfresco.utility.testrail.annotation.TestRail;
|
||||
import org.apache.commons.lang3.RandomStringUtils;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.testng.annotations.Ignore;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
/**
|
||||
@@ -29,7 +30,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Admin user deletes tags with Rest API and status code is 204")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void adminIsAbleToDeleteTags() throws Exception
|
||||
public void adminIsAbleToDeleteTags()
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
tag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
@@ -43,7 +44,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.SANITY,
|
||||
description = "Verify Manager user deletes tags created by admin user with Rest API and status code is 204")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
|
||||
public void managerIsAbleToDeleteTags() throws Exception
|
||||
public void managerIsAbleToDeleteTags()
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
tag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
@@ -56,7 +57,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Collaborator user deletes tags created by admin user with Rest API and status code is 204")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void collaboratorIsAbleToDeleteTags() throws Exception
|
||||
public void collaboratorIsAbleToDeleteTags()
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
tag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
@@ -69,7 +70,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Contributor user can't delete tags created by admin user with Rest API and status code is 403")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void contributorIsNotAbleToDeleteTagsForAnotherUserContent() throws Exception
|
||||
public void contributorIsNotAbleToDeleteTagsForAnotherUserContent()
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
tag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
@@ -82,7 +83,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Contributor user deletes tags created by him with Rest API and status code is 204")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void contributorIsAbleToDeleteTagsForHisContent() throws Exception
|
||||
public void contributorIsAbleToDeleteTagsForHisContent()
|
||||
{
|
||||
userModel = usersWithRoles.getOneUserWithRole(UserRole.SiteContributor);
|
||||
restClient.authenticateUser(userModel);
|
||||
@@ -96,7 +97,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify Consumer user can't delete tags created by admin user with Rest API and status code is 403")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void consumerIsNotAbleToDeleteTags() throws Exception
|
||||
public void consumerIsNotAbleToDeleteTags()
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
tag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
@@ -110,7 +111,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
description = "Verify user gets status code 401 if authentication call fails")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.SANITY })
|
||||
// @Bug(id="MNT-16904", description = "It fails only on environment with tenants")
|
||||
public void userIsNotAbleToDeleteTagIfAuthenticationFails() throws Exception
|
||||
public void userIsNotAbleToDeleteTagIfAuthenticationFails()
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
tag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
@@ -127,7 +128,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that if user has no permission to remove tag returned status code is 403. Check default error model schema")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void deleteTagWithUserWithoutPermissionCheckDefaultErrorModelSchema() throws Exception
|
||||
public void deleteTagWithUserWithoutPermissionCheckDefaultErrorModelSchema()
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
RestTagModel tag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
@@ -144,7 +145,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that if node does not exist returned status code is 404")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void deleteTagForANonexistentNode() throws Exception
|
||||
public void deleteTagForANonexistentNode()
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
RestTagModel tag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
@@ -159,7 +160,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that if tag does not exist returned status code is 404")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void deleteTagThatDoesNotExist() throws Exception
|
||||
public void deleteTagThatDoesNotExist()
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
RestTagModel tag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
@@ -172,7 +173,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that if tag id is empty returned status code is 405")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void deleteTagWithEmptyId() throws Exception
|
||||
public void deleteTagWithEmptyId()
|
||||
{
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
RestTagModel tag = restClient.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
@@ -185,7 +186,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS }, executionType = ExecutionType.REGRESSION,
|
||||
description = "Verify that folder tag can be deleted")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void deleteFolderTag() throws Exception
|
||||
public void deleteFolderTag()
|
||||
{
|
||||
FolderModel folderModel = dataContent.usingUser(adminUserModel).usingSite(siteModel).createFolder();;
|
||||
restClient.authenticateUser(adminUserModel);
|
||||
@@ -200,7 +201,8 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
executionType = ExecutionType.REGRESSION, description = "Verify Manager user can't delete deleted tag.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
@Bug(id = "ACE-5455")
|
||||
public void managerCannotDeleteDeletedTag() throws Exception
|
||||
@Ignore
|
||||
public void managerCannotDeleteDeletedTag()
|
||||
{
|
||||
tag = restClient.authenticateUser(adminUserModel)
|
||||
.withCoreAPI().usingResource(document).addTag(RandomData.getRandomName("tag"));
|
||||
@@ -216,7 +218,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS },
|
||||
executionType = ExecutionType.REGRESSION, description = "Verify Collaborator user can delete long tag.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void userCollaboratorCanDeleteLongTag() throws Exception
|
||||
public void userCollaboratorCanDeleteLongTag()
|
||||
{
|
||||
String longTag = RandomStringUtils.randomAlphanumeric(800);
|
||||
|
||||
@@ -231,7 +233,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS },
|
||||
executionType = ExecutionType.REGRESSION, description = "Verify Manager user can delete short tag.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void managerCanDeleteShortTag() throws Exception
|
||||
public void managerCanDeleteShortTag()
|
||||
{
|
||||
String shortTag = RandomStringUtils.randomAlphanumeric(10);
|
||||
|
||||
@@ -246,7 +248,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS },
|
||||
executionType = ExecutionType.REGRESSION, description = "Verify Admin can delete tag then add it again.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void adminRemovesTagAndAddsItAgain() throws Exception
|
||||
public void adminRemovesTagAndAddsItAgain()
|
||||
{
|
||||
String tagValue = RandomStringUtils.randomAlphanumeric(10);
|
||||
|
||||
@@ -267,7 +269,7 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
@TestRail(section = { TestGroup.REST_API, TestGroup.TAGS },
|
||||
executionType = ExecutionType.REGRESSION, description = "Verify Manager user can delete tag added by another user.")
|
||||
@Test(groups = { TestGroup.REST_API, TestGroup.TAGS, TestGroup.REGRESSION })
|
||||
public void managerCanDeleteTagAddedByAnotherUser() throws Exception
|
||||
public void managerCanDeleteTagAddedByAnotherUser()
|
||||
{
|
||||
tag = restClient.authenticateUser(usersWithRoles.getOneUserWithRole(UserRole.SiteCollaborator))
|
||||
.withCoreAPI().usingResource(document).addTag(RandomStringUtils.randomAlphanumeric(10));
|
||||
@@ -276,4 +278,4 @@ public class DeleteTagTests extends TagsDataPrep
|
||||
.withCoreAPI().usingResource(document).deleteTag(tag);
|
||||
restClient.assertStatusCodeIs(HttpStatus.NO_CONTENT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -9,7 +9,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-tests</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
</parent>
|
||||
|
||||
<developers>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo-packaging</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
|
12
pom.xml
12
pom.xml
@@ -2,7 +2,7 @@
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Alfresco Community Repo Parent</name>
|
||||
|
||||
@@ -52,8 +52,8 @@
|
||||
<dependency.alfresco-messaging-repo.version>1.2.20</dependency.alfresco-messaging-repo.version>
|
||||
<dependency.activiti-engine.version>5.23.0</dependency.activiti-engine.version>
|
||||
<dependency.activiti.version>5.23.0</dependency.activiti.version>
|
||||
<dependency.alfresco-transform-service.version>2.1.0-A2</dependency.alfresco-transform-service.version>
|
||||
<dependency.alfresco-transform-core.version>3.1.0-A2</dependency.alfresco-transform-core.version>
|
||||
<dependency.alfresco-transform-service.version>2.1.0-A5</dependency.alfresco-transform-service.version>
|
||||
<dependency.alfresco-transform-core.version>3.1.0-A5</dependency.alfresco-transform-core.version>
|
||||
<dependency.alfresco-greenmail.version>6.5</dependency.alfresco-greenmail.version>
|
||||
<dependency.acs-event-model.version>0.0.18</dependency.acs-event-model.version>
|
||||
|
||||
@@ -107,8 +107,8 @@
|
||||
<dependency.jakarta-jws-api.version>2.1.0</dependency.jakarta-jws-api.version>
|
||||
<dependency.jakarta-mail-api.version>1.6.5</dependency.jakarta-mail-api.version>
|
||||
<dependency.jakarta-json-api.version>1.1.6</dependency.jakarta-json-api.version>
|
||||
<dependency.jakarta-json-path.version>2.7.0</dependency.jakarta-json-path.version>
|
||||
<dependency.json-smart.version>2.4.8</dependency.json-smart.version>
|
||||
<dependency.jakarta-json-path.version>2.8.0</dependency.jakarta-json-path.version>
|
||||
<dependency.json-smart.version>2.4.10</dependency.json-smart.version>
|
||||
<dependency.jakarta-rpc-api.version>1.1.4</dependency.jakarta-rpc-api.version>
|
||||
|
||||
<alfresco.googledrive.version>3.4.0-M1</alfresco.googledrive.version>
|
||||
@@ -150,7 +150,7 @@
|
||||
<connection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</connection>
|
||||
<developerConnection>scm:git:https://github.com/Alfresco/alfresco-community-repo.git</developerConnection>
|
||||
<url>https://github.com/Alfresco/alfresco-community-repo</url>
|
||||
<tag>20.128</tag>
|
||||
<tag>20.139</tag>
|
||||
</scm>
|
||||
|
||||
<distributionManagement>
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
|
@@ -30,6 +30,7 @@ import static java.util.stream.Collectors.toList;
|
||||
import static org.alfresco.rest.antlr.WhereClauseParser.EQUALS;
|
||||
import static org.alfresco.rest.antlr.WhereClauseParser.IN;
|
||||
import static org.alfresco.rest.antlr.WhereClauseParser.MATCHES;
|
||||
import static org.alfresco.service.cmr.tagging.TaggingService.TAG_ROOT_NODE_REF;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -83,7 +84,6 @@ public class TagsImpl implements Tags
|
||||
private static final String PARAM_WHERE_TAG = "tag";
|
||||
static final String NOT_A_VALID_TAG = "An invalid parameter has been supplied";
|
||||
static final String NO_PERMISSION_TO_MANAGE_A_TAG = "Current user does not have permission to manage a tag";
|
||||
private final NodeRef tagParentNodeRef = new NodeRef("workspace://SpacesStore/tag:tag-root");
|
||||
|
||||
private Nodes nodes;
|
||||
private NodeService nodeService;
|
||||
@@ -329,7 +329,7 @@ public class TagsImpl implements Tags
|
||||
|
||||
private NodeRef checkTagRootAsNodePrimaryParent(String tagId, NodeRef tagNodeRef)
|
||||
{
|
||||
if ( tagNodeRef == null || !nodeService.getPrimaryParent(tagNodeRef).getParentRef().equals(tagParentNodeRef))
|
||||
if ( tagNodeRef == null || !nodeService.getPrimaryParent(tagNodeRef).getParentRef().equals(TAG_ROOT_NODE_REF))
|
||||
{
|
||||
throw new EntityNotFoundException(tagId);
|
||||
}
|
||||
|
@@ -26,6 +26,7 @@
|
||||
package org.alfresco.rest.api.model;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||
import org.alfresco.rest.framework.resource.UniqueId;
|
||||
@@ -50,7 +51,7 @@ public class Tag implements Comparable<Tag>
|
||||
public Tag(NodeRef nodeRef, String tag)
|
||||
{
|
||||
this.nodeRef = nodeRef;
|
||||
this.tag = tag;
|
||||
setTag(tag);
|
||||
}
|
||||
|
||||
@JsonProperty("id")
|
||||
@@ -72,7 +73,7 @@ public class Tag implements Comparable<Tag>
|
||||
|
||||
public void setTag(String tag)
|
||||
{
|
||||
this.tag = tag;
|
||||
this.tag = Optional.ofNullable(tag).map(String::toLowerCase).orElse(null);
|
||||
}
|
||||
|
||||
public Integer getCount()
|
||||
|
@@ -157,21 +157,21 @@ public class TagsImplTest
|
||||
{
|
||||
NodeRef tagNodeA = new NodeRef("tag://A/");
|
||||
NodeRef tagNodeB = new NodeRef("tag://B/");
|
||||
List<Pair<NodeRef, String>> tagPairs = List.of(new Pair<>(tagNodeA, "tagA"), new Pair<>(tagNodeB, "tagB"));
|
||||
List<Pair<NodeRef, String>> tagPairs = List.of(new Pair<>(tagNodeA, "taga"), new Pair<>(tagNodeB, "tagb"));
|
||||
|
||||
given(parametersMock.getPaging()).willReturn(pagingMock);
|
||||
given(taggingServiceMock.getTags(any(StoreRef.class), any(PagingRequest.class), any(), any())).willReturn(pagingResultsMock);
|
||||
given(pagingResultsMock.getTotalResultCount()).willReturn(new Pair<>(Integer.MAX_VALUE, 0));
|
||||
given(pagingResultsMock.getPage()).willReturn(tagPairs);
|
||||
given(parametersMock.getInclude()).willReturn(List.of("count"));
|
||||
// Only tagA is included in the returned list since tagB is not in use.
|
||||
given(taggingServiceMock.findTaggedNodesAndCountByTagName(STORE_REF_WORKSPACE_SPACESSTORE)).willReturn(List.of(new Pair<>("tagA", 5)));
|
||||
// Only taga is included in the returned list since tagb is not in use.
|
||||
given(taggingServiceMock.findTaggedNodesAndCountByTagName(STORE_REF_WORKSPACE_SPACESSTORE)).willReturn(List.of(new Pair<>("taga", 5)));
|
||||
|
||||
final CollectionWithPagingInfo<Tag> actualTags = objectUnderTest.getTags(STORE_REF_WORKSPACE_SPACESSTORE, parametersMock);
|
||||
|
||||
then(taggingServiceMock).should().findTaggedNodesAndCountByTagName(STORE_REF_WORKSPACE_SPACESSTORE);
|
||||
final List<Tag> expectedTags = List.of(Tag.builder().tag("tagA").nodeRef(tagNodeA).count(5).create(),
|
||||
Tag.builder().tag("tagB").nodeRef(tagNodeB).count(0).create());
|
||||
final List<Tag> expectedTags = List.of(Tag.builder().tag("taga").nodeRef(tagNodeA).count(5).create(),
|
||||
Tag.builder().tag("tagb").nodeRef(tagNodeB).count(0).create());
|
||||
assertEquals(expectedTags, actualTags.getCollection());
|
||||
}
|
||||
|
||||
@@ -450,17 +450,17 @@ public class TagsImplTest
|
||||
NodeRef tagNodeB = new NodeRef("tag://B/");
|
||||
given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID)).willReturn(CONTENT_NODE_REF);
|
||||
given(typeConstraintMock.matches(CONTENT_NODE_REF)).willReturn(true);
|
||||
List<Pair<String, NodeRef>> pairs = List.of(new Pair<>("tagA", new NodeRef("tag://A/")), new Pair<>("tagB", new NodeRef("tag://B/")));
|
||||
List<Pair<String, NodeRef>> pairs = List.of(new Pair<>("taga", new NodeRef("tag://A/")), new Pair<>("tagb", new NodeRef("tag://B/")));
|
||||
List<String> tagNames = pairs.stream().map(Pair::getFirst).collect(toList());
|
||||
List<Tag> tags = tagNames.stream().map(name -> Tag.builder().tag(name).create()).collect(toList());
|
||||
given(taggingServiceMock.addTags(CONTENT_NODE_REF, tagNames)).willReturn(pairs);
|
||||
given(taggingServiceMock.findTaggedNodesAndCountByTagName(STORE_REF_WORKSPACE_SPACESSTORE)).willReturn(List.of(new Pair<>("tagA", 4)));
|
||||
given(taggingServiceMock.findTaggedNodesAndCountByTagName(STORE_REF_WORKSPACE_SPACESSTORE)).willReturn(List.of(new Pair<>("taga", 4)));
|
||||
given(parametersMock.getInclude()).willReturn(List.of("count"));
|
||||
|
||||
List<Tag> actual = objectUnderTest.addTags(CONTENT_NODE_ID, tags, parametersMock);
|
||||
|
||||
final List<Tag> expected = List.of(Tag.builder().tag("tagA").nodeRef(tagNodeA).count(5).create(),
|
||||
Tag.builder().tag("tagB").nodeRef(tagNodeB).count(1).create());
|
||||
final List<Tag> expected = List.of(Tag.builder().tag("taga").nodeRef(tagNodeA).count(5).create(),
|
||||
Tag.builder().tag("tagb").nodeRef(tagNodeB).count(1).create());
|
||||
assertEquals("Unexpected tags returned.", expected, actual);
|
||||
}
|
||||
|
||||
@@ -489,7 +489,7 @@ public class TagsImplTest
|
||||
{
|
||||
given(nodesMock.validateOrLookupNode(CONTENT_NODE_ID)).willReturn(CONTENT_NODE_REF);
|
||||
given(parametersMock.getPaging()).willReturn(pagingMock);
|
||||
List<Pair<NodeRef, String>> pairs = List.of(new Pair<>(new NodeRef("tag://A/"), "tagA"), new Pair<>(new NodeRef("tag://B/"), "tagB"));
|
||||
List<Pair<NodeRef, String>> pairs = List.of(new Pair<>(new NodeRef("tag://A/"), "taga"), new Pair<>(new NodeRef("tag://B/"), "tagb"));
|
||||
given(taggingServiceMock.getTags(eq(CONTENT_NODE_REF), any(PagingRequest.class))).willReturn(pagingResultsMock);
|
||||
given(pagingResultsMock.getTotalResultCount()).willReturn(new Pair<>(null, null));
|
||||
given(pagingResultsMock.getPage()).willReturn(pairs);
|
||||
|
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>org.alfresco</groupId>
|
||||
<artifactId>alfresco-community-repo</artifactId>
|
||||
<version>20.128</version>
|
||||
<version>20.139</version>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
@@ -809,6 +809,10 @@
|
||||
<artifactId>reflections</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-lang</groupId>
|
||||
<artifactId>commons-lang</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
|
@@ -1,28 +1,28 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.email.server;
|
||||
|
||||
import java.util.HashSet;
|
||||
@@ -37,10 +37,7 @@ import org.alfresco.service.cmr.email.EmailMessageException;
|
||||
import org.alfresco.service.cmr.email.EmailService;
|
||||
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
|
||||
import org.alfresco.util.PropertyCheck;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.context.support.AbstractApplicationContext;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
/**
|
||||
* Base implementation of an email server.
|
||||
@@ -62,13 +59,13 @@ public abstract class EmailServer extends AbstractLifecycleBean
|
||||
private boolean requireTLS = false;
|
||||
private boolean authenticate = false;
|
||||
|
||||
private EmailService emailService;
|
||||
private AuthenticationComponent authenticationComponent;
|
||||
private EmailService emailService;
|
||||
private AuthenticationComponent authenticationComponent;
|
||||
private String unknownUser;
|
||||
|
||||
protected EmailServer()
|
||||
{
|
||||
this.enabled = false;
|
||||
|
||||
protected EmailServer()
|
||||
{
|
||||
this.enabled = false;
|
||||
this.port = 25;
|
||||
this.domain = null;
|
||||
this.maxConnections = 3;
|
||||
@@ -301,60 +298,6 @@ public abstract class EmailServer extends AbstractLifecycleBean
|
||||
}
|
||||
}
|
||||
|
||||
private static volatile Boolean stop = false;
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
if (args.length == 0)
|
||||
{
|
||||
usage();
|
||||
return;
|
||||
}
|
||||
|
||||
try (AbstractApplicationContext context = new ClassPathXmlApplicationContext(args))
|
||||
{
|
||||
if (!context.containsBean("emailServer"))
|
||||
{
|
||||
usage();
|
||||
return;
|
||||
}
|
||||
|
||||
Runtime.getRuntime().addShutdownHook(new Thread() {
|
||||
public void run()
|
||||
{
|
||||
stop = true;
|
||||
synchronized (stop)
|
||||
{
|
||||
stop.notifyAll();
|
||||
}
|
||||
}
|
||||
});
|
||||
System.out.println("Use Ctrl-C to shutdown EmailServer");
|
||||
|
||||
while (!stop)
|
||||
{
|
||||
synchronized (stop)
|
||||
{
|
||||
stop.wait();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (BeansException e)
|
||||
{
|
||||
System.err.println("Error creating context: " + e);
|
||||
usage();
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
private static void usage()
|
||||
{
|
||||
System.err.println("Use: EmailServer configLocation1, configLocation2, ...");
|
||||
System.err.println("\t configLocation - spring xml configs with EmailServer related beans (emailServer, emailServerConfiguration, emailService)");
|
||||
}
|
||||
|
||||
/**
|
||||
* authenticate with a user/password
|
||||
* @param userName
|
||||
|
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.email.server;
|
||||
|
||||
import org.alfresco.email.server.impl.subetha.SubethaEmailMessage;
|
||||
import org.alfresco.error.AlfrescoRuntimeException;
|
||||
import org.alfresco.service.cmr.email.EmailDelivery;
|
||||
import org.alfresco.service.cmr.email.EmailMessage;
|
||||
import org.alfresco.service.cmr.email.EmailService;
|
||||
import org.alfresco.service.cmr.repository.NodeRef;
|
||||
import org.springframework.extensions.surf.util.AbstractLifecycleBean;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
import org.springframework.remoting.rmi.RmiClientInterceptor;
|
||||
|
||||
/**
|
||||
* @author Michael Shavnev
|
||||
* @since 2.2
|
||||
*/
|
||||
public class EmailServiceRemotable extends AbstractLifecycleBean implements EmailService
|
||||
{
|
||||
private String rmiRegistryHost;
|
||||
|
||||
private int rmiRegistryPort;
|
||||
|
||||
private EmailService emailServiceProxy;
|
||||
|
||||
public void setRmiRegistryHost(String rmiRegistryHost)
|
||||
{
|
||||
this.rmiRegistryHost = rmiRegistryHost;
|
||||
}
|
||||
|
||||
public void setRmiRegistryPort(int rmiRegistryPort)
|
||||
{
|
||||
this.rmiRegistryPort = rmiRegistryPort;
|
||||
}
|
||||
|
||||
public void importMessage(EmailDelivery delivery, EmailMessage message)
|
||||
{
|
||||
if (message instanceof SubethaEmailMessage)
|
||||
{
|
||||
((SubethaEmailMessage) message).setRmiRegistry(rmiRegistryHost, rmiRegistryPort);
|
||||
}
|
||||
emailServiceProxy.importMessage(delivery, message);
|
||||
}
|
||||
|
||||
public void importMessage(EmailDelivery delivery, NodeRef nodeRef, EmailMessage message)
|
||||
{
|
||||
if (message instanceof SubethaEmailMessage)
|
||||
{
|
||||
((SubethaEmailMessage) message).setRmiRegistry(rmiRegistryHost, rmiRegistryPort);
|
||||
}
|
||||
emailServiceProxy.importMessage(delivery, nodeRef, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBootstrap(ApplicationEvent event)
|
||||
{
|
||||
if (rmiRegistryHost == null)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Property 'rmiRegistryHost' not set");
|
||||
}
|
||||
if (rmiRegistryPort == 0)
|
||||
{
|
||||
throw new AlfrescoRuntimeException("Property 'rmiRegistryPort' not set");
|
||||
}
|
||||
|
||||
RmiClientInterceptor rmiClientInterceptor = new RmiClientInterceptor();
|
||||
rmiClientInterceptor.setRefreshStubOnConnectFailure(true);
|
||||
rmiClientInterceptor.setServiceUrl("rmi://" + rmiRegistryHost + ":" + rmiRegistryPort + "/emailService");
|
||||
emailServiceProxy = (EmailService) ProxyFactory.getProxy(EmailService.class, rmiClientInterceptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onShutdown(ApplicationEvent event)
|
||||
{
|
||||
}
|
||||
}
|
@@ -1,35 +1,34 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.email.server.impl.subetha;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Date;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@@ -417,29 +416,12 @@ public class SubethaEmailMessage implements EmailMessage
|
||||
}
|
||||
return fileName;
|
||||
}
|
||||
|
||||
public void setRmiRegistry(String rmiRegistryHost, int rmiRegistryPort)
|
||||
{
|
||||
if (body instanceof SubethaEmailMessagePart)
|
||||
{
|
||||
((SubethaEmailMessagePart) body).setRmiRegistry(rmiRegistryHost, rmiRegistryPort);
|
||||
}
|
||||
|
||||
for (EmailMessagePart attachment : attachments)
|
||||
{
|
||||
if (attachment instanceof SubethaEmailMessagePart)
|
||||
{
|
||||
((SubethaEmailMessagePart) attachment).setRmiRegistry(rmiRegistryHost, rmiRegistryPort);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<String> getCC()
|
||||
{
|
||||
return cc;
|
||||
}
|
||||
|
||||
|
||||
public String getFrom()
|
||||
{
|
||||
return from;
|
||||
|
@@ -1,34 +1,31 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.email.server.impl.subetha;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
@@ -39,7 +36,6 @@ import javax.mail.Part;
|
||||
import org.alfresco.service.cmr.email.EmailMessageException;
|
||||
import org.alfresco.service.cmr.email.EmailMessagePart;
|
||||
import org.springframework.extensions.surf.util.ParameterCheck;
|
||||
import org.alfresco.util.remote.RemotableInputStream;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
@@ -64,9 +60,6 @@ public class SubethaEmailMessagePart implements EmailMessagePart
|
||||
private String contentType;
|
||||
private InputStream contentInputStream;
|
||||
|
||||
private String rmiRegistryHost;
|
||||
private int rmiRegistryPort;
|
||||
|
||||
protected SubethaEmailMessagePart()
|
||||
{
|
||||
super();
|
||||
@@ -145,20 +138,4 @@ public class SubethaEmailMessagePart implements EmailMessagePart
|
||||
}
|
||||
|
||||
|
||||
public void setRmiRegistry(String rmiRegistryHost, int rmiRegistryPort)
|
||||
{
|
||||
this.rmiRegistryHost = rmiRegistryHost;
|
||||
this.rmiRegistryPort = rmiRegistryPort;
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream out) throws IOException
|
||||
{
|
||||
contentInputStream = new RemotableInputStream(rmiRegistryHost, rmiRegistryPort, contentInputStream);
|
||||
out.defaultWriteObject();
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
|
||||
{
|
||||
in.defaultReadObject();
|
||||
}
|
||||
}
|
||||
|
@@ -47,7 +47,6 @@ import org.apache.http.client.methods.HttpPost;
|
||||
import org.apache.http.entity.ContentType;
|
||||
import org.apache.http.entity.mime.MultipartEntityBuilder;
|
||||
import org.apache.http.impl.client.CloseableHttpClient;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.util.EntityUtils;
|
||||
|
||||
/**
|
||||
|
@@ -26,9 +26,7 @@
|
||||
package org.alfresco.repo.security.authentication.identityservice;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
/**
|
||||
@@ -36,12 +34,9 @@ import org.springframework.web.util.UriComponentsBuilder;
|
||||
*
|
||||
* @author Gavin Cornwell
|
||||
*/
|
||||
public class IdentityServiceConfig implements InitializingBean
|
||||
public class IdentityServiceConfig
|
||||
{
|
||||
private static final String REALMS = "realms";
|
||||
private static final String CREDENTIALS_SECRET = "identity-service.credentials.secret";
|
||||
|
||||
private Properties globalProperties;
|
||||
|
||||
private int clientConnectionTimeout;
|
||||
private int clientSocketTimeout;
|
||||
@@ -50,11 +45,17 @@ public class IdentityServiceConfig implements InitializingBean
|
||||
private String clientSecret;
|
||||
private String authServerUrl;
|
||||
private String realm;
|
||||
|
||||
public void setGlobalProperties(Properties globalProperties)
|
||||
{
|
||||
this.globalProperties = globalProperties;
|
||||
}
|
||||
private int connectionPoolSize;
|
||||
private boolean allowAnyHostname;
|
||||
private boolean disableTrustManager;
|
||||
private String truststore;
|
||||
private String truststorePassword;
|
||||
private String clientKeystore;
|
||||
private String clientKeystorePassword;
|
||||
private String clientKeyPassword;
|
||||
private String realmKey;
|
||||
private int publicKeyCacheTtl;
|
||||
private boolean publicClient;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -91,11 +92,15 @@ public class IdentityServiceConfig implements InitializingBean
|
||||
{
|
||||
this.clientSocketTimeout = clientSocketTimeout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception
|
||||
|
||||
public void setConnectionPoolSize(int connectionPoolSize)
|
||||
{
|
||||
clientSecret = this.globalProperties.getProperty(CREDENTIALS_SECRET);
|
||||
this.connectionPoolSize = connectionPoolSize;
|
||||
}
|
||||
|
||||
public int getConnectionPoolSize()
|
||||
{
|
||||
return connectionPoolSize;
|
||||
}
|
||||
|
||||
public String getAuthServerUrl()
|
||||
@@ -128,6 +133,11 @@ public class IdentityServiceConfig implements InitializingBean
|
||||
this.resource = resource;
|
||||
}
|
||||
|
||||
public void setClientSecret(String clientSecret)
|
||||
{
|
||||
this.clientSecret = clientSecret;
|
||||
}
|
||||
|
||||
public String getClientSecret()
|
||||
{
|
||||
return Optional.ofNullable(clientSecret)
|
||||
@@ -141,4 +151,104 @@ public class IdentityServiceConfig implements InitializingBean
|
||||
.build()
|
||||
.toString();
|
||||
}
|
||||
|
||||
public void setAllowAnyHostname(boolean allowAnyHostname)
|
||||
{
|
||||
this.allowAnyHostname = allowAnyHostname;
|
||||
}
|
||||
|
||||
public boolean isAllowAnyHostname()
|
||||
{
|
||||
return allowAnyHostname;
|
||||
}
|
||||
|
||||
public void setDisableTrustManager(boolean disableTrustManager)
|
||||
{
|
||||
this.disableTrustManager = disableTrustManager;
|
||||
}
|
||||
|
||||
public boolean isDisableTrustManager()
|
||||
{
|
||||
return disableTrustManager;
|
||||
}
|
||||
|
||||
public void setTruststore(String truststore)
|
||||
{
|
||||
this.truststore = truststore;
|
||||
}
|
||||
|
||||
public String getTruststore()
|
||||
{
|
||||
return truststore;
|
||||
}
|
||||
|
||||
public void setTruststorePassword(String truststorePassword)
|
||||
{
|
||||
this.truststorePassword = truststorePassword;
|
||||
}
|
||||
|
||||
public String getTruststorePassword()
|
||||
{
|
||||
return truststorePassword;
|
||||
}
|
||||
|
||||
public void setClientKeystore(String clientKeystore)
|
||||
{
|
||||
this.clientKeystore = clientKeystore;
|
||||
}
|
||||
|
||||
public String getClientKeystore()
|
||||
{
|
||||
return clientKeystore;
|
||||
}
|
||||
|
||||
public void setClientKeystorePassword(String clientKeystorePassword)
|
||||
{
|
||||
this.clientKeystorePassword = clientKeystorePassword;
|
||||
}
|
||||
|
||||
public String getClientKeystorePassword()
|
||||
{
|
||||
return clientKeystorePassword;
|
||||
}
|
||||
|
||||
public void setClientKeyPassword(String clientKeyPassword)
|
||||
{
|
||||
this.clientKeyPassword = clientKeyPassword;
|
||||
}
|
||||
|
||||
public String getClientKeyPassword()
|
||||
{
|
||||
return clientKeyPassword;
|
||||
}
|
||||
|
||||
public void setRealmKey(String realmKey)
|
||||
{
|
||||
this.realmKey = realmKey;
|
||||
}
|
||||
|
||||
public String getRealmKey()
|
||||
{
|
||||
return realmKey;
|
||||
}
|
||||
|
||||
public void setPublicKeyCacheTtl(int publicKeyCacheTtl)
|
||||
{
|
||||
this.publicKeyCacheTtl = publicKeyCacheTtl;
|
||||
}
|
||||
|
||||
public int getPublicKeyCacheTtl()
|
||||
{
|
||||
return publicKeyCacheTtl;
|
||||
}
|
||||
|
||||
public void setPublicClient(boolean publicClient)
|
||||
{
|
||||
this.publicClient = publicClient;
|
||||
}
|
||||
|
||||
public boolean isPublicClient()
|
||||
{
|
||||
return publicClient;
|
||||
}
|
||||
}
|
||||
|
@@ -27,34 +27,81 @@ package org.alfresco.repo.security.authentication.identityservice;
|
||||
|
||||
import static java.util.Objects.requireNonNull;
|
||||
import static java.util.Optional.ofNullable;
|
||||
import static java.util.function.Predicate.not;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.interfaces.RSAPublicKey;
|
||||
import java.time.Duration;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.nimbusds.jose.JWSAlgorithm;
|
||||
import com.nimbusds.jose.jwk.source.DefaultJWKSetCache;
|
||||
import com.nimbusds.jose.jwk.source.JWKSource;
|
||||
import com.nimbusds.jose.jwk.source.RemoteJWKSet;
|
||||
import com.nimbusds.jose.proc.JWSVerificationKeySelector;
|
||||
import com.nimbusds.jose.proc.SecurityContext;
|
||||
import com.nimbusds.jose.util.ResourceRetriever;
|
||||
import com.nimbusds.jwt.proc.ConfigurableJWTProcessor;
|
||||
import com.nimbusds.openid.connect.sdk.op.OIDCProviderMetadata;
|
||||
|
||||
import org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacade.IdentityServiceFacadeException;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.http.client.HttpClient;
|
||||
import org.apache.http.client.config.RequestConfig;
|
||||
import org.apache.http.conn.ssl.NoopHostnameVerifier;
|
||||
import org.apache.http.conn.ssl.TrustAllStrategy;
|
||||
import org.apache.http.impl.client.HttpClientBuilder;
|
||||
import org.apache.http.impl.client.HttpClients;
|
||||
import org.apache.http.ssl.SSLContextBuilder;
|
||||
import org.apache.http.ssl.SSLContexts;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.http.client.SimpleClientHttpRequestFactory;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.RequestEntity;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
|
||||
import org.springframework.http.converter.FormHttpMessageConverter;
|
||||
import org.springframework.security.converter.RsaKeyConverters;
|
||||
import org.springframework.security.oauth2.client.http.OAuth2ErrorResponseErrorHandler;
|
||||
import org.springframework.security.oauth2.client.oidc.authentication.OidcIdTokenDecoderFactory;
|
||||
import org.springframework.security.oauth2.client.registration.ClientRegistration;
|
||||
import org.springframework.security.oauth2.client.registration.ClientRegistrations;
|
||||
import org.springframework.security.oauth2.client.registration.ClientRegistration.Builder;
|
||||
import org.springframework.security.oauth2.client.registration.ClientRegistration.ProviderDetails;
|
||||
import org.springframework.security.oauth2.core.AuthorizationGrantType;
|
||||
import org.springframework.security.oauth2.core.ClientAuthenticationMethod;
|
||||
import org.springframework.security.oauth2.core.DelegatingOAuth2TokenValidator;
|
||||
import org.springframework.security.oauth2.core.OAuth2AuthenticationException;
|
||||
import org.springframework.security.oauth2.core.OAuth2Error;
|
||||
import org.springframework.security.oauth2.core.OAuth2TokenValidator;
|
||||
import org.springframework.security.oauth2.core.converter.ClaimTypeConverter;
|
||||
import org.springframework.security.oauth2.core.http.converter.OAuth2AccessTokenResponseHttpMessageConverter;
|
||||
import org.springframework.security.oauth2.jose.jws.SignatureAlgorithm;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.jwt.JwtClaimNames;
|
||||
import org.springframework.security.oauth2.jwt.JwtClaimValidator;
|
||||
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||
import org.springframework.security.oauth2.jwt.JwtIssuerValidator;
|
||||
import org.springframework.security.oauth2.jwt.JwtTimestampValidator;
|
||||
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
|
||||
import org.springframework.web.client.RestOperations;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -75,7 +122,11 @@ public class IdentityServiceFacadeFactoryBean implements FactoryBean<IdentitySer
|
||||
|
||||
public void setIdentityServiceConfig(IdentityServiceConfig identityServiceConfig)
|
||||
{
|
||||
factory = new SpringBasedIdentityServiceFacadeFactory(identityServiceConfig);
|
||||
factory = new SpringBasedIdentityServiceFacadeFactory(
|
||||
new HttpClientProvider(identityServiceConfig)::createHttpClient,
|
||||
new ClientRegistrationProvider(identityServiceConfig)::createClientRegistration,
|
||||
new JwtDecoderProvider(identityServiceConfig)::createJwtDecoder
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -159,12 +210,18 @@ public class IdentityServiceFacadeFactoryBean implements FactoryBean<IdentitySer
|
||||
|
||||
private static class SpringBasedIdentityServiceFacadeFactory
|
||||
{
|
||||
private static final long CLOCK_SKEW_MS = 0;
|
||||
private final IdentityServiceConfig config;
|
||||
private final Supplier<HttpClient> httpClientProvider;
|
||||
private final Function<RestOperations, ClientRegistration> clientRegistrationProvider;
|
||||
private final BiFunction<RestOperations, ProviderDetails, JwtDecoder> jwtDecoderProvider;
|
||||
|
||||
SpringBasedIdentityServiceFacadeFactory(IdentityServiceConfig config)
|
||||
SpringBasedIdentityServiceFacadeFactory(
|
||||
Supplier<HttpClient> httpClientProvider,
|
||||
Function<RestOperations, ClientRegistration> clientRegistrationProvider,
|
||||
BiFunction<RestOperations, ProviderDetails, JwtDecoder> jwtDecoderProvider)
|
||||
{
|
||||
this.config = Objects.requireNonNull(config);
|
||||
this.httpClientProvider = Objects.requireNonNull(httpClientProvider);
|
||||
this.clientRegistrationProvider = Objects.requireNonNull(clientRegistrationProvider);
|
||||
this.jwtDecoderProvider = Objects.requireNonNull(jwtDecoderProvider);
|
||||
}
|
||||
|
||||
private IdentityServiceFacade createIdentityServiceFacade()
|
||||
@@ -173,65 +230,324 @@ public class IdentityServiceFacadeFactoryBean implements FactoryBean<IdentitySer
|
||||
// * Client is authenticating itself using basic auth
|
||||
// * Resource Owner Password Credentials Flow is used to authenticate Resource Owner
|
||||
|
||||
final RestTemplate restTemplate = createRestTemplate();
|
||||
final ClientRegistration clientRegistration = createClientRegistration();
|
||||
final JwtDecoder jwtDecoder = createJwtDecoder(clientRegistration);
|
||||
final ClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory(httpClientProvider.get());
|
||||
final RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
|
||||
final ClientRegistration clientRegistration = clientRegistrationProvider.apply(restTemplate);
|
||||
final JwtDecoder jwtDecoder = jwtDecoderProvider.apply(restTemplate, clientRegistration.getProviderDetails());
|
||||
|
||||
return new SpringBasedIdentityServiceFacade(restTemplate, clientRegistration, jwtDecoder);
|
||||
return new SpringBasedIdentityServiceFacade(createOAuth2RestTemplate(httpRequestFactory), clientRegistration, jwtDecoder);
|
||||
}
|
||||
|
||||
private RestTemplate createRestTemplate()
|
||||
private RestTemplate createOAuth2RestTemplate(ClientHttpRequestFactory requestFactory)
|
||||
{
|
||||
final SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
|
||||
requestFactory.setConnectTimeout(config.getClientConnectionTimeout());
|
||||
requestFactory.setReadTimeout(config.getClientSocketTimeout());
|
||||
|
||||
final RestTemplate restTemplate = new RestTemplate(Arrays.asList(new FormHttpMessageConverter(), new OAuth2AccessTokenResponseHttpMessageConverter()));
|
||||
restTemplate.setRequestFactory(requestFactory);
|
||||
restTemplate.setErrorHandler(new OAuth2ErrorResponseErrorHandler());
|
||||
|
||||
return restTemplate;
|
||||
}
|
||||
}
|
||||
|
||||
private ClientRegistration createClientRegistration()
|
||||
private static class HttpClientProvider
|
||||
{
|
||||
private final IdentityServiceConfig config;
|
||||
|
||||
private HttpClientProvider(IdentityServiceConfig config)
|
||||
{
|
||||
this.config = Objects.requireNonNull(config);
|
||||
}
|
||||
|
||||
private HttpClient createHttpClient()
|
||||
{
|
||||
try
|
||||
{
|
||||
return ClientRegistrations
|
||||
.fromIssuerLocation(config.getIssuerUrl())
|
||||
.clientId(config.getResource())
|
||||
.clientSecret(config.getClientSecret())
|
||||
.authorizationGrantType(AuthorizationGrantType.PASSWORD)
|
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC)
|
||||
.registrationId("ids")
|
||||
.build();
|
||||
HttpClientBuilder clientBuilder = HttpClients.custom();
|
||||
|
||||
applyConnectionConfiguration(clientBuilder);
|
||||
applySSLConfiguration(clientBuilder);
|
||||
|
||||
return clientBuilder.build();
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.warn("Failed to create ClientRegistration.", e);
|
||||
throw authorizationServerCantBeUsedException(e);
|
||||
throw new IllegalStateException("Failed to create ClientHttpRequestFactory. " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
private JwtDecoder createJwtDecoder(ClientRegistration clientRegistration)
|
||||
private void applyConnectionConfiguration(HttpClientBuilder builder)
|
||||
{
|
||||
final OidcIdTokenDecoderFactory decoderFactory = new OidcIdTokenDecoderFactory();
|
||||
decoderFactory.setJwtValidatorFactory(c -> new DelegatingOAuth2TokenValidator<>(
|
||||
new JwtTimestampValidator(Duration.of(CLOCK_SKEW_MS, ChronoUnit.MILLIS)),
|
||||
new JwtIssuerValidator(c.getProviderDetails().getIssuerUri()),
|
||||
new JwtClaimValidator<String>("typ", "Bearer"::equals),
|
||||
new JwtClaimValidator<String>(JwtClaimNames.SUB, Objects::nonNull)
|
||||
final RequestConfig requestConfig = RequestConfig.custom()
|
||||
.setConnectTimeout(config.getClientConnectionTimeout())
|
||||
.setSocketTimeout(config.getClientSocketTimeout())
|
||||
.build();
|
||||
|
||||
));
|
||||
builder.setDefaultRequestConfig(requestConfig)
|
||||
.setMaxConnTotal(config.getConnectionPoolSize());
|
||||
}
|
||||
|
||||
private void applySSLConfiguration(HttpClientBuilder builder) throws Exception
|
||||
{
|
||||
SSLContextBuilder sslContextBuilder = null;
|
||||
if (config.isDisableTrustManager())
|
||||
{
|
||||
sslContextBuilder = SSLContexts.custom()
|
||||
.loadTrustMaterial(TrustAllStrategy.INSTANCE);
|
||||
|
||||
}
|
||||
else if (isDefined(config.getTruststore()))
|
||||
{
|
||||
final char[] truststorePassword = asCharArray(config.getTruststorePassword(), null);
|
||||
sslContextBuilder = SSLContexts.custom()
|
||||
.loadTrustMaterial(new File(config.getTruststore()), truststorePassword);
|
||||
}
|
||||
|
||||
if (isDefined(config.getClientKeystore()))
|
||||
{
|
||||
if (sslContextBuilder == null)
|
||||
{
|
||||
sslContextBuilder = SSLContexts.custom();
|
||||
}
|
||||
final char[] keystorePassword = asCharArray(config.getClientKeystorePassword(), null);
|
||||
final char[] keyPassword = asCharArray(config.getClientKeyPassword(), keystorePassword);
|
||||
sslContextBuilder.loadKeyMaterial(new File(config.getClientKeystore()), keystorePassword, keyPassword);
|
||||
}
|
||||
|
||||
if (sslContextBuilder != null)
|
||||
{
|
||||
builder.setSSLContext(sslContextBuilder.build());
|
||||
}
|
||||
|
||||
if (config.isDisableTrustManager() || config.isAllowAnyHostname())
|
||||
{
|
||||
builder.setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE);
|
||||
}
|
||||
}
|
||||
|
||||
private char[] asCharArray(String value, char[] nullValue)
|
||||
{
|
||||
return Optional.ofNullable(value)
|
||||
.filter(not(String::isBlank))
|
||||
.map(String::toCharArray)
|
||||
.orElse(nullValue);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ClientRegistrationProvider
|
||||
{
|
||||
private final IdentityServiceConfig config;
|
||||
|
||||
private ClientRegistrationProvider(IdentityServiceConfig config)
|
||||
{
|
||||
this.config = Objects.requireNonNull(config);
|
||||
}
|
||||
|
||||
public ClientRegistration createClientRegistration(final RestOperations rest)
|
||||
{
|
||||
return possibleMetadataURIs()
|
||||
.stream()
|
||||
.map(u -> extractMetadata(rest, u))
|
||||
.filter(Optional::isPresent)
|
||||
.map(Optional::get)
|
||||
.findFirst()
|
||||
.map(this::createBuilder)
|
||||
.map(this::configureClientAuthentication)
|
||||
.map(Builder::build)
|
||||
.orElseThrow(() -> new IllegalStateException("Failed to create ClientRegistration."));
|
||||
}
|
||||
|
||||
private ClientRegistration.Builder createBuilder(OIDCProviderMetadata metadata)
|
||||
{
|
||||
return ClientRegistration
|
||||
.withRegistrationId("ids")
|
||||
.tokenUri(metadata.getTokenEndpointURI().toASCIIString())
|
||||
.jwkSetUri(metadata.getJWKSetURI().toASCIIString())
|
||||
.issuerUri(config.getIssuerUrl())
|
||||
.authorizationGrantType(AuthorizationGrantType.PASSWORD);
|
||||
}
|
||||
|
||||
private Builder configureClientAuthentication(Builder builder)
|
||||
{
|
||||
builder.clientId(config.getResource());
|
||||
if (config.isPublicClient())
|
||||
{
|
||||
return builder.clientSecret(null)
|
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_POST);
|
||||
}
|
||||
return builder.clientSecret(config.getClientSecret())
|
||||
.clientAuthenticationMethod(ClientAuthenticationMethod.CLIENT_SECRET_BASIC);
|
||||
}
|
||||
|
||||
private Optional<OIDCProviderMetadata> extractMetadata(RestOperations rest, URI metadataUri)
|
||||
{
|
||||
final String response;
|
||||
try
|
||||
{
|
||||
return decoderFactory.createDecoder(clientRegistration);
|
||||
final ResponseEntity<String> r = rest.exchange(RequestEntity.get(metadataUri).build(), String.class);
|
||||
if (r.getStatusCode() != HttpStatus.OK || !r.hasBody())
|
||||
{
|
||||
LOGGER.warn("Unexpected response from " + metadataUri + ". Status code: " + r.getStatusCode() + ", has body: " + r.hasBody() + ".");
|
||||
return Optional.empty();
|
||||
}
|
||||
response = r.getBody();
|
||||
}
|
||||
catch (RuntimeException e)
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.warn("Failed to get response from " + metadataUri + ". " + e.getMessage(), e);
|
||||
return Optional.empty();
|
||||
}
|
||||
try
|
||||
{
|
||||
return Optional.of(OIDCProviderMetadata.parse(response));
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOGGER.warn("Failed to parse metadata. " + e.getMessage(), e);
|
||||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
private Collection<URI> possibleMetadataURIs()
|
||||
{
|
||||
return List.of(UriComponentsBuilder.fromUriString(config.getIssuerUrl())
|
||||
.pathSegment(".well-known", "openid-configuration")
|
||||
.build().toUri());
|
||||
}
|
||||
}
|
||||
|
||||
static class JwtDecoderProvider
|
||||
{
|
||||
private static final SignatureAlgorithm SIGNATURE_ALGORITHM = SignatureAlgorithm.RS256;
|
||||
private final IdentityServiceConfig config;
|
||||
|
||||
JwtDecoderProvider(IdentityServiceConfig config)
|
||||
{
|
||||
this.config = Objects.requireNonNull(config);
|
||||
}
|
||||
|
||||
public JwtDecoder createJwtDecoder(RestOperations rest, ProviderDetails providerDetails)
|
||||
{
|
||||
try
|
||||
{
|
||||
final NimbusJwtDecoder decoder = buildJwtDecoder(rest, providerDetails);
|
||||
|
||||
decoder.setJwtValidator(createJwtTokenValidator(providerDetails));
|
||||
decoder.setClaimSetConverter(new ClaimTypeConverter(OidcIdTokenDecoderFactory.createDefaultClaimTypeConverters()));
|
||||
|
||||
return decoder;
|
||||
} catch (RuntimeException e)
|
||||
{
|
||||
LOGGER.warn("Failed to create JwtDecoder.", e);
|
||||
throw authorizationServerCantBeUsedException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private NimbusJwtDecoder buildJwtDecoder(RestOperations rest, ProviderDetails providerDetails)
|
||||
{
|
||||
if (isDefined(config.getRealmKey()))
|
||||
{
|
||||
final RSAPublicKey publicKey = parsePublicKey(config.getRealmKey());
|
||||
return NimbusJwtDecoder.withPublicKey(publicKey)
|
||||
.signatureAlgorithm(SIGNATURE_ALGORITHM)
|
||||
.build();
|
||||
}
|
||||
|
||||
final String jwkSetUri = requireValidJwkSetUri(providerDetails);
|
||||
return NimbusJwtDecoder.withJwkSetUri(jwkSetUri)
|
||||
.jwsAlgorithm(SIGNATURE_ALGORITHM)
|
||||
.restOperations(rest)
|
||||
.jwtProcessorCustomizer(this::reconfigureJWKSCache)
|
||||
.build();
|
||||
}
|
||||
|
||||
private void reconfigureJWKSCache(ConfigurableJWTProcessor<SecurityContext> jwtProcessor)
|
||||
{
|
||||
final Optional<RemoteJWKSet<SecurityContext>> jwkSource = ofNullable(jwtProcessor)
|
||||
.map(ConfigurableJWTProcessor::getJWSKeySelector)
|
||||
.filter(JWSVerificationKeySelector.class::isInstance).map(o -> (JWSVerificationKeySelector<SecurityContext>)o)
|
||||
.map(JWSVerificationKeySelector::getJWKSource)
|
||||
.filter(RemoteJWKSet.class::isInstance).map(o -> (RemoteJWKSet<SecurityContext>)o);
|
||||
if (jwkSource.isEmpty())
|
||||
{
|
||||
LOGGER.warn("Not able to reconfigure the JWK Cache. Unexpected JWKSource.");
|
||||
return;
|
||||
}
|
||||
|
||||
final Optional<URL> jwkSetUrl = jwkSource.map(RemoteJWKSet::getJWKSetURL);
|
||||
if (jwkSetUrl.isEmpty())
|
||||
{
|
||||
LOGGER.warn("Not able to reconfigure the JWK Cache. Unknown JWKSetURL.");
|
||||
return;
|
||||
}
|
||||
|
||||
final Optional<ResourceRetriever> resourceRetriever = jwkSource.map(RemoteJWKSet::getResourceRetriever);
|
||||
if (resourceRetriever.isEmpty())
|
||||
{
|
||||
LOGGER.warn("Not able to reconfigure the JWK Cache. Unknown ResourceRetriever.");
|
||||
return;
|
||||
}
|
||||
|
||||
final DefaultJWKSetCache cache = new DefaultJWKSetCache(config.getPublicKeyCacheTtl(), -1, TimeUnit.SECONDS);
|
||||
final JWKSource<SecurityContext> cachingJWKSource = new RemoteJWKSet<>(jwkSetUrl.get(), resourceRetriever.get(), cache);
|
||||
|
||||
jwtProcessor.setJWSKeySelector(new JWSVerificationKeySelector<>(
|
||||
JWSAlgorithm.parse(SIGNATURE_ALGORITHM.getName()),
|
||||
cachingJWKSource));
|
||||
}
|
||||
|
||||
private OAuth2TokenValidator<Jwt> createJwtTokenValidator(ProviderDetails providerDetails)
|
||||
{
|
||||
return new DelegatingOAuth2TokenValidator<>(
|
||||
new JwtTimestampValidator(Duration.of(0, ChronoUnit.MILLIS)),
|
||||
new JwtIssuerValidator(providerDetails.getIssuerUri()),
|
||||
new JwtClaimValidator<String>("typ", "Bearer"::equals),
|
||||
new JwtClaimValidator<String>(JwtClaimNames.SUB, Objects::nonNull));
|
||||
}
|
||||
|
||||
private RSAPublicKey parsePublicKey(String pem)
|
||||
{
|
||||
try
|
||||
{
|
||||
return tryToParsePublicKey(pem);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (isPemFormatException(e))
|
||||
{
|
||||
//For backward compatibility with Keycloak adapter
|
||||
return tryToParsePublicKey("-----BEGIN PUBLIC KEY-----\n" + pem + "\n-----END PUBLIC KEY-----");
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
private RSAPublicKey tryToParsePublicKey(String pem)
|
||||
{
|
||||
final InputStream pemStream = new ByteArrayInputStream(pem.getBytes(StandardCharsets.UTF_8));
|
||||
return RsaKeyConverters.x509().convert(pemStream);
|
||||
}
|
||||
|
||||
private boolean isPemFormatException(Exception e)
|
||||
{
|
||||
return e.getMessage() != null && e.getMessage().contains("-----BEGIN PUBLIC KEY-----");
|
||||
}
|
||||
|
||||
private String requireValidJwkSetUri(ProviderDetails providerDetails)
|
||||
{
|
||||
final String uri = providerDetails.getJwkSetUri();
|
||||
if (!isDefined(uri)) {
|
||||
OAuth2Error oauth2Error = new OAuth2Error("missing_signature_verifier",
|
||||
"Failed to find a Signature Verifier for: '"
|
||||
+ providerDetails.getIssuerUri()
|
||||
+ "'. Check to ensure you have configured the JwkSet URI.",
|
||||
null);
|
||||
throw new OAuth2AuthenticationException(oauth2Error, oauth2Error.toString());
|
||||
}
|
||||
return uri;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isDefined(String value)
|
||||
{
|
||||
return value != null && !value.isBlank();
|
||||
}
|
||||
}
|
||||
|
@@ -25,6 +25,12 @@
|
||||
*/
|
||||
package org.alfresco.repo.tagging;
|
||||
|
||||
import static java.util.Collections.emptyMap;
|
||||
|
||||
import static org.alfresco.model.ContentModel.ASSOC_SUBCATEGORIES;
|
||||
import static org.alfresco.model.ContentModel.PROP_NAME;
|
||||
import static org.alfresco.service.namespace.NamespaceService.CONTENT_MODEL_1_0_URI;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
@@ -50,11 +56,11 @@ import org.alfresco.query.EmptyPagingResults;
|
||||
import org.alfresco.query.PagingRequest;
|
||||
import org.alfresco.query.PagingResults;
|
||||
import org.alfresco.repo.audit.AuditComponent;
|
||||
import org.alfresco.repo.coci.CheckOutCheckInServicePolicies;
|
||||
import org.alfresco.repo.copy.CopyServicePolicies;
|
||||
import org.alfresco.repo.coci.CheckOutCheckInServicePolicies.OnCheckOut;
|
||||
import org.alfresco.repo.copy.CopyServicePolicies.BeforeCopyPolicy;
|
||||
import org.alfresco.repo.copy.CopyServicePolicies.OnCopyCompletePolicy;
|
||||
import org.alfresco.repo.node.NodeServicePolicies;
|
||||
import org.alfresco.repo.event2.EventGenerator;
|
||||
import org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy;
|
||||
import org.alfresco.repo.node.NodeServicePolicies.OnCreateNodePolicy;
|
||||
import org.alfresco.repo.node.NodeServicePolicies.OnMoveNodePolicy;
|
||||
import org.alfresco.repo.node.NodeServicePolicies.OnUpdatePropertiesPolicy;
|
||||
@@ -90,6 +96,7 @@ import org.alfresco.util.ISO9075;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.alfresco.util.ParameterCheck;
|
||||
import org.apache.commons.lang3.StringEscapeUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
@@ -100,16 +107,16 @@ import org.apache.commons.logging.LogFactory;
|
||||
*/
|
||||
public class TaggingServiceImpl implements TaggingService,
|
||||
TransactionListener,
|
||||
NodeServicePolicies.BeforeDeleteNodePolicy,
|
||||
NodeServicePolicies.OnMoveNodePolicy,
|
||||
CopyServicePolicies.OnCopyCompletePolicy,
|
||||
CopyServicePolicies.BeforeCopyPolicy
|
||||
BeforeDeleteNodePolicy,
|
||||
OnMoveNodePolicy,
|
||||
OnCopyCompletePolicy,
|
||||
BeforeCopyPolicy
|
||||
{
|
||||
protected static final String TAGGING_AUDIT_APPLICATION_NAME = "Alfresco Tagging Service";
|
||||
protected static final String TAGGING_AUDIT_ROOT_PATH = "/tagging";
|
||||
protected static final String TAGGING_AUDIT_KEY_NODEREF = "node";
|
||||
protected static final String TAGGING_AUDIT_KEY_TAGS = "tags";
|
||||
|
||||
|
||||
private static Log logger = LogFactory.getLog(TaggingServiceImpl.class);
|
||||
|
||||
private static Collator collator = Collator.getInstance();
|
||||
@@ -123,18 +130,19 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
private NamespaceService namespaceService;
|
||||
private PolicyComponent policyComponent;
|
||||
private AuditComponent auditComponent;
|
||||
|
||||
private EventGenerator eventGenerator;
|
||||
|
||||
/** Tag Details Delimiter */
|
||||
private static final String TAG_DETAILS_DELIMITER = "|";
|
||||
/** Next tag delimiter */
|
||||
private static final String NEXT_TAG_DELIMITER = "\n";
|
||||
|
||||
|
||||
private static Set<String> FORBIDDEN_TAGS_SEQUENCES = new HashSet<String>(Arrays.asList(new String[] {NEXT_TAG_DELIMITER, TAG_DETAILS_DELIMITER}));
|
||||
|
||||
|
||||
/** Policy behaviour */
|
||||
private JavaBehaviour updateTagBehaviour;
|
||||
private JavaBehaviour createTagBehaviour;
|
||||
|
||||
|
||||
/**
|
||||
* Set the cateogry service
|
||||
*/
|
||||
@@ -206,7 +214,16 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
{
|
||||
this.auditComponent = auditComponent;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the event generator.
|
||||
* @param eventGenerator
|
||||
*/
|
||||
public void setEventGenerator(EventGenerator eventGenerator)
|
||||
{
|
||||
this.eventGenerator = eventGenerator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Init method
|
||||
*/
|
||||
@@ -253,7 +270,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
new JavaBehaviour(this, "onCopyComplete", NotificationFrequency.EVERY_EVENT));
|
||||
|
||||
this.policyComponent.bindClassBehaviour(
|
||||
CheckOutCheckInServicePolicies.OnCheckOut.QNAME,
|
||||
OnCheckOut.QNAME,
|
||||
ContentModel.ASPECT_TAGGABLE,
|
||||
new JavaBehaviour(this, "afterCheckOut", NotificationFrequency.EVERY_EVENT));
|
||||
}
|
||||
@@ -311,7 +328,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.node.NodeServicePolicies.BeforeDeleteNodePolicy#beforeDeleteNode(org.alfresco.service.cmr.repository.NodeRef)
|
||||
* @see BeforeDeleteNodePolicy#beforeDeleteNode(NodeRef)
|
||||
*/
|
||||
public void beforeDeleteNode(NodeRef nodeRef)
|
||||
{
|
||||
@@ -456,11 +473,11 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
|
||||
public String getTagName(NodeRef nodeRef)
|
||||
{
|
||||
return (String)nodeService.getProperty(nodeRef, ContentModel.PROP_NAME);
|
||||
return (String)nodeService.getProperty(nodeRef, PROP_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#isTag(StoreRef, java.lang.String)
|
||||
* @see TaggingService#isTag(StoreRef, String)
|
||||
*/
|
||||
public boolean isTag(StoreRef storeRef, String tag)
|
||||
{
|
||||
@@ -469,7 +486,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#createTag(StoreRef, java.lang.String)
|
||||
* @see TaggingService#createTag(StoreRef, String)
|
||||
*/
|
||||
public NodeRef createTag(StoreRef storeRef, String tag)
|
||||
{
|
||||
@@ -480,7 +497,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#deleteTag(org.alfresco.service.cmr.repository.StoreRef, java.lang.String)
|
||||
* @see TaggingService#deleteTag(StoreRef, String)
|
||||
*/
|
||||
public void deleteTag(StoreRef storeRef, String tag)
|
||||
{
|
||||
@@ -510,11 +527,14 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
throw new TaggingException("Existing tag cannot be null");
|
||||
}
|
||||
|
||||
if (newTag == null)
|
||||
if (newTag == null || StringUtils.isBlank(newTag))
|
||||
{
|
||||
throw new TaggingException("New tag cannot be null");
|
||||
throw new TaggingException("New tag cannot be blank");
|
||||
}
|
||||
|
||||
existingTag = existingTag.toLowerCase();
|
||||
newTag = newTag.toLowerCase();
|
||||
|
||||
if (existingTag.equals(newTag))
|
||||
{
|
||||
throw new TaggingException("New and existing tags are the same");
|
||||
@@ -530,20 +550,23 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
throw new TagExistsException("Tag " + newTag + " already exists");
|
||||
}
|
||||
|
||||
List<NodeRef> taggedNodes = findTaggedNodes(storeRef, existingTag);
|
||||
NodeRef tagNodeRef = getTagNodeRef(storeRef, existingTag);
|
||||
nodeService.setProperty(tagNodeRef, PROP_NAME, newTag);
|
||||
nodeService.moveNode(tagNodeRef, TAG_ROOT_NODE_REF, ASSOC_SUBCATEGORIES, QName.createQName(CONTENT_MODEL_1_0_URI, newTag));
|
||||
|
||||
// Raise events on all tagged nodes and also fix the tag scopes.
|
||||
List<NodeRef> taggedNodes = findTaggedNodes(storeRef, existingTag);
|
||||
for (NodeRef nodeRef : taggedNodes)
|
||||
{
|
||||
removeTag(nodeRef, existingTag);
|
||||
addTag(nodeRef, newTag);
|
||||
eventGenerator.onUpdateProperties(nodeRef, emptyMap(), nodeService.getProperties(nodeRef));
|
||||
updateTagScope(nodeRef, Map.of(existingTag, false, newTag, true));
|
||||
}
|
||||
|
||||
deleteTag(storeRef, existingTag);
|
||||
|
||||
return getTagNodeRef(storeRef, newTag, true);
|
||||
return tagNodeRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#getTags(StoreRef)
|
||||
* @see TaggingService#getTags(StoreRef)
|
||||
*/
|
||||
public List<String> getTags(StoreRef storeRef)
|
||||
{
|
||||
@@ -553,7 +576,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
List<String> result = new ArrayList<String>(rootCategories.size());
|
||||
for (ChildAssociationRef rootCategory : rootCategories)
|
||||
{
|
||||
String name = (String)this.nodeService.getProperty(rootCategory.getChildRef(), ContentModel.PROP_NAME);
|
||||
String name = (String)this.nodeService.getProperty(rootCategory.getChildRef(), PROP_NAME);
|
||||
result.add(name);
|
||||
}
|
||||
return result;
|
||||
@@ -579,7 +602,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
{
|
||||
continue;
|
||||
}
|
||||
String name = (String)this.nodeService.getProperty(rootCategory.getChildRef(), ContentModel.PROP_NAME);
|
||||
String name = (String)this.nodeService.getProperty(rootCategory.getChildRef(), PROP_NAME);
|
||||
result.add(name);
|
||||
if (index == endIndex)
|
||||
{
|
||||
@@ -590,7 +613,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#getTags(org.alfresco.service.cmr.repository.StoreRef, java.lang.String)
|
||||
* @see TaggingService#getTags(StoreRef, String)
|
||||
*/
|
||||
public List<String> getTags(StoreRef storeRef, String filter)
|
||||
{
|
||||
@@ -607,7 +630,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
result = new ArrayList<String>(rootCategories.size());
|
||||
for (ChildAssociationRef rootCategory : rootCategories)
|
||||
{
|
||||
String name = (String)this.nodeService.getProperty(rootCategory.getChildRef(), ContentModel.PROP_NAME);
|
||||
String name = (String)this.nodeService.getProperty(rootCategory.getChildRef(), PROP_NAME);
|
||||
if (name.contains(filter.toLowerCase()) == true)
|
||||
{
|
||||
result.add(name);
|
||||
@@ -644,7 +667,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
{
|
||||
continue;
|
||||
}
|
||||
String name = (String)this.nodeService.getProperty(rootCategory.getChildRef(), ContentModel.PROP_NAME);
|
||||
String name = (String)this.nodeService.getProperty(rootCategory.getChildRef(), PROP_NAME);
|
||||
result.add(name);
|
||||
if (index == endIndex)
|
||||
{
|
||||
@@ -656,7 +679,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#hasTag(org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
|
||||
* @see TaggingService#hasTag(NodeRef, String)
|
||||
*/
|
||||
public boolean hasTag(NodeRef nodeRef, String tag)
|
||||
{
|
||||
@@ -665,7 +688,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#addTag(org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
|
||||
* @see TaggingService#addTag(NodeRef, String)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public NodeRef addTag(final NodeRef nodeRef, final String tagName)
|
||||
@@ -721,7 +744,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#addTags(org.alfresco.service.cmr.repository.NodeRef, java.util.List)
|
||||
* @see TaggingService#addTags(NodeRef, List)
|
||||
*/
|
||||
public List<Pair<String, NodeRef>> addTags(NodeRef nodeRef, List<String> tags)
|
||||
{
|
||||
@@ -778,7 +801,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#removeTag(org.alfresco.service.cmr.repository.NodeRef, java.lang.String)
|
||||
* @see TaggingService#removeTag(NodeRef, String)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void removeTag(NodeRef nodeRef, String tag)
|
||||
@@ -818,7 +841,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#removeTags(org.alfresco.service.cmr.repository.NodeRef, java.util.List)
|
||||
* @see TaggingService#removeTags(NodeRef, List)
|
||||
*/
|
||||
public void removeTags(NodeRef nodeRef, List<String> tags)
|
||||
{
|
||||
@@ -829,7 +852,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#getTags(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.query.PagingRequest)
|
||||
* @see TaggingService#getTags(NodeRef, PagingRequest)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
// TODO canned query
|
||||
@@ -852,7 +875,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
// grab all tags and sort (assume fairly low number of tags)
|
||||
for(NodeRef tagNode : currentTagNodes)
|
||||
{
|
||||
String tag = (String)this.nodeService.getProperty(tagNode, ContentModel.PROP_NAME);
|
||||
String tag = (String)this.nodeService.getProperty(tagNode, PROP_NAME);
|
||||
sortedTags.add(new Pair<NodeRef, String>(tagNode, tag));
|
||||
}
|
||||
Collections.sort(sortedTags, new Comparator<Pair<NodeRef, String>>()
|
||||
@@ -921,7 +944,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#getTags(org.alfresco.service.cmr.repository.StoreRef, org.alfresco.query.PagingRequest)
|
||||
* @see TaggingService#getTags(StoreRef, PagingRequest)
|
||||
*/
|
||||
public PagingResults<Pair<NodeRef, String>> getTags(StoreRef storeRef, PagingRequest pagingRequest, Collection<String> exactNamesFilter, Collection<String> alikeNamesFilter)
|
||||
{
|
||||
@@ -935,7 +958,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#getTags(org.alfresco.service.cmr.repository.NodeRef)
|
||||
* @see TaggingService#getTags(NodeRef)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<String> getTags(NodeRef nodeRef)
|
||||
@@ -951,7 +974,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
{
|
||||
for (NodeRef currentTagNode : currentTagNodes)
|
||||
{
|
||||
String tag = (String)this.nodeService.getProperty(currentTagNode, ContentModel.PROP_NAME);
|
||||
String tag = (String)this.nodeService.getProperty(currentTagNode, PROP_NAME);
|
||||
result.add(tag);
|
||||
}
|
||||
}
|
||||
@@ -961,7 +984,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#setTags(org.alfresco.service.cmr.repository.NodeRef, java.util.List)
|
||||
* @see TaggingService#setTags(NodeRef, List)
|
||||
*/
|
||||
public void setTags(NodeRef nodeRef, List<String> tags)
|
||||
{
|
||||
@@ -1022,7 +1045,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#clearTags(org.alfresco.service.cmr.repository.NodeRef)
|
||||
* @see TaggingService#clearTags(NodeRef)
|
||||
*/
|
||||
public void clearTags(NodeRef nodeRef)
|
||||
{
|
||||
@@ -1030,7 +1053,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#isTagScope(org.alfresco.service.cmr.repository.NodeRef)
|
||||
* @see TaggingService#isTagScope(NodeRef)
|
||||
*/
|
||||
public boolean isTagScope(NodeRef nodeRef)
|
||||
{
|
||||
@@ -1039,7 +1062,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#addTagScope(org.alfresco.service.cmr.repository.NodeRef)
|
||||
* @see TaggingService#addTagScope(NodeRef)
|
||||
*/
|
||||
public void addTagScope(NodeRef nodeRef)
|
||||
{
|
||||
@@ -1054,7 +1077,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#refreshTagScope(org.alfresco.service.cmr.repository.NodeRef, boolean)
|
||||
* @see TaggingService#refreshTagScope(NodeRef, boolean)
|
||||
*/
|
||||
public void refreshTagScope(NodeRef nodeRef, boolean async)
|
||||
{
|
||||
@@ -1067,7 +1090,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#removeTagScope(org.alfresco.service.cmr.repository.NodeRef)
|
||||
* @see TaggingService#removeTagScope(NodeRef)
|
||||
*/
|
||||
public void removeTagScope(NodeRef nodeRef)
|
||||
{
|
||||
@@ -1078,7 +1101,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#findTagScope(org.alfresco.service.cmr.repository.NodeRef)
|
||||
* @see TaggingService#findTagScope(NodeRef)
|
||||
*/
|
||||
public TagScope findTagScope(NodeRef nodeRef)
|
||||
{
|
||||
@@ -1115,7 +1138,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#findAllTagScopes(org.alfresco.service.cmr.repository.NodeRef)
|
||||
* @see TaggingService#findAllTagScopes(NodeRef)
|
||||
*/
|
||||
public List<TagScope> findAllTagScopes(NodeRef nodeRef)
|
||||
{
|
||||
@@ -1205,7 +1228,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#findTaggedNodes(StoreRef, java.lang.String)
|
||||
* @see TaggingService#findTaggedNodes(StoreRef, String)
|
||||
*/
|
||||
public List<NodeRef> findTaggedNodes(StoreRef storeRef, String tag)
|
||||
{
|
||||
@@ -1230,7 +1253,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#findTaggedNodes(StoreRef, java.lang.String, org.alfresco.service.cmr.repository.NodeRef)
|
||||
* @see TaggingService#findTaggedNodes(StoreRef, String, NodeRef)
|
||||
*/
|
||||
public List<NodeRef> findTaggedNodes(StoreRef storeRef, String tag, NodeRef nodeRef)
|
||||
{
|
||||
@@ -1459,7 +1482,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
// ===== Transaction Listener Callback Methods ===== //
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.transaction.TransactionListener#afterCommit()
|
||||
* @see TransactionListener#afterCommit()
|
||||
*/
|
||||
public void afterCommit()
|
||||
{
|
||||
@@ -1467,14 +1490,14 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.transaction.TransactionListener#afterRollback()
|
||||
* @see TransactionListener#afterRollback()
|
||||
*/
|
||||
public void afterRollback()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.transaction.TransactionListener#beforeCommit(boolean)
|
||||
* @see TransactionListener#beforeCommit(boolean)
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public void beforeCommit(boolean readOnly)
|
||||
@@ -1499,14 +1522,14 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.transaction.TransactionListener#beforeCompletion()
|
||||
* @see TransactionListener#beforeCompletion()
|
||||
*/
|
||||
public void beforeCompletion()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.repo.transaction.TransactionListener#flush()
|
||||
* @see TransactionListener#flush()
|
||||
*/
|
||||
public void flush()
|
||||
{
|
||||
@@ -1522,7 +1545,7 @@ public class TaggingServiceImpl implements TaggingService,
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.alfresco.service.cmr.tagging.TaggingService#findTaggedNodesAndCountByTagName(StoreRef)
|
||||
* @see TaggingService#findTaggedNodesAndCountByTagName(StoreRef)
|
||||
*/
|
||||
@Override
|
||||
public List<Pair<String, Integer>> findTaggedNodesAndCountByTagName(StoreRef storeRef)
|
||||
|
@@ -48,6 +48,8 @@ import org.alfresco.util.Pair;
|
||||
@AlfrescoPublicApi
|
||||
public interface TaggingService
|
||||
{
|
||||
NodeRef TAG_ROOT_NODE_REF = new NodeRef("workspace://SpacesStore/tag:tag-root");
|
||||
|
||||
/**
|
||||
* Indicates whether the tag already exists
|
||||
*
|
||||
|
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.util.remote;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.net.InetAddress;
|
||||
|
||||
import org.alfresco.util.remote.server.RemoteInputStreamServer;
|
||||
import org.alfresco.util.remote.server.RmiRemoteInputStreamServer;
|
||||
|
||||
/**
|
||||
* The data consuming side of the remote connection that the <code>InputStream</code> spans.
|
||||
*
|
||||
* @author <a href="mailto:Michael.Shavnev@effective-soft.com">Michael Shavnev</a>
|
||||
* @since Alfresco 2.2
|
||||
*/
|
||||
public class RemotableInputStream extends InputStream implements Serializable
|
||||
{
|
||||
private static final long serialVersionUID = 2434858590717000057L;
|
||||
|
||||
private int port;
|
||||
private String host;
|
||||
private String name;
|
||||
|
||||
transient private RemoteInputStreamServer inputStreamServer;
|
||||
|
||||
public RemotableInputStream(String host, int port, InputStream inputStream)
|
||||
{
|
||||
this.host = host;
|
||||
this.port = port;
|
||||
this.inputStreamServer = new RmiRemoteInputStreamServer(inputStream);
|
||||
}
|
||||
|
||||
public void close() throws IOException
|
||||
{
|
||||
inputStreamServer.close();
|
||||
}
|
||||
|
||||
public int read() throws IOException
|
||||
{
|
||||
return inputStreamServer.read();
|
||||
}
|
||||
|
||||
public int read(byte[] bytes) throws IOException
|
||||
{
|
||||
return inputStreamServer.read(bytes);
|
||||
}
|
||||
|
||||
public int read(byte[] bytes, int off, int len) throws IOException
|
||||
{
|
||||
return inputStreamServer.read(bytes, off, len);
|
||||
}
|
||||
|
||||
public long skip(long n) throws IOException
|
||||
{
|
||||
return inputStreamServer.skip(n);
|
||||
}
|
||||
|
||||
public int available() throws IOException
|
||||
{
|
||||
return inputStreamServer.available();
|
||||
}
|
||||
|
||||
public void mark(int readlimit)
|
||||
{
|
||||
inputStreamServer.mark(readlimit);
|
||||
}
|
||||
|
||||
public boolean markSupported()
|
||||
{
|
||||
return inputStreamServer.markSupported();
|
||||
}
|
||||
|
||||
public void reset() throws IOException
|
||||
{
|
||||
inputStreamServer.reset();
|
||||
}
|
||||
|
||||
private void writeObject(ObjectOutputStream out) throws IOException
|
||||
{
|
||||
name = inputStreamServer.start(host, port);
|
||||
out.defaultWriteObject();
|
||||
}
|
||||
|
||||
private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
|
||||
{
|
||||
in.defaultReadObject();
|
||||
inputStreamServer = (RemoteInputStreamServer) RmiRemoteInputStreamServer.obtain(host, port, name);
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
RemotableInputStream remotableInputStream = new RemotableInputStream(InetAddress.getLocalHost().getHostName(), 7777, new ByteArrayInputStream("test".getBytes()));
|
||||
|
||||
for (int b = -1; (b = remotableInputStream.read()) != -1;)
|
||||
{
|
||||
System.out.println((char) b);
|
||||
}
|
||||
|
||||
remotableInputStream = new RemotableInputStream(InetAddress.getLocalHost().getHostName(), 7777, new ByteArrayInputStream("test".getBytes()));
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||
oos.writeObject(remotableInputStream);
|
||||
|
||||
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
|
||||
remotableInputStream = (RemotableInputStream) ois.readObject();
|
||||
|
||||
for (int b = -1; (b = remotableInputStream.read()) != -1;)
|
||||
{
|
||||
System.out.println((char) b);
|
||||
}
|
||||
remotableInputStream.close();
|
||||
}
|
||||
}
|
@@ -1,90 +0,0 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.util.remote.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* The data producing side of the remote connection that the <code>InputStream</code> spans.
|
||||
*
|
||||
* @author <a href="mailto:Michael.Shavnev@effective-soft.com">Michael Shavnev</a>
|
||||
* @since Alfresco 2.2
|
||||
*/
|
||||
public abstract class AbstractRemoteInputStreamServer implements RemoteInputStreamServer
|
||||
{
|
||||
protected InputStream inputStream;
|
||||
|
||||
protected AbstractRemoteInputStreamServer(InputStream inputStream)
|
||||
{
|
||||
this.inputStream = inputStream;
|
||||
}
|
||||
|
||||
public int read() throws IOException
|
||||
{
|
||||
return inputStream.read();
|
||||
}
|
||||
|
||||
public int read(byte[] bytes) throws IOException
|
||||
{
|
||||
return inputStream.read(bytes);
|
||||
}
|
||||
|
||||
public int read(byte[] bytes, int off, int len) throws IOException
|
||||
{
|
||||
return inputStream.read(bytes, off, len);
|
||||
}
|
||||
|
||||
public long skip(long n) throws IOException
|
||||
{
|
||||
return inputStream.skip(n);
|
||||
}
|
||||
|
||||
public int available() throws IOException
|
||||
{
|
||||
return inputStream.available();
|
||||
}
|
||||
|
||||
public void mark(int readlimit)
|
||||
{
|
||||
inputStream.mark(readlimit);
|
||||
}
|
||||
|
||||
public boolean markSupported()
|
||||
{
|
||||
return inputStream.markSupported();
|
||||
}
|
||||
|
||||
public void reset() throws IOException
|
||||
{
|
||||
inputStream.reset();
|
||||
}
|
||||
|
||||
public void close() throws IOException
|
||||
{
|
||||
inputStream.close();
|
||||
}
|
||||
}
|
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.util.remote.server;
|
||||
|
||||
import java.rmi.RemoteException;
|
||||
|
||||
import org.springframework.remoting.rmi.RmiServiceExporter;
|
||||
|
||||
public class AlfrescoRMIServiceExporter extends RmiServiceExporter
|
||||
{
|
||||
private boolean enabled = true;
|
||||
|
||||
public void setEnabled(boolean enabled)
|
||||
{
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
public boolean isEnabled()
|
||||
{
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void prepare() throws RemoteException
|
||||
{
|
||||
if(enabled)
|
||||
{
|
||||
super.prepare();
|
||||
}
|
||||
}
|
||||
|
||||
public void destroy() throws RemoteException
|
||||
{
|
||||
if(enabled)
|
||||
{
|
||||
super.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.util.remote.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.rmi.RemoteException;
|
||||
|
||||
/**
|
||||
* Interface for remote input stream support.
|
||||
*
|
||||
* @author <a href="mailto:Michael.Shavnev@effective-soft.com">Michael Shavnev</a>
|
||||
* @since Alfresco 2.2
|
||||
*/
|
||||
public interface RemoteInputStreamServer
|
||||
{
|
||||
public String start(String host, int port) throws RemoteException;
|
||||
|
||||
public int read() throws IOException;
|
||||
|
||||
public int read(byte[] bytes) throws IOException;
|
||||
|
||||
public int read(byte[] bytes, int off, int len) throws IOException;
|
||||
|
||||
public long skip(long n) throws IOException;
|
||||
|
||||
public int available() throws IOException;
|
||||
|
||||
public void mark(int readlimit);
|
||||
|
||||
public boolean markSupported();
|
||||
|
||||
public void reset() throws IOException;
|
||||
|
||||
public void close() throws IOException;
|
||||
}
|
@@ -1,108 +0,0 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.util.remote.server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.rmi.RemoteException;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.springframework.remoting.rmi.RmiProxyFactoryBean;
|
||||
import org.springframework.remoting.rmi.RmiServiceExporter;
|
||||
|
||||
/**
|
||||
* Concrete implementation of a remoting InputStream based on RMI.
|
||||
*
|
||||
* @author <a href="mailto:Michael.Shavnev@effective-soft.com">Michael Shavnev</a>
|
||||
* @since Alfresco 2.2
|
||||
*/
|
||||
public class RmiRemoteInputStreamServer extends AbstractRemoteInputStreamServer
|
||||
{
|
||||
private RmiServiceExporter rmiServiceExporter;
|
||||
|
||||
public RmiRemoteInputStreamServer(InputStream inputStream)
|
||||
{
|
||||
super(inputStream);
|
||||
}
|
||||
|
||||
public String start(String host, int port) throws RemoteException
|
||||
{
|
||||
String name = inputStream.getClass().getName() + UUID.randomUUID();
|
||||
rmiServiceExporter = new RmiServiceExporter();
|
||||
rmiServiceExporter.setServiceName(name);
|
||||
rmiServiceExporter.setRegistryPort(port);
|
||||
rmiServiceExporter.setRegistryHost(host);
|
||||
rmiServiceExporter.setServiceInterface(RemoteInputStreamServer.class);
|
||||
rmiServiceExporter.setService(this);
|
||||
rmiServiceExporter.afterPropertiesSet();
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the stream and the RMI connection to the peer.
|
||||
*/
|
||||
public void close() throws IOException
|
||||
{
|
||||
try
|
||||
{
|
||||
inputStream.close();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (rmiServiceExporter != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
rmiServiceExporter.destroy();
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
throw new IOException(e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Utility method to lookup a remote stream peer over RMI.
|
||||
*/
|
||||
public static RemoteInputStreamServer obtain(String host, int port, String name) throws RemoteException
|
||||
{
|
||||
RmiProxyFactoryBean rmiProxyFactoryBean = new RmiProxyFactoryBean();
|
||||
rmiProxyFactoryBean.setServiceUrl("rmi://" + host + ":" + port + "/" + name);
|
||||
rmiProxyFactoryBean.setServiceInterface(RemoteInputStreamServer.class);
|
||||
rmiProxyFactoryBean.setRefreshStubOnConnectFailure(true);
|
||||
try
|
||||
{
|
||||
rmiProxyFactoryBean.afterPropertiesSet();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RemoteException("Error create rmi proxy");
|
||||
}
|
||||
return (RemoteInputStreamServer) rmiProxyFactoryBean.getObject();
|
||||
}
|
||||
}
|
@@ -24,8 +24,9 @@ repo.client-app.share.confirmResetPasswordTemplatePath=
|
||||
|
||||
repo.client-app.workspace.workspaceUrl=${repoBaseUrl}/workspace
|
||||
|
||||
repo.client-app.workspace.templateAssetsUrl=${workspaceUrl}/images
|
||||
#repo.client-app.workspace.templateAssetsUrl=${workspaceUrl}/images
|
||||
|
||||
repo.client-app.workspace.templateAssetsUrl=alfresco/templates/reset-password-email-templates/images
|
||||
# reset password request email template path
|
||||
repo.client-app.workspace.requestResetPasswordTemplatePath=alfresco/templates/reset-password-email-templates/forgot-password-email-template.ftl
|
||||
# reset password UI page url
|
||||
|
@@ -1,74 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE beans PUBLIC "-//SPRING/DTD BEAN//EN"
|
||||
"http://www.springframework.org/dtd/spring-beans.dtd">
|
||||
|
||||
<beans>
|
||||
|
||||
<!-- Remote FileFolderService exposure -->
|
||||
|
||||
<bean id="fileFolderRemoteServer" class="org.alfresco.repo.remote.FileFolderRemoteServer">
|
||||
<property name="transactionService">
|
||||
<ref bean="TransactionService"/>
|
||||
</property>
|
||||
<property name="fileFolderService">
|
||||
<ref bean="FileFolderService"/>
|
||||
</property>
|
||||
<property name="authenticationService">
|
||||
<ref bean="AuthenticationService"/>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="fileFolderRemoteRMI" class="org.springframework.remoting.rmi.RmiServiceExporter" parent="baseServiceExporter">
|
||||
<property name="service">
|
||||
<ref bean="fileFolderRemoteServer"/>
|
||||
</property>
|
||||
<property name="serviceInterface">
|
||||
<value>org.alfresco.service.cmr.remote.FileFolderRemote</value>
|
||||
</property>
|
||||
<property name="serviceName">
|
||||
<value>org.alfresco.FileFolderRemote</value>
|
||||
</property>
|
||||
<property name="registryPort">
|
||||
<value>${alfresco.rmi.services.port}</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Remote Loader exposure -->
|
||||
|
||||
<bean id="loaderRemoteServer" class="org.alfresco.repo.remote.LoaderRemoteServer">
|
||||
<property name="transactionService">
|
||||
<ref bean="TransactionService"/>
|
||||
</property>
|
||||
<property name="authenticationService">
|
||||
<ref bean="AuthenticationService"/>
|
||||
</property>
|
||||
<property name="nodeService">
|
||||
<ref bean="NodeService"/>
|
||||
</property>
|
||||
<property name="fileFolderService">
|
||||
<ref bean="FileFolderService"/>
|
||||
</property>
|
||||
<property name="checkOutCheckInService">
|
||||
<ref bean="CheckoutCheckinService"/>
|
||||
</property>
|
||||
<property name="fileFolderRemote">
|
||||
<ref bean="fileFolderRemoteServer"/>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<bean id="loaderRemoteServerRMI" class="org.springframework.remoting.rmi.RmiServiceExporter" parent="baseServiceExporter">
|
||||
<property name="service">
|
||||
<ref bean="loaderRemoteServer"/>
|
||||
</property>
|
||||
<property name="serviceInterface">
|
||||
<value>org.alfresco.service.cmr.remote.LoaderRemote</value>
|
||||
</property>
|
||||
<property name="serviceName">
|
||||
<value>org.alfresco.LoaderRemote</value>
|
||||
</property>
|
||||
<property name="registryPort">
|
||||
<value>${alfresco.rmi.services.port}</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
</beans>
|
@@ -86,9 +86,6 @@
|
||||
</bean>
|
||||
|
||||
<bean name="identityServiceConfig" class="org.alfresco.repo.security.authentication.identityservice.IdentityServiceConfig">
|
||||
<property name="globalProperties">
|
||||
<ref bean="global-properties" />
|
||||
</property>
|
||||
<property name="realm">
|
||||
<value>${identity-service.realm}</value>
|
||||
</property>
|
||||
@@ -98,12 +95,48 @@
|
||||
<property name="resource">
|
||||
<value>${identity-service.resource}</value>
|
||||
</property>
|
||||
<property name="clientSecret">
|
||||
<value>${identity-service.credentials.secret:#{null}}</value>
|
||||
</property>
|
||||
<property name="allowAnyHostname">
|
||||
<value>${identity-service.allow-any-hostname:false}</value>
|
||||
</property>
|
||||
<property name="disableTrustManager">
|
||||
<value>${identity-service.disable-trust-manager:false}</value>
|
||||
</property>
|
||||
<property name="truststore">
|
||||
<value>${identity-service.truststore:#{null}}</value>
|
||||
</property>
|
||||
<property name="truststorePassword">
|
||||
<value>${identity-service.truststore-password:#{null}}</value>
|
||||
</property>
|
||||
<property name="clientKeystore">
|
||||
<value>${identity-service.client-keystore:#{null}}</value>
|
||||
</property>
|
||||
<property name="clientKeystorePassword">
|
||||
<value>${identity-service.client-keystore-password:#{null}}</value>
|
||||
</property>
|
||||
<property name="clientKeyPassword">
|
||||
<value>${identity-service.client-key-password:#{null}}</value>
|
||||
</property>
|
||||
<property name="connectionPoolSize">
|
||||
<value>${identity-service.connection-pool-size:20}</value>
|
||||
</property>
|
||||
<property name="clientConnectionTimeout">
|
||||
<value>${identity-service.client-connection-timeout:2000}</value>
|
||||
</property>
|
||||
<property name="clientSocketTimeout">
|
||||
<value>${identity-service.client-socket-timeout:2000}</value>
|
||||
</property>
|
||||
<property name="realmKey">
|
||||
<value>${identity-service.realm-public-key:#{null}}</value>
|
||||
</property>
|
||||
<property name="publicKeyCacheTtl">
|
||||
<value>${identity-service.public-key-cache-ttl:86400}</value>
|
||||
</property>
|
||||
<property name="publicClient">
|
||||
<value>${identity-service.public-client:false}</value>
|
||||
</property>
|
||||
</bean>
|
||||
|
||||
<!-- Enable control over mapping between request and user ID -->
|
||||
|
@@ -9,4 +9,5 @@ identity-service.authentication.enable-username-password-authentication=true
|
||||
identity-service.auth-server-url=http://localhost:8180/auth
|
||||
identity-service.realm=alfresco
|
||||
identity-service.resource=alfresco
|
||||
identity-service.credentials.secret=
|
||||
identity-service.public-client=true
|
||||
|
@@ -37,13 +37,14 @@
|
||||
<bean id="taggingService" class="org.alfresco.repo.tagging.TaggingServiceImpl" init-method="init">
|
||||
<property name="nodeService" ref="NodeService"/>
|
||||
<property name="nodeServiceInternal" ref="nodeService"/>
|
||||
<property name="categoryService" ref="CategoryService"/>
|
||||
<property name="searchService" ref="SearchService"/>
|
||||
<property name="actionService" ref="ActionService"/>
|
||||
<property name="contentService" ref="ContentService"/>
|
||||
<property name="namespaceService" ref="NamespaceService"/>
|
||||
<property name="policyComponent" ref="policyComponent"/>
|
||||
<property name="auditComponent" ref="auditComponent"/>
|
||||
<property name="categoryService" ref="CategoryService"/>
|
||||
<property name="searchService" ref="SearchService"/>
|
||||
<property name="actionService" ref="ActionService"/>
|
||||
<property name="contentService" ref="ContentService"/>
|
||||
<property name="namespaceService" ref="NamespaceService"/>
|
||||
<property name="policyComponent" ref="policyComponent"/>
|
||||
<property name="auditComponent" ref="auditComponent"/>
|
||||
<property name="eventGenerator" ref="eventGeneratorV2"/>
|
||||
</bean>
|
||||
|
||||
<bean id="update-tagscope" class="org.alfresco.repo.tagging.UpdateTagScopesActionExecuter" parent="action-executer">
|
||||
|
@@ -1,12 +1,428 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Forgot Password</title>
|
||||
<style type="text/css">
|
||||
td {
|
||||
font-family: 'Helvetica Neue', Arial, sans-serif;
|
||||
}
|
||||
|
||||
body {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-webkit-text-size-adjust: none;
|
||||
width: 100% ! important;
|
||||
height: 100% !important;
|
||||
color: #727174;
|
||||
font-weight: 400;
|
||||
font-size: 18px;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
h2 {
|
||||
color: #727174;
|
||||
font-weight: 600;
|
||||
font-size: 22px;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #0c79bf;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
a.linkone {
|
||||
color: #0c79bf;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.appleLinks a {
|
||||
color: #0c79bf;
|
||||
}
|
||||
|
||||
.appleLinksWhite a {
|
||||
color: #0c79bf;
|
||||
}
|
||||
|
||||
.force-full-width {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
.body-padding {
|
||||
padding: 0 75px
|
||||
}
|
||||
|
||||
.force-width-80 {
|
||||
width: 80% !important;
|
||||
}
|
||||
|
||||
p {
|
||||
Margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.button {
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
font-family: sans-serif;
|
||||
font-weight: 400;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-webkit-text-size-adjust: none;
|
||||
}
|
||||
|
||||
.button a {
|
||||
color: #ffffff;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
img {
|
||||
max-width: 600px;
|
||||
outline: none;
|
||||
text-decoration: none;
|
||||
-ms-interpolation-mode: bicubic;
|
||||
}
|
||||
|
||||
a img {
|
||||
border: none;
|
||||
}
|
||||
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
mso-table-lspace: 0pt;
|
||||
mso-table-rspace: 0pt;
|
||||
}
|
||||
|
||||
#outlook a {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.ReadMsgBody {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ExternalClass {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.backgroundTable {
|
||||
margin: 0 auto;
|
||||
padding: 0;
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
table td {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.ExternalClass * {
|
||||
line-height: 115%;
|
||||
}
|
||||
|
||||
.ExternalClass {
|
||||
vertical-align: middle
|
||||
}
|
||||
|
||||
/*]]>*/
|
||||
</style>
|
||||
<style type="text/css" media="screen">
|
||||
@media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) { {
|
||||
@-ms-viewport {
|
||||
width: 320px;
|
||||
}
|
||||
@viewport {
|
||||
width: 320px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style type="text/css" media="screen">
|
||||
@media screen {
|
||||
* {
|
||||
font-family: 'Helvetica Neue', 'Arial', 'sans-serif' !important;
|
||||
}
|
||||
|
||||
.w280 {
|
||||
width: 280px !important;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
<style type="text/css" media="only screen and (max-width: 480px)">
|
||||
@media only screen and (max-width: 480px) {
|
||||
.full {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
table[class*="w320"] {
|
||||
width: 320px !important;
|
||||
}
|
||||
|
||||
td[class*="w320"] {
|
||||
width: 280px !important;
|
||||
padding-left: 20px !important;
|
||||
padding-right: 20px !important;
|
||||
}
|
||||
|
||||
img[class*="w320"] {
|
||||
width: 250px !important;
|
||||
height: 67px !important;
|
||||
}
|
||||
|
||||
td[class*="mobile-spacing"] {
|
||||
padding-top: 10px !important;
|
||||
padding-bottom: 10px !important;
|
||||
}
|
||||
|
||||
*[class*="mobile-hide"] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
*[class*="mobile-br"] {
|
||||
font-size: 8px !important;
|
||||
}
|
||||
|
||||
*[class*="mobile-brh"] {
|
||||
font-size: 1px !important;
|
||||
}
|
||||
|
||||
td[class*="mobile-w20"] {
|
||||
width: 20px !important;
|
||||
}
|
||||
|
||||
img[class*="mobile-w20"] {
|
||||
width: 20px !important;
|
||||
}
|
||||
|
||||
td[class*="mobile-center"] {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
table[class*="w100p"] {
|
||||
width: 100% !important;
|
||||
}
|
||||
|
||||
td[class*="activate-now"] {
|
||||
padding-right: 0 !important;
|
||||
padding-top: 20px !important;
|
||||
}
|
||||
|
||||
td[class*="mobile-resize"] {
|
||||
font-size: 22px !important;
|
||||
padding-left: 15px !important;
|
||||
}
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<p>You are receiving this email because you(or someone else) requested the password reset of your account.</p>
|
||||
<p>Please click on the following link, or paste this url into your browser to complete the process:</p>
|
||||
<body offset="0" class="body" style="padding:0; margin:0; display:block; background:#f3f4f4; -webkit-text-size-adjust:none; " bgcolor="#EEEEEE">
|
||||
<table align="center" cellpadding="0" cellspacing="0" width="100%" height="100%">
|
||||
<tr>
|
||||
<td align="center" valign="top" style="background-color:#f3f4f4; " width="100%">
|
||||
<table cellspacing="0" cellpadding="0" width="600" class="w320">
|
||||
<tr>
|
||||
<td align="center" valign="top">
|
||||
|
||||
<!--Snippet Block-->
|
||||
<table border="0" cellspacing="0" cellpadding="0" align="center" width="100%">
|
||||
<tr>
|
||||
<td>
|
||||
<table border="0" cellspacing="0" cellpadding="10" width="100%" align="center">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="left">
|
||||
<table align="center" width="100%" border="0" cellspacing="0" cellpadding="0">
|
||||
<tr>
|
||||
<td align="right">
|
||||
<div style="display:none;font-size:1px;color:#333333;line-height:1px;max-height:0px;max-width:0px;opacity:0;overflow:hidden;">
|
||||
-
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!--Header Block-->
|
||||
<table bgcolor="#FFFFFF" border="0" cellspacing="0" cellpadding="0" align="center" width="100%"
|
||||
style="border-left:solid 1px #dedee4; border-right:solid 1px #dedee4; border-bottom:solid 1px #dedee4; border-top:solid 1px #dedee4; width:100%!important; min-width:100%;">
|
||||
<tr style="width:100%;">
|
||||
<td>
|
||||
<table border="0" cellspacing="0" cellpadding="10" align="center" width="100%">
|
||||
<tr>
|
||||
<td align="left" valign="middle"><a style="color: #ffffff; text-decoration: none;" href=
|
||||
"http://go.alfresco.com/a0100K050L0000KZjI2d00U" target="_blank"
|
||||
><span style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 24px; color: #727174;"><img
|
||||
style="border:none; display:block; border-collapse:collapse; outline:none; text-decoration:none;"
|
||||
src="${template_assets_url}/hyland_logo.png" border="0"
|
||||
alt="Alfresco" width="122" height="38"></span></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
<td align="right" bgcolor="#FFFFFF">
|
||||
<table border="0" cellspacing="0" cellpadding="10" align="center" width="100%">
|
||||
<tr>
|
||||
<td align="right" valign="middle"><span
|
||||
style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 16px; font-weight:200; color: #727174;">Digital Workspace</span>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!--Break-->
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td height="10">
|
||||
<div class="mobile-br"> </div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!--Body Block 1-->
|
||||
<!--Banner Block-->
|
||||
<table cellspacing="0" cellpadding="0" width="100%" style="border-left:solid 1px #dedee4; border-right:solid 1px #dedee4; ">
|
||||
<tr>
|
||||
<td style="border-collapse:collapse; ">
|
||||
<table cellspacing="0" cellpadding="0" width="100%" style="background-color:#0c79bf; border:none; ">
|
||||
<tr>
|
||||
<td style="border-collapse:collapse; ">
|
||||
<div class="mktEditable" id="Banner Image 1"><span
|
||||
style="font-family:'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 24px; color: #ffffff;"><img
|
||||
src="${template_assets_url}/adw_logo.png" alt="Alfresco Products" style="width:100%; border:none;
|
||||
display:block; border-collapse:collapse; outline:none; text-decoration:none;"></span></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--Copy-->
|
||||
<table cellspacing="0" cellpadding="0" align="center" bgcolor="#FFFFFF"
|
||||
style="border-left:solid 1px #dedee4; border-right:solid 1px #dedee4; border-bottom:solid 1px #dedee4; " width="100%">
|
||||
<tr align="center">
|
||||
<td style="background-color:#ffffff; " align="center">
|
||||
<table class="force-width-80" cellspacing="0" cellpadding="12" align="center" bgcolor="#FFFFFF" width="80%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td align="left">
|
||||
<!--Headline Text-->
|
||||
<div class="mktEditable" id="Headline Text 1" align="left" style="vertical-align:middle; "><span
|
||||
style="color: #727174; margin: 0px; font-family: Gotham, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 22px; font-weight: 600; text-align: left; text-decoration: none; vertical-align:
|
||||
middle;"><p>${message("templates.reset-password-email.ftl.title")}</p></span></div>
|
||||
<div class="mktEditable" id="Body Text 1" align="left">
|
||||
<span style="color:#727174; font-family:Gotham, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size:18px;font-weight:400; text-align:left; text-decoration:none; -webkit-text-size-adjust:none;">
|
||||
<p>${message("templates.reset-password-email.ftl.detail")}</p>
|
||||
</span>
|
||||
|
||||
</div>
|
||||
|
||||
<!--Break-->
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td height="5">
|
||||
<div class="mobile-br"> </div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!--Button-->
|
||||
<table style="margin:0 auto; " cellspacing="0" cellpadding="0" width="100%">
|
||||
<tr>
|
||||
<td style="text-align:center; margin:0 auto; ">
|
||||
<div><!--[if mso]>
|
||||
<v:rect xmlns:v="urn:schemas-microsoft-com:vml"
|
||||
xmlns:w="urn:schemas-microsoft-com:office:word"
|
||||
style="height:45px;v-text-anchor:middle;width:220px;" stroke="f"
|
||||
fillcolor="#47AA2">
|
||||
<w:anchorlock/>
|
||||
<center>
|
||||
<![endif]-->
|
||||
<div class="mktEditable" id="Button Text"><a href="${reset_password_url}" style="background-color:#47aa42; color:#ffffff; display:inline-block; font-family:Gotham, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size:18px; font-weight:400; line-height:45px; text-align:center; text-decoration:none; width:220px;
|
||||
-webkit-text-size-adjust:none;">${message("templates.reset-password-email.ftl.reset_password_button")}</a></div>
|
||||
<span style="color:#727174; font-family:Gotham, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size:12px;font-weight:400; text-align:left; text-decoration:none; -webkit-text-size-adjust:none;">
|
||||
<p>${message("templates.reset-password-email.ftl.ignore_message")}</p>
|
||||
<span style="color:#727174; font-family:Gotham, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size:12px;font-weight:400; text-align:left; text-decoration:none; -webkit-text-size-adjust:none;">
|
||||
<hr>
|
||||
<p>${message("templates.reset-password-email.ftl.having_trouble_clicking_button")}</p>
|
||||
<p><a href="${reset_password_url}">${reset_password_url}</a></p>
|
||||
<p>If you received this in error, you can safely ignore it.</p>
|
||||
<p>Kind regards</p>
|
||||
</span>
|
||||
<!--[if mso]>
|
||||
</center>
|
||||
</v:rect>
|
||||
<![endif]--></div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!--Break-->
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td height="5">
|
||||
<div class="mobile-br"> </div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!--Break-->
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td height="10">
|
||||
<div class="mobile-br"> </div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!--Footer Block-->
|
||||
<table border="0" cellspacing="0" cellpadding="0" align="center" width="100%">
|
||||
<tr>
|
||||
<td align="center">
|
||||
<a style="color: #0c79bf; text-decoration: underline;" href="http://www.alfresco.com/company/contact"
|
||||
target="_blank"><span
|
||||
style="font-family: Gotham, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 10px; color: #0c79bf;">${message("templates.generic-email.ftl.contact_us")}</span></a>
|
||||
<span style="font-family: Gotham, 'Helvetica Neue', Helvetica, Arial,
|
||||
sans-serif; font-size: 10px; color: #b3b3b8;">© ${date?string["yyyy"]} Alfresco Software, Inc.
|
||||
${message("templates.generic-email.ftl.copy_right")}</span><br>
|
||||
<span style="font-family: Gotham, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 10px; color: #b3b3b8;">Bridge Ave, The Place Maidenhead SL6 1AF United Kingdom</span><br>
|
||||
<span style="font-family: Gotham, 'Helvetica Neue', Helvetica, Arial, sans-serif; font-size: 10px; color: #b3b3b8;">1825 S Grant St, Suite 900 San Mateo, CA 94402 USA</span><br>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!--Break-->
|
||||
<table width="100%">
|
||||
<tr>
|
||||
<td height="10">
|
||||
<div class="mobile-br"> </div>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
<!--Litmus Tracking-->
|
||||
<table style="display: none;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td style="width: 0px; display: none; overflow: hidden; max-height: 0px;">{{my.Litmus_Code}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</body>
|
||||
</html>
|
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
Binary file not shown.
After Width: | Height: | Size: 7.0 KiB |
@@ -2,7 +2,7 @@
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2022 Alfresco Software Limited
|
||||
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
@@ -25,6 +25,7 @@
|
||||
*/
|
||||
package org.alfresco;
|
||||
|
||||
import org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacadeFactoryBeanTest;
|
||||
import org.alfresco.repo.security.authentication.identityservice.LazyInstantiatingIdentityServiceFacadeUnitTest;
|
||||
import org.alfresco.repo.security.authentication.identityservice.SpringBasedIdentityServiceFacadeUnitTest;
|
||||
import org.alfresco.util.testing.category.DBTests;
|
||||
@@ -138,6 +139,7 @@ import org.junit.runners.Suite;
|
||||
org.alfresco.repo.search.impl.solr.facet.FacetQNameUtilsTest.class,
|
||||
org.alfresco.util.BeanExtenderUnitTest.class,
|
||||
org.alfresco.repo.solr.SOLRTrackingComponentUnitTest.class,
|
||||
IdentityServiceFacadeFactoryBeanTest.class,
|
||||
LazyInstantiatingIdentityServiceFacadeUnitTest.class,
|
||||
SpringBasedIdentityServiceFacadeUnitTest.class,
|
||||
org.alfresco.repo.security.authentication.CompositePasswordEncoderTest.class,
|
||||
|
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* #%L
|
||||
* Alfresco Repository
|
||||
* %%
|
||||
* Copyright (C) 2005 - 2023 Alfresco Software Limited
|
||||
* %%
|
||||
* This file is part of the Alfresco software.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* Alfresco is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Alfresco is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
* #L%
|
||||
*/
|
||||
package org.alfresco.repo.security.authentication.identityservice;
|
||||
|
||||
import static org.alfresco.repo.security.authentication.identityservice.IdentityServiceRemoteUserMapper.USERNAME_CLAIM;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.alfresco.repo.security.authentication.identityservice.IdentityServiceFacadeFactoryBean.JwtDecoderProvider;
|
||||
import org.junit.Test;
|
||||
import org.springframework.security.oauth2.client.registration.ClientRegistration.ProviderDetails;
|
||||
import org.springframework.security.oauth2.jwt.Jwt;
|
||||
import org.springframework.security.oauth2.jwt.JwtDecoder;
|
||||
|
||||
public class IdentityServiceFacadeFactoryBeanTest
|
||||
{
|
||||
@Test
|
||||
public void shouldCreateJwtDecoderWithoutIDSWhenPublicKeyIsProvided()
|
||||
{
|
||||
final IdentityServiceConfig config = mock(IdentityServiceConfig.class);
|
||||
when(config.getRealmKey()).thenReturn("MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAve3MabX/rp3LbE7/zNqKxuid8WT7y4qSXsNaiPvl/OVbNWW/cu5td1VndItYhH6/gL7Z5W/r4MOeTlz/fOdXfjrRJou2f3UiPQwLV9RdOH3oS4/BUe+sviD8Q3eRfWBWWz3yw8f2YNtD4bMztIMMjqthvwdEEb9S9jbxxD0o71Bsrz/FwPi7HhSDA+Z/p01Hct8m4wx13ZlKRd4YjyC12FBmi9MSgsrFuWzyQHhHTeBDoALpfuiut3rhVxUtFmVTpy6p9vil7C5J5pok4MXPH0dJCyDNQz05ww5+fD+tfksIEpFeokRpN226F+P21oQVFUWwYIaXaFlG/hfvwmnlfQIDAQAB");
|
||||
|
||||
final ProviderDetails providerDetails = mock(ProviderDetails.class);
|
||||
when(providerDetails.getIssuerUri()).thenReturn("https://my.issuer");
|
||||
|
||||
final JwtDecoderProvider provider = new JwtDecoderProvider(config);
|
||||
|
||||
final JwtDecoder decoder = provider.createJwtDecoder(null, providerDetails);
|
||||
|
||||
final Jwt decodedToken = decoder.decode("eyJhbGciOiJSUzI1NiJ9.eyJleHAiOjIxNDc0ODM2NDcsImp0aSI6IjEyMzQiLCJpc3MiOiJodHRwczovL215Lmlzc3VlciIsInN1YiI6ImFiYzEyMyIsInR5cCI6IkJlYXJlciIsInByZWZlcnJlZF91c2VybmFtZSI6InBpb3RyZWsifQ.k_KaOrLLh3QsT8mKphkcz2vKpulgxp92UoEDccpHJ1mxE3Pa3gFXPKTj4goUBKXieGPZRMvBDhfWNxMvRYZPiQr2NXJKapkh0bTd0qoaSWz9ICe9Nu3eg7_VA_nwUVPz_35wwmrxgVk0_kpUYQN_VtaO7ZgFE2sJzFjbkVls5aqfAMnEjEgQl837hqZvmlW2ZRWebtxXfQxAjtp0gcTg-xtAHKIINYo_1_uAtt_H9L8KqFaioxrVAEDDIlcKnb-Ks3Y62CrZauaGUJeN_aNj2gdOpdkhvCw79yJyZSGZ7okjGbidCNSAf7Bo2Y6h3dP1Gga7kRmD648ftZESrNvbyg");
|
||||
assertThat(decodedToken).isNotNull();
|
||||
|
||||
final Map<String, Object> claims = decodedToken.getClaims();
|
||||
assertThat(claims).isNotNull()
|
||||
.isNotEmpty()
|
||||
.containsEntry(USERNAME_CLAIM, "piotrek");
|
||||
}
|
||||
|
||||
}
|
@@ -25,10 +25,16 @@
|
||||
*/
|
||||
package org.alfresco.repo.tagging;
|
||||
|
||||
import static java.util.Collections.emptyMap;
|
||||
|
||||
import static org.alfresco.model.ContentModel.ASPECT_TAGGABLE;
|
||||
import static org.alfresco.model.ContentModel.PROP_TAGS;
|
||||
import static org.alfresco.model.ContentModel.ASSOC_SUBCATEGORIES;
|
||||
import static org.alfresco.model.ContentModel.PROP_NAME;
|
||||
import static org.alfresco.repo.tagging.TaggingServiceImpl.TAG_UPDATES;
|
||||
import static org.alfresco.service.cmr.repository.StoreRef.STORE_REF_WORKSPACE_SPACESSTORE;
|
||||
import static org.alfresco.service.cmr.search.SearchService.LANGUAGE_LUCENE;
|
||||
import static org.alfresco.service.cmr.tagging.TaggingService.TAG_ROOT_NODE_REF;
|
||||
import static org.alfresco.service.namespace.NamespaceService.CONTENT_MODEL_1_0_URI;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.catchThrowable;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
@@ -36,16 +42,15 @@ import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.BDDMockito.then;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.alfresco.model.ContentModel;
|
||||
import org.alfresco.repo.event2.EventGenerator;
|
||||
import org.alfresco.repo.policy.PolicyComponent;
|
||||
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
|
||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||
@@ -56,6 +61,7 @@ import org.alfresco.service.cmr.repository.StoreRef;
|
||||
import org.alfresco.service.cmr.search.CategoryService;
|
||||
import org.alfresco.service.cmr.search.ResultSet;
|
||||
import org.alfresco.service.cmr.search.SearchService;
|
||||
import org.alfresco.service.namespace.QName;
|
||||
import org.alfresco.util.Pair;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -84,6 +90,8 @@ public class TaggingServiceImplUnitTest
|
||||
private ResultSet resultSetMock;
|
||||
@Mock(extraInterfaces = List.class)
|
||||
private Serializable currentTagsMock;
|
||||
@Mock
|
||||
private EventGenerator eventGenerator;
|
||||
|
||||
@InjectMocks
|
||||
private TaggingServiceImpl taggingService;
|
||||
@@ -128,45 +136,25 @@ public class TaggingServiceImplUnitTest
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void testChangeTag()
|
||||
{
|
||||
final String newTagName = "new-tag-name";
|
||||
final NodeRef newTagNodeRef = new NodeRef(StoreRef.STORE_REF_WORKSPACE_SPACESSTORE, newTagName);
|
||||
given(searchServiceMock.query(any(), any(String.class), any(String.class))).willReturn(resultSetMock);
|
||||
given(resultSetMock.getNodeRefs()).willReturn(List.of(CONTENT_NODE_REF), Collections.emptyList());
|
||||
given(nodeServiceMock.hasAspect(CONTENT_NODE_REF, ASPECT_TAGGABLE)).willReturn(true);
|
||||
given(categoryServiceMock.getRootCategories(STORE_REF_WORKSPACE_SPACESSTORE, ASPECT_TAGGABLE, TAG_NAME, false)).willReturn(childAssociationsOf(TAG_NODE_REF));
|
||||
given(nodeServiceMock.getProperty(CONTENT_NODE_REF, PROP_TAGS)).willReturn(currentTagsMock);
|
||||
given(((List<NodeRef>) currentTagsMock).size()).willReturn(1);
|
||||
given(((List<NodeRef>) currentTagsMock).contains(TAG_NODE_REF)).willReturn(true);
|
||||
given(categoryServiceMock.getRootCategories(STORE_REF_WORKSPACE_SPACESSTORE, ASPECT_TAGGABLE, newTagName, true)).willReturn(childAssociationsOf(newTagNodeRef));
|
||||
given(((List<NodeRef>) currentTagsMock).contains(newTagNodeRef)).willReturn(false);
|
||||
given(searchServiceMock.query(STORE_REF_WORKSPACE_SPACESSTORE, LANGUAGE_LUCENE, "+PATH:\"/cm:taggable/cm:" + TAG_NAME + "/member\"")).willReturn(resultSetMock);
|
||||
given(resultSetMock.getNodeRefs()).willReturn(List.of(CONTENT_NODE_REF));
|
||||
|
||||
//when
|
||||
taggingService.changeTag(STORE_REF_WORKSPACE_SPACESSTORE, TAG_NAME, newTagName);
|
||||
|
||||
then((List<NodeRef>) currentTagsMock).should().remove(TAG_NODE_REF);
|
||||
then((List<NodeRef>) currentTagsMock).should().add(newTagNodeRef);
|
||||
then(nodeServiceMock).should(times(2)).setProperty(CONTENT_NODE_REF, PROP_TAGS, currentTagsMock);
|
||||
then(categoryServiceMock).should().deleteCategory(TAG_NODE_REF);
|
||||
then(categoryServiceMock).should(times(2)).getRootCategories(STORE_REF_WORKSPACE_SPACESSTORE, ASPECT_TAGGABLE, newTagName, true);
|
||||
}
|
||||
then(nodeServiceMock).should().setProperty(TAG_NODE_REF, PROP_NAME, newTagName);
|
||||
then(nodeServiceMock).should().moveNode(TAG_NODE_REF, TAG_ROOT_NODE_REF, ASSOC_SUBCATEGORIES, QName.createQName(CONTENT_MODEL_1_0_URI, newTagName));
|
||||
then(nodeServiceMock).should().getProperties(CONTENT_NODE_REF);
|
||||
then(nodeServiceMock).should().hasAspect(CONTENT_NODE_REF, ContentModel.ASPECT_TAGSCOPE);
|
||||
then(nodeServiceMock).should().getPrimaryParent(CONTENT_NODE_REF);
|
||||
then(nodeServiceMock).shouldHaveNoMoreInteractions();
|
||||
|
||||
@Test
|
||||
public void testChangeOrphanTag()
|
||||
{
|
||||
final String newTagName = "new-tag-name";
|
||||
given(searchServiceMock.query(any(), any(String.class), any(String.class))).willReturn(resultSetMock);
|
||||
given(resultSetMock.getNodeRefs()).willReturn(Collections.emptyList());
|
||||
given(categoryServiceMock.getRootCategories(STORE_REF_WORKSPACE_SPACESSTORE, ASPECT_TAGGABLE, TAG_NAME, false)).willReturn(childAssociationsOf(TAG_NODE_REF));
|
||||
|
||||
//when
|
||||
taggingService.changeTag(STORE_REF_WORKSPACE_SPACESSTORE, TAG_NAME, newTagName);
|
||||
|
||||
then(nodeServiceMock).should(never()).setProperty(any(), any(), any());
|
||||
then(categoryServiceMock).should().deleteCategory(TAG_NODE_REF);
|
||||
then(categoryServiceMock).should().getRootCategories(STORE_REF_WORKSPACE_SPACESSTORE, ASPECT_TAGGABLE, newTagName, true);
|
||||
then(eventGenerator).should().onUpdateProperties(eq(CONTENT_NODE_REF), eq(emptyMap()), any());
|
||||
then(eventGenerator).shouldHaveNoMoreInteractions();
|
||||
}
|
||||
|
||||
private static List<ChildAssociationRef> childAssociationsOf(final NodeRef... childNodeRefs)
|
||||
@@ -175,4 +163,4 @@ public class TaggingServiceImplUnitTest
|
||||
.map(childNodeRef -> new ChildAssociationRef(null, null, null, childNodeRef))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user