From e707e948577b927a28b86545d345e7b6c8606352 Mon Sep 17 00:00:00 2001
From: Georg Ehrke <dev@georgswebsite.de>
Date: Sun, 15 Jul 2012 16:31:28 +0200
Subject: [PATCH] subadmins can now add users

---
 lib/app.php                  | 13 ++++--
 lib/subadmin.php             | 36 +++++++++++----
 lib/util.php                 |  9 ++--
 settings/ajax/createuser.php | 29 ++++++++++--
 settings/js/users.js         | 89 ++++++++++++++++++++++++++----------
 settings/templates/users.php | 20 +++++---
 settings/users.php           | 12 +++--
 7 files changed, 149 insertions(+), 59 deletions(-)

diff --git a/lib/app.php b/lib/app.php
index 4c2c43ec26b..9c3411a76bc 100755
--- a/lib/app.php
+++ b/lib/app.php
@@ -293,16 +293,21 @@ class OC_App{
 		if (OC_User::isLoggedIn()) {
 			// personal menu
 			$settings[] = array( "id" => "personal", "order" => 1, "href" => OC_Helper::linkTo( "settings", "personal.php" ), "name" => $l->t("Personal"), "icon" => OC_Helper::imagePath( "settings", "personal.svg" ));
-
+			
 			// if there're some settings forms
 			if(!empty(self::$settingsForms))
 				// settings menu
 				$settings[]=array( "id" => "settings", "order" => 1000, "href" => OC_Helper::linkTo( "settings", "settings.php" ), "name" => $l->t("Settings"), "icon" => OC_Helper::imagePath( "settings", "settings.svg" ));
-
-			// if the user is an admin
-			if(OC_Group::inGroup( $_SESSION["user_id"], "admin" )) {
+			
+			//SubAdmins are also allowed to access user management
+			if(OC_SubAdmin::isSubAdmin($_SESSION["user_id"]) || OC_Group::inGroup( $_SESSION["user_id"], "admin" )){
 				// admin users menu
 				$settings[] = array( "id" => "core_users", "order" => 2, "href" => OC_Helper::linkTo( "settings", "users.php" ), "name" => $l->t("Users"), "icon" => OC_Helper::imagePath( "settings", "users.svg" ));
+			}
+			
+			
+			// if the user is an admin
+			if(OC_Group::inGroup( $_SESSION["user_id"], "admin" )) {
 				// admin apps menu
 				$settings[] = array( "id" => "core_apps", "order" => 3, "href" => OC_Helper::linkTo( "settings", "apps.php" ).'?installed', "name" => $l->t("Apps"), "icon" => OC_Helper::imagePath( "settings", "apps.svg" ));
 
diff --git a/lib/subadmin.php b/lib/subadmin.php
index aad657b024f..b6f0b3007fd 100644
--- a/lib/subadmin.php
+++ b/lib/subadmin.php
@@ -38,9 +38,6 @@ class OC_SubAdmin{
 	public static function createSubAdmin($uid, $gid){
 		$stmt = OC_DB::prepare('INSERT INTO *PREFIX*group_admin (gid,uid) VALUES(?,?)');
 		$result = $stmt->execute(array($gid, $uid));
-		if(OC_DB::isError($result)){
-			return false;
-		}
 		OC_Hook::emit( "OC_SubAdmin", "post_createSubAdmin", array( "gid" => $gid ));
 		return true;
 	}
@@ -54,9 +51,6 @@ class OC_SubAdmin{
 	public static function deleteSubAdmin($uid, $gid){
 		$stmt = OC_DB::prepare('DELETE FROM *PREFIX*group_admin WHERE gid = ? AND uid = ?');
 		$result = $stmt->execute(array($gid, $uid));
-		if(OC_DB::isError($result)){
-			return false;
-		}
 		OC_Hook::emit( "OC_SubAdmin", "post_deleteSubAdmin", array( "gid" => $gid ));
 		return true;
 	}
@@ -68,7 +62,7 @@ class OC_SubAdmin{
 	 */
 	public static function getSubAdminsGroups($uid){
 		$stmt = OC_DB::prepare('SELECT gid FROM *PREFIX*group_admin WHERE uid = ?');
-		$result = $stmt->execute(array($gid, $uid));
+		$result = $stmt->execute(array($uid));
 		$gids = array();
 		while($row = $result->fetchRow()){
 			$gids[] = $row['gid'];
@@ -83,7 +77,7 @@ class OC_SubAdmin{
 	 */
 	public static function getGroupsSubAdmins($gid){
 		$stmt = OC_DB::prepare('SELECT uid FROM *PREFIX*group_admin WHERE gid = ?');
-		$result = $stmt->execute(array($gid, $uid));
+		$result = $stmt->execute(array($gid));
 		$uids = array();
 		while($row = $result->fetchRow()){
 			$uids[] = $row['uid'];
@@ -97,11 +91,35 @@ class OC_SubAdmin{
 	 */
 	public static function getAllSubAdmins(){
 		$stmt = OC_DB::prepare('SELECT * FROM *PREFIX*group_admin');
-		$result = $stmt->execute(array($gid, $uid));
+		$result = $stmt->execute();
 		$subadmins = array();
 		while($row = $result->fetchRow()){
 			$subadmins[] = $row;
 		}
 		return $subadmins;
 	}
+	
+	/**
+	 * @brief checks if a user is a SubAdmin of a group
+	 * @return array
+	 */
+	public static function isSubAdminofGroup($uid, $gid){
+		$stmt = OC_DB::prepare('SELECT COUNT(*) as count FROM *PREFIX*group_admin where uid = ? AND gid = ?');
+		$result = $stmt->execute(array($uid, $gid));
+		$result = $result->fetchRow();
+		if($result['count'] >= 1){
+			return true;
+		}
+		return false;
+	}
+	
+	public static function isSubAdmin($uid){
+		$stmt = OC_DB::prepare('SELECT COUNT(*) as count FROM *PREFIX*group_admin WHERE uid = ?');
+		$result = $stmt->execute(array($uid));
+		$result = $result->fetchRow();
+		if($result['count'] > 0){
+			return true;
+		}
+		return false;
+	}
 }
diff --git a/lib/util.php b/lib/util.php
index de9171edc8e..2eb102dfa69 100755
--- a/lib/util.php
+++ b/lib/util.php
@@ -328,16 +328,13 @@ class OC_Util {
 		// Check if we are a user
 		self::checkLoggedIn();
 		if(OC_Group::inGroup(OC_User::getUser(),'admin')){
-			return OC_Group::getGroups();
+			return true;
 		}
-		$stmt = OC_DB::prepare('SELECT COUNT(*) as count FROM *PREFIX*group_admin WHERE uid = ?');
-		$result = $stmt->execute(array(OC_User::getUser()));
-		$result = $result->fetchRow();
-		if($result['count'] == 0){
+		if(!OC_SubAdmin::isSubAdmin(OC_User::getUser())){
 			header( 'Location: '.OC_Helper::linkToAbsolute( '', 'index.php' ));
 			exit();
 		}
-		return $groups;
+		return true;
 	}
 
 	/**
diff --git a/settings/ajax/createuser.php b/settings/ajax/createuser.php
index c56df4bc15a..41bf31a05f6 100644
--- a/settings/ajax/createuser.php
+++ b/settings/ajax/createuser.php
@@ -4,15 +4,36 @@
 require_once('../../lib/base.php');
 
 // Check if we are a user
-if( !OC_User::isLoggedIn() || !OC_Group::inGroup( OC_User::getUser(), 'admin' )){
+if( !OC_User::isLoggedIn() || (!OC_Group::inGroup( OC_User::getUser(), 'admin' ) && !OC_SubAdmin::isSubAdmin(OC_User::getUser()))){
 	OC_JSON::error(array("data" => array( "message" => "Authentication error" )));
 	exit();
 }
 OCP\JSON::callCheck();
 
-$groups = array();
-if( isset( $_POST["groups"] )){
-	$groups = $_POST["groups"];
+$isadmin = OC_Group::inGroup(OC_User::getUser(),'admin')?true:false;
+
+if($isadmin){
+	$groups = array();
+	if( isset( $_POST["groups"] )){
+		$groups = $_POST["groups"];
+	}
+}else{
+	$accessiblegroups = OC_SubAdmin::getSubAdminsGroups(OC_User::getUser());
+	$accessiblegroups = array_flip($accessiblegroups);
+	if(isset( $_POST["groups"] )){
+		$unauditedgroups = $_POST["groups"];
+		$groups = array();
+		foreach($unauditedgroups as $group){
+			if(array_key_exists($group, $accessiblegroups)){
+				$groups[] = $group;
+			}
+		}
+		if(count($groups) == 0){
+			$groups = array_flip($accessiblegroups);
+		}
+	}else{
+		$groups = array_flip($accessiblegroups);
+	}
 }
 $username = $_POST["username"];
 $password = $_POST["password"];
diff --git a/settings/js/users.js b/settings/js/users.js
index dfa28e4c4cb..c86949db384 100644
--- a/settings/js/users.js
+++ b/settings/js/users.js
@@ -84,18 +84,56 @@ $(document).ready(function(){
 	}
 	
 	function applyMultiplySelect(element){
+		console.log(element);
 		var checked=[];
 		var user=element.data('username');
-		if(element.data('userGroups')){
-			checked=element.data('userGroups').split(', ');
+		if($(element).attr('class') == 'groupsselect'){		
+			if(element.data('userGroups')){
+				checked=element.data('userGroups').split(', ');
+			}
+			if(user){
+				var checkHandeler=function(group){
+					if(user==OC.currentUser && group=='admin'){
+						return false;
+					}
+					$.post(
+						OC.filePath('settings','ajax','togglegroups.php'),
+						{
+							username:user,
+							group:group
+						},
+						function(){}
+					);
+				};
+			}else{
+				checkHandeler=false;
+			}
+			var addGroup = function(group) {
+				$('select[multiple]').each(function(index, element) {
+					if ($(element).find('option[value="'+group +'"]').length == 0) {
+						$(element).append('<option value="'+group+'">'+group+'</option>');
+					}
+				})
+			};
+			element.multiSelect({
+				createCallback:addGroup,
+				createText:'add group',
+				checked:checked,
+				oncheck:checkHandeler,
+				onuncheck:checkHandeler,
+				minWidth: 100,
+			});
 		}
-		if(user){
+		if($(element).attr('class') == 'subadminsselect'){	
+			if(element.data('subadmin')){
+				checked=element.data('subadmin').split(', ');
+			}
 			var checkHandeler=function(group){
-				if(user==OC.currentUser && group=='admin'){
+				if(group=='admin'){
 					return false;
 				}
 				$.post(
-					OC.filePath('settings','ajax','togglegroups.php'),
+					OC.filePath('settings','ajax','togglesubadmins.php'),
 					{
 						username:user,
 						group:group
@@ -103,24 +141,25 @@ $(document).ready(function(){
 					function(){}
 				);
 			};
-		}else{
-			checkHandeler=false;
+			
+			var addSubAdmin = function(group) {
+				console.log('addSubAdmin called');
+				console.log(group);
+				$('select[multiple]').each(function(index, element) {
+					if ($(element).find('option[value="'+group +'"]').length == 0) {
+						$(element).append('<option value="'+group+'">'+group+'</option>');
+					}
+				})
+			};
+			element.multiSelect({
+				createCallback:addSubAdmin,
+				createText:null,
+				checked:checked,
+				oncheck:checkHandeler,
+				onuncheck:checkHandeler,
+				minWidth: 100,
+			});
 		}
-		var addGroup = function(group) {
-			$('select[multiple]').each(function(index, element) {
-				if ($(element).find('option[value="'+group +'"]').length == 0) {
-					$(element).append('<option value="'+group+'">'+group+'</option>');
-				}
-			})
-		};
-		element.multiSelect({
-			createCallback:addGroup,
-			createText:'add group',
-			checked:checked,
-			oncheck:checkHandeler,
-			onuncheck:checkHandeler,
-			minWidth: 100,
-		});
 	}
 	$('select[multiple]').each(function(index,element){
 		applyMultiplySelect($(element));
@@ -255,12 +294,14 @@ $(document).ready(function(){
 					OC.dialogs.alert(result.data.message, 'Error creating user');
 				}
 				else {
+					groups = result.data.groups;
+					console.log(groups);
 					var tr=$('#content table tbody tr').first().clone();
 					tr.attr('data-uid',username);
 					tr.find('td.name').text(username);
-					var select=$('<select multiple="multiple" data-placehoder="Groups" title="Groups">');
+					var select=$('<select multiple="multiple" class="groupsselect" data-placehoder="Groups" title="Groups">');
 					select.data('username',username);
-					select.data('userGroups',groups.join(', '));
+					select.data('userGroups',groups);
 					tr.find('td.groups').empty();
 					var allGroups=$('#content table').data('groups').split(', ');
 					for(var i=0;i<groups.length;i++){
diff --git a/settings/templates/users.php b/settings/templates/users.php
index b16aa1ae16c..649fce107db 100644
--- a/settings/templates/users.php
+++ b/settings/templates/users.php
@@ -6,9 +6,12 @@
  */
 $allGroups=array();
 foreach($_["groups"] as $group) {
-	$allGroups[]=$group['name'];
+	$allGroups[] = $group['name'];
 }
-$_['subadmingroups'] = $_['groups'];
+$_['subadmingroups'] = $allGroups;
+$items = array_flip($_['subadmingroups']);
+unset($items['admin']);
+$_['subadmingroups'] = array_flip($items);
 ?>
 
 <div id="controls">
@@ -16,6 +19,7 @@ $_['subadmingroups'] = $_['groups'];
 		<input id="newusername" placeholder="<?php echo $l->t('Name')?>" /> <input
 			type="password" id="newuserpassword"
 			placeholder="<?php echo $l->t('Password')?>" /> <select
+			class="groupsselect"
 			id="newusergroups" data-placeholder="groups"
 			title="<?php echo $l->t('Groups')?>" multiple="multiple">
 			<?php foreach($_["groups"] as $group): ?>
@@ -62,7 +66,7 @@ $_['subadmingroups'] = $_['groups'];
 			<th id="headerPassword"><?php echo $l->t( 'Password' ); ?></th>
 			<th id="headerGroups"><?php echo $l->t( 'Groups' ); ?></th>
 			<?php if(is_array($_['subadmins']) || $_['subadmins']): ?>
-			<th id="headerSubAdmins"><?php echo $l->t('SubAdmins'); ?></th>
+			<th id="headerSubAdmins"><?php echo $l->t('SubAdmin'); ?></th>
 			<?php endif;?>
 			<th id="headerQuota"><?php echo $l->t( 'Quota' ); ?></th>
 			<th id="headerRemove">&nbsp;</th>
@@ -74,9 +78,10 @@ $_['subadmingroups'] = $_['groups'];
 			<td class="name"><?php echo $user["name"]; ?></td>
 			<td class="password"><span>●●●●●●●</span> <img class="svg action"
 				src="<?php echo image_path('core','actions/rename.svg')?>"
-				alt="set new password" title="set new password" />
+				alt="set new password" title="set new password"/>
 			</td>
 			<td class="groups"><select
+				class="groupsselect"
 				data-username="<?php echo $user['name'] ;?>"
 				data-user-groups="<?php echo $user['groups'] ;?>"
 				data-placeholder="groups" title="<?php echo $l->t('Groups')?>"
@@ -90,13 +95,14 @@ $_['subadmingroups'] = $_['groups'];
 			</td>
 			<?php if(is_array($_['subadmins']) || $_['subadmins']): ?>
 			<td class="subadmins"><select
+				class="subadminsselect"
 				data-username="<?php echo $user['name'] ;?>"
-				data-user-groups="<?php echo $user['groups'] ;?>"
+				data-subadmin="<?php echo $user['subadmin'] ;?>"
 				data-placeholder="subadmins" title="<?php echo $l->t('SubAdmin for ...')?>"
 				multiple="multiple">
 					<?php foreach($_["subadmingroups"] as $group): ?>
-					<option value="<?php echo $group['name'];?>">
-						<?php echo $group['name'];?>
+					<option value="<?php echo $group;?>">
+						<?php echo $group;?>
 					</option>
 					<?php endforeach;?>
 			</select>
diff --git a/settings/users.php b/settings/users.php
index e066956291b..60ffc337a72 100644
--- a/settings/users.php
+++ b/settings/users.php
@@ -19,20 +19,20 @@ $groups = array();
 
 $isadmin = OC_Group::inGroup(OC_User::getUser(),'admin')?true:false;
 if($isadmin){
-	$groups = OC_Group::getGroups();
+	$accessiblegroups = OC_Group::getGroups();
 	$accessibleusers = OC_User::getUsers();
 	$subadmins = OC_SubAdmin::getAllSubAdmins();
 }else{
-	$groups = OC_SubAdmin::getSubAdminsGroups(OC_User::getUser());
-	$accessibleusers = OC_Group::usersInGroups($groups);
+	$accessiblegroups = OC_SubAdmin::getSubAdminsGroups(OC_User::getUser());
+	$accessibleusers = OC_Group::usersInGroups($accessiblegroups);
 	$subadmins = false;
 }
 
 foreach($accessibleusers as $i){
-	$users[] = array( "name" => $i, "groups" => join( ", ", /*array_intersect(*/OC_Group::getUserGroups($i)/*, OC_SubAdmin::getSubAdminsGroups(OC_User::getUser()))*/),'quota'=>OC_Preferences::getValue($i,'files','quota','default'));
+	$users[] = array( "name" => $i, "groups" => join( ", ", /*array_intersect(*/OC_Group::getUserGroups($i)/*, OC_SubAdmin::getSubAdminsGroups(OC_User::getUser()))*/),'quota'=>OC_Preferences::getValue($i,'files','quota','default'),'subadmin'=>implode(', ',OC_SubAdmin::getSubAdminsGroups($i)));
 }
 
-foreach( $groups as $i ){
+foreach( $accessiblegroups as $i ){
 	// Do some more work here soon
 	$groups[] = array( "name" => $i );
 }
@@ -55,7 +55,9 @@ if (\OC_App::isEnabled( "files_sharing" ) ) {
 $tmpl = new OC_Template( "settings", "users", "user" );
 $tmpl->assign( "users", $users );
 $tmpl->assign( "groups", $groups );
+$tmpl->assign( 'isadmin', $isadmin);
 $tmpl->assign( 'subadmins', $subadmins);
+$tmpl->assign( 'numofgroups', count($accessiblegroups));
 $tmpl->assign( 'quota_preset', $quotaPreset);
 $tmpl->assign( 'default_quota', $defaultQuota);
 $tmpl->assign( 'share_notice', $shareNotice);