CRM-16757 - Use customized CertificateValidator
[civicrm-core.git] / api / v3 / Cxn.php
CommitLineData
5d5d3b35
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
4 | CiviCRM version 4.6 |
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
5d5d3b35 28/**
39151786
TO
29 * The Cxn API allows a Civi site to initiate a connection to a
30 * remote application. There are three primary actions:
31 *
32 * - register: Establish a new connection.
33 * - unregister: Destroy an existing connection.
34 * - get: Get a list of existing connections.
35 */
36
37/**
38 * Adjust metadata for "register" action.
39 *
40 * @param array $spec
41 * List of fields.
42 */
43function _civicrm_api3_cxn_register_spec(&$spec) {
44 $daoFields = CRM_Cxn_DAO_Cxn::fields();
45 $spec['app_guid'] = $daoFields['app_guid'];
46
47 if (!CRM_Cxn_BAO_Cxn::isAppMetaVerified()) {
48 $spec['app_meta_url'] = array(
49 'name' => 'app_meta_url',
50 'type' => CRM_Utils_Type::T_STRING,
51 'title' => ts('Application Metadata URL'),
52 'description' => 'Application Metadata URL',
53 'maxlength' => 255,
54 'size' => CRM_Utils_Type::HUGE,
55 );
56 }
57}
58
59/**
60 * Register with a remote application and create a new connection.
61 *
62 * One should generally identify an application using the app_guid.
63 * However, if you need to test a new/experimental application, then
64 * disable CIVICRM_CXN_CA and specify app_meta_url.
65 *
5d5d3b35
TO
66 * @param array $params
67 * Array with keys:
39151786
TO
68 * - app_guid: The unique identifer of the target application.
69 * - app_meta_url: The URL for the application's metadata.
5d5d3b35 70 * @return array
39151786 71 * @throws Exception
5d5d3b35
TO
72 */
73function civicrm_api3_cxn_register($params) {
39151786 74 if (!empty($params['app_meta_url'])) {
9ae2d27b 75 if (!CRM_Cxn_BAO_Cxn::isAppMetaVerified()) {
39151786 76 list ($status, $json) = CRM_Utils_HttpClient::singleton()->get($params['app_meta_url']);
5d5d3b35 77 if (CRM_Utils_HttpClient::STATUS_OK != $status) {
ace09e12 78 throw new API_Exception("Failed to download appMeta. (Bad HTTP response)");
5d5d3b35 79 }
39151786 80 $appMeta = json_decode($json, TRUE);
ace09e12
TO
81 if (empty($appMeta)) {
82 throw new API_Exception("Failed to download appMeta. (Malformed)");
83 }
5d5d3b35
TO
84 }
85 else {
86 // Note: The metadata includes a cert, but the details aren't signed.
87 // This is very useful in testing/development. In ordinary usage, we
9ae2d27b
TO
88 // rely on civicrm.org to sign the metadata for all apps en masse.
89 throw new API_Exception('This site is configured to only connect to applications with verified metadata.');
5d5d3b35
TO
90 }
91 }
39151786
TO
92 elseif (!empty($params['app_guid'])) {
93 $appMeta = civicrm_api3('CxnApp', 'getsingle', array(
6fb60f90 94 'appId' => $params['app_guid'],
39151786
TO
95 ));
96 }
5d5d3b35 97
39151786
TO
98 if (empty($appMeta) || !is_array($appMeta)) {
99 throw new API_Exception("Missing expected parameter: app_guid");
5d5d3b35 100 }
39151786 101 \Civi\Cxn\Rpc\AppMeta::validate($appMeta);
5d5d3b35 102
5d5d3b35 103 try {
7b4bbb34
TO
104 /** @var \Civi\Cxn\Rpc\RegistrationClient $client */
105 $client = \Civi\Core\Container::singleton()->get('cxn_reg_client');
39151786
TO
106 list($cxnId, $result) = $client->register($appMeta);
107 CRM_Cxn_BAO_Cxn::updateAppMeta($appMeta);
5d5d3b35
TO
108 }
109 catch (Exception $e) {
39151786 110 CRM_Cxn_BAO_Cxn::updateAppMeta($appMeta);
5d5d3b35
TO
111 throw $e;
112 }
113
0efb07c0
TO
114 return $result;
115}
116
39151786
TO
117function _civicrm_api3_cxn_unregister_spec(&$spec) {
118 $daoFields = CRM_Cxn_DAO_Cxn::fields();
119 $spec['cxn_guid'] = $daoFields['cxn_guid'];
120 $spec['app_guid'] = $daoFields['app_guid'];
121 $spec['force'] = array(
122 'name' => 'force',
123 'type' => CRM_Utils_Type::T_BOOLEAN,
124 'title' => ts('Force'),
125 'description' => 'Destroy connection even if the remote application is non-responsive.',
126 'default' => '0',
127 );
128}
129
0efb07c0 130/**
39151786
TO
131 * Unregister with a remote application; destroy an existing connection.
132 *
133 * Specify app_guid XOR cxn_guid.
134 *
0efb07c0
TO
135 * @param array $params
136 * Array with keys:
39151786
TO
137 * - cxn_guid: string
138 * - app_guid: string
139 * - force: bool
0efb07c0
TO
140 * @return array
141 */
142function civicrm_api3_cxn_unregister($params) {
a8b2e33f
TO
143 $cxnId = _civicrm_api3_cxn_parseCxnId($params);
144 $appMeta = CRM_Cxn_BAO_Cxn::getAppMeta($cxnId);
145
146 /** @var \Civi\Cxn\Rpc\RegistrationClient $client */
147 $client = \Civi\Core\Container::singleton()->get('cxn_reg_client');
148 list($cxnId, $result) = $client->unregister($appMeta, CRM_Utils_Array::value('force', $params, FALSE));
149
150 return $result;
151}
152
153/**
154 * @param array $params
155 * An array with cxn_guid and/or app_guid.
156 * @return string
157 * The CxnId. (If not available, then an exception is thrown.)
158 *
159 * @throws API_Exception
160 */
161function _civicrm_api3_cxn_parseCxnId($params) {
39151786
TO
162 $cxnId = NULL;
163
164 if (!empty($params['cxn_guid'])) {
165 $cxnId = $params['cxn_guid'];
166 }
167 elseif (!empty($params['app_guid'])) {
168 $cxnId = CRM_Core_DAO::singleValueQuery('SELECT cxn_guid FROM civicrm_cxn WHERE app_guid = %1', array(
169 1 => array($params['app_guid'], 'String'),
170 ));
171 if (!$cxnId) {
172 throw new API_Exception("The app_guid does not correspond to an active connection.");
173 }
174 }
175 if (!$cxnId) {
176 throw new API_Exception('Missing required parameter: cxn_guid');
5d5d3b35 177 }
a8b2e33f 178 return $cxnId;
5d5d3b35 179}
39151786 180
52079b6d
TO
181function _civicrm_api3_cxn_get_spec(&$spec) {
182 // Don't trust AJAX callers or other external code to modify, filter, or return the secret.
183 unset($spec['secret']);
184}
185
39151786
TO
186/**
187 * Returns an array of Cxn records.
188 *
189 * @param array $params
190 * Array of one or more valid property_name=>value pairs.
191 *
192 * @return array
193 * API result array.
194 */
195function civicrm_api3_cxn_get($params) {
52079b6d
TO
196 // Don't trust AJAX callers or other external code to modify, filter, or return the secret.
197 unset($params['secret']);
198
098de400
TO
199 $result = _civicrm_api3_basic_get(_civicrm_api3_get_BAO(__FUNCTION__), $params);
200 if (is_array($result['values'])) {
201 foreach (array_keys($result['values']) as $i) {
202 if (!empty($result['values'][$i]['app_meta'])) {
203 $result['values'][$i]['app_meta'] = json_decode($result['values'][$i]['app_meta'], TRUE);
204 }
205 if (!empty($result['values'][$i]['perm'])) {
206 $result['values'][$i]['perm'] = json_decode($result['values'][$i]['perm'], TRUE);
207 }
52079b6d
TO
208 // Don't trust AJAX callers or other external code to modify, filter, or return the secret.
209 unset($result['values'][$i]['secret']);
098de400
TO
210 }
211 }
52079b6d 212
098de400 213 return $result;
39151786 214}
a8b2e33f
TO
215
216/**
217 * Adjust metadata for "getlink" action.
218 *
219 * @param array $spec
220 * List of fields.
221 */
222function _civicrm_api3_cxn_getlink_spec(&$spec) {
223 $daoFields = CRM_Cxn_DAO_Cxn::fields();
224 $spec['app_guid'] = $daoFields['app_guid'];
225 $spec['cxn_guid'] = $daoFields['cxn_guid'];
226 $spec['page'] = array(
227 'name' => 'page',
228 'type' => CRM_Utils_Type::T_STRING,
229 'title' => ts('Page Type'),
230 'description' => 'The type of page (eg "settings")',
231 'maxlength' => 63,
232 'size' => CRM_Utils_Type::HUGE,
233 );
234}
235
236/**
237 *
238 * @param array $params
239 * Array with keys:
240 * - cxn_guid OR app_guid: string.
241 * - page: string.
242 * @return array
243 * @throws Exception
244 */
245function civicrm_api3_cxn_getlink($params) {
246 $cxnId = _civicrm_api3_cxn_parseCxnId($params);
247 $appMeta = CRM_Cxn_BAO_Cxn::getAppMeta($cxnId);
248
249 if (empty($params['page']) || !is_string($params['page'])) {
250 throw new API_Exception("Invalid page");
251 }
252
253 /** @var \Civi\Cxn\Rpc\RegistrationClient $client */
254 $client = \Civi\Core\Container::singleton()->get('cxn_reg_client');
255 return $client->call($appMeta, 'Cxn', 'getlink', array(
256 'page' => $params['page'],
257 ));
258}