Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1441 ariadna 1
<?php
2
 
3
namespace Aws\DSQL;
4
 
5
use Aws\Credentials\CredentialsInterface;
6
use Aws\Credentials\Credentials;
7
use Aws\Signature\SignatureV4;
8
use GuzzleHttp\Psr7\Request;
9
use GuzzleHttp\Psr7\Uri;
10
use GuzzleHttp\Promise;
11
use Aws;
12
 
13
/**
14
 * Generates auth tokens to connect to DSQL database clusters.
15
 */
16
class AuthTokenGenerator
17
{
18
    private const DB_CONNECT = 'DbConnect';
19
    private const DB_CONNECT_ADMIN = 'DbConnectAdmin';
20
    private const SIGNING_NAME = 'dsql';
21
    private const DEFAULT_EXPIRATION_TIME_SECONDS = 900;
22
 
23
    /**
24
     * @var Credentials|callable
25
     */
26
    private $credentialProvider;
27
 
28
    /**
29
     * The constructor takes an instance of Credentials or a CredentialProvider
30
     *
31
     * @param Credentials|callable $creds
32
     */
33
    public function __construct(Credentials | callable $creds)
34
    {
35
        if ($creds instanceof CredentialsInterface) {
36
            $promise = new Promise\FulfilledPromise($creds);
37
            $this->credentialProvider = Aws\constantly($promise);
38
        } else {
39
            $this->credentialProvider = $creds;
40
        }
41
    }
42
 
43
    /**
44
     * @param string $endpoint
45
     * @param string $region
46
     * @param int $expiration
47
     *
48
     * @return string
49
     */
50
    public function generateDbConnectAuthToken(
51
        string $endpoint,
52
        string $region,
53
        int $expiration = self::DEFAULT_EXPIRATION_TIME_SECONDS
54
    ): string
55
    {
56
        return $this->createToken($endpoint, $region, self::DB_CONNECT, $expiration);
57
    }
58
 
59
    /**
60
     * @param string $endpoint
61
     * @param string $region
62
     * @param int $expiration
63
     *
64
     * @return string
65
     */
66
    public function generateDbConnectAdminAuthToken(
67
        string $endpoint,
68
        string $region,
69
        int $expiration = self::DEFAULT_EXPIRATION_TIME_SECONDS
70
    ): string
71
    {
72
        return $this->createToken($endpoint, $region, self::DB_CONNECT_ADMIN, $expiration);
73
    }
74
 
75
    /**
76
     * Creates token for database connection
77
     *
78
     * @param string $endpoint The database hostname
79
     * @param string $region The region where the database is located
80
     * @param string $action Db action to perform
81
     * @param int $expiration The expiration of the token in seconds
82
     *
83
     * @return string Generated token
84
     */
85
    private function createToken(
86
        string $endpoint,
87
        string $region,
88
        string $action,
89
        int $expiration
90
    ): string
91
    {
92
        if ($expiration <= 0) {
93
            throw new \InvalidArgumentException(
94
                "Lifetime must be a positive number, was {$expiration}"
95
            );
96
        }
97
 
98
        if (empty($region)) {
99
            throw new \InvalidArgumentException('Region must be a non-empty string.');
100
        }
101
 
102
        if (empty($endpoint)) {
103
            throw new \InvalidArgumentException('Endpoint must be a non-empty string.');
104
        }
105
 
106
        $uri = new Uri($endpoint);
107
        if (empty($uri->getHost())) {
108
            $uri = $uri->withHost($endpoint);
109
        }
110
        $uri = $uri->withPath('/')->withQuery('Action=' . $action);
111
 
112
        $request = new Request('GET', $uri);
113
        $signer = new SignatureV4(self::SIGNING_NAME, $region);
114
        $provider = $this->credentialProvider;
115
 
116
        $url = (string) $signer->presign(
117
            $request,
118
            $provider()->wait(),
119
            '+' . $expiration . ' seconds'
120
        )->getUri();
121
 
122
        // Remove 2 extra slash from the presigned url result
123
        return substr($url, 2);
124
    }
125
}
126