Merge branch 'JohnFF-patch-1'
[civicrm-core.git] / tests / phpunit / api / v3 / ACLPermissionTest.php
1 <?php
2 /*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.5 |
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2014 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26 */
27
28 require_once 'CiviTest/CiviUnitTestCase.php';
29
30 /**
31 * This class is intended to test ACL permission using the multisite module
32 *
33 * @package CiviCRM_APIv3
34 * @subpackage API_Contact
35 */
36
37 class api_v3_ACLPermissionTest extends CiviUnitTestCase {
38 protected $_apiversion = 3;
39 protected $_params;
40
41 /**
42 * @var CRM_Utils_Hook_UnitTests
43 */
44 protected $hookClass = NULL;
45 public $DBResetRequired = FALSE;
46
47
48
49 protected $_entity;
50
51 function setUp() {
52 parent::setUp();
53 $baoObj = new CRM_Core_DAO();
54 $baoObj->createTestObject('CRM_Pledge_BAO_Pledge', array(), 1, 0);
55 $baoObj->createTestObject('CRM_Core_BAO_Phone', array(), 1, 0);
56 $this->hookClass = CRM_Utils_Hook::singleton();
57 $config = CRM_Core_Config::singleton();
58 $config->userPermissionClass->permissions = array();
59 }
60
61 /**
62 * (non-PHPdoc)
63 * @see CiviUnitTestCase::tearDown()
64 */
65 function tearDown() {
66 CRM_Utils_Hook::singleton()->reset();
67 $tablesToTruncate = array(
68 'civicrm_contact',
69 );
70 $this->quickCleanup($tablesToTruncate);
71 $config = CRM_Core_Config::singleton();
72 unset($config->userPermissionClass->permissions);
73 }
74
75 /**
76 * Function tests that an empty where hook returns no results
77 */
78 function testContactGetNoResultsHook() {
79 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereHookNoResults'));
80 $result = $this->callAPISuccess('contact', 'get', array(
81 'check_permissions' => 1,
82 'return' => 'display_name',
83 ));
84 $this->assertEquals(0, $result['count']);
85 }
86
87 /**
88 * Function tests all results are returned
89 */
90 function testContactGetAllResultsHook() {
91 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereHookAllResults'));
92 $result = $this->callAPISuccess('contact', 'get', array(
93 'check_permissions' => 1,
94 'return' => 'display_name',
95 ));
96
97 $this->assertEquals(2, $result['count']);
98 }
99
100 /**
101 * Function tests that deleted contacts are not returned
102 */
103 function testContactGetPermissionHookNoDeleted() {
104 $this->callAPISuccess('contact', 'create', array('id' => 2, 'is_deleted' => 1));
105 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereHookAllResults'));
106 $result = $this->callAPISuccess('contact', 'get', array(
107 'check_permissions' => 1,
108 'return' => 'display_name',
109 ));
110 $this->assertEquals(1, $result['count']);
111 }
112
113 /**
114 * test permissions limited by hook
115 */
116 function testContactGetHookLimitingHook() {
117 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereOnlySecond'));
118
119 $result = $this->callAPISuccess('contact', 'get', array(
120 'check_permissions' => 1,
121 'return' => 'display_name',
122 ));
123 $this->assertEquals(1, $result['count']);
124 }
125
126 /**
127 * confirm that without check permissions we still get 2 contacts returned
128 */
129 function testContactGetHookLimitingHookDontCheck() {
130 //
131 $result = $this->callAPISuccess('contact', 'get', array(
132 'check_permissions' => 0,
133 'return' => 'display_name',
134 ));
135 $this->assertEquals(2, $result['count']);
136 }
137
138 /**
139 * Check that id works as a filter
140 */
141 function testContactGetIDFilter() {
142 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereHookAllResults'));
143 $result = $this->callAPISuccess('contact', 'get', array(
144 'sequential' => 1,
145 'id' => 2,
146 'check_permissions' => 1,
147 ));
148
149 $this->assertEquals(1, $result['count']);
150 $this->assertEquals(2, $result['id']);
151 }
152
153 /**
154 * Check that address IS returned
155 */
156 function testContactGetAddressReturned() {
157 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereOnlySecond'));
158 $fullresult = $this->callAPISuccess('contact', 'get', array(
159 'sequential' => 1,
160 ));
161 //return doesn't work for all keys - can't fix that here so let's skip ...
162 //prefix & suffix are inconsistent due to CRM-7929
163 // unsure about others but return doesn't work on them
164 $elementsReturnDoesntSupport = array(
165 'prefix',
166 'suffix',
167 'gender',
168 'current_employer',
169 'phone_id',
170 'phone_type_id',
171 'phone',
172 'worldregion_id',
173 'world_region'
174 );
175 $expectedReturnElements = array_diff(array_keys($fullresult['values'][0]), $elementsReturnDoesntSupport);
176 $result = $this->callAPISuccess('contact', 'get', array(
177 'check_permissions' => 1,
178 'return' => $expectedReturnElements,
179 'sequential' => 1,
180 ));
181 $this->assertEquals(1, $result['count']);
182 foreach ($expectedReturnElements as $element) {
183 $this->assertArrayHasKey($element, $result['values'][0]);
184 }
185 }
186
187 /**
188 * Check that pledge IS not returned
189 */
190 function testContactGetPledgeIDNotReturned() {
191 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereHookAllResults'));
192 $this->callAPISuccess('contact', 'get', array(
193 'sequential' => 1,
194 ));
195 $result = $this->callAPISuccess('contact', 'get', array(
196 'check_permissions' => 1,
197 'return' => 'pledge_id',
198 'sequential' => 1,
199 ));
200 $this->assertArrayNotHasKey('pledge_id', $result['values'][0]);
201 }
202
203 /**
204 * Check that pledge IS not an allowable filter
205 */
206 function testContactGetPledgeIDNotFiltered() {
207 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereHookAllResults'));
208 $this->callAPISuccess('contact', 'get', array(
209 'sequential' => 1,
210 ));
211 $result = $this->callAPISuccess('contact', 'get', array(
212 'check_permissions' => 1,
213 'pledge_id' => 1,
214 'sequential' => 1,
215 ));
216 $this->assertEquals(2, $result['count']);
217 }
218
219 /**
220 * Check that chaining doesn't bypass permissions
221 */
222 function testContactGetPledgeNotChainable() {
223 $this->hookClass->setHook('civicrm_aclWhereClause', array($this, 'aclWhereOnlySecond'));
224 $this->callAPISuccess('contact', 'get', array(
225 'sequential' => 1,
226 ));
227 $this->callAPIFailure('contact', 'get', array(
228 'check_permissions' => 1,
229 'api.pledge.get' => 1,
230 'sequential' => 1,
231 ),
232 'Error in call to pledge_get : API permission check failed for pledge/get call; missing permission: access CiviCRM.'
233 );
234 }
235
236 /**
237 * no results returned
238 */
239 function aclWhereHookNoResults($type, &$tables, &$whereTables, &$contactID, &$where) {
240 }
241
242 /**
243 * all results returned
244 * @implements CRM_Utils_Hook::aclWhereClause
245 */
246 function aclWhereHookAllResults($type, &$tables, &$whereTables, &$contactID, &$where) {
247 $where = " (1) ";
248 }
249
250 /**
251 * full results returned
252 * @implements CRM_Utils_Hook::aclWhereClause
253 */
254 function aclWhereOnlySecond($type, &$tables, &$whereTables, &$contactID, &$where) {
255 $where = " contact_a.id > 1";
256 }
257 }
258