diff --git a/apps/files_sharing/appinfo/application.php b/apps/files_sharing/appinfo/application.php
index 10e3fdae982fe80f5afb5ae88043570c8b169c5b..9587d74f160cd1cb1a9187d825e0f67b0aaaf005 100644
--- a/apps/files_sharing/appinfo/application.php
+++ b/apps/files_sharing/appinfo/application.php
@@ -27,6 +27,7 @@ namespace OCA\Files_Sharing\AppInfo;
 use OCA\Files_Sharing\Helper;
 use OCA\Files_Sharing\MountProvider;
 use OCA\Files_Sharing\Propagation\PropagationManager;
+use OCA\Files_Sharing\Propagation\GroupPropagationManager;
 use OCP\AppFramework\App;
 use OC\AppFramework\Utility\SimpleContainer;
 use OCA\Files_Sharing\Controllers\ExternalSharesController;
@@ -128,6 +129,16 @@ class Application extends App {
 			);
 		});
 
+		$container->registerService('GroupPropagationManager', function (IContainer $c) {
+			/** @var \OCP\IServerContainer $server */
+			$server = $c->query('ServerContainer');
+			return new GroupPropagationManager(
+				$server->getUserSession(),
+				$server->getGroupManager(),
+				$c->query('PropagationManager')
+			);
+		});
+
 		/*
 		 * Register capabilities
 		 */
@@ -144,5 +155,7 @@ class Application extends App {
 	public function setupPropagation() {
 		$propagationManager = $this->getContainer()->query('PropagationManager');
 		\OCP\Util::connectHook('OC_Filesystem', 'setup', $propagationManager, 'globalSetup');
+
+		$this->getContainer()->query('GroupPropagationManager')->globalSetup();
 	}
 }
diff --git a/apps/files_sharing/lib/propagation/grouppropagationmanager.php b/apps/files_sharing/lib/propagation/grouppropagationmanager.php
new file mode 100644
index 0000000000000000000000000000000000000000..ba550dccec39a6909605e5031873265affc4c83b
--- /dev/null
+++ b/apps/files_sharing/lib/propagation/grouppropagationmanager.php
@@ -0,0 +1,133 @@
+<?php
+/**
+ * @author Vincent Petry <pvince81@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\Files_Sharing\Propagation;
+
+use OC\Files\Filesystem;
+use OC\Files\View;
+use OCP\IConfig;
+use OCP\IUserSession;
+use OCP\IGroup;
+use OCP\IUser;
+use OCP\IGroupManager;
+use OCA\Files_Sharing\Propagation\PropagationManager;
+
+/**
+ * Propagate changes on group changes
+ */
+class GroupPropagationManager {
+	/**
+	 * @var \OCP\IUserSession
+	 */
+	private $userSession;
+
+	/**
+	 * @var \OCP\IGroupManager
+	 */
+	private $groupManager;
+
+	/**
+	 * @var PropagationManager
+	 */
+	private $propagationManager;
+
+	/**
+	 * Items shared with a given user.
+	 * Key is user id and value is an array of shares.
+	 *
+	 * @var array
+	 */
+	private $userShares = [];
+
+	public function __construct(IUserSession $userSession, IGroupManager $groupManager, PropagationManager $propagationManager) {
+		$this->userSession = $userSession;
+		$this->groupManager = $groupManager;
+		$this->propagationManager = $propagationManager;
+	}
+
+	public function onPreProcessUser(IGroup $group, IUser $targetUser) {
+		$this->userShares[$targetUser->getUID()] = $this->getUserShares($targetUser->getUID());
+	}
+
+	public function onPostAddUser(IGroup $group, IUser $targetUser) {
+		$targetUserId = $targetUser->getUID();
+		$sharesAfter = $this->getUserShares($targetUserId);
+
+		$this->propagateSharesDiff($targetUserId, $sharesAfter, $this->userShares[$targetUserId]);
+		unset($this->userShares[$targetUserId]);
+	}
+
+	public function onPostRemoveUser(IGroup $group, IUser $targetUser) {
+		$targetUserId = $targetUser->getUID();
+		$sharesAfter = $this->getUserShares($targetUserId);
+
+		$this->propagateSharesDiff($targetUserId, $this->userShares[$targetUserId], $sharesAfter);
+		unset($this->userShares[$targetUserId]);
+	}
+
+	private function getUserShares($targetUserId) {
+		return \OCP\Share::getItemsSharedWithUser('file', $targetUserId);
+	}
+
+	/**
+	 * Propagate etag for the shares that are in $shares1 but not in $shares2.
+	 *
+	 * @param string $targetUserId user id for which to propagate shares
+	 * @param array $shares1
+	 * @param array $shares2
+	 */
+	private function propagateSharesDiff($targetUserId, $shares1, $shares2) {
+		$sharesToPropagate = array_udiff(
+			$shares1,
+			$shares2,
+			function($share1, $share2) {
+				return ($share2['id'] - $share1['id']);
+			}
+		);
+
+		\OC\Files\Filesystem::initMountPoints($targetUserId);
+		$this->propagationManager->propagateSharesToUser($sharesToPropagate, $targetUserId);
+	}
+
+	/**
+	 * To be called from setupFS trough a hook
+	 *
+	 * Sets up listening to changes made to shares owned by the current user
+	 */
+	public function globalSetup() {
+		$user = $this->userSession->getUser();
+		if (!$user) {
+			return;
+		}
+
+		$this->groupManager->listen('\OC\Group', 'preAddUser', [$this, 'onPreProcessUser']);
+		$this->groupManager->listen('\OC\Group', 'postAddUser', [$this, 'onPostAddUser']);
+		$this->groupManager->listen('\OC\Group', 'preRemoveUser', [$this, 'onPreProcessUser']);
+		$this->groupManager->listen('\OC\Group', 'postRemoveUser', [$this, 'onPostRemoveUser']);
+	}
+
+	public function tearDown() {
+		$this->groupManager->removeListener('\OC\Group', 'preAddUser', [$this, 'onPreProcessUser']);
+		$this->groupManager->removeListener('\OC\Group', 'postAddUser', [$this, 'onPostAddUser']);
+		$this->groupManager->removeListener('\OC\Group', 'preRemoveUser', [$this, 'onPreProcessUser']);
+		$this->groupManager->removeListener('\OC\Group', 'postRemoveUser', [$this, 'onPostRemoveUser']);
+	}
+}
diff --git a/apps/files_sharing/lib/propagation/propagationmanager.php b/apps/files_sharing/lib/propagation/propagationmanager.php
index d220551f8d65555291c10d58868e8ce6496a9e2c..35048f89cfbcb57be05ca9a38f90858b7a1846ab 100644
--- a/apps/files_sharing/lib/propagation/propagationmanager.php
+++ b/apps/files_sharing/lib/propagation/propagationmanager.php
@@ -80,6 +80,21 @@ class PropagationManager {
 		return $this->changePropagators[$user];
 	}
 
+	/**
+	 * Propagates etag changes for the given shares to the given user
+	 *
+	 * @param array array of shares for which to trigger etag change
+	 * @param string $user
+	 */
+	public function propagateSharesToUser($shares, $user) {
+		$changePropagator = $this->getChangePropagator($user);
+		foreach ($shares as $share) {
+			$changePropagator->addChange($share['file_target']);
+		}
+		$time = microtime(true);
+		$changePropagator->propagateChanges(floor($time));
+	}
+
 	/**
 	 * @param string $user
 	 * @return \OCA\Files_Sharing\Propagation\RecipientPropagator
diff --git a/apps/files_sharing/tests/grouppropagationmanager.php b/apps/files_sharing/tests/grouppropagationmanager.php
new file mode 100644
index 0000000000000000000000000000000000000000..6fc6ef7a5321fda50f5e308d1e0db80bfe57450d
--- /dev/null
+++ b/apps/files_sharing/tests/grouppropagationmanager.php
@@ -0,0 +1,175 @@
+<?php
+/**
+ * @author Morris Jobke <hey@morrisjobke.de>
+ * @author Robin Appelman <icewind@owncloud.com>
+ * @author Vincent Petry <pvince81@owncloud.com>
+ *
+ * @copyright Copyright (c) 2015, ownCloud, Inc.
+ * @license AGPL-3.0
+ *
+ * This code is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License, version 3,
+ * as published by the Free Software Foundation.
+ *
+ * This program 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 Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License, version 3,
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ *
+ */
+
+namespace OCA\Files_sharing\Tests;
+
+use OC\Files\View;
+use OCP\IGroupManager;
+use OCP\IGroup;
+use OCP\IUser;
+use OCP\Share;
+use OCA\Files_Sharing\Propagation\GroupPropagationManager;
+use OCA\Files_Sharing\Propagation\PropagationManager;
+
+class GroupPropagationManagerTest extends TestCase {
+
+	/**
+	 * @var GroupPropagationManager
+	 */
+	private $groupPropagationManager;
+
+	/**
+	 * @var IGroupManager
+	 */
+	private $groupManager;
+
+	/**
+	 * @var PropagationManager
+	 */
+	private $propagationManager;
+
+	/**
+	 * @var IGroup
+	 */
+	private $recipientGroup;
+
+	/**
+	 * @var IUser
+	 */
+	private $recipientUser;
+
+	/**
+	 * @var array
+	 */
+	private $fileInfo;
+
+	protected function setUp() {
+		parent::setUp();
+
+		$user = $this->getMockBuilder('\OCP\IUser')
+		             ->disableOriginalConstructor()
+		             ->getMock();
+		$user->method('getUID')->willReturn(self::TEST_FILES_SHARING_API_USER1);
+		$userSession = $this->getMockBuilder('\OCP\IUserSession')
+		                    ->disableOriginalConstructor()
+		                    ->getMock();
+		$userSession->method('getUser')->willReturn(selF::TEST_FILES_SHARING_API_USER1);
+
+		$this->propagationManager = $this->getMockBuilder('OCA\Files_Sharing\Propagation\PropagationManager')
+			->disableOriginalConstructor()
+			->getMock();
+
+		$this->groupManager = \OC::$server->getGroupManager();
+		$this->groupPropagationManager = new GroupPropagationManager(
+			$userSession,
+			$this->groupManager,
+			$this->propagationManager
+		);
+		$this->groupPropagationManager->globalSetup();
+
+		// since the sharing code is not mockable, we have to create a real folder
+		$this->loginAsUser(self::TEST_FILES_SHARING_API_USER1);
+		$view1 = new View('/' . self::TEST_FILES_SHARING_API_USER1 . '/files');
+		$view1->mkdir('/folder');
+
+		$this->fileInfo = $view1->getFileInfo('/folder');
+
+		$this->recipientGroup = $this->groupManager->get(self::TEST_FILES_SHARING_API_GROUP1);
+		$this->recipientUser = \OC::$server->getUserManager()->get(self::TEST_FILES_SHARING_API_USER3);
+
+		Share::shareItem(
+			'folder',
+			$this->fileInfo['fileid'],
+			Share::SHARE_TYPE_GROUP,
+			$this->recipientGroup->getGID(),
+			\OCP\Constants::PERMISSION_READ
+		);
+
+		$this->loginAsUser($this->recipientUser->getUID());
+	}
+
+	protected function tearDown() {
+		$this->groupPropagationManager->tearDown();
+		$this->recipientGroup->removeUser($this->recipientUser);
+		parent::tearDown();
+	}
+
+	public function testPropagateWhenAddedToGroup() {
+		$this->propagationManager->expects($this->once())
+			->method('propagateSharesToUser')
+			->with($this->callback(function($shares) {
+				if (count($shares) !== 1) {
+					return false;
+				}
+				$share = array_values($shares)[0];
+				return $share['file_source'] === $this->fileInfo['fileid'] &&
+					$share['share_with'] === $this->recipientGroup->getGID() &&
+					$share['file_target'] === '/folder';
+			}), $this->recipientUser->getUID());
+
+		$this->recipientGroup->addUser($this->recipientUser);
+	}
+
+	public function testPropagateWhenRemovedFromGroup() {
+		$this->recipientGroup->addUser($this->recipientUser);
+
+		$this->propagationManager->expects($this->once())
+			->method('propagateSharesToUser')
+			->with($this->callback(function($shares) {
+				if (count($shares) !== 1) {
+					return false;
+				}
+				$share = array_values($shares)[0];
+				return $share['file_source'] === $this->fileInfo['fileid'] &&
+					$share['share_with'] === $this->recipientGroup->getGID() &&
+					$share['file_target'] === '/folder';
+			}), $this->recipientUser->getUID());
+
+		$this->recipientGroup->removeUser($this->recipientUser);
+	}
+
+	public function testPropagateWhenRemovedFromGroupWithSubdirTarget() {
+		$this->recipientGroup->addUser($this->recipientUser);
+
+		// relogin to refresh mount points
+		$this->loginAsUser($this->recipientUser->getUID());
+		$recipientView = new View('/' . $this->recipientUser->getUID() . '/files');
+
+		$this->assertTrue($recipientView->mkdir('sub'));
+		$this->assertTrue($recipientView->rename('folder', 'sub/folder'));
+
+		$this->propagationManager->expects($this->once())
+			->method('propagateSharesToUser')
+			->with($this->callback(function($shares) {
+				if (count($shares) !== 1) {
+					return false;
+				}
+				$share = array_values($shares)[0];
+				return $share['file_source'] === $this->fileInfo['fileid'] &&
+					$share['share_with'] === $this->recipientGroup->getGID() &&
+					$share['file_target'] === '/sub/folder';
+			}), $this->recipientUser->getUID());
+
+		$this->recipientGroup->removeUser($this->recipientUser);
+	}
+}