3 * Bacula(R) - The Network Backup Solution
4 * Baculum - Bacula web interface
6 * Copyright (C) 2013-2015 Marcin Haba
8 * The main author of Baculum is Marcin Haba.
9 * The original author of Bacula is Kern Sibbald, with contributions
10 * from many others, a complete list can be found in the file AUTHORS.
12 * You may use this file and others of this release according to the
13 * license defined in the LICENSE file, which includes the Affero General
14 * Public License, v3.0 ("AGPLv3") and some additional permissions and
15 * terms pursuant to its AGPLv3 Section 7.
17 * This notice must be preserved when any source code is
18 * conveyed and/or propagated.
20 * Bacula(R) is a registered trademark of Kern Sibbald.
23 Prado::using('Application.Class.Errors');
25 class API extends TModule {
27 const API_VERSION = '0.1';
31 private $allowedErrors = array(
32 GenericError::ERROR_NO_ERRORS,
33 BconsoleError::ERROR_INVALID_COMMAND,
34 PoolError::ERROR_NO_VOLUMES_IN_POOL_TO_UPDATE
37 private function getConnection() {
39 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
40 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
41 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
42 curl_setopt($ch, CURLOPT_COOKIE, 'PHPSESSID=' . md5(session_id()));
43 curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
44 curl_setopt($ch, CURLOPT_USERPWD, $this->appCfg['baculum']['login'] . ':' . $this->appCfg['baculum']['password']);
48 private function getAPIHeaders() {
50 'X-Baculum-API: ' . self::API_VERSION,
51 'X-Baculum-User: ' . $this->Application->User->getName(),
52 'X-Baculum-Pwd: ' . $this->Application->User->getPwd(),
53 'Accept: application/json'
58 public function init($config) {
59 $this->initSessionCache();
60 $this->appCfg = $this->Application->getModule('configuration')->getApplicationConfig();
63 private function getURL() {
64 $protocol = !empty($_SERVER['HTTPS']) ? 'https' : 'http';
65 $host = $_SERVER['SERVER_NAME'];
66 $port = $_SERVER['SERVER_PORT'];
67 $urlPrefix = $this->Application->getModule('friendly-url')->getUrlPrefix();
68 $url = sprintf('%s://%s:%d%s/', $protocol, $host, $port, $urlPrefix);
72 private function setParamsToUrl(&$url) {
73 $url .= (preg_match('/\?/', $url) === 1 ? '&' : '?' ) . 'director=' . ((array_key_exists('director', $_SESSION)) ? $_SESSION['director'] : '');
74 $this->Application->getModule('logging')->log(__FUNCTION__, PHP_EOL . PHP_EOL . 'EXECUTE URL ==> ' . $url . ' <==' . PHP_EOL . PHP_EOL, Logging::CATEGORY_APPLICATION, __FILE__, __LINE__);
78 * API REQUESTS METHODS (get, set, create, delete)
81 public function get(array $params, $use_cache = false) {
84 if ($use_cache === true) {
85 $cached = $this->getSessionCache($params);
87 if (!is_null($cached)) {
90 $url = $this->getURL() . implode('/', $params);
91 $this->setParamsToUrl($url);
92 $ch = $this->getConnection();
93 curl_setopt($ch, CURLOPT_URL, $url);
94 curl_setopt($ch, CURLOPT_HTTPHEADER, $this->getAPIHeaders());
95 $result = curl_exec($ch);
97 $ret = $this->preParseOutput($result);
98 if ($use_cache === true && $ret->error === 0) {
99 $this->setSessionCache($params, $ret);
105 public function set(array $params, array $options) {
106 $url = $this->getURL() . implode('/', $params);
107 $this->setParamsToUrl($url);
108 $data = http_build_query(array('update' => $options));
109 $ch = $this->getConnection();
110 curl_setopt($ch, CURLOPT_URL, $url);
111 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
112 curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge($this->getAPIHeaders(), array('X-HTTP-Method-Override: PUT', 'Content-Length: ' . strlen($data), 'Expect:')));
113 curl_setopt($ch, CURLOPT_POST, true);
114 curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
115 $result = curl_exec($ch);
117 return $this->preParseOutput($result);
120 public function create(array $params, array $options) {
121 $url = $this->getURL() . implode('/', $params);
122 $this->setParamsToUrl($url);
123 $data = http_build_query(array('create' => $options));
124 $ch = $this->getConnection();
125 curl_setopt($ch, CURLOPT_URL, $url);
126 curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge($this->getAPIHeaders(), array('Expect:')));
127 curl_setopt($ch, CURLOPT_POST, true);
128 curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
129 $result = curl_exec($ch);
131 return $this->preParseOutput($result);
134 public function remove(array $params) {
135 $url = $this->getURL() . implode('/', $params);
136 $this->setParamsToUrl($url);
137 $ch = $this->getConnection();
138 curl_setopt($ch, CURLOPT_URL, $url);
139 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
140 curl_setopt($ch, CURLOPT_HTTPHEADER, array_merge($this->getAPIHeaders(), array('X-HTTP-Method-Override: DELETE')));
141 $result = curl_exec($ch);
143 return $this->preParseOutput($result);
146 private function preParseOutput($result) {
147 $this->Application->getModule('logging')->log(__FUNCTION__, $result, Logging::CATEGORY_APPLICATION, __FILE__, __LINE__);
148 $resource = json_decode($result);
150 if(is_object($resource) && property_exists($resource, 'error')) {
151 if(!in_array($resource->error, $this->allowedErrors)) {
152 $error = $resource->error;
155 $error = AuthorizationError::ERROR_AUTHORIZATION_TO_WEBGUI_PROBLEM;
158 $this->Application->getModule('logging')->log(__FUNCTION__, $resource, Logging::CATEGORY_APPLICATION, __FILE__, __LINE__);
159 if(!is_null($error)) {
160 // Note! Redirection to error page takes place here.
161 $this->Response->redirect($this->Service->constructUrl('BaculumError',array('error' => $error), false));
167 public function initSessionCache($force = false) {
168 if (!isset($_SESSION) || !array_key_exists('cache', $_SESSION) || !is_array($_SESSION['cache']) || $force === true) {
169 $_SESSION['cache'] = array();
173 private function getSessionCache(array $params) {
175 $key = $this->getSessionKey($params);
176 if ($this->isSessionValue($key)) {
177 $cached = $_SESSION['cache'][$key];
182 private function setSessionCache(array $params, $value) {
183 $key = $this->getSessionKey($params);
184 $_SESSION['cache'][$key] = $value;
187 private function getSessionKey(array $params) {
188 $key = implode(';', $params);
189 $key = base64_encode($key);
193 private function isSessionValue($key) {
194 $is_value = array_key_exists($key, $_SESSION['cache']);