Skip to content

Commit 5f0cc37

Browse files
authored
Merge pull request #55 from ydb-platform/create-credentials
Added credentials authentication
2 parents 00e1ac8 + aeae503 commit 5f0cc37

14 files changed

+614
-89
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
* added credentials authentication
12
* added CI test
23

34
## 1.5.1

README.md

Lines changed: 159 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ First, create a database using [Yandex Cloud Console](https://cloud.yandex.com/d
2828

2929
YDB supports the following authentication methods:
3030

31+
- Access token
3132
- OAuth token
3233
- JWT + private key
3334
- JWT + JSON file
@@ -65,7 +66,34 @@ $config = [
6566

6667
$ydb = new Ydb($config);
6768
```
69+
or:
70+
```php
71+
<?php
72+
73+
use YdbPlatform\Ydb\Ydb;
74+
use YdbPlatform\Ydb\Auth\AccessTokenAuthentication;
75+
76+
$config = [
77+
78+
// Database path
79+
'database' => '/ru-central1/b1glxxxxxxxxxxxxxxxx/etn0xxxxxxxxxxxxxxxx',
80+
81+
// Database endpoint
82+
'endpoint' => 'ydb.serverless.yandexcloud.net:2135',
83+
84+
// Auto discovery (dedicated server only)
85+
'discovery' => false,
86+
87+
// IAM config
88+
'iam_config' => [
89+
'root_cert_file' => './CA.pem', // Root CA file (dedicated server only!)
90+
],
91+
92+
'credentials' => new AccessTokenAuthentication('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')
93+
];
6894

95+
$ydb = new Ydb($config);
96+
```
6997
## OAuth token
7098

7199
You should obtain [a new OAuth token](https://cloud.yandex.com/docs/iam/concepts/authorization/oauth-token).
@@ -101,6 +129,35 @@ $config = [
101129
$ydb = new Ydb($config);
102130
```
103131

132+
or
133+
```php
134+
<?php
135+
136+
use YdbPlatform\Ydb\Ydb;
137+
use YdbPlatform\Ydb\Auth\OAuthTokenAuthentication;
138+
139+
$config = [
140+
141+
// Database path
142+
'database' => '/ru-central1/b1glxxxxxxxxxxxxxxxx/etn0xxxxxxxxxxxxxxxx',
143+
144+
// Database endpoint
145+
'endpoint' => 'ydb.serverless.yandexcloud.net:2135',
146+
147+
// Auto discovery (dedicated server only)
148+
'discovery' => false,
149+
150+
// IAM config
151+
'iam_config' => [
152+
'temp_dir' => './tmp', // Temp directory
153+
'root_cert_file' => './CA.pem', // Root CA file (dedicated server only!)
154+
],
155+
156+
'credentials' => new OAuthTokenAuthentication('AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA')
157+
];
158+
159+
$ydb = new Ydb($config);
160+
```
104161
## JWT + private key
105162

106163
Create [a service account](https://cloud.yandex.com/docs/iam/operations/sa/create) with the `editor` role, then create a private key. Also you need a key ID and a service account ID.
@@ -128,10 +185,36 @@ $config = [
128185
];
129186

130187
$ydb = new Ydb($config);
131-
132188
```
133189

190+
or
191+
```php
192+
<?php
193+
194+
use YdbPlatform\Ydb\Ydb;
195+
use YdbPlatform\Ydb\Auth\JwtWithPrivateKeyAuthentication;
196+
197+
$config = [
198+
'database' => '/ru-central1/b1glxxxxxxxxxxxxxxxx/etn0xxxxxxxxxxxxxxxx',
199+
'endpoint' => 'ydb.serverless.yandexcloud.net:2135',
200+
'discovery' => false,
201+
'iam_config' => [
202+
'temp_dir' => './tmp', // Temp directory
203+
'root_cert_file' => './CA.pem', // Root CA file (dedicated server only!)
204+
205+
// Private key authentication
206+
'key_id' => 'ajexxxxxxxxx',
207+
'service_account_id' => 'ajeyyyyyyyyy',
208+
'private_key_file' => './private.key',
209+
],
210+
211+
'credentials' => new JwtWithPrivateKeyAuthentication(
212+
"ajexxxxxxxxx","ajeyyyyyyyyy",'./private.key')
213+
214+
];
134215

216+
$ydb = new Ydb($config);
217+
```
135218
## JWT + JSON file
136219

137220
Create [a service account](https://cloud.yandex.com/docs/iam/operations/sa/create) with the `editor` role.
@@ -161,6 +244,27 @@ $config = [
161244
$ydb = new Ydb($config);
162245
```
163246

247+
or:
248+
```php
249+
<?php
250+
251+
use YdbPlatform\Ydb\Ydb;
252+
use YdbPlatform\Ydb\Auth\JwtWithJsonAuthentication;
253+
254+
$config = [
255+
'database' => '/ru-central1/b1glxxxxxxxxxxxxxxxx/etn0xxxxxxxxxxxxxxxx',
256+
'endpoint' => 'ydb.serverless.yandexcloud.net:2135',
257+
'discovery' => false,
258+
'iam_config' => [
259+
'temp_dir' => './tmp', // Temp directory
260+
'root_cert_file' => './CA.pem', // Root CA file (dedicated server only!)
261+
],
262+
263+
'credentials' => new JwtWithJsonAuthentication('./jwtjson.json')
264+
];
265+
266+
$ydb = new Ydb($config);
267+
```
164268
## Metadata URL
165269

166270
When you deploy a project to VM or function at Yandex.Cloud, you are able to connect to the database using [Metadata URL](https://cloud.yandex.com/docs/compute/operations/vm-connect/auth-inside-vm). Before you start, you should link your service account to an existing or new VM or function.
@@ -189,7 +293,33 @@ $config = [
189293
];
190294

191295
$ydb = new Ydb($config);
296+
```
297+
or
298+
```php
299+
<?php
300+
301+
use YdbPlatform\Ydb\Ydb;
302+
use YdbPlatform\Ydb\Auth\MetadataAuthentication;
192303

304+
$config = [
305+
306+
// Database path
307+
'database' => '/ru-central1/b1glxxxxxxxxxxxxxxxx/etn0xxxxxxxxxxxxxxxx',
308+
309+
// Database endpoint
310+
'endpoint' => 'ydb.serverless.yandexcloud.net:2135',
311+
312+
// Auto discovery (dedicated server only)
313+
'discovery' => false,
314+
315+
// IAM config
316+
'iam_config' => [
317+
'temp_dir' => './tmp', // Temp directory
318+
],
319+
'credentials' => new MetadataAuthentication()
320+
];
321+
322+
$ydb = new Ydb($config);
193323
```
194324

195325
## Anonymous
@@ -218,7 +348,35 @@ $config = [
218348
];
219349

220350
$ydb = new Ydb($config);
351+
```
352+
353+
or:
354+
```php
355+
<?php
356+
357+
use YdbPlatform\Ydb\Ydb;
358+
use YdbPlatform\Ydb\Auth\AnonymousAuthentication;
359+
360+
$config = [
221361

362+
// Database path
363+
'database' => '/local',
364+
365+
// Database endpoint
366+
'endpoint' => 'localhost:2136',
367+
368+
// Auto discovery (dedicated server only)
369+
'discovery' => false,
370+
371+
// IAM config
372+
'iam_config' => [
373+
'insecure' => true,
374+
],
375+
376+
'credentials' => new AnonymousAuthentication()
377+
];
378+
379+
$ydb = new Ydb($config);
222380
```
223381

224382
# Usage

src/Auth/Auth.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
namespace YdbPlatform\Ydb\Auth;
4+
5+
use DateTime;
6+
use YdbPlatform\Ydb\Iam;
7+
8+
abstract class Auth
9+
{
10+
public abstract function getTokenInfo(): TokenInfo;
11+
12+
public abstract function getName(): string;
13+
14+
protected $logger;
15+
16+
public function logger(){
17+
return $this->logger;
18+
}
19+
20+
public function setLogger($logger){
21+
$this->logger = $logger;
22+
}
23+
24+
/**
25+
* @param string $expiresAt
26+
* @return int
27+
*/
28+
protected function convertExpiresAt($expiresAt)
29+
{
30+
if (is_int($expiresAt)) {
31+
return $expiresAt;
32+
}
33+
34+
$time = time() + 60 * 60 * Iam::DEFAULT_TOKEN_EXPIRES_AT;
35+
if (preg_match('/^(\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})(?:\.\d+)?(.*)$/', $expiresAt, $matches)) {
36+
$time = new DateTime($matches[1] . $matches[2]);
37+
$time = (int)$time->format('U');
38+
}
39+
return $time;
40+
}
41+
}

src/Auth/IamAuth.php

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?php
2+
3+
namespace YdbPlatform\Ydb\Auth;
4+
5+
use YdbPlatform\Ydb\Exception;
6+
use YdbPlatform\Ydb\Iam;
7+
8+
abstract class IamAuth extends Auth
9+
{
10+
/**
11+
* @return mixed|null
12+
* @throws Exception
13+
*/
14+
public function requestToken($request_data): mixed
15+
{
16+
$this->logger()->info('YDB: Obtaining new IAM token...');
17+
18+
$curl = curl_init(Iam::IAM_TOKEN_API_URL);
19+
20+
curl_setopt_array($curl, [
21+
CURLOPT_RETURNTRANSFER => 1,
22+
CURLOPT_SSL_VERIFYPEER => 0,
23+
CURLOPT_SSL_VERIFYHOST => 0,
24+
CURLOPT_HEADER => 0,
25+
CURLOPT_POSTFIELDS => json_encode($request_data),
26+
CURLOPT_HTTPHEADER => [
27+
'Accept: application/json',
28+
'Content-Type: application/json',
29+
],
30+
]);
31+
32+
$result = curl_exec($curl);
33+
34+
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
35+
36+
if ($status === 200) {
37+
$token = json_decode($result);
38+
39+
if (isset($token->iamToken)) {
40+
$this->logger()->info('YDB: Obtained new IAM token [...' . substr($token->iamToken, -6) . '].');
41+
return $token;
42+
} else {
43+
$this->logger()->error('YDB: Failed to obtain new IAM token', [
44+
'status' => $status,
45+
'result' => $token,
46+
]);
47+
throw new Exception('Failed to obtain new iamToken: no token was received.');
48+
}
49+
} else {
50+
$this->logger()->error('YDB: Failed to obtain new IAM token', [
51+
'status' => $status,
52+
'result' => $result,
53+
]);
54+
throw new Exception('Failed to obtain new iamToken: response status is ' . $status);
55+
}
56+
}
57+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace YdbPlatform\Ydb\Auth\Implement;
4+
5+
use YdbPlatform\Ydb\Auth\TokenInfo;
6+
7+
class AccessTokenAuthentication extends \YdbPlatform\Ydb\Auth\Auth
8+
{
9+
/**
10+
* @var string
11+
*/
12+
protected $access_token;
13+
14+
public function __construct(string $access_token)
15+
{
16+
$this->access_token = $access_token;
17+
}
18+
19+
public function getTokenInfo(): TokenInfo
20+
{
21+
return new TokenInfo($this->access_token, time()+24*60*60);
22+
}
23+
24+
public function getName(): string
25+
{
26+
return 'Access token';
27+
}
28+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
namespace YdbPlatform\Ydb\Auth\Implement;
4+
5+
use YdbPlatform\Ydb\Auth\TokenInfo;
6+
7+
class AnonymousAuthentication extends \YdbPlatform\Ydb\Auth\Auth
8+
{
9+
10+
public function __construct()
11+
{
12+
}
13+
14+
public function getTokenInfo(): TokenInfo
15+
{
16+
return new TokenInfo("", time()+24*3600);
17+
}
18+
19+
public function getName(): string
20+
{
21+
return 'Anonymous';
22+
}
23+
}

0 commit comments

Comments
 (0)