@@ -837,16 +837,20 @@ public void setRecordGroup(
837837 required = true
838838 )
839839 Integer groupIdentifier ,
840+ @ Parameter (hidden = true )
841+ HttpSession session ,
840842 HttpServletRequest request
841843 )
842844 throws Exception {
843845
846+ ServiceContext context = ApiUtils .createServiceContext (request );
847+ ApplicationContext appContext = ApplicationContextHolder .get ();
848+
844849 Locale locale = languageUtils .parseAcceptLanguage (request .getLocales ());
845850
846851 checkGroupIsWorkspace (groupIdentifier , locale );
847852
848853 AbstractMetadata metadata = ApiUtils .canEditRecord (metadataUuid , request );
849- ApplicationContext appContext = ApplicationContextHolder .get ();
850854
851855 java .util .Optional <Group > group = groupRepository .findById (groupIdentifier );
852856 if (!group .isPresent ()) {
@@ -861,14 +865,127 @@ public void setRecordGroup(
861865 oldGroup = groupRepository .findById (previousGroup ).get ();
862866 }
863867
868+ //update group ownership
864869 metadata .getSourceInfo ().setGroupOwner (groupIdentifier );
865870 metadataManager .save (metadata );
871+
872+ //need to update permissions.
873+ // 1. drop ALL permissions for the "old" group
874+ // 2. ADD these permissions to the new group.
875+
876+ // get the current set of privileges
877+ SharingResponse sharingResponse = getRecordSharingSettings (metadataUuid , session , request );
878+
879+ //copy so we can publish the diff (we are modifying sharingResponse with updated permissions)
880+ var originalSharingResponse = new SharingResponse ();
881+ originalSharingResponse .setGroupOwner (sharingResponse .getGroupOwner ());
882+ originalSharingResponse .setOwner (sharingResponse .getOwner ());
883+ var copyPrivs = sharingResponse .getPrivileges ().stream ()
884+ .map (x -> {
885+ var result = new GroupPrivilege ();
886+ result .setGroup (x .getGroup ());
887+ result .setReserved (x .isReserved ());
888+ result .setRestricted (x .isRestricted ());
889+ result .setUserGroup (x .isUserGroup ());
890+ result .setUserProfile (x .getUserProfiles ());
891+ result .setOperations (new HashMap <>(x .getOperations ()));
892+ return result ;
893+ })
894+ .collect (Collectors .toList ());
895+ originalSharingResponse .setPrivileges (copyPrivs );
896+
897+
898+ //old permissions
899+ Integer sourceUsr = metadata .getSourceInfo ().getOwner ();
900+ String metadataId = String .valueOf (metadata .getId ());
901+ Integer oldGroupId = oldGroup != null ? oldGroup .getId () : null ;
902+ Vector <OperationAllowedId > oldPriv = retrievePrivileges (context , metadataId , sourceUsr , oldGroupId );
903+
904+
905+ //modify the sharingResponse (current permissions from DB) with new privileges (group XFER).
906+ for (var groupPriv : sharingResponse .getPrivileges ()) {
907+ if (Objects .equals (groupPriv .getGroup (), previousGroup )) {
908+ //old group: permissions - remove them (set all false)
909+ var ops =groupPriv .getOperations ();
910+ ops .replaceAll ((o , v ) -> false );
911+ } else if (Objects .equals (groupPriv .getGroup (), groupIdentifier )) {
912+ //new group: permissions - ADD the old groups permissions
913+ var ops =groupPriv .getOperations ();
914+ for (var addOp : oldPriv ) {
915+ var opName = ReservedOperation .lookup (addOp .getOperationId ());
916+ ops .put (opName .toString (), true );
917+ }
918+ }
919+ }
920+
921+ //convert object for the two apis (getRecordSharingSettings vs setOperations)
922+ var newPrivileges = sharingResponse .getPrivileges ().stream ()
923+ .map (p -> {
924+ var result = new GroupOperations ();
925+ result .setGroup (p .getGroup ());
926+ result .setOperations (p .getOperations ());
927+ return result ;
928+ })
929+ .collect (Collectors .toList ());
930+
931+
932+ SharingParameter sharingParameter = new SharingParameter ();
933+ sharingParameter .setClear (true ); // remove all permissions then add the new ones
934+ sharingParameter .setPrivileges (newPrivileges );
935+
936+ List <Operation > operationList = operationRepository .findAll ();
937+ Map <String , Integer > operationMap = new HashMap <>(operationList .size ());
938+ for (Operation o : operationList ) {
939+ operationMap .put (o .getName (), o .getId ());
940+ }
941+ List <GroupOperations > privileges = sharingParameter .getPrivileges ();
942+
943+ //--- in case of owner, privileges for groups 0,1 and GUEST are disabled
944+ //--- and are not sent to the server. So we cannot remove them
945+ boolean skipAllReservedGroup = !accessManager .hasReviewPermission (context , Integer .toString (metadata .getId ()));
946+
947+ MetadataProcessingReport metadataProcessingReport = null ;
948+ List <MetadataPublicationNotificationInfo > metadataListToNotifyPublication = new ArrayList <>();
949+ boolean notifyByEmail = StringUtils .isNoneEmpty (sm .getValue (SYSTEM_METADATAPRIVS_PUBLICATION_NOTIFICATIONLEVEL ));
950+ Locale [] feedbackLocales = feedbackLanguages .getLocales (request .getLocale ());
951+
952+ //actually update DB
953+ setOperations (sharingParameter ,
954+ this .dataManager ,
955+ context ,
956+ appContext ,
957+ metadata ,
958+ operationMap ,
959+ privileges ,
960+ sourceUsr ,
961+ skipAllReservedGroup ,
962+ metadataProcessingReport ,
963+ request ,
964+ metadataListToNotifyPublication ,
965+ notifyByEmail
966+ );
967+
968+ if (notifyByEmail && !metadataListToNotifyPublication .isEmpty ()) {
969+ metadataPublicationMailNotifier .notifyPublication (feedbackLocales ,
970+ metadataListToNotifyPublication );
971+ }
972+
973+
974+
866975 dataManager .indexMetadata (String .valueOf (metadata .getId ()), true );
867976
977+ //publish group change
868978 new RecordGroupOwnerChangeEvent (metadata .getId (),
869979 ApiUtils .getUserSession (request .getSession ()).getUserIdAsInt (),
870980 ObjectJSONUtils .convertObjectInJsonObject (oldGroup , RecordGroupOwnerChangeEvent .FIELD ),
871981 ObjectJSONUtils .convertObjectInJsonObject (group .get (), RecordGroupOwnerChangeEvent .FIELD )).publish (appContext );
982+
983+ //publish permissions change
984+ new RecordPrivilegesChangeEvent (metadata .getId (),
985+ ApiUtils .getUserSession (request .getSession ()).getUserIdAsInt (),
986+ ObjectJSONUtils .convertObjectInJsonObject (originalSharingResponse .getPrivileges (), RecordPrivilegesChangeEvent .FIELD ),
987+ ObjectJSONUtils .convertObjectInJsonObject (newPrivileges , RecordPrivilegesChangeEvent .FIELD )).publish (appContext );
988+
872989 }
873990
874991 @ io .swagger .v3 .oas .annotations .Operation (
@@ -895,10 +1012,12 @@ public SharingResponse getSharingSettings(
8951012 )
8961013 throws Exception {
8971014 ServiceContext context = ApiUtils .createServiceContext (request );
898- UserSession userSession = ApiUtils .getUserSession (session );
8991015
9001016 SharingResponse sharingResponse = new SharingResponse ();
901- sharingResponse .setOwner (userSession .getUserId ());
1017+ if (session != null ) {
1018+ UserSession userSession = ApiUtils .getUserSession (session );
1019+ sharingResponse .setOwner (userSession .getUserId ());
1020+ }
9021021
9031022 List <Operation > allOperations = operationRepository .findAll ();
9041023
0 commit comments