diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..cd8eb86 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +; This file is for unifying the coding style for different editors and IDEs. +; More information at http://editorconfig.org + +root = true + +[*] +charset = utf-8 +indent_size = 4 +indent_style = space +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..a4c4fed --- /dev/null +++ b/.gitattributes @@ -0,0 +1,12 @@ +# Path-based git attributes +# https://www.kernel.org/pub/software/scm/git/docs/gitattributes.html + +# Ignore all test and documentation with "export-ignore". +/.github export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +/.travis.yml export-ignore +/phpunit.xml.dist export-ignore +/.scrutinizer.yml export-ignore +/tests export-ignore +/docs export-ignore diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 0000000..26fb7b7 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,32 @@ +# Contributing + +Contributions are **welcome** and will be fully **credited**. + +We accept contributions via Pull Requests on [Github](https://github.com/:vendor/:package_name). + + +## Pull Requests + +- **[PSR-2 Coding Standard](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)** - Check the code style with ``$ composer check-style`` and fix it with ``$ composer fix-style``. + +- **Add tests!** - Your patch won't be accepted if it doesn't have tests. + +- **Document any change in behaviour** - Make sure the `README.md` and any other relevant documentation are kept up-to-date. + +- **Consider our release cycle** - We try to follow [SemVer v2.0.0](http://semver.org/). Randomly breaking public APIs is not an option. + +- **Create feature branches** - Don't ask us to pull from your master branch. + +- **One pull request per feature** - If you want to do more than one thing, send multiple pull requests. + +- **Send coherent history** - Make sure each individual commit in your pull request is meaningful. If you had to make multiple intermediate commits while developing, please [squash them](http://www.git-scm.com/book/en/v2/Git-Tools-Rewriting-History#Changing-Multiple-Commit-Messages) before submitting. + + +## Running Tests + +``` bash +$ composer test +``` + + +**Happy coding**! \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 0000000..cf35057 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -0,0 +1,49 @@ + + +Please prefix your issue with one of the following: **[BUG]** **[PROPOSAL]** **[QUESTION]**. + +## Detailed description + +Provide a detailed description of the change or addition you are proposing. + +Make it clear if the issue is a bug, an enhancement or just a question. + +## Context + +Why is this change important to you? How would you use it? + +How can it benefit other users? + +## Possible implementation + +Not obligatory, but suggest an idea for implementing addition or change. + +## Your environment + +Include as many relevant details about the environment you experienced the bug in and how to reproduce it. + +* Version used (e.g. PHP 5.6, HHVM 3): +* Operating system and version (e.g. Ubuntu 16.04, Windows 7): +* Link to your project: +* ... +* ... + + +**In raising this issue, I confirm the following (please check boxes):** + +- [ ] I have read and understood the [contributors guide](CONTRIBUTING.md). +- [ ] I have checked that the bug-fix I am reporting can be replicated, or that the feature I am suggesting isn't already present. +- [ ] I have checked the pull requests tab for existing solutions/implementations to my issue/suggestion. + +**My familiarity with the project is as follows (check one):** + +- [ ] I have never used the project. +- [ ] I have used the project briefly. +- [ ] I have used the project extensively, but have not contributed previously. +- [ ] I am an active contributor to the project. + +**Other details required** + +--- + +{issue content here} diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..4f181d6 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,43 @@ + + +## Description + +Describe your changes in detail. + +## Motivation and context + +Why is this change required? What problem does it solve? + +If it fixes an open issue, please link to the issue here (if you write `fixes #num` +or `closes #num`, the issue will be automatically closed when the pull is accepted.) + +## How has this been tested? + +Please describe in detail how you tested your changes. + +Include details of your testing environment, and the tests you ran to +see how your change affects other areas of the code, etc. + +## Screenshots (if appropriate) + +## Types of changes + +What types of changes does your code introduce? Put an `x` in all the boxes that apply: +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to change) + +## Checklist: + +Go over all the following points, and put an `x` in all the boxes that apply. + +Please, please, please, don't send your pull request until all of the boxes are ticked. Once your pull request is created, it will trigger a build on our [continuous integration](http://www.phptherightway.com/#continuous-integration) server to make sure your [tests and code style pass](https://help.github.com/articles/about-required-status-checks/). + +- [ ] I have read the **[CONTRIBUTING](CONTRIBUTING.md)** document. +- [ ] My pull request addresses exactly one patch/feature. +- [ ] I have created a branch for this patch/feature. +- [ ] Each individual commit in the pull request is meaningful. +- [ ] I have added tests to cover my changes. +- [ ] If my change requires a change to the documentation, I have updated it accordingly. + +If you're unsure about any of these, don't hesitate to ask. We're here to help! \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..073e37a --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +build +composer.lock +vendor diff --git a/.scrutinizer.yml b/.scrutinizer.yml new file mode 100644 index 0000000..aea6609 --- /dev/null +++ b/.scrutinizer.yml @@ -0,0 +1,23 @@ +filter: + excluded_paths: [tests/*] + +checks: + php: + remove_extra_empty_lines: true + remove_php_closing_tag: true + remove_trailing_whitespace: true + fix_use_statements: + remove_unused: true + preserve_multiple: false + preserve_blanklines: true + order_alphabetically: true + fix_php_opening_tag: true + fix_linefeed: true + fix_line_ending: true + fix_identation_4spaces: true + fix_doc_comments: true + +tools: + external_code_coverage: + timeout: 600 + runs: 3 diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..47bd662 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,36 @@ +language: php + +php: + - 5.6 + - 7.0 + - 7.1 + - hhvm + +# This triggers builds to run on the new TravisCI infrastructure. +# See: http://docs.travis-ci.com/user/workers/container-based-infrastructure/ +sudo: false + +## Cache composer +cache: + directories: + - $HOME/.composer/cache + +matrix: + include: + - php: 5.6 + env: 'COMPOSER_FLAGS="--prefer-stable --prefer-lowest"' + +before_script: + - travis_retry composer self-update + - travis_retry composer update ${COMPOSER_FLAGS} --no-interaction --prefer-dist + +script: + - vendor/bin/phpcs --standard=psr2 src/ + - vendor/bin/phpunit --coverage-text --coverage-clover=coverage.clover + +after_script: + - | + if [[ "$TRAVIS_PHP_VERSION" != 'hhvm' && "$TRAVIS_PHP_VERSION" != '7.0' ]]; then + wget https://scrutinizer-ci.com/ocular.phar + php ocular.phar code-coverage:upload --format=php-clover coverage.clover + fi \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..ce5ce6e --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,5 @@ +# Changelog + +All Notable changes to `gsuite-checker` will be documented in this file. + +Updates should follow the [Keep a CHANGELOG](http://keepachangelog.com/) principles. diff --git a/CONDUCT.md b/CONDUCT.md new file mode 100644 index 0000000..1ff6862 --- /dev/null +++ b/CONDUCT.md @@ -0,0 +1,74 @@ +# Contributor Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as +contributors and maintainers pledge to making participation in our project and +our community a harassment-free experience for everyone, regardless of age, body +size, disability, ethnicity, gender identity and expression, level of experience, +nationality, personal appearance, race, religion, or sexual identity and +orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment +include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or +advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic + address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable +behavior and are expected to take appropriate and fair corrective action in +response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or +reject comments, commits, code, wiki edits, issues, and other contributions +that are not aligned to this Code of Conduct, or to ban temporarily or +permanently any contributor for other behaviors that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces +when an individual is representing the project or its community. Examples of +representing a project or community include using an official project e-mail +address, posting via an official social media account, or acting as an appointed +representative at an online or offline event. Representation of a project may be +further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by contacting the project team at `syed at lukonet.com`. All +complaints will be reviewed and investigated and will result in a response that +is deemed necessary and appropriate to the circumstances. The project team is +obligated to maintain confidentiality with regard to the reporter of an incident. +Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good +faith may face temporary or permanent repercussions as determined by other +members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, +available at [http://contributor-covenant.org/version/1/4][version] + +[homepage]: http://contributor-covenant.org +[version]: http://contributor-covenant.org/version/1/4/ \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..3d43028 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +# The MIT License (MIT) + +Copyright (c) 2017 Syed Irfaq R. + +> Permission is hereby granted, free of charge, to any person obtaining a copy +> of this software and associated documentation files (the "Software"), to deal +> in the Software without restriction, including without limitation the rights +> to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +> copies of the Software, and to permit persons to whom the Software is +> furnished to do so, subject to the following conditions: +> +> The above copyright notice and this permission notice shall be included in +> all copies or substantial portions of the Software. +> +> THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +> IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +> FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +> AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +> LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +> OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +> THE SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..ae8ac76 --- /dev/null +++ b/README.md @@ -0,0 +1,77 @@ +# GSuite Checker + +[![Join the PHP Chat community][ico-phpchat]][link-phpchat] +[![Latest Version on Packagist][ico-version]][link-packagist] +[![Software License][ico-license]](LICENSE.md) +[![Build Status][ico-travis]][link-travis] +[![Coverage Status][ico-scrutinizer]][link-scrutinizer] +[![Quality Score][ico-code-quality]][link-code-quality] +[![Total Downloads][ico-downloads]][link-downloads] + +> Google Suite AKA GSuite (Formerly known as Google Apps) Checker for Domains. It lets you determine if a domain has an active GSuite Account. + +> The checker can check up to **25** domains simultaneously in a pool of requests. + +## Install + +Via Composer + +``` bash +$ composer require irazasyed/gsuite-checker +``` + +## Usage + +``` php +$domains = ['test.com', 'domain.com', 'example.com']; + +$gsuite = Irazasyed\GsuiteChecker::make($domains)->check(); + +$result = $gsuite->all(); +``` + +The result is an array of domain => status. + +There are 3 status codes: + +- **-1** - The request was rejected due to whatever issues and should be retried. +- **0** - There is no GSuite Account associated with the domain. +- **1** - There is a GSuite Account associated with the domain. + +## Change log + +Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. + +## Contributing + +Please see [CONTRIBUTING](.github/CONTRIBUTING.md) and [CONDUCT](CONDUCT.md) for details. + +## Security + +If you discover any security related issues, please email syed at lukonet.com instead of using the issue tracker. + +## Credits + +- [Syed Irfaq R.][link-author] +- [All Contributors][link-contributors] + +## License + +The MIT License (MIT). Please see [License File](LICENSE.md) for more information. + +[ico-phpchat]: https://img.shields.io/badge/Join-PHP%20Chat-blue.svg?style=flat-square +[ico-version]: https://img.shields.io/packagist/v/irazasyed/gsuite-checker.svg?style=flat-square +[ico-license]: https://img.shields.io/badge/license-MIT-brightgreen.svg?style=flat-square +[ico-travis]: https://img.shields.io/travis/irazasyed/gsuite-checker/master.svg?style=flat-square +[ico-scrutinizer]: https://img.shields.io/scrutinizer/coverage/g/irazasyed/gsuite-checker.svg?style=flat-square +[ico-code-quality]: https://img.shields.io/scrutinizer/g/irazasyed/gsuite-checker.svg?style=flat-square +[ico-downloads]: https://img.shields.io/packagist/dt/irazasyed/gsuite-checker.svg?style=flat-square + +[link-phpchat]: https://phpchat.co/?ref=gsuite-checker +[link-packagist]: https://packagist.org/packages/irazasyed/gsuite-checker +[link-travis]: https://travis-ci.org/irazasyed/gsuite-checker +[link-scrutinizer]: https://scrutinizer-ci.com/g/irazasyed/gsuite-checker/code-structure +[link-code-quality]: https://scrutinizer-ci.com/g/irazasyed/gsuite-checker +[link-downloads]: https://packagist.org/packages/irazasyed/gsuite-checker +[link-author]: https://github.com/irazasyed +[link-contributors]: ../../contributors diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..23f87d4 --- /dev/null +++ b/composer.json @@ -0,0 +1,56 @@ +{ + "name": "irazasyed/gsuite-checker", + "type": "library", + "description": "Google Suite (GSuite) formerly known as Google Apps Multi-Domains Checker.", + "keywords": [ + "irazasyed", + "gsuite-checker", + "laravel gsuite-checker", + "laravel", + "google suite", + "google apps", + "google apps checker", + "google suite checker", + "gsuite checker" + ], + "homepage": "https://github.com/irazasyed/gsuite-checker", + "license": "MIT", + "authors": [ + { + "name": "Syed Irfaq R.", + "homepage": "https://github.com/irazasyed", + "role": "Developer" + } + ], + "require": { + "php" : "~5.6||~7.0", + "guzzlehttp/guzzle": "^6.2" + }, + "require-dev": { + "phpunit/phpunit" : "~4.0||~5.0", + "squizlabs/php_codesniffer": "^2.3" + }, + "autoload": { + "psr-4": { + "Irazasyed\\GsuiteChecker\\": "src" + } + }, + "autoload-dev": { + "psr-4": { + "Irazasyed\\GsuiteChecker\\": "tests" + } + }, + "scripts": { + "test": "phpunit", + "check-style": "phpcs -p --standard=PSR2 --runtime-set ignore_errors_on_exit 1 --runtime-set ignore_warnings_on_exit 1 src tests", + "fix-style": "phpcbf -p --standard=PSR2 --runtime-set ignore_errors_on_exit 1 --runtime-set ignore_warnings_on_exit 1 src tests" + }, + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "config": { + "sort-packages": true + } +} diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..fabbf3e --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,29 @@ + + + + + tests + + + + + src/ + + + + + + + + + + diff --git a/src/GsuiteChecker.php b/src/GsuiteChecker.php new file mode 100644 index 0000000..653d4cc --- /dev/null +++ b/src/GsuiteChecker.php @@ -0,0 +1,175 @@ +domains = (array)$domains; + } + + /** + * Create a new instance if the value isn't one already. + * + * @param mixed $domains + * + * @return static + */ + public static function make($domains = []) + { + return new static($domains); + } + + /** + * Check whether the domain(s) have a Google Suite account associated with them. + * + * @return $this + */ + public function check() + { + Promise\each_limit( + $this->getPromises(), + $this->concurrency, + [$this, 'responseHandler'], + [$this, 'responseHandler'] + )->wait(); + + return $this; + } + + /** + * Get all promises. + * + * @return Generator + */ + protected function getPromises() + { + foreach ($this->domains as $domain) { + $uri = "https://www.google.com/a/{$domain}/ServiceLogin?https://docs.google.com/a/{$domain}"; + + yield $this->getHttpClient()->requestAsync('GET', $uri); + } + } + + /** + * Get HTTP Client. + * + * @return Client + */ + protected function getHttpClient() + { + if (null === $this->httpClient) { + $this->httpClient = new Client([ + 'connect_timeout' => $this->connectTimeout, + 'headers' => [ + 'User-Agent' => $this->defaultUA(), + ], + ]); + } + + return $this->httpClient; + } + + /** + * Default User Agent. + * + * @return string + */ + protected function defaultUA() + { + 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'; + } + + /** + * Get all of the domains. + * + * @return array + */ + public function all() + { + return $this->domains; + } + + /** + * Handle Response and Update Status of Domains. + * + * @param ResponseInterface|RequestException $response + * @param $index + */ + public function responseHandler($response, $index) + { + /** @var string $domain Get the domain */ + $domain = $this->domains[$index]; + + /** Remove it from the list */ + unset($this->domains[$index]); + + /** @var $status Gsuite status of the domain */ + $status = $this->status($response); + + /** Put the domain and status to the list */ + $this->domains[$domain] = $status; + } + + /** + * Determine status of GSuite based on response body. + * + * @param ResponseInterface|RequestException $response + * + * @return int + */ + protected function status($response) + { + if ($response instanceof RequestException) { + return -1; + } + + return $this->strContains($response->getBody(), 'Server error') ? 0 : 1; + } + + /** + * Determine if a given string contains a given substring. + * + * @param string $haystack + * @param string|array $needles + * + * @return bool + */ + protected function strContains($haystack, $needles) + { + foreach ((array)$needles as $needle) { + if ($needle != '' && mb_strpos($haystack, $needle) !== false) { + return true; + } + } + + return false; + } +} diff --git a/tests/ExampleTest.php b/tests/ExampleTest.php new file mode 100644 index 0000000..4d09765 --- /dev/null +++ b/tests/ExampleTest.php @@ -0,0 +1,14 @@ +assertTrue(true); + } +}