--- /dev/null
+<?php
+/*
+ * Bacula(R) - The Network Backup Solution
+ * Baculum - Bacula web interface
+ *
+ * Copyright (C) 2013-2023 Kern Sibbald
+ *
+ * The main author of Baculum is Marcin Haba.
+ * The original author of Bacula is Kern Sibbald, with contributions
+ * from many others, a complete list can be found in the file AUTHORS.
+ *
+ * You may use this file and others of this release according to the
+ * license defined in the LICENSE file, which includes the Affero General
+ * Public License, v3.0 ("AGPLv3") and some additional permissions and
+ * terms pursuant to its AGPLv3 Section 7.
+ *
+ * This notice must be preserved when any source code is
+ * conveyed and/or propagated.
+ *
+ * Bacula(R) is a registered trademark of Kern Sibbald.
+ */
+
+namespace Baculum\API\Modules;
+
+use PDO;
+
+/**
+ * Microsoft 365 plugin manager module.
+ *
+ * @author Marcin Haba <marcin.haba@bacula.pl>
+ * @category Module
+ * @package Baculum API
+ */
+class PluginM365Manager extends APIModule {
+
+ /**
+ * Get Microsoft 365 jobs by tenant and email owner.
+ *
+ * @param string $tenant tenant name
+ * @param string $owner email owner
+ * @param array $criteria SQL criteria
+ * @return array job list or empty array if no job found
+ */
+ public function getJobsByTenantAndOwner($tenant, $owner, $criteria = []) {
+ $params = count($criteria) > 0 ? $criteria : [];
+
+ // email owner
+ $params['MetaEmail.EmailOwner'] = [];
+ $params['MetaEmail.EmailOwner'][] = [
+ 'operator' => 'AND',
+ 'vals' => [$owner]
+ ];
+
+ // email tenant
+ $params['MetaEmail.EmailTenant'] = [];
+ $params['MetaEmail.EmailTenant'][] = [
+ 'operator' => 'AND',
+ 'vals' => [$tenant]
+ ];
+
+ // job types
+ $params['Job.Type'] = [];
+ $params['Job.Type'][] = [
+ 'operator' => 'IN',
+ 'vals' => ['B']
+ ];
+
+ // job status
+ $params['Job.JobStatus'] = [];
+ $params['Job.JobStatus'][] = [
+ 'operator' => 'IN',
+ 'vals' => ['T', 'f', 'E', 'A', 'e']
+ ];
+
+ $where = Database::getWhere($params);
+
+ $sql = 'SELECT DISTINCT Job.JobId AS jobid,
+ Job.Name AS name,
+ Job.StartTime AS starttime,
+ Job.EndTime AS endtime,
+ Job.JobFiles AS jobfiles,
+ Job.JobBytes AS jobbytes
+ FROM Job
+ LEFT JOIN MetaEmail USING (JobId)
+ ' . $where['where'] . '
+ ORDER BY Job.EndTime DESC';
+
+ $statement = Database::runQuery($sql, $where['params']);
+ return $statement->fetchAll(PDO::FETCH_OBJ);
+ }
+}
--- /dev/null
+<?php
+/*
+ * Bacula(R) - The Network Backup Solution
+ * Baculum - Bacula web interface
+ *
+ * Copyright (C) 2013-2023 Kern Sibbald
+ *
+ * The main author of Baculum is Marcin Haba.
+ * The original author of Bacula is Kern Sibbald, with contributions
+ * from many others, a complete list can be found in the file AUTHORS.
+ *
+ * You may use this file and others of this release according to the
+ * license defined in the LICENSE file, which includes the Affero General
+ * Public License, v3.0 ("AGPLv3") and some additional permissions and
+ * terms pursuant to its AGPLv3 Section 7.
+ *
+ * This notice must be preserved when any source code is
+ * conveyed and/or propagated.
+ *
+ * Bacula(R) is a registered trademark of Kern Sibbald.
+ */
+
+use Baculum\Common\Modules\Errors\ClientError;
+use Baculum\Common\Modules\Errors\PluginError;
+use Baculum\Common\Modules\Errors\PluginM365Error;
+
+/**
+ * Microsoft 365 plugin email job list endpoint.
+ *
+ * @author Marcin Haba <marcin.haba@bacula.pl>
+ * @category API
+ * @package Baculum API
+ */
+class PluginM365EmailJobList extends BaculumAPIServer {
+
+ public function get() {
+ $misc = $this->getModule('misc');
+ $client = null;
+ $clientid = $this->Request->contains('id') ? (int)$this->Request['id'] : 0;
+ $result = $this->getModule('bconsole')->bconsoleCommand(
+ $this->director,
+ ['.client'],
+ null,
+ true
+ );
+ if ($result->exitcode === 0) {
+ $client_val = $this->getModule('client')->getClientById($clientid);
+ if (is_object($client_val) && in_array($client_val->name, $result->output)) {
+ $client = $client_val->name;
+ } else {
+ $this->output = ClientError::MSG_ERROR_CLIENT_DOES_NOT_EXISTS;
+ $this->error = ClientError::ERROR_CLIENT_DOES_NOT_EXISTS;
+ return;
+ }
+ } else {
+ $this->output = PluginError::MSG_ERROR_WRONG_EXITCODE;
+ $this->error = PluginError::ERROR_WRONG_EXITCODE;
+ return;
+ }
+ $tenantid = $this->Request->contains('tenantid') ? $this->Request['tenantid'] : '';
+ $fd_plugin_cfg = $this->getModule('fd_plugin_cfg')->getConfig('m365', $client, $tenantid);
+ if (!empty($tenantid) && (!$misc->isValidUUID($tenantid) || count($fd_plugin_cfg) == 0)) {
+ $this->output = PluginM365Error::MSG_ERROR_TENANT_DOES_NOT_EXISTS;
+ $this->error = PluginM365Error::ERROR_TENANT_DOES_NOT_EXISTS;
+ return;
+ }
+ $tenant = $fd_plugin_cfg['tenant_name'];
+ $emailowner = $this->Request->contains('emailowner') && $misc->isValidNameExt($this->Request['emailowner']) ? $this->Request['emailowner'] : '';
+ if (empty($emailowner)) {
+ $this->output = PluginM365Error::MSG_ERROR_EMAIL_DOES_NOT_EXISTS;
+ $this->error = PluginM365Error::ERROR_EMAIL_DOES_NOT_EXISTS;
+ return;
+ }
+
+ $result = $this->getModule('bconsole')->bconsoleCommand(
+ $this->director,
+ ['.jobs'],
+ null,
+ true
+ );
+ if ($result->exitcode === 0) {
+ $params['Job.Name'] = [];
+ $params['Job.Name'][] = [
+ 'operator' => 'OR',
+ 'vals' => $result->output
+ ];
+ $result = $this->getModule('m365')->getJobsByTenantAndOwner(
+ $tenant,
+ $emailowner,
+ $params
+ );
+ $this->output = $result;
+ $this->error = PluginM365Error::ERROR_NO_ERRORS;
+ } else {
+ $this->output = PluginM365Error::MSG_ERROR_WRONG_EXITCODE . ', Error => ' . $result->exitcode . ' Output => ' . implode(PHP_EOL, $result->output);
+ $this->error = PluginM365Error::ERROR_WRONG_EXITCODE;
+ }
+ }
+}
<module id="changer_command" class="Baculum\API\Modules\ChangerCommand" />
<!-- plugin modules -->
<module id="fd_plugin_cfg" class="Baculum\API\Modules\PluginFDConfig" />
+ <!-- M365 modules -->
+ <module id="m365" class="Baculum\API\Modules\PluginM365Manager" />
</modules>
</configuration>
<url ServiceParameter="PluginM365ListLoggedUsers" pattern="api/v2/plugins/m365/{id}/{tenantid}/users/" parameters.id="\d+" parameters.tenantid="[a-zA-Z0-9:.\-_ ]+" />
<url ServiceParameter="PluginM365EmailList" pattern="api/v2/plugins/m365/{id}/{tenantid}/emails/" parameters.id="\d+" parameters.tenantid="[a-zA-Z0-9:.\-_ ]+" />
<url ServiceParameter="PluginM365EmailAttachmentList" pattern="api/v2/plugins/m365/{id}/{tenantid}/emails/attachments/" parameters.id="\d+" parameters.tenantid="[a-zA-Z0-9:.\-_ ]+" />
+ <url ServiceParameter="PluginM365EmailJobList" pattern="api/v2/plugins/m365/{id}/{tenantid}/jobs/" parameters.id="\d+" parameters.tenantid="[a-zA-Z0-9:.\-_ ]+" />
<!-- vSphere Plugin -->
<url ServiceParameter="PluginVSphereListServers" pattern="api/v2/plugins/vsphere/{id}/servers" parameters.id="\d+" />
<url ServiceParameter="PluginVSphereListHosts" pattern="api/v2/plugins/vsphere/{id}/hosts" parameters.id="\d+" />
]
}
},
+ "/api/v2/plugins/m365/{clientid}/{tenantid}/jobs": {
+ "get": {
+ "tags": ["plugins"],
+ "summary": "Microsoft 365 plugin job list for specific email account.",
+ "description": "Get Microsoft 365 plugin job list for specific email account.",
+ "responses": {
+ "200": {
+ "description": "List of Microsoft 365 jobs for given email",
+ "content": {
+ "application/json": {
+ "schema": {
+ "type": "object",
+ "properties": {
+ "output": {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "jobid": {
+ "type": "integer",
+ "description": "Job identifier"
+ },
+ "name": {
+ "type": "string",
+ "description": "Job name"
+ },
+ "starttime": {
+ "type": "string",
+ "description": "Start time"
+ },
+ "endtime": {
+ "type": "string",
+ "description": "Start time"
+ },
+ "jobfiles": {
+ "type": "integer",
+ "description": "Job files"
+ },
+ "jobbytes": {
+ "type": "integer",
+ "description": "Job bytes"
+ }
+ }
+ }
+ },
+ "error": {
+ "type": "integer",
+ "description": "Error code",
+ "enum": [0, 1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 160, 161, 1000]
+ }
+ }
+ }
+ }
+ }
+ }
+ },
+ "parameters": [
+ {
+ "$ref": "#/components/parameters/ClientId"
+ },
+ {
+ "$ref": "#/components/parameters/TenantId"
+ },
+ {
+ "name": "emailowner",
+ "in": "query",
+ "required": true,
+ "description": "Email to get jobs",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ]
+ }
+ },
"/api/v2/plugins/vsphere/{clientid}/servers": {
"get": {
"tags": ["plugins"],
*/
class PluginM365Error extends PluginError {
const ERROR_TENANT_DOES_NOT_EXISTS = 160;
+ const ERROR_EMAIL_DOES_NOT_EXISTS = 161;
const MSG_ERROR_TENANT_DOES_NOT_EXISTS = 'Tenant does not exist.';
+ const MSG_ERROR_EMAIL_DOES_NOT_EXISTS = 'Email does not exist.';
}