mirror of
				https://github.com/Icinga/icingaweb2.git
				synced 2025-10-31 03:14:31 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			192 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			192 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| /* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
 | |
| 
 | |
| namespace Icinga\Forms\Config\User;
 | |
| 
 | |
| use Exception;
 | |
| use Icinga\Application\Logger;
 | |
| use Icinga\Data\DataArray\ArrayDatasource;
 | |
| use Icinga\Web\Form;
 | |
| use Icinga\Web\Notification;
 | |
| 
 | |
| /**
 | |
|  * Form for creating one or more group memberships
 | |
|  */
 | |
| class CreateMembershipForm extends Form
 | |
| {
 | |
|     /**
 | |
|      * The user group backends to fetch groups from
 | |
|      *
 | |
|      * Each backend must implement the Icinga\Data\Extensible and Icinga\Data\Selectable interface.
 | |
|      *
 | |
|      * @var array
 | |
|      */
 | |
|     protected $backends;
 | |
| 
 | |
|     /**
 | |
|      * The username to create memberships for
 | |
|      *
 | |
|      * @var string
 | |
|      */
 | |
|     protected $userName;
 | |
| 
 | |
|     /**
 | |
|      * Set the user group backends to fetch groups from
 | |
|      *
 | |
|      * @param   array   $backends
 | |
|      *
 | |
|      * @return  $this
 | |
|      */
 | |
|     public function setBackends($backends)
 | |
|     {
 | |
|         $this->backends = $backends;
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Set the username to create memberships for
 | |
|      *
 | |
|      * @param   string  $userName
 | |
|      *
 | |
|      * @return  $this
 | |
|      */
 | |
|     public function setUsername($userName)
 | |
|     {
 | |
|         $this->userName = $userName;
 | |
|         return $this;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Create and add elements to this form
 | |
|      *
 | |
|      * @param   array   $formData   The data sent by the user
 | |
|      */
 | |
|     public function createElements(array $formData)
 | |
|     {
 | |
|         $query = $this->createDataSource()->select()->from('group', array('group_name', 'backend_name'));
 | |
| 
 | |
|         $options = array();
 | |
|         foreach ($query as $row) {
 | |
|             $options[$row->backend_name . ';' . $row->group_name] = $row->group_name . ' (' . $row->backend_name . ')';
 | |
|         }
 | |
| 
 | |
|         $this->addElement(
 | |
|             'multiselect',
 | |
|             'groups',
 | |
|             array(
 | |
|                 'required'      => true,
 | |
|                 'multiOptions'  => $options,
 | |
|                 'label'         => $this->translate('Groups'),
 | |
|                 'description'   => sprintf(
 | |
|                     $this->translate('Select one or more groups where to add %s as member'),
 | |
|                     $this->userName
 | |
|                 ),
 | |
|                 'class'         => 'grant-permissions'
 | |
|             )
 | |
|         );
 | |
| 
 | |
|         $this->setTitle(sprintf($this->translate('Create memberships for %s'), $this->userName));
 | |
|         $this->setSubmitLabel($this->translate('Create'));
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Instantly redirect back in case the user is already a member of all groups
 | |
|      */
 | |
|     public function onRequest()
 | |
|     {
 | |
|         if ($this->createDataSource()->select()->from('group')->count() === 0) {
 | |
|             Notification::info(sprintf($this->translate('User %s is already a member of all groups'), $this->userName));
 | |
|             $this->getResponse()->redirectAndExit($this->getRedirectUrl());
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Create the memberships for the user
 | |
|      *
 | |
|      * @return  bool
 | |
|      */
 | |
|     public function onSuccess()
 | |
|     {
 | |
|         $backendMap = array();
 | |
|         foreach ($this->backends as $backend) {
 | |
|             $backendMap[$backend->getName()] = $backend;
 | |
|         }
 | |
| 
 | |
|         $single = null;
 | |
|         foreach ($this->getValue('groups') as $backendAndGroup) {
 | |
|             list($backendName, $groupName) = explode(';', $backendAndGroup, 2);
 | |
|             try {
 | |
|                 $backendMap[$backendName]->insert(
 | |
|                     'group_membership',
 | |
|                     array(
 | |
|                         'group_name'    => $groupName,
 | |
|                         'user_name'     => $this->userName
 | |
|                     )
 | |
|                 );
 | |
|             } catch (Exception $e) {
 | |
|                 Notification::error(sprintf(
 | |
|                     $this->translate('Failed to add "%s" as group member for "%s"'),
 | |
|                     $this->userName,
 | |
|                     $groupName
 | |
|                 ));
 | |
|                 $this->error($e->getMessage());
 | |
|                 return false;
 | |
|             }
 | |
| 
 | |
|             $single = $single === null;
 | |
|         }
 | |
| 
 | |
|         if ($single) {
 | |
|             Notification::success(
 | |
|                 sprintf($this->translate('Membership for group %s created successfully'), $groupName)
 | |
|             );
 | |
|         } else {
 | |
|             Notification::success($this->translate('Memberships created successfully'));
 | |
|         }
 | |
| 
 | |
|         return true;
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Create and return a data source to fetch all groups from all backends where the user is not already a member of
 | |
|      *
 | |
|      * @return  ArrayDatasource
 | |
|      */
 | |
|     protected function createDataSource()
 | |
|     {
 | |
|         $groups = $failures = array();
 | |
|         foreach ($this->backends as $backend) {
 | |
|             try {
 | |
|                 $memberships = $backend
 | |
|                     ->select()
 | |
|                     ->from('group_membership', array('group_name'))
 | |
|                     ->where('user_name', $this->userName)
 | |
|                     ->fetchColumn();
 | |
|                 foreach ($backend->select(array('group_name')) as $row) {
 | |
|                     if (! in_array($row->group_name, $memberships)) { // TODO(jom): Apply this as native query filter
 | |
|                         $row->backend_name = $backend->getName();
 | |
|                         $groups[] = $row;
 | |
|                     }
 | |
|                 }
 | |
|             } catch (Exception $e) {
 | |
|                 $failures[] = array($backend->getName(), $e);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         if (empty($groups) && !empty($failures)) {
 | |
|             // In case there are only failures, throw the very first exception again
 | |
|             throw $failures[0][1];
 | |
|         } elseif (! empty($failures)) {
 | |
|             foreach ($failures as $failure) {
 | |
|                 Logger::error($failure[1]);
 | |
|                 Notification::warning(sprintf(
 | |
|                     $this->translate('Failed to fetch any groups from backend %s. Please check your log'),
 | |
|                     $failure[0]
 | |
|                 ));
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         return new ArrayDatasource($groups);
 | |
|     }
 | |
| }
 |