6649f7e29ccd3724b83d1a72442e9eedeae8d851
[tine20] / tine20 / Tinebase / Model / Grants.php
1 <?php
2 /**
3  * grants model of a container
4  * 
5  * @package     Tinebase
6  * @subpackage  Record
7  * @license     http://www.gnu.org/licenses/agpl.html AGPL Version 3
8  * @copyright   Copyright (c) 2007-2014 Metaways Infosystems GmbH (http://www.metaways.de)
9  * @author      Cornelius Weiss <c.weiss@metaways.de>
10  */
11
12 /**
13  * grants model
14  * 
15  * @package     Tinebase
16  * @subpackage  Record
17  *  
18  */
19 class Tinebase_Model_Grants extends Tinebase_Record_Abstract
20 {
21     /**
22      * grant to read all records of a container / a single record
23      */
24     const GRANT_READ     = 'readGrant';
25     
26     /**
27      * grant to add a record to a container
28      */
29     const GRANT_ADD      = 'addGrant';
30     
31     /**
32      * grant to edit all records of a container / a single record
33      */
34     const GRANT_EDIT     = 'editGrant';
35     
36     /**
37      * grant to delete  all records of a container / a single record
38      */
39     const GRANT_DELETE   = 'deleteGrant';
40     
41     /**
42      * grant to _access_ records marked as private (GRANT_X = GRANT_X * GRANT_PRIVATE)
43      */
44     const GRANT_PRIVATE = 'privateGrant';
45     
46     /**
47      * grant to export all records of a container / a single record
48      */
49     const GRANT_EXPORT = 'exportGrant';
50     
51     /**
52      * grant to sync all records of a container / a single record
53      */
54     const GRANT_SYNC = 'syncGrant';
55     
56     /**
57      * grant to administrate a container
58      */
59     const GRANT_ADMIN    = 'adminGrant';
60     
61     /**
62      * grant to see freebusy info in calendar app
63      * @todo move to Calendar_Model_Grant once we are able to cope with app specific grant classes
64      */
65     const GRANT_FREEBUSY = 'freebusyGrant';
66
67     /**
68      * grant to download file nodes
69      */
70     const GRANT_DOWNLOAD = 'downloadGrant';
71
72     /**
73      * grant to publish nodes in Filemanager
74      * @todo move to Filemanager_Model_Grant once we are able to cope with app specific grant classes
75      */
76     const GRANT_PUBLISH = 'publishGrant';
77
78     /**
79      * key in $_validators/$_properties array for the filed which 
80      * represents the identifier
81      * 
82      * @var string
83      */    
84     protected $_identifier = 'id';
85     
86     /**
87      * application the record belongs to
88      *
89      * @var string
90      */
91     protected $_application = 'Tinebase';
92
93     /**
94      * constructor
95      * 
96      * @param mixed $_data
97      * @param bool $_bypassFilters
98      * @param mixed $_convertDates
99      */
100     public function __construct($_data = null, $_bypassFilters = false, $_convertDates = null)
101     {
102         $this->_validators = array(
103             'id'            => array('Alnum', 'allowEmpty' => true),
104             'record_id'     => array('allowEmpty' => true),
105             'account_grant' => array('allowEmpty' => true),
106             'account_id'    => array('presence' => 'required', 'allowEmpty' => true, 'default' => '0'),
107             'account_type'  => array('presence' => 'required', array('InArray', array(
108                 Tinebase_Acl_Rights::ACCOUNT_TYPE_ANYONE,
109                 Tinebase_Acl_Rights::ACCOUNT_TYPE_USER,
110                 Tinebase_Acl_Rights::ACCOUNT_TYPE_GROUP,
111                 Tinebase_Acl_Rights::ACCOUNT_TYPE_ROLE
112             ))),
113         );
114         
115         foreach ($this->getAllGrants() as $grant) {
116             $this->_validators[$grant] = array(
117                 new Zend_Validate_InArray(array(true, false), true), 
118                 'default' => false,
119                 'presence' => 'required',
120                 'allowEmpty' => true
121             );
122             
123             // initialize in case validators are switched off
124             $this->{$grant} = false;
125         }
126         
127         parent::__construct($_data, $_bypassFilters, $_convertDates);
128     }
129     
130     /**
131      * get all possible grants
132      *
133      * @return  array   all container grants
134      */
135     public static function getAllGrants()
136     {
137         $allGrants = array(
138             self::GRANT_READ,
139             self::GRANT_ADD,
140             self::GRANT_EDIT,
141             self::GRANT_DELETE,
142             self::GRANT_PRIVATE,
143             self::GRANT_EXPORT,
144             self::GRANT_SYNC,
145             self::GRANT_ADMIN,
146             self::GRANT_FREEBUSY,
147             self::GRANT_DOWNLOAD,
148             self::GRANT_PUBLISH,
149         );
150     
151         return $allGrants;
152     }
153
154     /**
155      * checks record grant
156      * 
157      * @param string $grant
158      * @param Tinebase_Model_FullUser $user
159      * @return boolean
160      */
161     public function userHasGrant($grant, Tinebase_Model_FullUser $user = null)
162     {
163         if ($user === null) {
164             $user = Tinebase_Core::getUser();
165         }
166         
167         if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ 
168             . ' Check grant ' . $grant . ' for user ' . $user->getId() . ' in ' . print_r($this->toArray(), true));
169         
170         if (! is_object($user)) {
171             if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ 
172                 . ' No user object');
173             return false;
174         }
175         
176         if (! in_array($grant, $this->getAllGrants()) || ! isset($this->{$grant}) || ! $this->{$grant}) {
177             if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ 
178                 . ' Grant not defined or not set');
179             return false;
180         }
181         
182         switch ($this->account_type) {
183             case Tinebase_Acl_Rights::ACCOUNT_TYPE_GROUP:
184                 if (! in_array($user->getId(), Tinebase_Group::getInstance()->getGroupMembers($this->account_id))) {
185                     if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ 
186                         . ' Current user not member of group ' . $this->account_id);
187                     return false;
188                 }
189                 break;
190             case Tinebase_Acl_Rights::ACCOUNT_TYPE_USER:
191                 if ($user->getId() !== $this->account_id) {
192                     if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ 
193                         . ' Grant not available for current user (account_id of grant: ' . $this->account_id . ')');
194                     return false;
195                 }
196                 break;
197             case Tinebase_Acl_Rights::ACCOUNT_TYPE_ROLE:
198                 $userId = $user->getId();
199                 foreach (Tinebase_Acl_Roles::getInstance()->getRoleMembers($this->account_id) as $roleMember) {
200                     if (Tinebase_Acl_Rights::ACCOUNT_TYPE_USER === $roleMember['account_type'] &&
201                             $userId === $roleMember['account_id']) {
202                         return true;
203                     }
204                     if (Tinebase_Acl_Rights::ACCOUNT_TYPE_GROUP === $roleMember['account_type'] &&
205                         in_array($user->getId(), Tinebase_Group::getInstance()->getGroupMembers($this->account_id))) {
206                         return true;
207                     }
208                 }
209                 if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__
210                     . ' Current user not member of role ' . $this->account_id);
211                 return false;
212         }
213         
214         return true;
215     }
216
217     /**
218      * fills record with all grants and adds account id
219      */
220     public function sanitizeAccountIdAndFillWithAllGrants()
221     {
222         if (empty($this->account_id)) {
223             if ($this->account_type === Tinebase_Acl_Rights::ACCOUNT_TYPE_USER && 
224                 is_object(Tinebase_Core::getUser())) 
225             {
226                 $this->account_id = Tinebase_Core::getUser()->getId();
227             } else if ($this->account_type === Tinebase_Acl_Rights::ACCOUNT_TYPE_GROUP || 
228                 Tinebase_Config::getInstance()->get(Tinebase_Config::ANYONE_ACCOUNT_DISABLED))
229             {
230                 $this->account_type = Tinebase_Acl_Rights::ACCOUNT_TYPE_GROUP;
231                 $this->account_id = Tinebase_Group::getInstance()->getDefaultAdminGroup()->getId();
232             } else {
233                 $this->account_type = Tinebase_Acl_Rights::ACCOUNT_TYPE_ANYONE;
234                 $this->account_id = 0;
235             }
236         }
237         
238         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ 
239             . ' Set all available grants for ' . $this->account_type . ' with id ' . $this->account_id);
240         
241         foreach ($this->getAllGrants() as $grant) {
242             $this->$grant = true;
243         }
244         
245         return $this;
246     }
247
248     /**
249      * return default grants with read for user group and write/admin for admin group
250      *
251      * @param array $_additionalGrants
252      * @param array $_additionalAdminGrants
253      * @return Tinebase_Record_RecordSet of Tinebase_Model_Grants
254      */
255     public static function getDefaultGrants($_additionalGrants = array(), $_additionalAdminGrants = array())
256     {
257         $groupsBackend = Tinebase_Group::getInstance();
258         return new Tinebase_Record_RecordSet('Tinebase_Model_Grants', array(
259             array_merge(array(
260                 'account_id' => $groupsBackend->getDefaultGroup()->getId(),
261                 'account_type' => Tinebase_Acl_Rights::ACCOUNT_TYPE_GROUP,
262                 Tinebase_Model_Grants::GRANT_READ => true,
263                 Tinebase_Model_Grants::GRANT_EXPORT => true,
264                 Tinebase_Model_Grants::GRANT_SYNC => true,
265             ), $_additionalGrants),
266             array_merge(array_merge(array(
267                 'account_id' => $groupsBackend->getDefaultAdminGroup()->getId(),
268                 'account_type' => Tinebase_Acl_Rights::ACCOUNT_TYPE_GROUP,
269                 Tinebase_Model_Grants::GRANT_READ => true,
270                 Tinebase_Model_Grants::GRANT_ADD => true,
271                 Tinebase_Model_Grants::GRANT_EDIT => true,
272                 Tinebase_Model_Grants::GRANT_DELETE => true,
273                 Tinebase_Model_Grants::GRANT_ADMIN => true,
274                 Tinebase_Model_Grants::GRANT_EXPORT => true,
275                 Tinebase_Model_Grants::GRANT_SYNC => true,
276             ), $_additionalGrants), $_additionalAdminGrants),
277         ), TRUE);
278     }
279
280     /**
281      * return personal grants for given account
282      *
283      * @param string|Tinebase_Model_User          $_accountId
284      * @param array $_additionalGrants
285      * @return Tinebase_Record_RecordSet of Tinebase_Model_Grants
286      */
287     public static function getPersonalGrants($_accountId, $_additionalGrants = array())
288     {
289         $accountId = Tinebase_Model_User::convertUserIdToInt($_accountId);
290         $grants = array(Tinebase_Model_Grants::GRANT_READ      => true,
291             Tinebase_Model_Grants::GRANT_ADD       => true,
292             Tinebase_Model_Grants::GRANT_EDIT      => true,
293             Tinebase_Model_Grants::GRANT_DELETE    => true,
294             Tinebase_Model_Grants::GRANT_EXPORT    => true,
295             Tinebase_Model_Grants::GRANT_SYNC      => true,
296             Tinebase_Model_Grants::GRANT_ADMIN     => true,
297         );
298         $grants = array_merge($grants, $_additionalGrants);
299         return new Tinebase_Record_RecordSet('Tinebase_Model_Grants', array(array_merge(array(
300             'account_id'     => $accountId,
301             'account_type'   => Tinebase_Acl_Rights::ACCOUNT_TYPE_USER,
302         ), $grants)));
303     }
304 }