From 0445d993e021ef1b348cd85703f07db232b007fe Mon Sep 17 00:00:00 2001 From: Naif Date: Fri, 19 Oct 2018 20:08:25 +0300 Subject: [PATCH] refactor classes name --- .gitignore | 1 + README.md | 84 ++++++++++ composer.json | 28 ++++ composer.lock | 292 ++++++++++++++++++++++++++++++++++ src/Config.php | 9 ++ src/Email.php | 52 ++++++ src/Facades/CpanelMail.php | 11 ++ src/cPanel.php | 112 +++++++++++++ src/cPanelBaseModule.php | 72 +++++++++ src/cPanelEmail.php | 172 ++++++++++++++++++++ src/cPanelServiceProvider.php | 35 ++++ 11 files changed, 868 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 src/Config.php create mode 100644 src/Email.php create mode 100644 src/Facades/CpanelMail.php create mode 100644 src/cPanel.php create mode 100644 src/cPanelBaseModule.php create mode 100644 src/cPanelEmail.php create mode 100644 src/cPanelServiceProvider.php diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..61ead86 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/vendor diff --git a/README.md b/README.md new file mode 100644 index 0000000..167076c --- /dev/null +++ b/README.md @@ -0,0 +1,84 @@ +# PHP Laravel cPanel +A php laravel package to manage cPanel email accounts + +## Installation +``` +composer require naif/php-cpanel-email +``` + +Add service provider and alias to config/app.php +``` +Under Providers: +\Naif\cPanelMail\cPanelServiceProvider::class, + +Under aliases: +'cPanel' => \Naif\cPanelMail\Facades\cPanelMail::class, +``` + +Add these to your .env +``` +CPANEL_DOMAIN=your_domain.com +CPANEL_HOST=https://your_domain.com +CPANEL_PORT=2083 // cPanel port Default is: 2083 +CPANEL_VERSION=2 // cPanel api current version +CPANEL_USERNAME=your_cpanel_username +CPANEL_PASSWORD=your_cpanel_password +``` +## Usage + +Create a class object +```php +$cpanel = new cPanel() +``` + +Get a list of all email addresses +```php +$cpanel->getEmailAddresses() + +Response: +array:5 [ + 0 => Email {#227 ▼ + +user: "abc" + +domain: "domain.com" + +email: "abc@domain.com" + +_diskused: 0 + +_diskquota: 0 + +humandiskused: "None" + +humandiskquota: "None" + +suspended_incoming: 0 + +suspended_login: 0 + +mtime: 1539715896 + } + ] +``` + +Create a new email account +```php +$cpanel->create('username','password') + +Response: +[ + "status" => "success" + "message" => "Email address has been added successfully" +] +``` + +Delete an new email account +```php +$cpanel->delete('email_address') + +Response: +[ + "status" => "success" + "message" => "Email address has been deleted successfully" +] +``` + +## Support: +naif@naif.io + +https://www.linkedin.com/in/naif + +## License +The MIT License (MIT). Please see [License File](LICENSE.md) for more information. + diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..08a2544 --- /dev/null +++ b/composer.json @@ -0,0 +1,28 @@ +{ + "name": "naif/php-cpanel-email", + "description": "Manage cPanel Email Addresses", + "keywords": [ + "cPanel", + "email", + "email_address", + "php" + ], + "type": "library", + "license": "MIT", + "authors": [ + { + "name": "Naif Alshaye", + "email": "naif@naif.io" + } + ], + "minimum-stability": "dev", + "require": { + "guzzlehttp/guzzle": "^6.3@dev" + }, + "autoload": { + "psr-4": { + "App\\": "app/", + "Naif\\cPanelMail\\": "src/" + } + } +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..93d5c41 --- /dev/null +++ b/composer.lock @@ -0,0 +1,292 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "content-hash": "1b7b3f5c3c8fb894494658569ceba370", + "packages": [ + { + "name": "guzzlehttp/guzzle", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/guzzle/guzzle.git", + "reference": "2798c457a4fc5a9bda4587ea0da9b177e22aff5a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/2798c457a4fc5a9bda4587ea0da9b177e22aff5a", + "reference": "2798c457a4fc5a9bda4587ea0da9b177e22aff5a", + "shasum": "" + }, + "require": { + "guzzlehttp/promises": "^1.0", + "guzzlehttp/psr7": "^1.4", + "php": ">=5.5" + }, + "require-dev": { + "ext-curl": "*", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.4 || ^7.0", + "psr/log": "^1.0" + }, + "suggest": { + "psr/log": "Required for using the Log middleware" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.3-dev" + } + }, + "autoload": { + "files": [ + "src/functions_include.php" + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle is a PHP HTTP client library", + "homepage": "http://guzzlephp.org/", + "keywords": [ + "client", + "curl", + "framework", + "http", + "http client", + "rest", + "web service" + ], + "time": "2018-10-08T11:42:37+00:00" + }, + { + "name": "guzzlehttp/promises", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/guzzle/promises.git", + "reference": "136531aa4e42f9b1971a47fb0faf60da00d2fefa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/promises/zipball/136531aa4e42f9b1971a47fb0faf60da00d2fefa", + "reference": "136531aa4e42f9b1971a47fb0faf60da00d2fefa", + "shasum": "" + }, + "require": { + "php": ">=5.5.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Promise\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + } + ], + "description": "Guzzle promises library", + "keywords": [ + "promise" + ], + "time": "2018-03-25T01:26:01+00:00" + }, + { + "name": "guzzlehttp/psr7", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/guzzle/psr7.git", + "reference": "4b981cdeb8c13d22a6c193554f8c686f53d5c958" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/4b981cdeb8c13d22a6c193554f8c686f53d5c958", + "reference": "4b981cdeb8c13d22a6c193554f8c686f53d5c958", + "shasum": "" + }, + "require": { + "php": ">=5.4.0", + "psr/http-message": "~1.0", + "ralouphie/getallheaders": "^2.0.5" + }, + "provide": { + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.5-dev" + } + }, + "autoload": { + "psr-4": { + "GuzzleHttp\\Psr7\\": "src/" + }, + "files": [ + "src/functions_include.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Michael Dowling", + "email": "mtdowling@gmail.com", + "homepage": "https://github.com/mtdowling" + }, + { + "name": "Tobias Schultze", + "homepage": "https://github.com/Tobion" + } + ], + "description": "PSR-7 message implementation that also provides common utility methods", + "keywords": [ + "http", + "message", + "request", + "response", + "stream", + "uri", + "url" + ], + "time": "2018-07-29T08:09:46+00:00" + }, + { + "name": "psr/http-message", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363", + "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "time": "2016-08-06T14:39:51+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "2.0.5", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/5601c8a83fbba7ef674a7369456d12f1e0d0eafa", + "reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "phpunit/phpunit": "~3.7.0", + "satooshi/php-coveralls": ">=1.0" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "time": "2016-02-11T07:05:27+00:00" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": { + "guzzlehttp/guzzle": 20 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/src/Config.php b/src/Config.php new file mode 100644 index 0000000..2297358 --- /dev/null +++ b/src/Config.php @@ -0,0 +1,9 @@ + env('CPANEL_DOMAIN'), + 'host' => env('CPANEL_HOST'), + 'port' => env('CPANEL_PORT'), + 'version' => env('CPANEL_VERSION'), + 'username' => env('CPANEL_USERNAME'), + 'password' => env('CPANEL_PASSWORD'), +]; \ No newline at end of file diff --git a/src/Email.php b/src/Email.php new file mode 100644 index 0000000..6aadecf --- /dev/null +++ b/src/Email.php @@ -0,0 +1,52 @@ +setProperties($item); + } + + public function destroy() + { + $cpanel = app()->make(cPanel::class); + + return $cpanel + ->email() + ->destroy($this); + } + + /** + * @param $item + */ + private function setProperties($item) + { + if ($item != null) { + foreach ($item as $key => $value) { + if (property_exists($this, $key)) { + if ($key == '_diskquota' && $value <= 1000){ + $value = $value * 1024 * 1024; + } + $this->{$key} = $value; + } + } + } + if ( ! $this->email && ($this->user && $this->domain)) { + $this->email = $this->user . "@" . $this->domain; + } + } + +} \ No newline at end of file diff --git a/src/Facades/CpanelMail.php b/src/Facades/CpanelMail.php new file mode 100644 index 0000000..cc258ca --- /dev/null +++ b/src/Facades/CpanelMail.php @@ -0,0 +1,11 @@ +url = config('Config.host') . ':' . config('Config.port'); + $this->cleanConfig(); + } + + public function email() + { + return new cPanelEmail(); + } + + /** + * Adiciona campos da array informada nas configurações + * + * @param array $fields + */ + public function mergeFields(array $fields) + { + $this->fallbackFields = $this->fields; + + if (is_array($fields)) { + $this->fields = array_merge($this->fields, $fields); + } + } + + public function cleanConfig() + { + $this->fields = [ + 'cpanel_jsonapi_user' => config('Config.username'), + 'cpanel_jsonapi_apiversion' => config('Config.version'), + 'cpanel_jsonapi_module' => 'Email', + 'cpanel_jsonapi_func' => '', + ]; + } + + /** + * @return array + */ + public function getEmailAddresses() + { + $emails = $this->email()->fetch()->all(); + $list = []; + foreach ($emails as $email){ + array_push($list,$email); + } + return $list; + } + + + /** + * @param $email_address + * @param $password + * @return array + */ + public function create($email_address, $password) + { + if ($email_address) { + $email = new Email(); + $email->email = $email_address . '@' . config('Config.domain'); + try { + $response = $this->email()->store($email,$password); + + if ($response->count() > 0) { + return ['status'=>'success', 'message'=>'Email address has been added successfully']; + } + return ['status'=>'error', 'message'=>'Failed to add email address!']; + } catch (\Exception $e) { + return ['status'=>'error', 'message'=>$e->getMessage()]; + } + } + } + + /** + * @param $email_address + * @return array + */ + public function delete($email_address) + { + if ($email_address) { + $email = new Email(); + $email->domain = config('Config.domain'); + $email->user = $email_address; + try { + $response = $this->email()->destroy($email); + if ($response) { + return ['status'=>'success', 'message'=>'Email address has been deleted successfully']; + } + return ['status'=>'error', 'message'=>'Failed to delete email address!']; + } catch (\Exception $e){ + return ['status'=>'error', 'message'=>$e->getMessage()]; + } + } + } +} \ No newline at end of file diff --git a/src/cPanelBaseModule.php b/src/cPanelBaseModule.php new file mode 100644 index 0000000..2f3997d --- /dev/null +++ b/src/cPanelBaseModule.php @@ -0,0 +1,72 @@ +cpanel = app()->make(cPanel::class); + $this->config['base_uri'] = $this->cpanel->url; + } + + /** + * @return mixed + * @throws \Exception + */ + protected function getApiData() + { + $client = new Client($this->config); + $response = $client->post('/json-api/cpanel', [ + 'auth' => [config('Config.username'), config('Config.password')], + 'form_params' => $this->cpanel->fields, + ]); + $apiData = json_decode($response->getBody()->getContents()); + $this->cpanel->cleanConfig(); + $this->errorHandler($apiData->cpanelresult); + return $apiData->cpanelresult; + } + + /** + * throws an Exception if there is any error + * + * @param $cpanelresult + * + * @throws \Exception + */ + protected function errorHandler($cpanelresult) + { + if (isset($cpanelresult->data->status) || isset($cpanelresult->error)) { + + if (isset($cpanelresult->data->status) && $cpanelresult->data[0]->status == 0) { + if (preg_match('/permission to read the zone/', $cpanelresult->data[0]->statusmsg)) { + throw new \Exception("You don't have permissions to read data from this domain"); + } + + throw new \Exception($cpanelresult->data[0]->statusmsg); + } + + if (isset($cpanelresult->error)) { + if (preg_match('/Permission denied/', $cpanelresult->error)) { + throw new \Exception("You don't have permissions to execute this action."); + } + if (preg_match('/You do not have an email account named/', $cpanelresult->error)) { + throw new \Exception("You do not own this email account."); + } + + throw new \Exception($cpanelresult->error); + } + } + } + +} \ No newline at end of file diff --git a/src/cPanelEmail.php b/src/cPanelEmail.php new file mode 100644 index 0000000..f9d051c --- /dev/null +++ b/src/cPanelEmail.php @@ -0,0 +1,172 @@ +cpanel->mergeFields([ + 'cpanel_jsonapi_module' => 'Email', + ]); + } + + /** + * returns an emails collection + * + * @return Collection + */ + public function fetch() + { + + $this->cpanel->mergeFields([ + 'cpanel_jsonapi_func' => 'listpopswithdisk', + ]); + + $response = $this->getApiData(); + + return $this->collectEmails($response); + } + + /** + * Filters the search to the given email address + * + * @param $email + * + * @return $this + */ + public function filter($email) + { + $this->cpanel->mergeFields([ + 'regex' => $email, + ]); + return $this; + } + + /** + * Filters the search to the given domain name + * + * @param $domain + * + * @return $this + */ + public function filterDomain($domain) + { + + $this->cpanel->mergeFields([ + 'domain' => $domain, + ]); + + return $this; + } + + /** + * Stores a new email if there isnt any with the specified information + * + * @param Email $email + * @param $password + * + * @return Collection + * @throws \Exception + */ + public function store(Email $email, $password) + { + if ($this->cpanel->email()->filter($email->email)->fetch()->count()) { + throw new \Exception("The e-mail \"" . $email->email . "\" already exists."); + } + + $this->cpanel->mergeFields([ + 'cpanel_jsonapi_func' => 'addpop', + 'domain' => $email->domain, + 'email' => $email->email, + 'password' => $password, + 'quota' => 0, // 50mb = 52428800b + ]); + $this->getApiData(); + + return $this->cpanel->email()->filter($email->email)->fetch(); + } + + /** + * Changes the password from the given email + * + * @param Email $email + * @param $password + * + * @return bool + */ + public function updatePassword(Email $email, $password) + { + $this->cpanel->mergeFields([ + 'cpanel_jsonapi_func' => 'passwdpop', + 'domain' => $email->domain, + 'email' => $email->user, + 'password' => $password, + ]); + $this->getApiData(); + return true; + } + + /** + * Change the quota from the given email + * + * @param Email $email + * + * @return bool + * @throws \Exception + */ + public function updateQuota(Email $email) + { + if (!$email->domain || !$email->user || ! $email->_diskquota){ + throw new \Exception("Invalid Email Object, must fill the domain, user and _diskquota properties."); + } + $this->cpanel->mergeFields([ + 'cpanel_jsonapi_func' => 'editquota', + 'domain' => $email->domain, + 'email' => $email->user, + 'quota' => $email->_diskquota / 1024 / 1024, // convert to mb + ]); + $this->getApiData(); + return true; + } + + /** + * Remove the given email + * + * @param Email $email + * + * @return bool + */ + public function destroy(Email $email) + { + $this->cpanel->mergeFields([ + 'cpanel_jsonapi_func' => 'delpop', + 'domain' => $email->domain, + 'email' => $email->user, + ]); + $this->getApiData(); + return true; + } + + /** + * @param $response + * + * @return Collection + * @throws \Exception + */ + private function collectEmails($response) + { + $itens = $response->data; + $emails = new Collection(); + foreach ($itens as $item) { + $emails->push( + new Email($item) + ); + } + return $emails; + } +} \ No newline at end of file diff --git a/src/cPanelServiceProvider.php b/src/cPanelServiceProvider.php new file mode 100644 index 0000000..41473b3 --- /dev/null +++ b/src/cPanelServiceProvider.php @@ -0,0 +1,35 @@ +publishes(['swalker2.cpanel']); + } + + /** + * Register any application services. + * + * @return void + */ + public function register() + { + $this->mergeConfigFrom( + __DIR__ . '/Config.php', 'Config' + ); + + $this->app->singleton(cPanel::class, function () { + return new cPanel(); + }); + } +}