Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Webuzo provider implementation #66

Merged
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
2 changes: 2 additions & 0 deletions src/LaravelServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Upmind\ProvisionProviders\SharedHosting\InterWorx\Provider as InterWorx;
use Upmind\ProvisionProviders\SharedHosting\DirectAdmin\Provider as DirectAdmin;
use Upmind\ProvisionProviders\SharedHosting\CentosWeb\Provider as CentosWeb;
use Upmind\ProvisionProviders\SharedHosting\Webuzo\Provider as Webuzo;

class LaravelServiceProvider extends ProvisionServiceProvider
{
Expand All @@ -34,5 +35,6 @@ public function boot()
$this->bindProvider('shared-hosting', 'solidcp', SolidCP::class);
$this->bindProvider('shared-hosting', 'direct-admin', DirectAdmin::class);
$this->bindProvider('shared-hosting', 'centos-web', CentosWeb::class);
$this->bindProvider('shared-hosting', 'webuzo', Webuzo::class);
}
}
319 changes: 319 additions & 0 deletions src/Webuzo/Api.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,319 @@
<?php

declare(strict_types=1);

namespace Upmind\ProvisionProviders\SharedHosting\Webuzo;

use Illuminate\Support\Arr;
use Upmind\ProvisionBase\Helper;
use GuzzleHttp\Client;
use RuntimeException;
use Illuminate\Support\Str;
use Upmind\ProvisionProviders\SharedHosting\Data\AccountInfo;
use Upmind\ProvisionProviders\SharedHosting\Data\CreateParams;
use Upmind\ProvisionProviders\SharedHosting\Data\UnitsConsumed;
use Upmind\ProvisionProviders\SharedHosting\Data\UsageData;
use Upmind\ProvisionProviders\SharedHosting\Webuzo\Data\Configuration;
use Upmind\ProvisionBase\Exception\ProvisionFunctionError;

class Api
{
private Configuration $configuration;

protected Client $client;

public function __construct(Client $client, Configuration $configuration)
{
$this->client = $client;
$this->configuration = $configuration;
}

/**
* @throws \GuzzleHttp\Exception\GuzzleException
* @throws \Upmind\ProvisionBase\Exception\ProvisionFunctionError
*/
public function makeRequest(
string $command,
?array $body = null,
?string $method = 'POST'
): ?array
{
$requestParams = [];

if ($command == 'sso') {
$requestParams['query']['loginAs'] = $body['username'];
$requestParams['query']['noip'] = 1;
}

$requestParams['query']['api'] = 'json';
$requestParams['query']['act'] = $command;

if ($body) {
$requestParams['form_params'] = $body;
}

if (isset($this->configuration->api_key)) {
$requestParams['form_params']['apikey'] = $this->configuration->api_key;

if (isset($this->configuration->username)) {
$requestParams['form_params']['apiuser'] = $this->configuration->username;
} else {
$requestParams['form_params']['apiuser'] = 'root';
}
}

$response = $this->client->request($method, '/index.php', $requestParams);
$result = $response->getBody()->getContents();

$response->getBody()->close();

if ($result === "") {
return null;
}

return $this->parseResponseData($result);
}

/**
* @throws \Upmind\ProvisionBase\Exception\ProvisionFunctionError
*/
private function parseResponseData(string $response): array
{
$parsedResult = json_decode($response, true);

if ($error = $this->getResponseErrorMessage($parsedResult)) {
throw ProvisionFunctionError::create($error)
->withData([
'response' => $response,
]);
}

return $parsedResult;
}

private function getResponseErrorMessage(array $response): ?string
{
if (isset($response['error'])) {
$message = '';
foreach ($response['error'] as $error) {
$message .= strip_tags($error) . '; ';
}
return $message;
}

return null;
}

public function createAccount(CreateParams $params, string $username, bool $asReseller): void
{
$password = $params->password ?: Helper::generatePassword();

$body = [
'create_user' => 1,
'user' => $username,
'user_passwd' => $password,
'cnf_user_passwd' => $password,
'domain' => $params->domain,
'email' => $params->email,
'plan' => $params->package_name,
];

$this->makeRequest('add_user', $body);

if ($asReseller) {
$this->setReseller($username, 1);
}
}

/**
* @throws \Upmind\ProvisionBase\Exception\ProvisionFunctionError
* @throws \RuntimeException
*/
public function getAccountData(string $username): array
{
$account = $this->getUserDetails($username);

return [
'username' => $username,
RoussKS marked this conversation as resolved.
Show resolved Hide resolved
'domain' => $account['domain'] ?? null,
'reseller' => $account['type'] == 2,
'server_hostname' => $this->configuration->hostname,
'package_name' => $account['plan'] != "" ? $account['plan'] : "Unknown",
'suspended' => $account['status'] === 'suspended',
'suspend_reason' => $account['suspend_reason'] ?? null,
'ip' => $account['ip'] ?? null,
];
}

/**
* @throws \GuzzleHttp\Exception\GuzzleException
* @throws \Upmind\ProvisionBase\Exception\ProvisionFunctionError
*/
public function getUserDetails(string $username): ?array
{
$body = [
'search' => $username,
];

$response = $this->makeRequest('users', $body);

foreach ($response['users'] as $name => $account) {
if ($name === trim($username)) {
return $account;
}
}

throw ProvisionFunctionError::create("User does not exist")
->withData([
'username' => $username,
]);
}

/**
* @throws \Upmind\ProvisionBase\Exception\ProvisionFunctionError
* @throws \RuntimeException
*/
public function getAccountUsage(string $username): UsageData
{
$account = $this->getUserDetails($username)['resource'];

$disk = UnitsConsumed::create()
->setUsed((int)$account['disk']['used_bytes'] / (1024 * 1024))
->setLimit(($account['disk']['limit_bytes'] == 0 || $account['disk']['limit_bytes'] == 'unlimited')
? null : (int)$account['disk']['limit_bytes'] / (1024 * 1024));

$bandwidth = UnitsConsumed::create()
->setUsed((int)$account['bandwidth']['used_bytes'] / (1024 * 1024))
->setLimit(($account['bandwidth']['limit_bytes'] == 0 || $account['bandwidth']['limit_bytes'] == 'unlimited')
? null : (int)$account['bandwidth']['limit_bytes'] / (1024 * 1024));

$inodes = UnitsConsumed::create()
->setUsed((int)$account['inode']['used'])
->setLimit($account['inode']['limit'] == 'unlimited'
? null : (int)$account['inode']['limit']);

$mailboxes = UnitsConsumed::create()
->setUsed((int)$account['email_account']['used'])
->setLimit($account['email_account']['limit'] == 'unlimited'
? null : (int)$account['email_account']['limit']);

return UsageData::create()
RoussKS marked this conversation as resolved.
Show resolved Hide resolved
->setDiskMb($disk)
->setBandwidthMb($bandwidth)
->setInodes($inodes)
->setMailboxes($mailboxes);
}

/**
* @throws \Upmind\ProvisionBase\Exception\ProvisionFunctionError
* @throws \RuntimeException
*/
public function suspendAccount(string $username): void
{
$body = [
'suspend' => $username
];

$this->makeRequest('users', $body);
}

/**
* @throws \Upmind\ProvisionBase\Exception\ProvisionFunctionError
* @throws \RuntimeException
*/
public function unsuspendAccount(string $username): void
{
$body = [
'unsuspend' => $username
];

$this->makeRequest('users', $body);
}

/**
* @throws \Upmind\ProvisionBase\Exception\ProvisionFunctionError
* @throws \RuntimeException
*/
public function deleteAccount(string $username): void
{
$body = [
'delete_user' => $username
];

$this->makeRequest('users', $body);
}

/**
* @throws \Upmind\ProvisionBase\Exception\ProvisionFunctionError
* @throws \RuntimeException
*/
public function updatePackage(string $username, string $package): void
{
$account = $this->getUserDetails($username);

$body = [
'edit_user' => 1,
'user' => $username,
'user_name' => $username,
'domain' => $account['domain'],
'email' => $account['email'],
'plan' => $package
];

$this->makeRequest('add_user', $body);
}

/**
* @throws \Upmind\ProvisionBase\Exception\ProvisionFunctionError
* @throws \RuntimeException
*/
public function updatePassword(string $username, string $password): void
{
$account = $this->getUserDetails($username);

$body = [
'edit_user' => 1,
'user' => $username,
'user_name' => $username,
'domain' => $account['domain'],
'email' => $account['email'],
'plan' => $account['plan'],
'user_passwd' => $password,
'cnf_user_passwd' => $password
];

$this->makeRequest('add_user', $body);
}

/**
* @throws \Upmind\ProvisionBase\Exception\ProvisionFunctionError
* @throws \RuntimeException
*/
public function getLoginUrl(string $username): string
{
$body = [
'username' => $username,
];

$response = $this->makeRequest('sso', $body);

return $response['done']['url'];
}

public function setReseller(string $username, int $isReseller)
{
$account = $this->getUserDetails($username);

$body = [
'edit_user' => 1,
'user' => $username,
'user_name' => $username,
'domain' => $account['domain'],
'email' => $account['email'],
'plan' => $account['plan'],
'reseller' => $isReseller,
];

$this->makeRequest('add_user', $body);
}
}
28 changes: 28 additions & 0 deletions src/Webuzo/Data/Configuration.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Upmind\ProvisionProviders\SharedHosting\Webuzo\Data;

use Upmind\ProvisionBase\Provider\DataSet\DataSet;
use Upmind\ProvisionBase\Provider\DataSet\Rules;

/**
* Webuzo API credentials.
* @property-read string $hostname API hostname
* @property-read string $api_key API key
* @property-read string $username Username
* @property-read string $password Password
*/
class Configuration extends DataSet
{
public static function rules(): Rules
{
return new Rules([
'hostname' => ['required', 'string'],
'api_key' => ['required_without_all:username,password', 'nullable', 'string'],
'username' => ['required_without:api_key', 'nullable', 'string'],
'password' => ['required_without:api_key', 'nullable', 'string'],
]);
}
}
Loading