Completed
Push — master ( 65e3b0...b26a8a )
by
unknown
31:46 queued 19:29
created

LazyOpsPlugin::getUserId()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 0
dl 0
loc 7
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author Thomas Müller <[email protected]>
4
 *
5
 * @copyright Copyright (c) 2018, ownCloud GmbH
6
 * @license AGPL-3.0
7
 *
8
 * This code is free software: you can redistribute it and/or modify
9
 * it under the terms of the GNU Affero General Public License, version 3,
10
 * as published by the Free Software Foundation.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
 * GNU Affero General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License, version 3,
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
19
 *
20
 */
21
22
namespace OCA\DAV\DAV;
23
24
use OCA\DAV\JobStatus\Entity\JobStatus;
25
use OCA\DAV\JobStatus\Entity\JobStatusMapper;
26
use OCP\ILogger;
27
use OCP\IURLGenerator;
28
use OCP\IUserSession;
29
use OCP\Shutdown\IShutdownManager;
30
use Sabre\DAV\Exception;
31
use Sabre\DAV\Server;
32
use Sabre\DAV\ServerPlugin;
33
use Sabre\DAV\UUIDUtil;
34
use Sabre\HTTP\RequestInterface;
35
use Sabre\HTTP\Response;
36
use Sabre\HTTP\ResponseInterface;
37
38
/**
39
 * Class LazyOpsPlugin
40
 *
41
 * @package OCA\DAV\DAV
42
 */
43
class LazyOpsPlugin extends ServerPlugin {
44
45
	/** @var Server */
46
	private $server;
47
	/** @var string */
48
	private $jobId;
49
	/** @var JobStatus */
50
	private $entity;
51
	/** @var IUserSession */
52
	private $userSession;
53
	/** @var IURLGenerator */
54
	private $urlGenerator;
55
	/** @var IShutdownManager */
56
	private $shutdownManager;
57
	/** @var ILogger */
58
	private $logger;
59
	/** @var JobStatusMapper */
60
	private $mapper;
61
62
	public function __construct(IUserSession $userSession,
63
								IURLGenerator $urlGenerator,
64
								IShutdownManager $shutdownManager,
65
								JobStatusMapper $jobStatusMapper,
66
								ILogger $logger) {
67
		$this->userSession = $userSession;
68
		$this->urlGenerator = $urlGenerator;
69
		$this->shutdownManager = $shutdownManager;
70
		$this->logger = $logger;
71
		$this->mapper = $jobStatusMapper;
72
	}
73
74
	/**
75
	 * @param Server $server
76
	 */
77
	public function initialize(Server $server) {
78
		$this->server = $server;
79
		$server->on('method:MOVE', [$this, 'httpMove'], 90);
80
	}
81
82
	/**
83
	 * @param RequestInterface $request
84
	 * @param ResponseInterface $response
85
	 * @return bool
86
	 * @throws Exception\NotAuthenticated
87
	 */
88
	public function httpMove(RequestInterface $request, ResponseInterface $response) {
89
		if (!$request->getHeader('OC-LazyOps')) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $request->getHeader('OC-LazyOps') of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
90
			return true;
91
		}
92
93
		$this->jobId = UUIDUtil::getUUID();
94
		$this->setJobStatus([
95
			'status' => 'init'
96
		]);
97
		$userId = $this->getUserId();
98
		$location = $this->urlGenerator
99
				->linkTo('', 'remote.php') . "/dav/job-status/{$userId}/{$this->jobId}";
100
101
		$response->setStatus(202);
102
		$response->setHeader('Connection', 'close');
103
		$response->setHeader('OC-JobStatus-Location', $location);
104
105
		$this->shutdownManager->register(function () use ($request, $response) {
106
			return $this->afterResponse($request, $response);
107
		}, IShutdownManager::HIGH);
108
109
		return false;
110
	}
111
112
	public function afterResponse(RequestInterface $request, ResponseInterface $response) {
113
		if (!$request->getHeader('OC-LazyOps')) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $request->getHeader('OC-LazyOps') of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
114
			return true;
115
		}
116
117
		\flush();
118
		$request->removeHeader('OC-LazyOps');
119
		$responseDummy = new Response();
120
		try {
121
			$this->setJobStatus([
122
				'status' => 'started'
123
			]);
124
			$this->server->emit('method:MOVE', [$request, $responseDummy]);
125
126
			$this->setJobStatus([
127
				'status' => 'finished',
128
				'fileId' => $response->getHeader('OC-FileId'),
129
				'ETag' => $response->getHeader('ETag')
130
			]);
131
		} catch (\Exception $ex) {
132
			$this->logger->logException($ex);
133
134
			$this->setJobStatus([
135
				'status' => 'error',
136
				'errorCode' => $ex instanceof Exception ? $ex->getHTTPCode() : 500,
137
				'errorMessage' => $ex->getMessage()
138
			]);
139
		}
140
		return false;
141
	}
142
143
	private function setJobStatus(array $status) {
144
		if ($this->entity === null) {
145
			$userId = $this->getUserId();
146
147
			$this->entity = new JobStatus();
148
			$this->entity->setStatusInfo(\json_encode($status));
149
			$this->entity->setUserId($userId);
150
			$this->entity->setUuid($this->jobId);
151
			$this->mapper->insert($this->entity);
152
		} else {
153
			$this->entity->setStatusInfo(\json_encode($status));
154
			$this->mapper->update($this->entity);
155
		}
156
	}
157
158
	/**
159
	 * @return string
160
	 * @throws Exception\NotAuthenticated
161
	 */
162
	private function getUserId() {
163
		$user = $this->userSession->getUser();
164
		if ($user === null) {
165
			throw new Exception\NotAuthenticated();
166
		}
167
		return $user->getUID();
168
	}
169
}
170