mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-06-30 18:15:39 +00:00
40164: Merged V4.0.2 to V4.1-BUG-FIX (4.1.1) - Partial merge of r39519 on V4.1 which included something from V4.1-BUG-FIX 39494: ALF-15170: Can't change folder permissions in Private or Public-moderated sites - Fix by Dmitry V 38899: ALF-15005: Merged V4.0-BUG-FIX to PATCHES/V4.0.2 37920: ALF-13816: Permission Denied on web-client browsing if parent does not inherit permissions - FileFolderService getNamePath() now performs toFileInfo() as SystemUser. 40167: Merged V4.1 (4.1.0) to V4.1-BUG-FIX (4.1.1) 40156: Adds defensive code to avoid situations where the parent can't be found (e.g. RM-474) 40144: ALF-11027: update URLs to deploy to our internal-snapshot Maven repo, so that GoogleDocs integration can take advantage of it 40121: Chinese: Translation update based on EN r40086 40120: Dutch: Translation update based on EN r40086 40119: Japanese: Translation update based on EN r40086 40118: Italian: Translation update based on EN r40086 40117: French: Translation update based on EN r40086 40116: Spanish: Translation update based on EN r40086 40115: German: Translation update based on EN r40086 40103: Unit test fix following removal of AVM file context. 40076: Fixes encoding error introduced in r40072. 40072: Error message string updates, based on feedback from Docs. 40069: ALF-15364 CloudSync: folder sync with lock on-premise - pulled new file is not auto-locked 40068: Java doc corrections. 40067: CloudSync: ALF-15287 - folder sync to a clashing name hierarchy causes file to be indirectly synced to the wrong place - was "An unsynced file which was synced indirectly will be synced in the documentLibrary" - plus unit test 40065: Removal of potential NullPointerException (not observed). 40063: Chinese: Translation updates from Gloria, based on EN r40019 40062: Dutch: Translation updates from Gloria, based on EN r40019 40061: Italian: Translation updates from Gloria, based on EN r40019 40060: French: Translation updates from Gloria, based on EN r40019 40059: Japanese: Translation updates from Gloria, based on EN r40019 40058: Spanish: Translation updates from Gloria, based on EN r40019 40057: German: Translation updates from Gloria, based on EN r40019 40054: CloudSync: add simple *folder* sync unit test ! 40053: ALF-15218 - AVM must not be visible by default in VFS mount points 40036: Addressing the important question raised in ALF-14950. I have decided that, as pointed out by MikeF, a sensible solution for handling secondary child-assocs that link nodes to synced folders would be to NOT sync those nodes. So I've made it such that new nodes are only added into a syncset if they are created as *primary* children of a synced folder. If they are secondary children, they are not added as members. Test case for same. 40019: Having fixed the TemporaryNodes @Rule in rev 40010 so that it handles checked-out test files gracefully, I'm removing Jan's workaround for a checked-out test file. 40017: During work for ALF-15296, I've fixed up the error handling during sync set creation. See ts doc: https://ts.alfresco.com/share/page/site/projectodin/document-details?nodeRef=workspace://SpacesStore/47bf11a3-8d30-4377-a373-1c1d3fba6018 Now Sync Set creation can fail if there are some problems with the provided direct member nodes. If there are problems with any indirect members, that will not cause the sync to fail during setup, but subsequent pushes to the Cloud will fail with appropriate error reporting. Exceptions during the creation of a syncset can now report multiple failed nodes. Rewrote the cannotCreateTwoSyncSetDefinitionsWithOverlappingLocalMembers() testcase to be creatingTwoSyncSetDefinitionsWithOverlappingLocalMembersShouldSilentlyDropTheOverlaps() Extra test cases for sync setup: syncing a list of ineligible nodes should throw an exception. Syncing a list of nodes, some of which are ineligible, should skip the ineligable ones. Syncing a folder containing already-synced child nodes and unwriteable child nodes should silently skip the already-synced, but include the unwriteable nodes as members (which will fail to sync). Various tidy-ups and comments to explain this behaviour to the next coder, which may be me. :) 40014: ALF-15218 - AVM must not be visible by default in VFS mount points 40010: Enhancement to TemporaryNodes JUnit @Rule so that it gracefully handles checked-out nodes during test code. 39996: ALF-14377: Need to decide what to do when SSD creator user is no longer valid 39986: Chinese: Translation updates from Gloria, based on EN r39671 39985: Dutch: Translation updates from Gloria, based on EN r39671 39984: Japanese: Translation updates from Gloria, based on EN r39671 39983: Italian: Translation updates from Gloria, based on EN r39671 39982: French: Translation updates from Gloria, based on EN r39671 39981: Spanish: Translation updates from Gloria, based on EN r39671 39980: German: Translation updates from Gloria, based on EN r39671 39957: CloudSync: minor - some info logging (applies to src + tgt) 39943: CloudSync: fix remainder of ALF-15130 - sync time for initial sync of working copy (+ unit test) 39942: ALF-14911 - Path shown in the version comments does not match the path shown in the sync status dialogue - first part share paths are now handled separatly 39933: ALF-14179: Merged PATCHES/V4.0.2 to V4.1 39929: ALF-15330: Merged V3.4-BUG-FIX to PATCHES/V4.0.2 39681: Fix CIFS hang on file open of MS Office document. ALF-13578, ALF-15092. Async packet queue not being cleared at end of request processing. 39924: CSS fixes for the sync panel 39918: Merged DEV to V4.1 39911: ALF-15263 : XAM: XAM Connector cannot be installed on Alfresco v4.1 39915: ALF-14908: Update Sync status dialogue to include the local root folder for indirectly synced nodes 39904: ALF-15041: Cloud Sync doesn't work with IE7 39903: ALF-15041: Cloud Sync doesn't work with IE7 39902: ALF-15041: Cloud Sync doesn't work with IE7 39883: CloudSync: fix ALF-15270 - moving directly synced node (on source) causes target node to be deleted - ... add related move file sync unit test 39876: ALF-15301: IE8 specific: It is impossible creating a new folder in a cloud target selection window/Cloud location 39864: ALF-15003 Sync failed for the file (where write access on source removed for sync owner) but no matter this file appears in Cloud 39863: ALF-15268: Cancel button disabled in the target selection window for new folder creation in Cloud 39860: ALF-14908: Update Sync status dialogue to include the local root folder for indirectly synced nodes. 39859: ALF-15249 Add a new method hasSyncSetDefintions, with unit test, and use this to skip the Sync Pull step on-premise if no SSDs have been defined on the local system 39847: ALF-15185: YUI Overlay Mozilla Scrollbar fix should be prevented in recent versions of Firefox too. 39826: ALF-14377 - Need to decide what to do when SSD creator user is no longer valid Implementation of "last gasp" unsync for the case where the sync set owner does not exist. 39820: ALF-15267: Edit online is available for locked on-premise copy and can unlock it ALF-15284: The actions "Upload New Version" and "Inline Edit" should not be available for a "synced" and "locked" node 39812: UI Bug Fixes: - ALF-15174: Uses already copied slingshot.properties file for message strings needed in both repo and Share - Cloud delete file message shouldn't refer to the cloud 39810: ALF-15221: Cloud Sync Status: Failure message when getting location is misleading 39767: CloudSync: fix ALF-15145 - Unsync of a folder (sync) that has a working copy file causes indirect icon to remain ... ... on working copy (until checkin or cancel checkout) 39748: CloudSync: fix compile error - failed manual "merge" (oops, sorry) 39747: ALF-14377 Need to decide what to do when SSD creator user is no longer valid - part 1 nodes are marked. 39735: CloudSync: ALF-14483 - multi-threaded SyncTracker - fix related to unit test failure (affecting CLOUD1 but not V4.1) - also add default (info) Sync log level 39729: Merged PATCHES/V4.0.2 to V4.1 39725: ALF-15176: Multi-threaded SOLR tracking suddenly stops leaving transactions unindexed - Debugged on environment provided by Antonio - If the last incomplete batch in a chunk consists entirely of empty transactions (or transactions consisting entirely of nodes updated in later transactions) it would loop forever 39687: Enterprise license for enterprise remote api project 39686: Replaced GPL license with enterprise licence. 39683: ALF-15162 - Unclear error message when delta syncing and the target is gone 39677: ALF-14903 Move the Sync allowed/not-allowed check, based on Network/Tenant, to AbstractCloudSyncAbstractWebScript, and have this used by the webscripts based on this too. Then, allow UnSync to proceed no matter what the tenant status, and add unit tests 39673: New unit test for adding checked out nodes into a sync set. 39670: Rework to cloud key license stuff - introduces a ValidLicenseEvent 39664: CloudSync: ALF-14483 - SyncTracker unit tests - simple file sync test - initially run with single-threaded push/pull (will require further investigation on cloud branch) 39653: ALF-15041: Cloud Sync doesn't work with IE7 39643: ALF-15220: Indirect sync and sync failed indicators appeared together on nodes during the demo 39641: ALF-15230 Refactor the lazy container creation code, to use the new SystemNodeUtils helper 39640: ALF-15231 Restore, with refactorings / making more general, the ability to lazy create the remote credentials container if bootstrap has not created it (eg on Cloud) 39639: ALF-15238: Bitrock Installer: Readme.txt should be updated - Alfresco version is 4.0 39633: CloudSync: ALF-14483 - SyncTracker - enable sync sets to be processed in parallel - wip default of 6 threads (3 to push / 3 to pull) 39616: CloudSync: CloudSync: ALF-14483 - SyncTracker - multiple syncs (to different tgt folders) with multiple files - make sure the multi-threaded tracker is excercised via automated unit tests 39613: Refactor of test code. SyncTrackerComponentTest now uses JUnit Rules to manage temporary content and to undo mocking out of services. 39607: CloudSync: ALF-14483 - SyncTracker - enable sync sets to be pushed in parallel - wip / default 3 threads 39606: CloudSync: minor log level adjustments - eg. info vs debug (vs trace) 39598: CloudSync: ALF-14655 - update simple file sync (to test multiple sync'd files) 39597: CloudSync: tweak a couple of unit tests - add "run id" to allow them to be locally re-runnable (in case of error) 39589: ALF-15098: Folder Picker causes JS error in the document details page 39587: ALF-15222: Cloud Folder picker: Newly created folder isn't selected 39580: CloudSync: fix Unsync - to ensure we don't leave sync aspects (such as failed, which reappears if src file is re-synced) - found by MF ... thanks - unit test added 39574: Cloud lacks a guest mode, so switch to unauthenticated for the sync mode fetch (user credentials may not be available) 39566: Allow the sync mode to be fetched by guest (it need not be hidden), then fetch from Share as guest, to avoid problems when fetching the sync mode if the current user's credentials have expired (otherwise it breaks the redirect back to the login) 39561: Merged THOR1 to V4.1 (try to say that in a hurry!) 39553: ALF-15149: Prevent an infinite loop in AlfrescoSolrEventListener.RemoveNullEntriesCacheMatch.updateCache() 39550: Synced folder shouldn't be filtered in the cloud folder picker. The user should be able to see them but not select them (the synced folder should be greyed out) 39548: CloudSync: ALF-14655 - add SyncTracker unit test for simple file sync - initial re-work of SyncTrackerComponentTest ... to make it easier to add more tests (and re-use test fragments) - add simple unit test for "file sync" (F4) => sync, push, pull, unsync ... - ... also fix potential SyncService unsync issue on target (found by new test) 39547: Bug fixes (spotted during demo): - Remove the "synced with errors" filter from dashlets and doclibrary for the cloud version - Remove the last '>' symbol in the info dialogue (path for "Cloud in the Location") 39546: Merged integrations/GoogleDocs/BRANCHES/OAUTH_V4.1 to BRANCHES/V4.1: 39504: [ALF-14926][GOOGLEDOCS-23] Merge OAuth2 Credentials Store Service 39516: Add missing license to OAuth2 Credentials Classes 39517: oAuth1 Credentials Store Service 39540: Some fixes to issues identified by findbugs. 39532: Revert cloud welcome dashlet text. git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@40273 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
296 lines
10 KiB
Java
296 lines
10 KiB
Java
/*
|
|
* Copyright (C) 2005-2012 Alfresco Software Limited.
|
|
*
|
|
* This file is part of Alfresco
|
|
*
|
|
* 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/>.
|
|
*/
|
|
package org.alfresco.repo.oauth2;
|
|
|
|
import java.util.Date;
|
|
import java.util.List;
|
|
|
|
import org.alfresco.error.AlfrescoRuntimeException;
|
|
import org.alfresco.query.CannedQueryPageDetails;
|
|
import org.alfresco.query.PagingRequest;
|
|
import org.alfresco.query.PagingResults;
|
|
import org.alfresco.repo.remotecredentials.OAuth2CredentialsInfoImpl;
|
|
import org.alfresco.repo.remotecredentials.RemoteCredentialsModel;
|
|
import org.alfresco.service.cmr.oauth2.OAuth2CredentialsStoreService;
|
|
import org.alfresco.service.cmr.remotecredentials.OAuth2CredentialsInfo;
|
|
import org.alfresco.service.cmr.remotecredentials.RemoteCredentialsService;
|
|
import org.alfresco.service.cmr.remoteticket.NoSuchSystemException;
|
|
|
|
/**
|
|
* @author Jared Ottley
|
|
*/
|
|
public class OAuth2CredentialsStoreServiceImpl implements OAuth2CredentialsStoreService
|
|
{
|
|
private RemoteCredentialsService remoteCredentialsService;
|
|
|
|
public void setRemoteCredentialsService(RemoteCredentialsService remoteCredentialsService)
|
|
{
|
|
this.remoteCredentialsService = remoteCredentialsService;
|
|
}
|
|
|
|
/**
|
|
* Add or Update OAuth2 Credentials for the current user to the OAuth2
|
|
* Credential Store
|
|
*
|
|
* @param remoteSystemId
|
|
* @param accessToken
|
|
* @param refresh Token
|
|
* @param expiresAt
|
|
* @param issuedAt if null, the current Datetime will be used
|
|
* @return OAuth2CredentialsInfo
|
|
*/
|
|
@Override
|
|
public OAuth2CredentialsInfo storePersonalOAuth2Credentials(String remoteSystemId,
|
|
String accessToken, String refreshToken, Date expiresAt, Date issuedAt)
|
|
throws NoSuchSystemException
|
|
{
|
|
|
|
OAuth2CredentialsInfo credentials = buildPersonalOAuth2CredentialsInfo(remoteSystemId,
|
|
accessToken, refreshToken, expiresAt, issuedAt);
|
|
|
|
if (credentials.getNodeRef() != null)
|
|
{
|
|
return (OAuth2CredentialsInfo) remoteCredentialsService.updateCredentials(credentials);
|
|
}
|
|
else
|
|
{
|
|
return (OAuth2CredentialsInfo) remoteCredentialsService.createPersonCredentials(
|
|
remoteSystemId, credentials);
|
|
}
|
|
|
|
}
|
|
|
|
/**
|
|
* Add Shared OAuth2 Credentials to the OAuth2 Credential Store
|
|
*
|
|
* @param remoteSystemId
|
|
* @param accessToken
|
|
* @param refreshToken
|
|
* @param expiresAt
|
|
* @param issuedAt
|
|
* @return OAuth2CredentialsInfo
|
|
*/
|
|
@Override
|
|
public OAuth2CredentialsInfo storeSharedOAuth2Credentials(String remoteSystemId,
|
|
String accessToken, String refreshToken, Date expiresAt, Date issuedAt)
|
|
throws NoSuchSystemException
|
|
{
|
|
OAuth2CredentialsInfo credentials = buildSharedOAuth2CredentialsInfo(remoteSystemId,
|
|
accessToken, refreshToken, expiresAt, issuedAt);
|
|
|
|
return (OAuth2CredentialsInfo) remoteCredentialsService.createSharedCredentials(
|
|
remoteSystemId, credentials);
|
|
}
|
|
|
|
/**
|
|
* @param exisitingCredentials
|
|
* @param remoteSystemId
|
|
* @param accessToken
|
|
* @param refreshToken
|
|
* @param expiresAt
|
|
* @param issuedAt
|
|
* @return OAuth2CredentialsInfo
|
|
*/
|
|
@Override
|
|
public OAuth2CredentialsInfo updateSharedOAuth2Credentials(
|
|
OAuth2CredentialsInfo exisitingCredentials, String remoteSystemId,
|
|
String accessToken, String refreshToken, Date expiresAt, Date issuedAt)
|
|
throws NoSuchSystemException
|
|
{
|
|
List<OAuth2CredentialsInfo> shared = listSharedOAuth2Credentials(remoteSystemId);
|
|
|
|
for (OAuth2CredentialsInfo credential : shared)
|
|
{
|
|
if (credential.getNodeRef().equals(exisitingCredentials.getNodeRef()))
|
|
{
|
|
OAuth2CredentialsInfoImpl credentials = new OAuth2CredentialsInfoImpl(
|
|
exisitingCredentials.getNodeRef(),
|
|
exisitingCredentials.getRemoteSystemName(),
|
|
exisitingCredentials.getRemoteSystemContainerNodeRef());
|
|
|
|
credentials.setOauthAccessToken(accessToken);
|
|
credentials.setOauthRefreshToken(refreshToken);
|
|
credentials.setOauthTokenExpiresAt(expiresAt);
|
|
if (issuedAt != null)
|
|
{
|
|
credentials.setOauthTokenIssuedAt(issuedAt);
|
|
}
|
|
else
|
|
{
|
|
credentials.setOauthTokenIssuedAt(new Date());
|
|
}
|
|
|
|
return (OAuth2CredentialsInfo) remoteCredentialsService
|
|
.updateCredentials(credentials);
|
|
|
|
}
|
|
}
|
|
|
|
throw new AlfrescoRuntimeException(
|
|
"Cannot update Credentials which haven't been persisted yet!");
|
|
}
|
|
|
|
/**
|
|
* @param remoteSystemId
|
|
* @param accessToken
|
|
* @param refreshToken
|
|
* @param expiresAt
|
|
* @param issuedAt
|
|
* @return OAuth2CredentialsInfo
|
|
*/
|
|
private OAuth2CredentialsInfo buildPersonalOAuth2CredentialsInfo(String remoteSystemId,
|
|
String accessToken, String refreshToken, Date expiresAt, Date issuedAt)
|
|
{
|
|
OAuth2CredentialsInfoImpl credentials = new OAuth2CredentialsInfoImpl();
|
|
|
|
OAuth2CredentialsInfoImpl existing = (OAuth2CredentialsInfoImpl) getPersonalOAuth2Credentials(remoteSystemId);
|
|
if (existing != null)
|
|
{
|
|
credentials = existing;
|
|
}
|
|
|
|
credentials.setOauthAccessToken(accessToken);
|
|
credentials.setOauthRefreshToken(refreshToken);
|
|
credentials.setOauthTokenExpiresAt(expiresAt);
|
|
if (issuedAt != null)
|
|
{
|
|
credentials.setOauthTokenIssuedAt(issuedAt);
|
|
}
|
|
else
|
|
{
|
|
credentials.setOauthTokenIssuedAt(new Date());
|
|
}
|
|
|
|
return credentials;
|
|
}
|
|
|
|
/**
|
|
* @param remoteSystemId
|
|
* @param accessToken
|
|
* @param refreshToken
|
|
* @param expiresAt
|
|
* @param issuedAt
|
|
* @return OAuth2CredentialsInfo
|
|
*/
|
|
private OAuth2CredentialsInfo buildSharedOAuth2CredentialsInfo(String remoteSystemId,
|
|
String accessToken, String refreshToken, Date expiresAt, Date issuedAt)
|
|
{
|
|
OAuth2CredentialsInfoImpl credentials = new OAuth2CredentialsInfoImpl();
|
|
|
|
credentials.setOauthAccessToken(accessToken);
|
|
credentials.setOauthRefreshToken(refreshToken);
|
|
credentials.setOauthTokenExpiresAt(expiresAt);
|
|
if (issuedAt != null)
|
|
{
|
|
credentials.setOauthTokenIssuedAt(issuedAt);
|
|
}
|
|
else
|
|
{
|
|
credentials.setOauthTokenIssuedAt(new Date());
|
|
}
|
|
|
|
return credentials;
|
|
}
|
|
|
|
/**
|
|
* Get the current users OAuth2Credentials for the remote systems
|
|
*
|
|
* @param remoteSystemId
|
|
* @return OAuth2CredentialsInfo
|
|
*/
|
|
@Override
|
|
public OAuth2CredentialsInfo getPersonalOAuth2Credentials(String remoteSystemId)
|
|
throws NoSuchSystemException
|
|
{
|
|
return (OAuth2CredentialsInfo) remoteCredentialsService
|
|
.getPersonCredentials(remoteSystemId);
|
|
}
|
|
|
|
/**
|
|
* @param remoteSystemId
|
|
* @return List<OAuth2CredentialInfo>
|
|
*/
|
|
@Override
|
|
public List<OAuth2CredentialsInfo> listSharedOAuth2Credentials(String remoteSystemId)
|
|
throws NoSuchSystemException
|
|
{
|
|
PagingRequest paging = new PagingRequest(CannedQueryPageDetails.DEFAULT_PAGE_SIZE);
|
|
@SuppressWarnings("unchecked")
|
|
PagingResults<OAuth2CredentialsInfo> pagingResults = (PagingResults<OAuth2CredentialsInfo>) remoteCredentialsService
|
|
.listSharedCredentials(remoteSystemId,
|
|
RemoteCredentialsModel.TYPE_OAUTH2_CREDENTIALS, paging);
|
|
return pagingResults.getPage();
|
|
}
|
|
|
|
/**
|
|
* Delete the current users OAuth2 Credentials for the remote system
|
|
*
|
|
* @param remoteSystemId
|
|
* @return boolean
|
|
*/
|
|
@Override
|
|
public boolean deletePersonalOAuth2Credentials(String remoteSystemId)
|
|
throws NoSuchSystemException
|
|
{
|
|
OAuth2CredentialsInfo credentials = getPersonalOAuth2Credentials(remoteSystemId);
|
|
|
|
if (credentials == null) { return false; }
|
|
|
|
remoteCredentialsService.deleteCredentials(credentials);
|
|
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
public boolean deleteSharedOAuth2Credentials(String remoteSystemId,
|
|
OAuth2CredentialsInfo credentials) throws NoSuchSystemException
|
|
{
|
|
List<OAuth2CredentialsInfo> shared = listSharedOAuth2Credentials(remoteSystemId);
|
|
|
|
if (shared.isEmpty()) { return false; }
|
|
|
|
for (OAuth2CredentialsInfo credential : shared)
|
|
{
|
|
if (credential.getNodeRef().equals(credentials.getNodeRef()))
|
|
{
|
|
remoteCredentialsService.deleteCredentials(credential);
|
|
}
|
|
else
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* @param succeeded
|
|
* @param credentials
|
|
* @return
|
|
*/
|
|
@Override
|
|
public OAuth2CredentialsInfo updateCredentialsAuthenticationSucceeded(boolean succeeded,
|
|
OAuth2CredentialsInfo credentials)
|
|
{
|
|
return (OAuth2CredentialsInfo) remoteCredentialsService
|
|
.updateCredentialsAuthenticationSucceeded(succeeded, credentials);
|
|
}
|
|
}
|