Commit 5d5d3b35 authored by totten's avatar totten

CRM-16173 - Add Cxn.register API. Add extern/cxn.php endpoint.

parent 4bb94be4
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.6 |
+--------------------------------------------------------------------+
| Copyright (C) 2011 Marty Wright |
| Licensed to CiviCRM under the Academic Free License version 3.0. |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
| CiviCRM is free software; you can copy, modify, and distribute it |
| under the terms of the GNU Affero General Public License |
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
| |
| CiviCRM is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| See the GNU Affero General Public License for more details. |
| |
| You should have received a copy of the GNU Affero General Public |
| License and the CiviCRM Licensing Exception along |
| with this program; if not, contact CiviCRM LLC |
| at info[AT]civicrm[DOT]org. If you have questions about the |
| GNU Affero General Public License or the licensing of CiviCRM, |
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/
/**
*
* @package CRM
* @copyright CiviCRM LLC (c) 2004-2014
* $Id$
*
*/
/**
* This class helps to manage connections to third-party apps.
*/
class CRM_Cxn_BAO_Cxn extends CRM_Cxn_DAO_Cxn {
public static function getSiteCallbackUrl() {
$config = CRM_Core_Config::singleton();
if (preg_match('/^(http|https):/', $config->resourceBase)) {
$civiUrl = $config->resourceBase;
}
else {
$civiUrl = rtrim(CRM_Utils_System::baseURL(), '/') . '/' . ltrim($config->resourceBase, '/');
}
return rtrim($civiUrl, '/') . '/extern/cxn.php';
}
public static function updateAppMeta($appMeta) {
\Civi\Cxn\Rpc\AppMeta::validate($appMeta);
CRM_Core_DAO::executeQuery('UPDATE civicrm_cxn SET app_meta = %1 WHERE app_id = %2', array(
1 => array(json_encode($appMeta), 'String'),
2 => array($appMeta['appId'], 'String'),
));
}
}
<?php
class CRM_Cxn_CiviCxnStore implements Civi\Cxn\Rpc\CxnStore\CxnStoreInterface {
protected $cxns = array();
/**
* @inheritDoc
*/
public function getAll() {
if (!$this->cxns) {
$this->cxns = array();
$dao = new CRM_Cxn_DAO_Cxn();
$dao->find();
while ($dao->fetch()) {
$cxn = $this->convertDaoToCxn($dao);
$this->cxns[$cxn['cxnId']] = $cxn;
}
}
return $this->cxns;
}
/**
* @inheritDoc
*/
public function getByCxnId($cxnId) {
if (isset($this->cxns[$cxnId])) {
return $this->cxns[$cxnId];
}
$dao = new CRM_Cxn_DAO_Cxn();
$dao->cxn_id = $cxnId;
if ($dao->find(TRUE)) {
$this->cxns[$cxnId] = $this->convertDaoToCxn($dao);
return $this->cxns[$cxnId];
}
else {
return NULL;
}
}
/**
* @inheritDoc
*/
public function getByAppId($appId) {
$dao = new CRM_Cxn_DAO_Cxn();
$dao->app_id = $appId;
if ($dao->find(TRUE)) {
$this->cxns[$dao->cxn_id] = $this->convertDaoToCxn($dao);
return $this->cxns[$dao->cxn_id];
}
else {
return NULL;
}
}
/**
* @inheritDoc
*/
public function add($cxn) {
$dao = new CRM_Cxn_DAO_Cxn();
$dao->cxn_id = $cxn['cxnId'];
$dao->find(TRUE);
$this->convertCxnToDao($cxn, $dao);
$dao->save();
$sql = '
UPDATE civicrm_cxn SET created_date = modified_date
WHERE created_date IS NULL
AND cxn_guid = %1
';
CRM_Core_DAO::executeQuery($sql, array(
1 => array($cxn['cxnId'], 'String'),
));
$this->cxns[$cxn['cxnId']] = $cxn;
}
/**
* @inheritDoc
*/
public function remove($cxnId) {
CRM_Core_DAO::executeQuery('DELETE FROM civicrm_cxn WHERE cxn_id = %1', array(
1 => array($cxnId, 'String'),
));
unset($this->cxns[$cxnId]);
}
/**
* @param CRM_Cxn_DAO_Cxn $dao
* @return array
* Array-encoded connection details.
*/
protected function convertDaoToCxn($dao) {
$appMeta = json_decode($dao->app_meta, TRUE);
return array(
'cxnId' => $dao->cxn_id,
'secret' => $dao->secret,
'appId' => $dao->app_id,
'appUrl' => $appMeta['appUrl'],
'siteUrl' => CRM_Cxn_BAO_Cxn::getSiteCallbackUrl(),
'perm' => json_decode($dao->perm, TRUE),
);
}
/**
* @param array $cxn
* Array-encoded connection details.
* @param CRM_Cxn_DAO_Cxn $dao
*/
protected function convertCxnToDao($cxn, $dao) {
$dao->cxn_id = $cxn['cxnId'];
$dao->secret = $cxn['secret'];
$dao->app_id = $cxn['appId'];
$dao->perm = json_encode($cxn['perm']);
// Note: we don't save siteUrl because it's more correct to regenerate on-demand.
// Note: we don't save appUrl, but other processes will update appMeta.
}
}
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.6 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2014 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
| CiviCRM is free software; you can copy, modify, and distribute it |
| under the terms of the GNU Affero General Public License |
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
| |
| CiviCRM is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| See the GNU Affero General Public License for more details. |
| |
| You should have received a copy of the GNU Affero General Public |
| License and the CiviCRM Licensing Exception along |
| with this program; if not, contact CiviCRM LLC |
| at info[AT]civicrm[DOT]org. If you have questions about the |
| GNU Affero General Public License or the licensing of CiviCRM, |
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/
/**
* @param array $params
* Array with keys:
* - appMeta: the application's metadata.
* @return array
*/
function civicrm_api3_cxn_register($params) {
if (empty($params['appMeta']) && !empty($params['appMetaUrl'])) {
if (defined('CIVICRM_CXN_VERIFY') && !CIVICRM_CXN_VERIFY) {
list ($status, $json) = CRM_Utils_HttpClient::singleton()->get($params['appMetaUrl']);
if (CRM_Utils_HttpClient::STATUS_OK != $status) {
throw new API_Exception("Failed to download appMeta.");
}
$params['appMeta'] = json_decode($json, TRUE);
}
else {
// Note: The metadata includes a cert, but the details aren't signed.
// This is very useful in testing/development. In ordinary usage, we
// rely on a general signature for the full batch of all metadata.
throw new API_Exception('This site is configured to only use verified metadata.');
}
}
if (empty($params['appMeta']) || !is_array($params['appMeta'])) {
throw new API_Exception("Missing expected parameter: appMeta (array)");
}
\Civi\Cxn\Rpc\AppMeta::validate($params['appMeta']);
// FIXME Move cxnStore and client into Container.
$cxnStore = new CRM_Cxn_CiviCxnStore();
try {
$client = new \Civi\Cxn\Rpc\RegistrationClient(NULL, $cxnStore, CRM_Cxn_BAO_Cxn::getSiteCallbackUrl());
$client->setLog(new CRM_Utils_SystemLogger());
list($cxnId, $isOk) = $client->register($params['appMeta']);
CRM_Cxn_BAO_Cxn::updateAppMeta($params['appMeta']);
}
catch (Exception $e) {
CRM_Cxn_BAO_Cxn::updateAppMeta($params['appMeta']);
throw $e;
}
if ($isOk) {
$result = array(
'cxnId' => $cxnId,
);
return civicrm_api3_create_success();
}
else {
return civicrm_api3_create_error('Connection failed');
}
}
<?php
/*
+--------------------------------------------------------------------+
| CiviCRM version 4.6 |
+--------------------------------------------------------------------+
| Copyright CiviCRM LLC (c) 2004-2014 |
+--------------------------------------------------------------------+
| This file is a part of CiviCRM. |
| |
| CiviCRM is free software; you can copy, modify, and distribute it |
| under the terms of the GNU Affero General Public License |
| Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
| |
| CiviCRM is distributed in the hope that it will be useful, but |
| WITHOUT ANY WARRANTY; without even the implied warranty of |
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
| See the GNU Affero General Public License for more details. |
| |
| You should have received a copy of the GNU Affero General Public |
| License and the CiviCRM Licensing Exception along |
| with this program; if not, contact CiviCRM LLC |
| at info[AT]civicrm[DOT]org. If you have questions about the |
| GNU Affero General Public License or the licensing of CiviCRM, |
| see the CiviCRM license FAQ at http://civicrm.org/licensing |
+--------------------------------------------------------------------+
*/
require_once '../civicrm.config.php';
$config = CRM_Core_Config::singleton();
CRM_Utils_System::loadBootStrap(array(), FALSE);
$apiServer = new \Civi\Cxn\Rpc\ApiServer(new CRM_Cxn_CiviCxnStore());
$apiServer->setLog(new CRM_Utils_SystemLogger());
$apiServer->setRouter(function ($cxn, $entity, $action, $params) {
require_once 'api/v3/utils.php';
// Note: cxnId is authenticated before router is called.
$dao = new CRM_Cxn_DAO_Cxn();
$dao->cxn_id = $cxn['cxnId'];
if (empty($cxn['cxnId']) || !$dao->find(TRUE) || !$dao->cxn_id) {
return civicrm_api3_create_error('Failed to lookup connection authorizations.');
}
if (!$dao->is_active) {
return civicrm_api3_create_error('Connection is inactive');
}
// FIXME: apply $dao->perm
return civicrm_api($entity, $action, $params);
});
$apiServer->handleAndRespond(file_get_contents('php://input'));
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment