|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
declare(strict_types=1); |
|
4
|
|
|
|
|
5
|
|
|
/** |
|
6
|
|
|
* balloon |
|
7
|
|
|
* |
|
8
|
|
|
* @copyright Copryright (c) 2012-2019 gyselroth GmbH (https://gyselroth.com) |
|
9
|
|
|
* @license GPL-3.0 https://opensource.org/licenses/GPL-3.0 |
|
10
|
|
|
*/ |
|
11
|
|
|
|
|
12
|
|
|
namespace Balloon\App\Wopi; |
|
13
|
|
|
|
|
14
|
|
|
use Balloon\App\Wopi\Session\Session; |
|
15
|
|
|
use Balloon\App\Wopi\Session\SessionInterface; |
|
16
|
|
|
use Balloon\Filesystem\Exception; |
|
17
|
|
|
use Balloon\Filesystem\Node\File; |
|
18
|
|
|
use Balloon\Server; |
|
19
|
|
|
use Balloon\Server\User; |
|
20
|
|
|
use InvalidArgumentException; |
|
21
|
|
|
use MongoDB\BSON\UTCDateTime; |
|
22
|
|
|
use MongoDB\Database; |
|
23
|
|
|
|
|
24
|
|
|
class SessionManager |
|
25
|
|
|
{ |
|
26
|
|
|
/** |
|
27
|
|
|
* Valid until. |
|
28
|
|
|
* |
|
29
|
|
|
* @var int |
|
30
|
|
|
*/ |
|
31
|
|
|
protected $access_token_ttl = 3600; |
|
32
|
|
|
|
|
33
|
|
|
/** |
|
34
|
|
|
* Database. |
|
35
|
|
|
* |
|
36
|
|
|
* @var Database |
|
37
|
|
|
*/ |
|
38
|
|
|
protected $db; |
|
39
|
|
|
|
|
40
|
|
|
/** |
|
41
|
|
|
* Host manager. |
|
42
|
|
|
* |
|
43
|
|
|
* @var HostManager |
|
44
|
|
|
*/ |
|
45
|
|
|
protected $host_manager; |
|
46
|
|
|
|
|
47
|
|
|
/** |
|
48
|
|
|
* Server. |
|
49
|
|
|
*/ |
|
50
|
|
|
protected $server; |
|
51
|
|
|
|
|
52
|
|
|
/** |
|
53
|
|
|
* Session. |
|
54
|
|
|
*/ |
|
55
|
|
|
public function __construct(Database $db, Server $server, HostManager $host_manager, array $config = []) |
|
56
|
|
|
{ |
|
57
|
|
|
$this->db = $db; |
|
58
|
|
|
$this->server = $server; |
|
59
|
|
|
$this->host_manager = $host_manager; |
|
60
|
|
|
$this->setOptions($config); |
|
61
|
|
|
} |
|
62
|
|
|
|
|
63
|
|
|
/** |
|
64
|
|
|
* Set options. |
|
65
|
|
|
*/ |
|
66
|
|
View Code Duplication |
public function setOptions(array $config = []): SessionManager |
|
|
|
|
|
|
67
|
|
|
{ |
|
68
|
|
|
foreach ($config as $option => $value) { |
|
69
|
|
|
switch ($option) { |
|
70
|
|
|
case 'access_token_ttl': |
|
71
|
|
|
$this->access_token_ttl = (int) $value; |
|
72
|
|
|
|
|
73
|
|
|
break; |
|
74
|
|
|
default: |
|
75
|
|
|
throw new InvalidArgumentException('invalid option '.$option.' given'); |
|
76
|
|
|
} |
|
77
|
|
|
} |
|
78
|
|
|
|
|
79
|
|
|
return $this; |
|
80
|
|
|
} |
|
81
|
|
|
|
|
82
|
|
|
/** |
|
83
|
|
|
* Authenticate. |
|
84
|
|
|
*/ |
|
85
|
|
|
public function authenticate(string $token): User |
|
86
|
|
|
{ |
|
87
|
|
|
$result = $this->db->wopi->findOne([ |
|
88
|
|
|
'token' => $token, |
|
89
|
|
|
'ttl' => [ |
|
90
|
|
|
'$gte' => new UTCDateTime(), |
|
91
|
|
|
], |
|
92
|
|
|
]); |
|
93
|
|
|
|
|
94
|
|
|
if (null === $result) { |
|
95
|
|
|
throw new Exception\Forbidden('token is not valid for the requested node'); |
|
96
|
|
|
} |
|
97
|
|
|
|
|
98
|
|
|
return $this->server->getUserById($result['user']); |
|
99
|
|
|
} |
|
100
|
|
|
|
|
101
|
|
|
/** |
|
102
|
|
|
* Get session by id. |
|
103
|
|
|
*/ |
|
104
|
|
|
public function getByToken(File $file, string $token): SessionInterface |
|
105
|
|
|
{ |
|
106
|
|
|
$result = $this->db->wopi->findOne([ |
|
107
|
|
|
'token' => $token, |
|
108
|
|
|
'ttl' => [ |
|
109
|
|
|
'$gte' => new UTCDateTime(), |
|
110
|
|
|
], |
|
111
|
|
|
]); |
|
112
|
|
|
|
|
113
|
|
|
if (null === $result) { |
|
114
|
|
|
throw new Exception\Forbidden('session does not exists'); |
|
115
|
|
|
} |
|
116
|
|
|
|
|
117
|
|
|
$result['client'] = $this->host_manager->getClientUrl(); |
|
118
|
|
|
$user = $this->server->getUserById($result['user']); |
|
119
|
|
|
|
|
120
|
|
|
return new Session($file, $user, $result); |
|
121
|
|
|
} |
|
122
|
|
|
|
|
123
|
|
|
/** |
|
124
|
|
|
* Create session. |
|
125
|
|
|
*/ |
|
126
|
|
|
public function create(File $file, User $user): SessionInterface |
|
127
|
|
|
{ |
|
128
|
|
|
$data = [ |
|
129
|
|
|
'token' => $this->createToken(), |
|
130
|
|
|
'ttl' => new UTCDateTime((time() + $this->access_token_ttl) * 1000), |
|
131
|
|
|
'user' => $user->getId(), |
|
132
|
|
|
'node' => $file->getId(), |
|
133
|
|
|
]; |
|
134
|
|
|
|
|
135
|
|
|
$this->db->wopi->insertOne($data); |
|
136
|
|
|
$data['client'] = $this->host_manager->getClientUrl(); |
|
137
|
|
|
|
|
138
|
|
|
return new Session($file, $user, $data); |
|
139
|
|
|
} |
|
140
|
|
|
|
|
141
|
|
|
/** |
|
142
|
|
|
* Create token. |
|
143
|
|
|
*/ |
|
144
|
|
|
protected function createToken(): string |
|
145
|
|
|
{ |
|
146
|
|
|
return bin2hex(random_bytes(32)); |
|
147
|
|
|
} |
|
148
|
|
|
} |
|
149
|
|
|
|
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.