├── .editorconfig ├── CHANGELOG.md ├── CONDUCT.md ├── LICENSE.md ├── README.md ├── composer.json └── src └── GsuiteChecker.php /.editorconfig: -------------------------------------------------------------------------------- 1 | ; This file is for unifying the coding style for different editors and IDEs. 2 | ; More information at http://editorconfig.org 3 | 4 | root = true 5 | 6 | [*] 7 | charset = utf-8 8 | indent_size = 4 9 | indent_style = space 10 | end_of_line = lf 11 | insert_final_newline = true 12 | trim_trailing_whitespace = true 13 | 14 | [*.md] 15 | trim_trailing_whitespace = false 16 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All Notable changes to `gsuite-checker` will be documented in this file. 4 | 5 | Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) principles. 6 | -------------------------------------------------------------------------------- /CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | * Using welcoming and inclusive language 18 | * Being respectful of differing viewpoints and experiences 19 | * Gracefully accepting constructive criticism 20 | * Focusing on what is best for the community 21 | * Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | * The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | * Trolling, insulting/derogatory comments, and personal or political attacks 28 | * Public or private harassment 29 | * Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | * Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at `syed at lukonet.com`. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at [http://contributor-covenant.org/version/1/4][version] 72 | 73 | [homepage]: http://contributor-covenant.org 74 | [version]: http://contributor-covenant.org/version/1/4/ -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # The MIT License (MIT) 2 | 3 | Copyright (c) 2017 Syed Irfaq R. 4 | 5 | > Permission is hereby granted, free of charge, to any person obtaining a copy 6 | > of this software and associated documentation files (the "Software"), to deal 7 | > in the Software without restriction, including without limitation the rights 8 | > to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | > copies of the Software, and to permit persons to whom the Software is 10 | > furnished to do so, subject to the following conditions: 11 | > 12 | > The above copyright notice and this permission notice shall be included in 13 | > all copies or substantial portions of the Software. 14 | > 15 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | > IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | > FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | > AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | > LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | > OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | > THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # GSuite Checker 2 | 3 | [![Join PHP Chat][ico-phpchat]][link-phpchat] 4 | [![Chat on Telegram][ico-telegram]][link-telegram] 5 | [![Latest Version on Packagist][ico-version]][link-packagist] 6 | [![Software License][ico-license]](LICENSE.md) 7 | [![Total Downloads][ico-downloads]][link-downloads] 8 | 9 | > Google Suite AKA GSuite (Formerly known as Google Apps) Checker for Domains. It lets you determine if a domain has an active GSuite Account. 10 | 11 | > The checker can check up to **25** domains simultaneously in a pool of requests. 12 | 13 | ## Install 14 | 15 | Via Composer 16 | 17 | ``` bash 18 | $ composer require irazasyed/gsuite-checker 19 | ``` 20 | 21 | ## Usage 22 | 23 | ``` php 24 | $domains = ['test.com', 'domain.com', 'example.com']; 25 | 26 | $gsuite = Irazasyed\GsuiteChecker::make($domains)->check(); 27 | 28 | $result = $gsuite->all(); 29 | ``` 30 | 31 | The result is an array of domain => status. 32 | 33 | There are 3 status codes: 34 | 35 | - **-1** - The request was rejected due to whatever issues and should be retried. 36 | - **0** - There is no GSuite Account associated with the domain. 37 | - **1** - There is a GSuite Account associated with the domain. 38 | 39 | ## Change log 40 | 41 | Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. 42 | 43 | ## Contributing 44 | 45 | Please see [CONTRIBUTING](.github/CONTRIBUTING.md) and [CONDUCT](CONDUCT.md) for details. 46 | 47 | ## Security 48 | 49 | If you discover any security related issues, please email syed at lukonet.com instead of using the issue tracker. 50 | 51 | ## Credits 52 | 53 | - [Syed Irfaq R.][link-author] 54 | - [All Contributors][link-contributors] 55 | 56 | ## License 57 | 58 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 59 | 60 | [ico-phpchat]: https://img.shields.io/badge/Slack-PHP%20Chat-5c6aaa.svg?style=flat-square&logo=slack&labelColor=4A154B 61 | [ico-telegram]: https://img.shields.io/badge/@PHPChatCo-2CA5E0.svg?style=flat-square&logo=telegram&label=Telegram 62 | [ico-version]: https://img.shields.io/packagist/v/irazasyed/gsuite-checker.svg?style=flat-square 63 | [ico-license]: https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square 64 | [ico-travis]: https://img.shields.io/travis/irazasyed/gsuite-checker/master.svg?style=flat-square 65 | [ico-scrutinizer]: https://img.shields.io/scrutinizer/coverage/g/irazasyed/gsuite-checker.svg?style=flat-square 66 | [ico-code-quality]: https://img.shields.io/scrutinizer/g/irazasyed/gsuite-checker.svg?style=flat-square 67 | [ico-downloads]: https://img.shields.io/packagist/dt/irazasyed/gsuite-checker.svg?style=flat-square 68 | 69 | [link-phpchat]: https://phpchat.co/?ref=gsuite-checker 70 | [link-telegram]: https://t.me/PHPChatCo 71 | [link-packagist]: https://packagist.org/packages/irazasyed/gsuite-checker 72 | [link-travis]: https://travis-ci.org/irazasyed/gsuite-checker 73 | [link-scrutinizer]: https://scrutinizer-ci.com/g/irazasyed/gsuite-checker/code-structure 74 | [link-code-quality]: https://scrutinizer-ci.com/g/irazasyed/gsuite-checker 75 | [link-downloads]: https://packagist.org/packages/irazasyed/gsuite-checker 76 | [link-author]: https://github.com/irazasyed 77 | [link-contributors]: ../../contributors 78 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "irazasyed/gsuite-checker", 3 | "type": "library", 4 | "description": "Google Suite (GSuite) formerly known as Google Apps Multi-Domains Checker.", 5 | "keywords": [ 6 | "irazasyed", 7 | "gsuite-checker", 8 | "laravel gsuite-checker", 9 | "laravel", 10 | "google suite", 11 | "google apps", 12 | "google apps checker", 13 | "google suite checker", 14 | "gsuite checker" 15 | ], 16 | "homepage": "https://github.com/irazasyed/gsuite-checker", 17 | "license": "MIT", 18 | "authors": [ 19 | { 20 | "name": "Syed Irfaq R.", 21 | "homepage": "https://github.com/irazasyed", 22 | "role": "Developer" 23 | } 24 | ], 25 | "require": { 26 | "php" : "^7.3 || ^8.0", 27 | "guzzlehttp/guzzle": "^6.2 || ^7.0.1" 28 | }, 29 | "require-dev": { 30 | "phpunit/phpunit": "^8.5.5 || ^9.3.5" 31 | }, 32 | "autoload": { 33 | "psr-4": { 34 | "Irazasyed\\GsuiteChecker\\": "src" 35 | } 36 | }, 37 | "autoload-dev": { 38 | "psr-4": { 39 | "Irazasyed\\GsuiteChecker\\": "tests" 40 | } 41 | }, 42 | "scripts": { 43 | "test": "phpunit" 44 | }, 45 | "extra": { 46 | "branch-alias": { 47 | "dev-master": "1.0-dev" 48 | } 49 | }, 50 | "config": { 51 | "sort-packages": true 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/GsuiteChecker.php: -------------------------------------------------------------------------------- 1 | domains = (array) $domains; 36 | } 37 | 38 | /** 39 | * Create a new instance if the value isn't one already. 40 | * 41 | * @param mixed $domains 42 | * 43 | * @return static 44 | */ 45 | public static function make($domains = []) 46 | { 47 | return new static($domains); 48 | } 49 | 50 | /** 51 | * Check whether the domain(s) have a Google Suite account associated with them. 52 | * 53 | * @return $this 54 | */ 55 | public function check() 56 | { 57 | Promise\each_limit( 58 | $this->getPromises(), 59 | $this->concurrency, 60 | [$this, 'responseHandler'], 61 | [$this, 'responseHandler'] 62 | )->wait(); 63 | 64 | return $this; 65 | } 66 | 67 | /** 68 | * Get all promises. 69 | * 70 | * @return Generator 71 | */ 72 | protected function getPromises() 73 | { 74 | foreach ($this->domains as $domain) { 75 | $uri = "https://www.google.com/a/{$domain}/ServiceLogin?https://docs.google.com/a/{$domain}"; 76 | 77 | yield $this->getHttpClient()->requestAsync('GET', $uri); 78 | } 79 | } 80 | 81 | /** 82 | * Get HTTP Client. 83 | * 84 | * @return Client 85 | */ 86 | protected function getHttpClient() 87 | { 88 | if (null === $this->httpClient) { 89 | $this->httpClient = new Client([ 90 | 'connect_timeout' => $this->connectTimeout, 91 | 'headers' => [ 92 | 'User-Agent' => $this->defaultUA(), 93 | ], 94 | ]); 95 | } 96 | 97 | return $this->httpClient; 98 | } 99 | 100 | /** 101 | * Default User Agent. 102 | * 103 | * @return string 104 | */ 105 | protected function defaultUA() 106 | { 107 | return 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36'; 108 | } 109 | 110 | /** 111 | * Get all of the domains. 112 | * 113 | * @return array 114 | */ 115 | public function all() 116 | { 117 | return $this->domains; 118 | } 119 | 120 | /** 121 | * Handle Response and Update Status of Domains. 122 | * 123 | * @param ResponseInterface|RequestException $response 124 | * @param $index 125 | */ 126 | public function responseHandler($response, $index) 127 | { 128 | /** @var string $domain Get the domain */ 129 | $domain = $this->domains[$index]; 130 | 131 | /* Remove it from the list */ 132 | unset($this->domains[$index]); 133 | 134 | /** @var $status Gsuite status of the domain */ 135 | $status = $this->status($response); 136 | 137 | /* Put the domain and status to the list */ 138 | $this->domains[$domain] = $status; 139 | } 140 | 141 | /** 142 | * Determine status of GSuite based on response body. 143 | * 144 | * @param ResponseInterface|RequestException $response 145 | * 146 | * @return int 147 | */ 148 | protected function status($response) 149 | { 150 | if ($response instanceof RequestException) { 151 | return -1; 152 | } 153 | 154 | return $this->strContains($response->getBody(), 'Server error') ? 0 : 1; 155 | } 156 | 157 | /** 158 | * Determine if a given string contains a given substring. 159 | * 160 | * @param string $haystack 161 | * @param string|array $needles 162 | * 163 | * @return bool 164 | */ 165 | protected function strContains($haystack, $needles) 166 | { 167 | foreach ((array) $needles as $needle) { 168 | if ($needle != '' && mb_strpos($haystack, $needle) !== false) { 169 | return true; 170 | } 171 | } 172 | 173 | return false; 174 | } 175 | } 176 | --------------------------------------------------------------------------------