2013-11-15 18:22:46 +01:00
< ? php
/**
* EGroupware - Mail Folder ACL - interface class
*
* @ link http :// www . egroupware . org
* @ package mail
* @ author Hadi Nategh [ hn @ stylite . de ]
* @ copyright ( c ) 2013 by Stylite AG < info - AT - stylite . de >
* @ license http :// opensource . org / licenses / gpl - license . php GPL - GNU General Public License
2014-04-03 14:31:52 +02:00
* @ version $Id $
2013-11-15 18:22:46 +01:00
*/
class mail_acl
{
/**
* Methods callable via menuaction
*
* @ var array
*/
var $public_functions = array (
'edit' => True ,
);
2013-11-28 16:08:41 +01:00
/**
* static used define abbrevations for common access rights
*
* @ array
*
*/
var $aclRightsAbbrvs = array (
'lrs' => array ( 'label' => 'readable' , 'title' => 'Allows a user to read the contents of the mailbox.' ),
'lprs' => array ( 'label' => 'post' , 'title' => 'Allows a user to read the mailbox and post to it through the delivery system by sending mail to the submission address of the mailbox.' ),
'ilprs' => array ( 'label' => 'append' , 'title' => 'Allows a user to read the mailbox and append messages to it, either via IMAP or through the delivery system.' ),
2014-02-28 16:39:46 +01:00
'ilprsw' => array ( 'label' => 'write' , 'title' => 'Allows a user to read the maibox, post to it, append messages to it, and delete messages or the mailbox itself. The only right not given is the right to change the ACL of the mailbox.' ),
'aeiklprstwx' => array ( 'label' => 'all' , 'title' => 'The user has all possible rights on the mailbox. This is usually granted to users only on the mailboxes they own.' ),
2013-11-28 16:08:41 +01:00
'custom' => array ( 'label' => 'custom' , 'title' => 'User defined combination of rights for the ACL' ),
);
2013-11-15 18:22:46 +01:00
/**
* instance of mail_bo
*
* @ var mail_bo
*/
var $mail_bo ;
/**
*
* @ var mail_account
*/
var $current_account ;
2013-11-28 16:08:41 +01:00
2013-11-15 18:22:46 +01:00
/**
* Constructor
*
*
*/
function __construct ()
{
2013-12-20 17:17:12 +01:00
$acc_id = $_GET [ 'acc_id' ] ? $_GET [ 'acc_id' ] : $GLOBALS [ 'egw_info' ][ 'user' ][ 'preferences' ][ 'mail' ][ 'ActiveProfileID' ];
$this -> mail_bo = mail_bo :: getInstance ( false , $acc_id );
2013-11-28 16:08:41 +01:00
2013-11-15 18:22:46 +01:00
}
/**
2014-07-22 15:56:36 +02:00
* Edit folder ACLs of account ( s )
2013-11-15 18:22:46 +01:00
*
2014-07-22 15:56:36 +02:00
* @ param string $content = null
* @ param array $msg = ''
2013-11-28 16:08:41 +01:00
*
2013-11-15 18:22:46 +01:00
*/
function edit ( array $content = null , $msg = '' )
{
2013-11-28 16:08:41 +01:00
$tmpl = new etemplate_new ( 'mail.acl' );
2013-12-05 14:49:02 +01:00
$mailbox = base64_decode ( $_GET [ 'mailbox' ]);
2013-11-15 18:22:46 +01:00
if ( ! is_array ( $content ))
{
if ( ! empty ( $mailbox ))
{
2013-12-05 14:49:02 +01:00
$content [ 'mailbox' ] = $mailbox ;
2013-11-28 16:08:41 +01:00
$acl = ( array ) $this -> retrive_acl ( $mailbox , $msg );
$n = 1 ;
2014-04-15 18:09:19 +02:00
foreach ( $acl as $key => $value )
2013-11-28 16:08:41 +01:00
{
2013-12-09 11:10:51 +01:00
$virtuals = array_pop ( array_values (( array ) $value ));
$rights = array_shift ( array_values (( array ) $value ));
2013-11-28 16:08:41 +01:00
2013-12-09 11:10:51 +01:00
foreach ( $rights as $right )
2013-11-28 16:08:41 +01:00
{
$content [ 'grid' ][ $n ][ 'acl_' . $right ] = true ;
}
2013-12-09 11:10:51 +01:00
$virtualD = array ( 'e' , 't' );
$content [ 'grid' ][ $n ][ 'acl_c' ] = array_diff ( $virtuals [ 'c' ], array_intersect ( $rights , $virtuals [ 'c' ])) ? false : true ; //c=kx more information rfc4314, Obsolote Rights
$content [ 'grid' ][ $n ][ 'acl_d' ] = array_diff ( $virtualD , array_intersect ( $rights , $virtuals [ 'd' ])) ? false : true ; //d=et more information rfc4314, Obsolote Rights
2014-02-28 16:39:46 +01:00
sort ( $rights );
2013-12-09 11:10:51 +01:00
$acl_abbrvs = implode ( '' , $rights );
2013-12-05 08:58:45 +01:00
2013-11-28 16:08:41 +01:00
if ( array_key_exists ( $acl_abbrvs , $this -> aclRightsAbbrvs ))
{
$content [ 'grid' ][ $n ][ 'acl' ] = $acl_abbrvs ;
}
else
{
$content [ 'grid' ][ $n ][ 'acl' ] = 'custom' ;
}
2014-04-15 18:09:19 +02:00
if (( $account_id = $this -> mail_bo -> icServer -> getMailBoxAccountId ( $key )))
2014-02-28 13:44:27 +01:00
{
$content [ 'grid' ][ $n ++ ][ 'acc_id' ] = $account_id ;
}
else
{
2014-04-15 18:09:19 +02:00
$content [ 'grid' ][ $n ++ ][ 'acc_id' ] = $key ;
2014-02-28 13:44:27 +01:00
}
2013-11-28 16:08:41 +01:00
}
2014-02-28 13:44:27 +01:00
//error_log(__METHOD__."() acl=".array2string($acl).' --> grid='.array2string($content['grid']));
2013-11-15 18:22:46 +01:00
}
2014-04-15 18:09:19 +02:00
//Set the acl entry in the last row with lrs as default ACL
2014-02-28 14:08:50 +01:00
array_push ( $content [ 'grid' ], array (
2014-04-15 18:09:19 +02:00
'acc_id' => '' ,
'acl_l' => true ,
'acl_r' => true ,
'acl_s' => true ));
2013-11-15 18:22:46 +01:00
}
2013-11-28 16:08:41 +01:00
else
{
list ( $button ) = @ each ( $content [ 'button' ]);
if ( ! empty ( $content [ 'grid' ][ 'delete' ]))
{
$button = 'delete' ;
}
switch ( $button )
{
case 'save' :
case 'apply' :
if ( $content )
{
$validation_err = $this -> update_acl ( $content , $msg );
if ( $validation_err )
{
foreach ( $validation_err as & $row )
{
$tmpl -> set_validation_error ( 'grid[' . $row . ']' . '[acc_id]' , " You must fill this field! " );
}
}
2014-08-22 15:18:47 +02:00
2013-12-02 18:09:35 +01:00
//Add new row at the end
if ( $content [ 'grid' ][ count ( $content [ 'grid' ])][ 'acc_id' ])
array_push ( $content [ 'grid' ], array ( 'acc_id' => '' ));
2013-11-28 16:08:41 +01:00
}
else
{
$msg .= " \ n " . lang ( " Error: Could not save ACL " ) . ' ' . lang ( " reason! " );
}
//Send message
2014-08-22 15:18:47 +02:00
egw_framework :: message ( $msg );
2013-11-28 16:08:41 +01:00
if ( $button == " apply " ) break ;
2014-08-22 15:18:47 +02:00
//Fall through
2013-11-28 16:08:41 +01:00
case 'cancel' :
egw_framework :: window_close ();
common :: egw_exit ();
break ;
case 'delete' :
2013-12-05 08:58:45 +01:00
$aclRvmCnt = $this -> remove_acl ( $content , $msg );
if ( is_array ( $aclRvmCnt ))
{
$content [ 'grid' ] = $aclRvmCnt ;
}
else
{
2013-12-20 17:17:12 +01:00
error_log ( __METHOD__ . __LINE__ . " () " . " The remove_acl suppose to return an array back, something is wrong there " );
2013-12-05 08:58:45 +01:00
}
2014-08-22 15:18:47 +02:00
egw_framework :: message ( $msg );
2013-11-28 16:08:41 +01:00
}
}
2014-02-28 18:00:53 +01:00
$readonlys = $sel_options = array ();
2013-11-28 16:08:41 +01:00
$sel_options [ 'acl' ] = $this -> aclRightsAbbrvs ;
2014-04-15 18:09:19 +02:00
2014-08-22 15:18:47 +02:00
//Make the account owner's fields all readonly as owner has all rights and should not be able to change them
foreach ( $content [ 'grid' ] as $key => $fields )
2014-04-15 18:09:19 +02:00
{
2014-08-22 15:18:47 +02:00
if ( $fields [ 'acc_id' ] == $this -> mail_bo -> icServer -> acc_imap_username ||
$fields [ 'acc_id' ][ 0 ] == $this -> mail_bo -> icServer -> acc_imap_username )
2014-04-15 18:09:19 +02:00
{
2014-08-22 15:18:47 +02:00
foreach ( $fields as $index => $val )
{
$readonlys [ 'grid' ][ $key ][ $index ] = true ;
}
2014-04-15 18:09:19 +02:00
$readonlys [ 'grid' ][ 'delete[' . $key . ']' ] = true ;
2014-08-22 15:18:47 +02:00
$readonlys [ 'grid' ][ $key ][ 'acl_recursive' ] = true ;
$preserv [ 'grid' ][ $key ] = $fields ;
$preserv [ 'grid' ][ $key ][ 'acl_recursive' ] = false ;
2014-04-15 18:09:19 +02:00
}
}
2014-08-22 15:18:47 +02:00
//Make entry row's delete button readonly
2014-04-15 18:09:19 +02:00
$readonlys [ 'grid' ][ 'delete[' . count ( $content [ 'grid' ]) . ']' ] = true ;
2013-12-05 14:49:02 +01:00
$preserv [ 'mailbox' ] = $content [ 'mailbox' ];
2013-11-28 16:08:41 +01:00
$content [ 'msg' ] = $msg ;
2014-02-28 18:00:53 +01:00
$content [ 'grid' ][ 'account_type' ] = $this -> mail_bo -> icServer -> supportsGroupAcl () ? 'both' : 'accounts' ;
2013-11-28 16:08:41 +01:00
$tmpl -> exec ( 'mail.mail_acl.edit' , $content , $sel_options , $readonlys , $preserv , 2 );
2013-11-15 18:22:46 +01:00
}
/**
2013-11-28 16:08:41 +01:00
* Update ACL rights of a folder or including subfolders for an account ( s )
2013-11-15 18:22:46 +01:00
*
2013-11-28 16:08:41 +01:00
* @ param array $content content including the acl rights
* @ param Boolean $recursive boolean flag FALSE | TRUE . If it is FALSE , only the folder take in to account , but in case of TRUE
* the mailbox including all its subfolders will be considered .
* @ param string $msg Message
*
2013-11-15 18:22:46 +01:00
*/
2013-11-28 16:08:41 +01:00
function update_acl ( $content , & $msg )
2013-11-15 18:22:46 +01:00
{
2013-11-28 16:08:41 +01:00
$validator = array ();
2014-08-22 15:18:47 +02:00
2013-11-28 16:08:41 +01:00
foreach ( $content [ 'grid' ] as $keys => $value )
{
2013-12-05 08:58:45 +01:00
$recursive = $value [ 'acl_recursive' ];
2013-11-28 16:08:41 +01:00
unset ( $value [ 'acc_id' ]);
unset ( $value [ 'acl_recursive' ]);
unset ( $value [ 'acl' ]);
2013-12-05 08:58:45 +01:00
2013-11-28 16:08:41 +01:00
$options = array ();
2014-02-28 14:08:50 +01:00
foreach ( array_keys ( $value ) as $key )
2013-11-28 16:08:41 +01:00
{
if ( $value [ $key ] == true )
{
$right = explode ( " acl_ " , $key );
2013-12-09 11:10:51 +01:00
if ( $right [ 1 ] === 'c' ) $right [ 1 ] = 'kx' ; // c = kx , rfc 4314
if ( $right [ 1 ] === 'd' ) $right [ 1 ] = 'et' ; // d = et , rfc 4314
2013-11-28 16:08:41 +01:00
$options [ 'rights' ] .= $right [ 1 ];
}
}
2014-08-22 15:18:47 +02:00
$username = $content [ 'grid' ][ $keys ][ 'acc_id' ] == $this -> mail_bo -> icServer -> acc_imap_username
? $content [ 'grid' ][ $keys ][ 'acc_id' ] : $content [ 'grid' ][ $keys ][ 'acc_id' ][ 0 ];
2014-05-15 16:33:27 +02:00
//error_log(__METHOD__."(".__LINE__.") setACL($content[mailbox], $username, ".array2string($options).", $recursive)");
2014-02-28 13:44:27 +01:00
if ( is_numeric ( $username ) && ( $u = $this -> mail_bo -> icServer -> getMailBoxUserName ( $username )))
{
$username = $u ;
}
if ( ! empty ( $username ))
2013-11-28 16:08:41 +01:00
{
2014-02-28 13:44:27 +01:00
//error_log(__METHOD__."() setACL($content[mailbox], $username, ".array2string($options).", $recursive)");
2014-08-22 15:18:47 +02:00
if (( $ret = $this -> setACL ( $content [ 'mailbox' ], $username , $options , $recursive , $msg )))
{
$msg = lang ( " The Folder %1 's ACLs saved! " , $content [ 'mailbox' ]);
}
else
{
$msg = lang ( 'Error while setting folder ' . $content [ 'mailbox' ] . $msg );
}
2013-11-28 16:08:41 +01:00
}
else
{
if ( $keys !== count ( $content [ 'grid' ]))
{
2013-12-05 08:58:45 +01:00
array_push ( $validator , $keys );
2013-12-20 17:17:12 +01:00
$msg = lang ( " Error:Could not save the ACL! Because some names are empty! " );
2013-11-28 16:08:41 +01:00
}
}
}
2014-04-15 18:09:19 +02:00
if ( is_array ( $validator ))
{
return $validator ;
}
2013-11-15 18:22:46 +01:00
}
/**
* Retrive Folder ACL rights
2013-11-28 16:08:41 +01:00
* @ todo rights 'c' and 'd' should be fixed
2013-11-15 18:22:46 +01:00
*/
function retrive_acl ( $mailbox , & $msg )
{
2013-11-28 16:08:41 +01:00
if (( $acl = $this -> getACL ( $mailbox )))
2013-11-15 18:22:46 +01:00
{
2013-11-28 16:08:41 +01:00
$msg = lang ( 'ACL rights retrived successfully!' );
return $acl ;
2013-11-15 18:22:46 +01:00
}
else
{
2013-11-28 16:08:41 +01:00
$msg = lang ( 'Get ACL rights failed from IMAP server!' );
2013-11-15 18:22:46 +01:00
}
}
2013-11-28 16:08:41 +01:00
/**
* remove_acl
2013-12-05 08:58:45 +01:00
* This method take content of acl rights , and will delete the one from ACL IMAP ,
* for selected folder and / or its subfolders
2013-11-28 16:08:41 +01:00
*
* @ param Array $content content array of popup window
* @ param string $msg message
*
2013-12-05 08:58:45 +01:00
* @ return Array An array as new content for grid
2013-11-28 16:08:41 +01:00
*/
2013-12-05 08:58:45 +01:00
function remove_acl ( $content , & $msg )
2013-11-28 16:08:41 +01:00
{
$row_num = array_keys ( $content [ 'grid' ][ 'delete' ], " pressed " );
2014-02-28 14:08:50 +01:00
if ( $row_num ) $row_num = $row_num [ 0 ];
2013-12-05 08:58:45 +01:00
$recursive = $content [ 'grid' ][ $row_num ][ 'acl_recursive' ];
2013-11-28 16:08:41 +01:00
$identifier = $content [ 'grid' ][ $row_num ][ 'acc_id' ][ 0 ];
2014-05-15 16:33:27 +02:00
if ( is_numeric ( $identifier ) && ( $u = $this -> mail_bo -> icServer -> getMailBoxUserName ( $identifier )))
{
$identifier = $u ;
}
//error_log(__METHOD__.__LINE__."(".$content['mailbox'].", ".$identifier.", ".$recursive.")");
2013-12-05 08:58:45 +01:00
if (( $res = $this -> deleteACL ( $content [ 'mailbox' ], $identifier , $recursive )))
{
unset ( $content [ 'grid' ][ $row_num ]);
unset ( $content [ 'grid' ][ 'delete' ]);
if ( $recursive )
{
$msg = lang ( " The %1 's acl, including its subfolders, removed from the %2! " , $content [ 'mailbox' ], $identifier );
}
else
{
$msg = lang ( " The %1 's acl removed from the %2! " , $content [ 'mailbox' ], $identifier );
}
return array_combine ( range ( 1 , count ( $content [ 'grid' ])), array_values ( $content [ 'grid' ]));
}
else
{
$msg = lang ( " An error happend while trying to remove ACL rights from the account %1. " , $identifier );
return false ;
}
2013-11-28 16:08:41 +01:00
}
/**
* Delete ACL rights of a folder or including subfolders from an account
*
* @ param String $mailbox folder name that needs to be edited
* @ param String $identifier The identifier to delete .
* @ param Boolean $recursive boolean flag FALSE | TRUE . If it is FALSE , only the folder take in to account , but in case of TRUE
* the mailbox including all its subfolders will be considered .
*
2013-12-05 08:58:45 +01:00
* @ return Boolean FALSE in case of any exceptions and TRUE in case of success
2013-11-28 16:08:41 +01:00
*/
function deleteACL ( $mailbox , $identifier , $recursive )
{
2013-12-05 08:58:45 +01:00
if ( $recursive )
2013-11-28 16:08:41 +01:00
{
2013-12-05 08:58:45 +01:00
$folders = $this -> getSubfolders ( $mailbox );
2013-11-28 16:08:41 +01:00
}
2013-12-05 08:58:45 +01:00
else
2013-11-28 16:08:41 +01:00
{
2014-04-15 11:05:03 +02:00
$folders = ( array ) $mailbox ;
2013-12-05 08:58:45 +01:00
}
foreach ( $folders as $sbFolders )
{
try
{
$this -> mail_bo -> icServer -> deleteACL ( $sbFolders , $identifier );
}
catch ( Exception $e )
{
error_log ( __METHOD__ . " Could not delete ACL rights of folder " . $mailbox . " for account " . $identifier . " because of " . $e -> getMessage ());
return false ;
}
2013-11-28 16:08:41 +01:00
}
2013-12-05 08:58:45 +01:00
return true ;
}
2013-11-28 16:08:41 +01:00
2013-12-05 08:58:45 +01:00
/**
* Get subfolders of a mailbox
*
* @ param string $mailbox structural folder name
*
* @ return Array an array including all subfolders of given mailbox | returns an empty array in case of no subfolders
*
*/
function getSubfolders ( $mailbox )
{
$delimiter = $this -> mail_bo -> getHierarchyDelimiter ();
$nameSpace = $this -> mail_bo -> _getNameSpaces ();
$prefix = $this -> mail_bo -> getFolderPrefixFromNamespace ( $nameSpace , $mailbox );
if (( $subFolders = $this -> mail_bo -> getMailBoxesRecursive ( $mailbox , $delimiter , $prefix )))
{
return $subFolders ;
}
else
{
return array ();
}
2013-11-28 16:08:41 +01:00
}
/**
* Set ACL rights of a folder or including subfolders to an account
* @ param String $mailbox folder name that needs to be edited
2014-08-22 15:18:47 +02:00
* @ param String $identifier The identifier to set .
2013-11-28 16:08:41 +01:00
* @ param Array $options Additional options :
2014-04-15 18:09:19 +02:00
* - rights : ( string ) The rights to alter or set .
* - action : ( string , optional ) If 'add' or 'remove' , adds or removes the
* specified rights . Sets the rights otherwise .
2013-11-28 16:08:41 +01:00
* @ param Boolean $recursive boolean flag FALSE | TRUE . If it is FALSE , only the folder take in to account , but in case of TRUE
* the mailbox including all its subfolders will be considered .
* @ param String $msg message
2013-12-05 08:58:45 +01:00
* @ return Boolean FALSE in case of any exceptions and TRUE in case of success ,
2013-11-28 16:08:41 +01:00
*
*/
2014-08-22 15:18:47 +02:00
function setACL ( $mailbox , $identifier , $options , $recursive , & $msg )
2013-11-28 16:08:41 +01:00
{
2013-12-05 08:58:45 +01:00
if ( $recursive )
2013-11-28 16:08:41 +01:00
{
2013-12-05 08:58:45 +01:00
$folders = $this -> getSubfolders ( $mailbox );
2013-11-28 16:08:41 +01:00
}
2013-12-05 08:58:45 +01:00
else
2013-11-28 16:08:41 +01:00
{
2014-04-15 11:05:03 +02:00
$folders = ( array ) $mailbox ;
2013-12-05 08:58:45 +01:00
}
foreach ( $folders as $sbFolders )
{
try
{
$this -> mail_bo -> icServer -> setACL ( $sbFolders , $identifier , $options );
}
catch ( Exception $e )
{
2014-08-22 15:18:47 +02:00
$msg = $e -> getMessage ();
2013-12-05 08:58:45 +01:00
error_log ( __METHOD__ . " Could not set ACL rights on folder " . $mailbox . " for account " . $identifier . " because of " . $e -> getMessage ());
return false ;
}
2013-11-28 16:08:41 +01:00
}
2013-12-05 08:58:45 +01:00
return true ;
2013-11-28 16:08:41 +01:00
}
/**
* Get ACL rights of a folder from an account
*
* @ param String $mailbox folder name that needs to be read
* @ return Boolean FALSE in case of any exceptions and if TRUE in case of success ,
*/
function getACL ( $mailbox )
{
2014-04-22 16:15:58 +02:00
try
2013-11-28 16:08:41 +01:00
{
2014-04-22 16:15:58 +02:00
$acl = $this -> mail_bo -> icServer -> getACL ( $mailbox );
return $acl ;
} catch ( Exception $e ) {
error_log ( __METHOD__ . " Could not get ACL rights from folder " . $mailbox . " because of " . $e -> getMessage ());
return false ;
2013-11-28 16:08:41 +01:00
}
}
2013-12-20 17:17:12 +01:00
}