LP#1718032 Patron merge honors group perms; no self-merge
authorBill Erickson <berickxx@gmail.com>
Tue, 7 Aug 2018 18:27:47 +0000 (14:27 -0400)
committerBill Erickson <berickxx@gmail.com>
Mon, 13 Aug 2018 18:29:57 +0000 (14:29 -0400)
Ensure the staff performing a patron merge have sufficient permission to
edit all users involved in the merge process, in addition the
MERGE_USERS permssion.

Prevent staff from merging their own logged in account.

Signed-off-by: Bill Erickson <berickxx@gmail.com>
Signed-off-by: Michele Morgan <mmorgan@noblenet.org>
Open-ILS/src/perlmods/lib/OpenILS/Application/Actor.pm
Open-ILS/src/templates/staff/circ/patron/index.tt2
Open-ILS/web/js/ui/default/staff/circ/patron/app.js

index 503cf35..f0bfa2e 100644 (file)
@@ -3378,7 +3378,13 @@ sub merge_users {
     my $colls = $e->search_money_collections_tracker({usr => $user_ids}, {idlist => 1});
     return OpenILS::Event->new('MERGED_USER_IN_COLLECTIONS', payload => $user_ids) if @$colls;
 
     my $colls = $e->search_money_collections_tracker({usr => $user_ids}, {idlist => 1});
     return OpenILS::Event->new('MERGED_USER_IN_COLLECTIONS', payload => $user_ids) if @$colls;
 
+    return OpenILS::Event->new('MERGE_SELF_NOT_ALLOWED')
+        if $master_id == $e->requestor->id;
+
     my $master_user = $e->retrieve_actor_user($master_id) or return $e->die_event;
     my $master_user = $e->retrieve_actor_user($master_id) or return $e->die_event;
+    my $evt = group_perm_failed($e, $e->requestor, $master_user);
+    return $evt if $evt;
+
     my $del_addrs = ($U->ou_ancestor_setting_value(
         $master_user->home_ou, 'circ.user_merge.delete_addresses', $e)) ? 't' : 'f';
     my $del_cards = ($U->ou_ancestor_setting_value(
     my $del_addrs = ($U->ou_ancestor_setting_value(
         $master_user->home_ou, 'circ.user_merge.delete_addresses', $e)) ? 't' : 'f';
     my $del_cards = ($U->ou_ancestor_setting_value(
@@ -3387,7 +3393,13 @@ sub merge_users {
         $master_user->home_ou, 'circ.user_merge.deactivate_cards', $e)) ? 't' : 'f';
 
     for my $src_id (@$user_ids) {
         $master_user->home_ou, 'circ.user_merge.deactivate_cards', $e)) ? 't' : 'f';
 
     for my $src_id (@$user_ids) {
+
         my $src_user = $e->retrieve_actor_user($src_id) or return $e->die_event;
         my $src_user = $e->retrieve_actor_user($src_id) or return $e->die_event;
+        my $evt = group_perm_failed($e, $e->requestor, $src_user);
+        return $evt if $evt;
+
+        return OpenILS::Event->new('MERGE_SELF_NOT_ALLOWED')
+            if $src_id == $e->requestor->id;
 
         return $e->die_event unless $e->allowed('MERGE_USERS', $src_user->home_ou);
         if($src_user->home_ou ne $master_user->home_ou) {
 
         return $e->die_event unless $e->allowed('MERGE_USERS', $src_user->home_ou);
         if($src_user->home_ou ne $master_user->home_ou) {
index 94849f2..dc9c1b2 100644 (file)
@@ -76,6 +76,7 @@ angular.module('egCoreMod').run(['egStrings', function(s) {
   s.PAGE_TITLE_PATRON_HOLDS = "[% l('Holds') %]";
   s.PAGE_TITLE_PATRON_ITEMS_OUT = "[% l('Items Out') %]";
   s.PAGE_TITLE_PATRON_EDIT = "[% l('Edit') %]";
   s.PAGE_TITLE_PATRON_HOLDS = "[% l('Holds') %]";
   s.PAGE_TITLE_PATRON_ITEMS_OUT = "[% l('Items Out') %]";
   s.PAGE_TITLE_PATRON_EDIT = "[% l('Edit') %]";
+  s.MERGE_SELF_NOT_ALLOWED = "[% l('Logged in account cannot be merged') %]"
 }]);
 </script>
 
 }]);
 </script>
 
index fa8a60e..d37ed64 100644 (file)
@@ -691,13 +691,20 @@ function($scope,  $q,  $routeParams,  $timeout,  $window,  $location,  egCore ,
         angular.forEach(items, function(i) {
             patron_ids.push(i.id());
         });
         angular.forEach(items, function(i) {
             patron_ids.push(i.id());
         });
-        egPatronMerge.do_merge(patron_ids).then(function() {
-            // ensure that we're not drawing from cached
-            // resuts, as a successful merge just deleted a
-            // record
-            delete patronSvc.lastSearch;
-            $scope.gridControls.refresh();
-        });
+        egPatronMerge.do_merge(patron_ids).then(
+            function() {
+                // ensure that we're not drawing from cached
+                // resuts, as a successful merge just deleted a
+                // record
+                delete patronSvc.lastSearch;
+                $scope.gridControls.refresh();
+            },
+            function(evt) {
+                if (evt && evt.textcode == 'MERGE_SELF_NOT_ALLOWED') {
+                    ngToast.warning(egCore.strings.MERGE_SELF_NOT_ALLOWED);
+                }
+            }
+        );
     }
    
 }])
     }
    
 }])