Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions examples/authentication/00-authentication.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

use Rede\v2\eRede;
use Rede\v2\Store;
use Monolog\Logger;
use Psr\Log\LogLevel;
use Rede\Environment;
use Monolog\Handler\StreamHandler;

require_once __DIR__ . '/../../vendor/autoload.php';

$client_id = getenv('EREDE_CLIENT_ID') ?: '';
$client_secret = getenv('EREDE_CLIENT_SECRET') ?: '';

$logger = new Logger('eRede');
$logger->pushHandler(new StreamHandler('php://stdout', LogLevel::DEBUG));

$eRede = new eRede(
new Store(
filiation: $client_id,
token: $client_secret,
environment: Environment::sandbox()
),
$logger
);

// echo $eRede->generateOAuthToken()->toString();
echo json_encode($eRede->generateOAuthToken()->getCredentials(), JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES);
44 changes: 44 additions & 0 deletions src/Rede/AbstractAuthentication.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Rede;

abstract class AbstractAuthentication
{
/**
* Which environment will this store used for?
* @var CredentialsEnvironment
*/
protected CredentialsEnvironment $environment;

abstract public function getCredentials(): array;
abstract public function toString(): string;

public function __construct(?CredentialsEnvironment $environment = null)
{
$this->environment = $environment ?? CredentialsEnvironment::production();
}

/**
* @return CredentialsEnvironment
*/
public function getEnvironment(): CredentialsEnvironment
{
return $this->environment;
}

/**
* @param CredentialsEnvironment $environment
*
* @return $this
*/
public function setEnvironment(CredentialsEnvironment $environment): static
{
$this->environment = $environment;
return $this;
}

public static function make(...$rest): AbstractAuthentication
{
return new static(...$rest);
}
}
22 changes: 22 additions & 0 deletions src/Rede/AuthenticationCredentials.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

namespace Rede;

class AuthenticationCredentials
{
public function __construct(
private string $clientId,
private string $clientSecret,
) {
}

public function getClientId(): string
{
return $this->clientId;
}

public function getClientSecret(): string
{
return $this->clientSecret;
}
}
44 changes: 44 additions & 0 deletions src/Rede/BasicAuthentication.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?php

namespace Rede;

class BasicAuthentication extends AbstractAuthentication
{
public function __construct(private Store $store, ?CredentialsEnvironment $environment)
{
parent::__construct($environment);
}

public function getUsername(): string
{
return $this->store->getFiliation();
}

public function getPassword(): string
{
return $this->store->getToken();
}

public function setUsername(string $username): void
{
$this->store->setFiliation($username);
}

public function setPassword(string $password): void
{
$this->store->setToken($password);
}

public function getCredentials(): array
{
return [
'username' => $this->store->getFiliation(),
'password' => $this->store->getToken(),
];
}

public function toString(): string
{
return 'Basic ' . base64_encode(sprintf('%s:%s', $this->store->getFiliation(), $this->store->getToken()));
}
}
76 changes: 76 additions & 0 deletions src/Rede/BearerAuthentication.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

namespace Rede;

class BearerAuthentication extends AbstractAuthentication
{
private ?int $expiresIn = null;
private ?string $token = null;
private string $type = 'Bearer';

public function getToken(): ?string
{
return $this->token;
}

public function getExpiresIn(): ?int
{
return $this->expiresIn;
}

public function getType(): string
{
return $this->type;
}

public function setToken(?string $token): self
{
$this->token = $token;
return $this;
}

public function setExpiresIn(?int $expiresIn): self
{
$this->expiresIn = $expiresIn;
return $this;
}

public function setType(string $type): self
{
$this->type = $type;
return $this;
}

public function getCredentials(): array
{
return [
'type' => $this->type,
'token' => $this->token,
'expires_in' => $this->expiresIn,
];
}

public static function withCredentials(array $credentials): self
{
$instance = new self();

if (isset($credentials['token_type'])) {
$instance->type = $credentials['token_type'];
}

if (isset($credentials['access_token'])) {
$instance->token = $credentials['access_token'];
}

if (isset($credentials['expires_in'])) {
$instance->expiresIn = $credentials['expires_in'];
}

return $instance;
}

public function toString(): string
{
return sprintf('%s %s', $this->type, $this->token);
}
}
56 changes: 56 additions & 0 deletions src/Rede/CredentialsEnvironment.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

namespace Rede;

class CredentialsEnvironment extends Environment
{
public const PRODUCTION = 'https://api.userede.com.br/redelabs';
public const SANDBOX = 'https://rl7-sandbox-api.useredecloud.com.br';
public const VERSION = '';

/**
* @var string
*/
private string $endpoint;

/**
* Creates an environment with its base url and version
*
* @param string $baseUrl
*/
private function __construct(string $baseUrl)
{
$this->endpoint = sprintf('%s/%s', $baseUrl, self::VERSION);
}

public function getEndpoint(string $service): string
{
return $this->endpoint . $service;
}

public function getIp(): ?string
{
return parent::getIp();
}

public function getSessionId(): ?string
{
return parent::getSessionId();
}

/**
* @return CredentialsEnvironment A preconfigured production environment
*/
public static function production(): CredentialsEnvironment
{
return new CredentialsEnvironment(CredentialsEnvironment::PRODUCTION);
}

/**
* @return CredentialsEnvironment A preconfigured sandbox environment
*/
public static function sandbox(): CredentialsEnvironment
{
return new CredentialsEnvironment(CredentialsEnvironment::SANDBOX);
}
}
101 changes: 101 additions & 0 deletions src/Rede/Service/AbstractAuthenticationService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php

namespace Rede\Service;

use Psr\Log\LoggerInterface;
use Rede\AbstractAuthentication;

abstract class AbstractAuthenticationService
{
private array $headers = [
'Accept: application/json',
];

public function __construct(private AbstractAuthentication $authentication, private ?LoggerInterface $logger = null)
{
}

abstract protected function getService(): string;
abstract public function execute(): AbstractAuthentication;
abstract protected function parseResponse(string $response, int $statusCode): AbstractAuthentication;

public function withHeaders(array $headers): self
{
$this->headers = $headers;
return $this;
}

public function addHeader(string $header, string $value): self
{
$this->headers[] = "$header: $value";
return $this;
}

protected function sendRequest(string $method, string $service, array $data = []): AbstractAuthentication
{
$body = http_build_query($data);

$this->addHeader('Authorization', $this->authentication->toString());

$curl = curl_init($this->authentication->getEnvironment()->getEndpoint($this->getService()));

curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $this->headers);

curl_setopt($curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, true);

if ($method === 'POST') {
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
}

$this->logger?->debug(
trim(
sprintf(
"Request Rede\n%s %s\n%s\n\n%s",
$method,
$this->authentication->getEnvironment()->getEndpoint($this->getService()),
implode("\n", $this->headers),
$method === 'POST' ? $body : ''
)
)
);

$response = curl_exec($curl);
$httpInfo = curl_getinfo($curl);

$this->logger?->debug(
sprintf(
"Response Rede\nStatus Code: %s\n\n%s",
$httpInfo['http_code'],
preg_replace_callback(
'/"access_token"\s*:\s*"([^"]+)"/i',
function ($m) {
$token = $m[1];
$len = mb_strlen($token);
$mask = '*****';
$start = 4;
$end = 4;
$left = mb_substr($token, 0, $start);
$right = mb_substr($token, $len - $end, $end);
return '"access_token":"' . $left . $mask . $right . '"';
},
$response
)
)
);

if (curl_errno($curl)) {
throw new \RuntimeException(sprintf('Curl error[%s]: %s', curl_errno($curl), curl_error($curl)));
}

if (!is_string($response)) {
throw new \RuntimeException('Error obtaining a response from the API');
}

curl_close($curl);

return $this->parseResponse($response, $httpInfo['http_code']);
}
}
Loading