Test
This commit is contained in:
parent
327aa77e08
commit
5e949d93f8
46 changed files with 1705 additions and 68 deletions
2
.idea/.gitignore
vendored
Normal file
2
.idea/.gitignore
vendored
Normal file
|
@ -0,0 +1,2 @@
|
|||
# Default ignored files
|
||||
/workspace.xml
|
6
.idea/misc.xml
Normal file
6
.idea/misc.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JavaScriptSettings">
|
||||
<option name="languageLevel" value="ES6" />
|
||||
</component>
|
||||
</project>
|
8
.idea/modules.xml
Normal file
8
.idea/modules.xml
Normal file
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/vpn.keks.cloud.iml" filepath="$PROJECT_DIR$/.idea/vpn.keks.cloud.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
118
.idea/php.xml
Normal file
118
.idea/php.xml
Normal file
|
@ -0,0 +1,118 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="PhpIncludePathManager">
|
||||
<include_path>
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/php-invoker" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/php-file-iterator" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/php-text-template" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/php-timer" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/code-unit" />
|
||||
<path value="$PROJECT_DIR$/vendor/myclabs/deep-copy" />
|
||||
<path value="$PROJECT_DIR$/vendor/guzzlehttp/psr7" />
|
||||
<path value="$PROJECT_DIR$/vendor/guzzlehttp/guzzle" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/php-code-coverage" />
|
||||
<path value="$PROJECT_DIR$/vendor/ralouphie/getallheaders" />
|
||||
<path value="$PROJECT_DIR$/vendor/guzzlehttp/promises" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/resource-operations" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/version" />
|
||||
<path value="$PROJECT_DIR$/vendor/fakerphp/faker" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/recursion-context" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/environment" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/exporter" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/object-reflector" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/cli-parser" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/object-enumerator" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/global-state" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/type" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/lines-of-code" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/comparator" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/diff" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
|
||||
<path value="$PROJECT_DIR$/vendor/sebastian/complexity" />
|
||||
<path value="$PROJECT_DIR$/vendor/hamcrest/hamcrest-php" />
|
||||
<path value="$PROJECT_DIR$/vendor/phar-io/version" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-iconv" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/http-foundation" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/deprecation-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php80" />
|
||||
<path value="$PROJECT_DIR$/vendor/phar-io/manifest" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/service-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/mime" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-mbstring" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-ctype" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/css-selector" />
|
||||
<path value="$PROJECT_DIR$/vendor/tijsverkoyen/css-to-inline-styles" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/finder" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/routing" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/http-client-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php72" />
|
||||
<path value="$PROJECT_DIR$/vendor/dragonmantank/cron-expression" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-idn" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/process" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/string" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/error-handler" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/translation" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-grapheme" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-intl-normalizer" />
|
||||
<path value="$PROJECT_DIR$/vendor/facade/flare-client-php" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/event-dispatcher-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/facade/ignition-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/console" />
|
||||
<path value="$PROJECT_DIR$/vendor/facade/ignition" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/translation-contracts" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/http-kernel" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/polyfill-php73" />
|
||||
<path value="$PROJECT_DIR$/vendor/vlucas/phpdotenv" />
|
||||
<path value="$PROJECT_DIR$/vendor/voku/portable-ascii" />
|
||||
<path value="$PROJECT_DIR$/vendor/league/flysystem" />
|
||||
<path value="$PROJECT_DIR$/vendor/league/mime-type-detection" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-docblock" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpdocumentor/reflection-common" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpdocumentor/type-resolver" />
|
||||
<path value="$PROJECT_DIR$/vendor/opis/closure" />
|
||||
<path value="$PROJECT_DIR$/vendor/nunomaduro/collision" />
|
||||
<path value="$PROJECT_DIR$/vendor/brick/math" />
|
||||
<path value="$PROJECT_DIR$/vendor/monolog/monolog" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpspec/prophecy" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/event-dispatcher" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/http-message" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/http-client" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/log" />
|
||||
<path value="$PROJECT_DIR$/vendor/asm89/stack-cors" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/simple-cache" />
|
||||
<path value="$PROJECT_DIR$/vendor/dnoegel/php-xdg-base-dir" />
|
||||
<path value="$PROJECT_DIR$/vendor/psr/container" />
|
||||
<path value="$PROJECT_DIR$/vendor/symfony/var-dumper" />
|
||||
<path value="$PROJECT_DIR$/vendor/league/commonmark" />
|
||||
<path value="$PROJECT_DIR$/vendor/egulias/email-validator" />
|
||||
<path value="$PROJECT_DIR$/vendor/nikic/php-parser" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpunit/phpunit" />
|
||||
<path value="$PROJECT_DIR$/vendor/nesbot/carbon" />
|
||||
<path value="$PROJECT_DIR$/vendor/filp/whoops" />
|
||||
<path value="$PROJECT_DIR$/vendor/theseer/tokenizer" />
|
||||
<path value="$PROJECT_DIR$/vendor/swiftmailer/swiftmailer" />
|
||||
<path value="$PROJECT_DIR$/vendor/ramsey/collection" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/lexer" />
|
||||
<path value="$PROJECT_DIR$/vendor/ramsey/uuid" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/inflector" />
|
||||
<path value="$PROJECT_DIR$/vendor/doctrine/instantiator" />
|
||||
<path value="$PROJECT_DIR$/vendor/psy/psysh" />
|
||||
<path value="$PROJECT_DIR$/vendor/graham-campbell/result-type" />
|
||||
<path value="$PROJECT_DIR$/vendor/laravel/framework" />
|
||||
<path value="$PROJECT_DIR$/vendor/composer" />
|
||||
<path value="$PROJECT_DIR$/vendor/fideloper/proxy" />
|
||||
<path value="$PROJECT_DIR$/vendor/fruitcake/laravel-cors" />
|
||||
<path value="$PROJECT_DIR$/vendor/laravel/tinker" />
|
||||
<path value="$PROJECT_DIR$/vendor/mockery/mockery" />
|
||||
<path value="$PROJECT_DIR$/vendor/phpoption/phpoption" />
|
||||
<path value="$PROJECT_DIR$/vendor/webmozart/assert" />
|
||||
<path value="$PROJECT_DIR$/vendor/s1lentium/iptools" />
|
||||
</include_path>
|
||||
</component>
|
||||
<component name="PhpUnit">
|
||||
<phpunit_settings>
|
||||
<PhpUnitSettings configuration_file_path="$PROJECT_DIR$/phpunit.xml" custom_loader_path="$PROJECT_DIR$/vendor/autoload.php" use_configuration_file="true" />
|
||||
</phpunit_settings>
|
||||
</component>
|
||||
</project>
|
6
.idea/vcs.xml
Normal file
6
.idea/vcs.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="$PROJECT_DIR$" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
120
.idea/vpn.keks.cloud.iml
Normal file
120
.idea/vpn.keks.cloud.iml
Normal file
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="WEB_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/database/seeders" isTestSource="false" packagePrefix="Database\Seeders\" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/app" isTestSource="false" packagePrefix="App\" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" packagePrefix="Tests\" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/database/factories" isTestSource="false" packagePrefix="Database\Factories\" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/spec" isTestSource="true" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/asm89/stack-cors" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/brick/math" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/composer" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/dnoegel/php-xdg-base-dir" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/inflector" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/instantiator" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/doctrine/lexer" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/dragonmantank/cron-expression" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/egulias/email-validator" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/facade/flare-client-php" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/facade/ignition" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/facade/ignition-contracts" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/fakerphp/faker" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/fideloper/proxy" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/filp/whoops" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/fruitcake/laravel-cors" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/graham-campbell/result-type" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/guzzle" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/promises" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/guzzlehttp/psr7" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/hamcrest/hamcrest-php" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/framework" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/laravel/tinker" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/league/commonmark" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/league/flysystem" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/league/mime-type-detection" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/mockery/mockery" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/monolog/monolog" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/myclabs/deep-copy" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/nesbot/carbon" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/nikic/php-parser" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/nunomaduro/collision" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/opis/closure" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/manifest" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phar-io/version" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-common" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/reflection-docblock" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpdocumentor/type-resolver" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpoption/phpoption" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpspec/prophecy" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-code-coverage" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-file-iterator" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-invoker" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-text-template" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/php-timer" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/phpunit/phpunit" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/container" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/event-dispatcher" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-client" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/http-message" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/log" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psr/simple-cache" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/psy/psysh" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/ralouphie/getallheaders" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/ramsey/collection" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/ramsey/uuid" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/s1lentium/iptools" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/cli-parser" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/code-unit" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/code-unit-reverse-lookup" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/comparator" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/complexity" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/diff" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/environment" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/exporter" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/global-state" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/lines-of-code" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/object-enumerator" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/object-reflector" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/recursion-context" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/resource-operations" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/type" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/sebastian/version" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/swiftmailer/swiftmailer" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/console" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/css-selector" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/deprecation-contracts" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/error-handler" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/event-dispatcher-contracts" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/finder" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-client-contracts" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-foundation" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/http-kernel" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/mime" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-ctype" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-iconv" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-grapheme" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-idn" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-intl-normalizer" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-mbstring" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php72" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php73" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/polyfill-php80" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/process" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/routing" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/service-contracts" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/string" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/translation-contracts" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/symfony/var-dumper" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/theseer/tokenizer" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/tijsverkoyen/css-to-inline-styles" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/vlucas/phpdotenv" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/voku/portable-ascii" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/vendor/webmozart/assert" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
0
Dockerfile
Normal file
0
Dockerfile
Normal file
62
README.md
62
README.md
|
@ -1,61 +1,5 @@
|
|||
<p align="center"><a href="https://laravel.com" target="_blank"><img src="https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg" width="400"></a></p>
|
||||
# vpn.keks.cloud
|
||||
|
||||
<p align="center">
|
||||
<a href="https://travis-ci.org/laravel/framework"><img src="https://travis-ci.org/laravel/framework.svg" alt="Build Status"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/dt/laravel/framework" alt="Total Downloads"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/v/laravel/framework" alt="Latest Stable Version"></a>
|
||||
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/l/laravel/framework" alt="License"></a>
|
||||
</p>
|
||||
GUI to config VPN
|
||||
|
||||
## About Laravel
|
||||
|
||||
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:
|
||||
|
||||
- [Simple, fast routing engine](https://laravel.com/docs/routing).
|
||||
- [Powerful dependency injection container](https://laravel.com/docs/container).
|
||||
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
|
||||
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
|
||||
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
|
||||
- [Robust background job processing](https://laravel.com/docs/queues).
|
||||
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
|
||||
|
||||
Laravel is accessible, powerful, and provides tools required for large, robust applications.
|
||||
|
||||
## Learning Laravel
|
||||
|
||||
Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework.
|
||||
|
||||
If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains over 1500 video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library.
|
||||
|
||||
## Laravel Sponsors
|
||||
|
||||
We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the Laravel [Patreon page](https://patreon.com/taylorotwell).
|
||||
|
||||
### Premium Partners
|
||||
|
||||
- **[Vehikl](https://vehikl.com/)**
|
||||
- **[Tighten Co.](https://tighten.co)**
|
||||
- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
|
||||
- **[64 Robots](https://64robots.com)**
|
||||
- **[Cubet Techno Labs](https://cubettech.com)**
|
||||
- **[Cyber-Duck](https://cyber-duck.co.uk)**
|
||||
- **[Many](https://www.many.co.uk)**
|
||||
- **[Webdock, Fast VPS Hosting](https://www.webdock.io/en)**
|
||||
- **[DevSquad](https://devsquad.com)**
|
||||
- **[OP.GG](https://op.gg)**
|
||||
|
||||
## Contributing
|
||||
|
||||
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
|
||||
|
||||
## Code of Conduct
|
||||
|
||||
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
|
||||
|
||||
## Security Vulnerabilities
|
||||
|
||||
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
|
||||
|
||||
## License
|
||||
|
||||
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
|
||||
Used https://github.com/suquant/wgrest
|
||||
|
|
78
app/Console/Commands/ImportDevices.php
Normal file
78
app/Console/Commands/ImportDevices.php
Normal file
|
@ -0,0 +1,78 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\User;
|
||||
use App\Models\VPN;
|
||||
use App\Models\VPNAccess;
|
||||
use App\Services\WGRest;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class ImportDevices extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'wgrest:import-devices';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Get All Devices from WGREST server and add to db';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @param WGRest $wgrest
|
||||
* @return int
|
||||
*/
|
||||
public function handle(WGRest $wgrest)
|
||||
{
|
||||
$res = $wgrest->listDevices();
|
||||
|
||||
foreach($res as $network) {
|
||||
$setAdmins = false;
|
||||
$this->info("Update Device: ".$network["name"]);
|
||||
$vpn = VPN::query()->where("name", "=", $network["name"])->first();
|
||||
if(is_null($vpn)) {
|
||||
$this->info("Create New Device: ".$network["name"]);
|
||||
$vpn = new VPN();
|
||||
$vpn->displayName = $network["name"];
|
||||
$setAdmins = true;
|
||||
}
|
||||
|
||||
$vpn->name = $network["name"];
|
||||
$vpn->listen_port = $network["listen_port"];
|
||||
$vpn->network = $network["network"];
|
||||
$vpn->private_key = $network["private_key"];
|
||||
$vpn->public_key = $network["public_key"];
|
||||
$vpn->saveOrFail();
|
||||
|
||||
if($setAdmins) {
|
||||
$admins = User::findAdmins();
|
||||
foreach($admins as $admin) {
|
||||
$access = new VPNAccess();
|
||||
$access->user_id = $admin->id;
|
||||
$access->vpn_id = $vpn->id;
|
||||
$access->status = "Admin";
|
||||
$access->saveOrFail();
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
84
app/Console/Commands/ImportPeers.php
Normal file
84
app/Console/Commands/ImportPeers.php
Normal file
|
@ -0,0 +1,84 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands;
|
||||
|
||||
use App\Models\Peer;
|
||||
use App\Models\User;
|
||||
use App\Models\VPN;
|
||||
use App\Models\VPNAccess;
|
||||
use App\Services\WGRest;
|
||||
use Illuminate\Console\Command;
|
||||
use IPTools\Network;
|
||||
|
||||
class ImportPeers extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'wgrest:import-peers';
|
||||
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = 'Get All Peers for all Devices';
|
||||
|
||||
/**
|
||||
* Create a new command instance.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @param WGRest $wgrest
|
||||
* @return int
|
||||
*/
|
||||
public function handle(WGRest $wgrest)
|
||||
{
|
||||
$vpns = VPN::query()->get();
|
||||
foreach ($vpns as $vpn) {
|
||||
$internalPeers = Peer::query()->where("vpn_id", "=", $vpn->id)->get();
|
||||
$this->info("Import for ".$vpn->name);
|
||||
$knownpeers=[];
|
||||
foreach ($internalPeers as $p) {
|
||||
$knownpeers[] = $p->public_key;
|
||||
}
|
||||
|
||||
$peers = $wgrest->getPeers($vpn->name);
|
||||
foreach ($peers as $peer) {
|
||||
if(!in_array($peer["public_key"], $knownpeers)) {
|
||||
$this->info("Import ".$peer["public_key"]);
|
||||
$peerToSave = new Peer();
|
||||
$peerToSave->name = "import";
|
||||
$peerToSave->public_key = $peer["public_key"];
|
||||
$peerToSave->allowed_ips = implode(",", $peer["allowed_ips"]);
|
||||
if(isset($peer["preshared_key"])) {
|
||||
$peerToSave->preshared_key = $peer["preshared_key"];
|
||||
}
|
||||
|
||||
if(count($peer["allowed_ips"]) == 1) {
|
||||
$n = Network::parse($peer["allowed_ips"][0]);
|
||||
if((string)$n->getNetmask()=="255.255.255.255") {
|
||||
$peerToSave->ip = (string)$n->getIP();
|
||||
$peerToSave->allowed_ips = null;
|
||||
}
|
||||
}
|
||||
|
||||
$peerToSave->imported = true;
|
||||
$peerToSave->vpn_id = $vpn->id;
|
||||
$peerToSave->saveOrFail();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace App\Console;
|
||||
|
||||
use App\Console\Commands\ImportDevices;
|
||||
use App\Console\Commands\ImportPeers;
|
||||
use Illuminate\Console\Scheduling\Schedule;
|
||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||
|
||||
|
@ -13,7 +15,8 @@ class Kernel extends ConsoleKernel
|
|||
* @var array
|
||||
*/
|
||||
protected $commands = [
|
||||
//
|
||||
ImportDevices::class,
|
||||
ImportPeers::class
|
||||
];
|
||||
|
||||
/**
|
||||
|
|
17
app/Helper/WGKey.php
Normal file
17
app/Helper/WGKey.php
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
namespace App\Helper;
|
||||
|
||||
class WGKey
|
||||
{
|
||||
static public function generatePrivateKeyForPeer() {
|
||||
$folder = sys_get_temp_dir()."/".uniqid("wg-");
|
||||
mkdir($folder);
|
||||
exec("cd ".$folder."; wg genkey > privkey; cat privkey | wg pubkey > pubkey; wg genpsk > presharedkey");
|
||||
|
||||
$keys = [];
|
||||
$keys["public"] = trim(file_get_contents($folder."/pubkey"));
|
||||
$keys["privkey"] = trim(file_get_contents($folder."/privkey"));
|
||||
$keys["presharedkey"] = trim(file_get_contents($folder."/presharedkey"));
|
||||
return $keys;
|
||||
}
|
||||
}
|
17
app/Http/Controllers/DashboardController.php
Normal file
17
app/Http/Controllers/DashboardController.php
Normal file
|
@ -0,0 +1,17 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
|
||||
class DashboardController extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
|
||||
public function dashboardView() {
|
||||
return view("dashboard.dashboard");
|
||||
}
|
||||
}
|
113
app/Http/Controllers/PeerController.php
Normal file
113
app/Http/Controllers/PeerController.php
Normal file
|
@ -0,0 +1,113 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Helper\WGKey;
|
||||
use App\Models\Peer;
|
||||
use App\Models\VPN;
|
||||
use App\Services\WGRest;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use IPTools\IP;
|
||||
use IPTools\Network;
|
||||
|
||||
class PeerController extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
|
||||
public function overview() {
|
||||
$user = Auth::user();
|
||||
$vpn_id = session()->get("current_vpn");
|
||||
$peers1 = Peer::query()->where("vpn_id", "=", $vpn_id)->where("user_id", "!=", $user->id)->get();
|
||||
$peers2 = Peer::query()->where("vpn_id", "=", $vpn_id)->whereNull("user_id")->get();
|
||||
$peers = [];
|
||||
foreach ($peers1 as $p){
|
||||
$peers[] = $p;
|
||||
}
|
||||
foreach ($peers2 as $p) {
|
||||
$peers[] = $p;
|
||||
}
|
||||
$mypeers = Peer::query()->where("vpn_id", "=", $vpn_id)->where("user_id", "=", $user->id)->get();
|
||||
return view("peer.overview",["peers" => $peers, "mypeers" => $mypeers]);
|
||||
}
|
||||
|
||||
public function newView() {
|
||||
|
||||
return view("peer.new");
|
||||
}
|
||||
|
||||
public function new(Request $request) {
|
||||
$vpn_id = session()->get("current_vpn");
|
||||
$vpn = VPN::query()->where("id", "=", $vpn_id)->firstOrFail();
|
||||
|
||||
$peer = new Peer();
|
||||
$peer->name = $request->input("name");
|
||||
$peer->user_id = Auth::user()->id;
|
||||
$peer->vpn_id = $vpn_id;
|
||||
|
||||
//Calculate IP
|
||||
$nework = Network::parse($vpn->network);
|
||||
$peers = Peer::query()->where("vpn_id", "=", $vpn->id)->get();
|
||||
$usedIPs = [];
|
||||
foreach ($peers as $p) {
|
||||
$usedIPs[] = $p->ip;
|
||||
}
|
||||
$first = true;
|
||||
foreach ($nework as $ip) {
|
||||
if($first) {
|
||||
$first = false;
|
||||
continue;
|
||||
}
|
||||
if(in_array($ip, $usedIPs)) {
|
||||
continue;
|
||||
}
|
||||
$peer->ip = (string)$ip;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Generate Key
|
||||
if($request->input("genKeys")) {
|
||||
$keys = WGKey::generatePrivateKeyForPeer();
|
||||
$peer->public_key = $keys["privkey"];
|
||||
$peer->preshared_key = $keys["presharedkey"];
|
||||
} else {
|
||||
$peer->public_key = $request->input("public_key");
|
||||
$peer->preshared_key = $request->input("preshared_key");
|
||||
}
|
||||
|
||||
$peer->saveOrFail();
|
||||
if($request->input("genKeys")) {
|
||||
return view("peer.install", ["keys" => $keys, "peer" => $peer]);
|
||||
}
|
||||
}
|
||||
|
||||
public function syncPeers(WGRest $WGRest) {
|
||||
$vpn_id = session()->get("current_vpn");
|
||||
$this->syncPeersNow($vpn_id, $WGRest);
|
||||
return redirect("/vpn?id=".$vpn_id);
|
||||
}
|
||||
|
||||
private function syncPeersNow($vpnId, WGRest $WGRest) {
|
||||
$vpn = VPN::query()->where("id", "=", $vpnId)->firstOrFail();
|
||||
$peers = Peer::query()->where("vpn_id", "=", $vpn->id)->get();
|
||||
|
||||
$validePublicKeys = [];
|
||||
foreach ($peers as $peer) {
|
||||
$WGRest->createPeer($vpn->name, $peer->public_key, $peer->preshared_key, [$peer->ip."/32"]);
|
||||
$validePublicKeys[] = $peer->public_key;
|
||||
}
|
||||
|
||||
$wgPeers = $WGRest->getPeers($vpn->name);
|
||||
foreach ($wgPeers as $peer) {
|
||||
if(!in_array($peer["public_key"], $validePublicKeys)) {
|
||||
$WGRest->deletePeer($vpn->name, $peer["peer_id"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
68
app/Http/Controllers/PublicController.php
Normal file
68
app/Http/Controllers/PublicController.php
Normal file
|
@ -0,0 +1,68 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Privilege;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class PublicController extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
|
||||
public function loginView() {
|
||||
if(Auth::check()) {
|
||||
return redirect("/dashboard");
|
||||
}
|
||||
return view("public.login");
|
||||
}
|
||||
|
||||
public function registerView(Request $request) {
|
||||
return view("public.register");
|
||||
}
|
||||
|
||||
public function register(Request $request) {
|
||||
$validatedData = $request->validate([
|
||||
'email' => ['required', 'email:rfc,dns'],
|
||||
'password' => ['required'],
|
||||
'password2' => ['required', 'same:password']
|
||||
]);
|
||||
|
||||
//How Many user already exists, check to make the first user admin
|
||||
$userCount = User::query()->count('id');
|
||||
|
||||
$user = new User();
|
||||
$user->email = $validatedData["email"];
|
||||
$user->password = Hash::make($validatedData["password"]);
|
||||
$user->saveOrFail();
|
||||
|
||||
$privilege = new Privilege();
|
||||
$privilege->user_id = $user->id;
|
||||
if($userCount == 0) {
|
||||
$privilege->admin = true;
|
||||
$privilege->createVPN = true;
|
||||
}
|
||||
$privilege->saveOrFail();
|
||||
|
||||
return redirect("/login");
|
||||
}
|
||||
|
||||
public function login(Request $request) {
|
||||
$validatedData = $request->validate([
|
||||
'email' => ['required', 'email:rfc'],
|
||||
'password' => ['required']
|
||||
]);
|
||||
|
||||
if(Auth::attempt($validatedData)) {
|
||||
return redirect("/dashboard");
|
||||
}
|
||||
|
||||
return view("public.login", ["msg"=> "Login failed"]);
|
||||
}
|
||||
}
|
58
app/Http/Controllers/UsersController.php
Normal file
58
app/Http/Controllers/UsersController.php
Normal file
|
@ -0,0 +1,58 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Privilege;
|
||||
use App\Models\User;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class UsersController extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
|
||||
public function overview() {
|
||||
$user = Auth::user();
|
||||
if(!$user->hasPrivilege("admin")) {
|
||||
return response('Unauthenticated.', 401);
|
||||
}
|
||||
|
||||
$users = User::query()->get();
|
||||
|
||||
return view("users.overview", ["users" => $users]);
|
||||
}
|
||||
|
||||
public function updateUser(Request $request) {
|
||||
$user = Auth::user();
|
||||
if(!$user->hasPrivilege("admin")) {
|
||||
return response('Unauthenticated.', 401);
|
||||
}
|
||||
|
||||
$validatedData = $request->validate([
|
||||
'id' => ['required', 'integer'],
|
||||
'createVPN' => ['boolean'],
|
||||
'admin' => ['boolean']
|
||||
]);
|
||||
|
||||
$p = Privilege::query()->where("user_id", "=", $validatedData["id"])->first();
|
||||
|
||||
if(isset($validatedData["createVPN"]) && $validatedData["createVPN"]) {
|
||||
$p->createVPN = true;
|
||||
} else {
|
||||
$p->createVPN = false;
|
||||
}
|
||||
|
||||
if(isset($validatedData["admin"]) && $validatedData["admin"]) {
|
||||
$p->admin = true;
|
||||
} else {
|
||||
$p->admin = false;
|
||||
}
|
||||
|
||||
$p->saveOrFail();
|
||||
return redirect("/users");
|
||||
}
|
||||
}
|
77
app/Http/Controllers/VPNController.php
Normal file
77
app/Http/Controllers/VPNController.php
Normal file
|
@ -0,0 +1,77 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\Peer;
|
||||
use App\Models\User;
|
||||
use App\Models\VPN;
|
||||
use App\Services\WGRest;
|
||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Routing\Controller as BaseController;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use IPTools\Network;
|
||||
|
||||
class VPNController extends BaseController
|
||||
{
|
||||
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
|
||||
|
||||
public function overview(Request $request) {
|
||||
$id = $request->input("id");
|
||||
$vpn = VPN::query()->where("id", "=", $id)->first();
|
||||
session()->put("current_vpn", $vpn->id);
|
||||
View::share("currentVPNName", $vpn->name);
|
||||
|
||||
//Calculate Free IPS
|
||||
$network = Network::parse($vpn->network);
|
||||
$usedIPs = Peer::query()->where("vpn_id", "=", $vpn->id)->count();
|
||||
|
||||
$percent = (100 / $network->count()) * $usedIPs ;
|
||||
|
||||
return view("vpn.overview", ["currentVPN"=>$vpn, "percent" => $percent ]);
|
||||
}
|
||||
|
||||
public function accessView() {
|
||||
$vpn_id = session()->get("current_vpn");
|
||||
$users = User::query()->get();
|
||||
return view("vpn.access", ["users" => $users, "vpn_id" => $vpn_id]);
|
||||
}
|
||||
|
||||
public function setAccess(Request $request) {
|
||||
$vpn_id = session()->get("current_vpn");
|
||||
$user = User::query()->where("id", "=", $request->input("id"))->firstOrFail();
|
||||
$user->setVPNRole($vpn_id, $request->input("access"));
|
||||
|
||||
return redirect("/vpn/access");
|
||||
}
|
||||
|
||||
public function newView() {
|
||||
return view("vpn.new");
|
||||
}
|
||||
|
||||
public function new(Request $request) {
|
||||
$vpn = new VPN();
|
||||
$vpn->name = $request->input("name");
|
||||
$vpn->displayName = $request->input("display_name");
|
||||
$vpn->listen_port = $request->input("port");
|
||||
$vpn->network = $request->input("network");
|
||||
|
||||
$privateKey = $request->input("private_key");
|
||||
if(empty($privateKey)) {
|
||||
$privateKey = exec('wg genkey');
|
||||
}
|
||||
$vpn->private_key = $privateKey;
|
||||
$vpn->public_key = null;
|
||||
$vpn->saveOrFail();
|
||||
}
|
||||
|
||||
public function sendToRest(WGRest $WGRest) {
|
||||
$vpn_id = session()->get("current_vpn");
|
||||
$vpn = VPN::query()->where("id", "=", $vpn_id)->firstOrFail();
|
||||
|
||||
$WGRest->createDevice($vpn->name, $vpn->listen_port, $vpn->private_key, $vpn->network);
|
||||
return redirect("/vpn?id=".$vpn->id);
|
||||
}
|
||||
}
|
24
app/Http/Middleware/AuthMiddleware.php
Normal file
24
app/Http/Middleware/AuthMiddleware.php
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class AuthMiddleware
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
if(Auth::check()) {
|
||||
return $next($request);
|
||||
}
|
||||
return redirect("/login?url=".$request->url());
|
||||
}
|
||||
}
|
47
app/Http/Middleware/GUIMiddleware.php
Normal file
47
app/Http/Middleware/GUIMiddleware.php
Normal file
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use App\Models\VPN;
|
||||
use Closure;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use \Illuminate\Support\Facades\View;
|
||||
|
||||
class GUIMiddleware
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
{
|
||||
|
||||
//Get Curretn user
|
||||
$user = Auth::user();
|
||||
View::share("user", $user);
|
||||
|
||||
//Get ALL VPNS
|
||||
$vpn = VPN::findForUser($user->id);
|
||||
View::share("vpn", $vpn);
|
||||
|
||||
//Get Selectet VPN
|
||||
$currentVPNId = session()->get("current_vpn");
|
||||
if($currentVPNId === null && count($vpn)==1) {
|
||||
session()->put("current_vpn", $vpn[0]->id);
|
||||
$currentVPNId = $vpn[0]->id;
|
||||
}
|
||||
|
||||
$currentVPN = VPN::query()->where("id", "=", $currentVPNId)->first();
|
||||
if($currentVPN != null) {
|
||||
View::share("currentVPNName", $currentVPN->name);
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
31
app/Models/Peer.php
Normal file
31
app/Models/Peer.php
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
class Peer extends Authenticatable
|
||||
{
|
||||
use HasFactory, Notifiable;
|
||||
|
||||
protected $table = "peers";
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'public_key',
|
||||
'allowed_ips',
|
||||
'preshared_key',
|
||||
'user_id',
|
||||
'vpn_id',
|
||||
'ip',
|
||||
];
|
||||
|
||||
}
|
25
app/Models/Privilege.php
Normal file
25
app/Models/Privilege.php
Normal file
|
@ -0,0 +1,25 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
class Privilege extends Authenticatable
|
||||
{
|
||||
use HasFactory, Notifiable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'admin',
|
||||
'createVPN'
|
||||
];
|
||||
|
||||
}
|
|
@ -40,4 +40,40 @@ class User extends Authenticatable
|
|||
protected $casts = [
|
||||
'email_verified_at' => 'datetime',
|
||||
];
|
||||
|
||||
public function hasPrivilege($name) {
|
||||
$p = Privilege::query()->where("user_id", "=", $this->id)->first();
|
||||
if($p->$name) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public function setVPNRole(int $vpnID, string $accessName) {
|
||||
$access = VPNAccess::query()->where("user_id", "=", $this->id)->where("vpn_id", "=", $vpnID)->first();
|
||||
if($access === null) {
|
||||
$access = new VPNAccess();
|
||||
$access->user_id = $this->id;
|
||||
$access->vpn_id = $vpnID;
|
||||
}
|
||||
$access->status = $accessName;
|
||||
$access->saveOrFail();
|
||||
}
|
||||
|
||||
public function getVPNRole(int $vpnId) {
|
||||
$access = VPNAccess::query()->where("user_id", "=", $this->id)->where("vpn_id", "=", $vpnId)->first();
|
||||
if($access === null) {
|
||||
return "None";
|
||||
}
|
||||
return $access->status;
|
||||
}
|
||||
|
||||
static public function findAdmins() {
|
||||
$admins = Privilege::query()->where("admin", "=", true)->get();
|
||||
$users = [];
|
||||
foreach($admins as $admin) {
|
||||
$users[] = User::query()->where("id", "=", $admin->user_id)->firstOrFail();
|
||||
}
|
||||
return $users;
|
||||
}
|
||||
}
|
||||
|
|
41
app/Models/VPN.php
Normal file
41
app/Models/VPN.php
Normal file
|
@ -0,0 +1,41 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
class VPN extends Authenticatable
|
||||
{
|
||||
use HasFactory, Notifiable;
|
||||
|
||||
protected $table = "vpns";
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'displayName',
|
||||
'listen_port',
|
||||
'network',
|
||||
'private_key',
|
||||
'public_key'
|
||||
];
|
||||
|
||||
static public function findForUser(int $user_id) {
|
||||
$access = VPNAccess::query()->where("user_id", "=", $user_id)->get();
|
||||
$vpns = [];
|
||||
foreach ($access as $a) {
|
||||
if($a->status != "None") {
|
||||
$vpns[] = VPN::query()->where("id", "=", $a->vpn_id)->firstOrFail();
|
||||
}
|
||||
}
|
||||
return $vpns;
|
||||
}
|
||||
|
||||
}
|
27
app/Models/VPNAccess.php
Normal file
27
app/Models/VPNAccess.php
Normal file
|
@ -0,0 +1,27 @@
|
|||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Contracts\Auth\MustVerifyEmail;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
class VPNAccess extends Authenticatable
|
||||
{
|
||||
use HasFactory, Notifiable;
|
||||
|
||||
protected $table = "vpn_access";
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'user_id',
|
||||
'vpn_id',
|
||||
'status'
|
||||
];
|
||||
|
||||
}
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Services\WGRest;
|
||||
use GuzzleHttp\Client;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
|
@ -13,7 +15,12 @@ class AppServiceProvider extends ServiceProvider
|
|||
*/
|
||||
public function register()
|
||||
{
|
||||
//
|
||||
$this->app->singleton(WGRest::class, function ($app) {
|
||||
$client = new Client(["base_uri"=>"http://home.kekskurse.de:8000/"]);
|
||||
|
||||
$wgrest = new WGRest($client, "secret");
|
||||
return $wgrest;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -23,6 +30,6 @@ class AppServiceProvider extends ServiceProvider
|
|||
*/
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
|
||||
}
|
||||
}
|
||||
|
|
56
app/Services/WGRest.php
Normal file
56
app/Services/WGRest.php
Normal file
|
@ -0,0 +1,56 @@
|
|||
<?php
|
||||
namespace App\Services;
|
||||
|
||||
use GuzzleHttp\Client;
|
||||
|
||||
class WGRest
|
||||
{
|
||||
/* @var \GuzzleHttp\Client $client */
|
||||
private $client;
|
||||
|
||||
private $token;
|
||||
|
||||
public function __construct(Client $client, string $token)
|
||||
{
|
||||
$this->client = $client;
|
||||
$this->token = $token;
|
||||
}
|
||||
|
||||
public function createDevice(string $name, int $listen_port, string $private_key, string $network) {
|
||||
$data = [];
|
||||
$data["name"] = $name;
|
||||
$data["listen_port"] = $listen_port;
|
||||
$data["private_key"] = $private_key;
|
||||
$data["network"] = $network;
|
||||
|
||||
$res = $this->client->request("POST", "/devices/", ["json" => $data, "headers" => ["Token" => $this->token]]);
|
||||
}
|
||||
|
||||
public function listDevices() {
|
||||
$res = $this->client->request("GET", "/devices/", ["headers" => ["Token" => $this->token]]);
|
||||
|
||||
return json_decode($res->getBody(), true);
|
||||
}
|
||||
|
||||
public function createPeer(string $vpn_name, string $public_key, string $preshared_key, array $allowed_ips) {
|
||||
$data = [];
|
||||
$data["public_key"] = $public_key;
|
||||
$data["allowed_ips"] = $allowed_ips;
|
||||
$data["preshared_key"] = $preshared_key;
|
||||
|
||||
$res = $this->client->request("POST", "/devices/".$vpn_name."/peers", ["json" => $data, "headers" => ["Token" => $this->token]]);
|
||||
}
|
||||
|
||||
public function getPeers(string $vpn_name) {
|
||||
$res = $this->client->request("GET", "/devices/".$vpn_name."/peers", ["headers" => ["Token" => $this->token]]);
|
||||
|
||||
return json_decode($res->getBody(), true);
|
||||
}
|
||||
|
||||
public function deletePeer(string $vpn_name, string $peer_id) {
|
||||
$res = $this->client->request("DELETE", "/devices/".$vpn_name."/peers/".$peer_id, ["headers" => ["Token" => $this->token]]);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -11,9 +11,10 @@
|
|||
"php": "^7.3|^8.0",
|
||||
"fideloper/proxy": "^4.4",
|
||||
"fruitcake/laravel-cors": "^2.0",
|
||||
"guzzlehttp/guzzle": "^7.0.1",
|
||||
"guzzlehttp/guzzle": "^7.2",
|
||||
"laravel/framework": "^8.12",
|
||||
"laravel/tinker": "^2.5"
|
||||
"laravel/tinker": "^2.5",
|
||||
"s1lentium/iptools": "^1.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"facade/ignition": "^2.5",
|
||||
|
|
53
composer.lock
generated
53
composer.lock
generated
|
@ -4,7 +4,7 @@
|
|||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "fac753ae2702317b354e7eb283f28cbc",
|
||||
"content-hash": "fc90d2119cc669b7ff0da2f60d113e6e",
|
||||
"packages": [
|
||||
{
|
||||
"name": "asm89/stack-cors",
|
||||
|
@ -2210,6 +2210,57 @@
|
|||
],
|
||||
"time": "2020-08-18T17:17:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "s1lentium/iptools",
|
||||
"version": "v1.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/S1lentium/IPTools.git",
|
||||
"reference": "f6f8ab6132ca7443bd7cced1681f5066d725fd5f"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/S1lentium/IPTools/zipball/f6f8ab6132ca7443bd7cced1681f5066d725fd5f",
|
||||
"reference": "f6f8ab6132ca7443bd7cced1681f5066d725fd5f",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-bcmath": "*",
|
||||
"php": ">=5.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "~4.0",
|
||||
"satooshi/php-coveralls": "~1.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"IPTools\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Safarov Alisher",
|
||||
"email": "alisher.safarov@outlook.com",
|
||||
"homepage": "https://github.com/S1lentium"
|
||||
}
|
||||
],
|
||||
"description": "PHP Library for manipulating network addresses (IPv4 and IPv6)",
|
||||
"keywords": [
|
||||
"IP",
|
||||
"IP-Tools",
|
||||
"cidr",
|
||||
"ipv4",
|
||||
"ipv6",
|
||||
"network",
|
||||
"subnet"
|
||||
],
|
||||
"time": "2018-09-19T06:15:53+00:00"
|
||||
},
|
||||
{
|
||||
"name": "swiftmailer/swiftmailer",
|
||||
"version": "v6.2.3",
|
||||
|
|
|
@ -15,13 +15,22 @@ class CreateUsersTable extends Migration
|
|||
{
|
||||
Schema::create('users', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('email')->unique();
|
||||
$table->timestamp('email_verified_at')->nullable();
|
||||
$table->string('password');
|
||||
$table->rememberToken();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create("privileges", function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger("user_id");
|
||||
$table->boolean("admin")->default(false);
|
||||
$table->boolean("createVPN")->default(false);
|
||||
$table->timestamps();
|
||||
|
||||
$table->foreign('user_id')->references('id')->on('users');
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
49
database/migrations/2020_11_07_163856_vpn.php
Normal file
49
database/migrations/2020_11_07_163856_vpn.php
Normal file
|
@ -0,0 +1,49 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class Vpn extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('vpns', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string("name")->comment("Device Name");
|
||||
$table->string("displayName");
|
||||
$table->string("listen_port");
|
||||
$table->string("network");
|
||||
$table->string("private_key");
|
||||
$table->string("public_key")->nullable();
|
||||
$table->timestamps();
|
||||
});
|
||||
|
||||
Schema::create("vpn_access", function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->unsignedBigInteger("user_id");
|
||||
$table->unsignedBigInteger("vpn_id");
|
||||
$table->enum("status", ["None", "User", "Admin"]);
|
||||
$table->timestamps();
|
||||
|
||||
$table->foreign('user_id')->references('id')->on('users');
|
||||
$table->foreign('vpn_id')->references('id')->on('vpns');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('vpns');
|
||||
Schema::dropIfExists('vpn_access');
|
||||
}
|
||||
}
|
43
database/migrations/2020_11_07_234319_peers.php
Normal file
43
database/migrations/2020_11_07_234319_peers.php
Normal file
|
@ -0,0 +1,43 @@
|
|||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class Peers extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('peers', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string("name");
|
||||
$table->string("public_key");
|
||||
$table->string("ip")->nullable();
|
||||
$table->string("allowed_ips")->nullable();
|
||||
$table->string("preshared_key")->nullable();
|
||||
$table->boolean("imported")->default(false);
|
||||
$table->unsignedBigInteger("user_id")->nullable();
|
||||
$table->unsignedBigInteger("vpn_id");
|
||||
$table->timestamps();
|
||||
|
||||
$table->foreign('user_id')->references('id')->on('users');
|
||||
$table->foreign('vpn_id')->references('id')->on('vpns');
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::dropIfExists('peers');
|
||||
}
|
||||
}
|
1
public/css
Symbolic link
1
public/css
Symbolic link
|
@ -0,0 +1 @@
|
|||
../resources/css
|
12
resources/css/bootstrap.min.css
vendored
Normal file
12
resources/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
14
resources/views/dashboard/dashboard.blade.php
Normal file
14
resources/views/dashboard/dashboard.blade.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<!-- Stored in resources/views/child.blade.php -->
|
||||
|
||||
@extends('layout.app')
|
||||
|
||||
@section('title', 'VPN')
|
||||
|
||||
@section('content')
|
||||
<div class="row"">
|
||||
<div class="col-md-12">
|
||||
<h1>Dashboard</h1>
|
||||
{{ $user->email }}
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
73
resources/views/layout/app.blade.php
Normal file
73
resources/views/layout/app.blade.php
Normal file
|
@ -0,0 +1,73 @@
|
|||
<!-- Stored in resources/views/layouts/app.blade.php -->
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>@yield('title')</title>
|
||||
<link rel="stylesheet" href="/css/bootstrap.min.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
<nav class="navbar navbar-expand-lg navbar-dark bg-primary" style="margin-top: 20px;">
|
||||
<a class="navbar-brand" href="/dashboard">VPN</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarColor01" aria-controls="navbarColor01" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse" id="navbarColor01">
|
||||
<ul class="navbar-nav mr-auto">
|
||||
@if($user->hasPrivilege("createVPN") || count($vpn) > 1)
|
||||
<li class="nav-item dropdown">
|
||||
<a class="nav-link dropdown-toggle" data-toggle="dropdown" href="#" role="button" aria-haspopup="true" aria-expanded="false">
|
||||
@if(isset($currentVPNName))
|
||||
{{ $currentVPNName }}
|
||||
@else
|
||||
VPN
|
||||
@endif
|
||||
</a>
|
||||
<div class="dropdown-menu">
|
||||
@foreach($vpn as $v)
|
||||
<a class="dropdown-item" href="/vpn?id={{ $v->id }}">{{ $v->name }}</a>
|
||||
@endforeach
|
||||
<div class="dropdown-divider"></div>
|
||||
<a class="dropdown-item" href="/vpn/new">New</a>
|
||||
</div>
|
||||
</li>
|
||||
@endif
|
||||
@if(isset($currentVPNName))
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/vpn/peer">Peers</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">API-Key</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/vpn/access">Access</a>
|
||||
</li>
|
||||
@endif
|
||||
|
||||
</ul>
|
||||
|
||||
</div>
|
||||
<div class="navbar-collapse">
|
||||
<ul class="navbar-nav ml-auto">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="/users">Users</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="#">Logout</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
</nav>
|
||||
|
||||
<div class="row" style="min-height: 30px;"></div>
|
||||
@yield('content')
|
||||
</div>
|
||||
</body>
|
||||
<script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script>
|
||||
@yield('script')
|
||||
</html>
|
14
resources/views/layout/public.blade.php
Normal file
14
resources/views/layout/public.blade.php
Normal file
|
@ -0,0 +1,14 @@
|
|||
<!-- Stored in resources/views/layouts/app.blade.php -->
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<title>@yield('title')</title>
|
||||
<link rel="stylesheet" href="/css/bootstrap.min.css">
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<div class="container">
|
||||
@yield('content')
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
23
resources/views/peer/install.blade.php
Normal file
23
resources/views/peer/install.blade.php
Normal file
|
@ -0,0 +1,23 @@
|
|||
<!-- Stored in resources/views/child.blade.php -->
|
||||
|
||||
@extends('layout.app')
|
||||
|
||||
@section('title', 'VPN')
|
||||
|
||||
@section('content')
|
||||
<div class="row"">
|
||||
<div class="col-md-12">
|
||||
<h1>Keys</h1>
|
||||
<p>This is your private key, save it somewhere without this key you can't connect to the VPN. You can't get this Key a secound time from this Wepage.</p>
|
||||
<input disabled class="form-control" value="{{ $keys["privkey"] }}">
|
||||
<br>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>IP</th>
|
||||
<td>{{ $peer->ip }}</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
44
resources/views/peer/new.blade.php
Normal file
44
resources/views/peer/new.blade.php
Normal file
|
@ -0,0 +1,44 @@
|
|||
<!-- Stored in resources/views/child.blade.php -->
|
||||
|
||||
@extends('layout.app')
|
||||
|
||||
@section('title', 'VPN')
|
||||
|
||||
@section('content')
|
||||
<div class="row"">
|
||||
<div class="col-md-12">
|
||||
<h1>New Peer</h1>
|
||||
<form method="post">
|
||||
@csrf
|
||||
<label>Name</label>
|
||||
<input name="name" class="form-control">
|
||||
<span id="keys">
|
||||
<label>Public Key</label>
|
||||
<input name="public_key" id="public_key" class="form-control">
|
||||
<label>Preshared Key</label>
|
||||
<input name="preshared_key" id="preshared_key" class="form-control">
|
||||
</span>
|
||||
<input style="margin-top: 15px;" type="checkbox" id="genKeys" name="genKeys"> Generate Keys at the Server <b>Very Insecure!</b>
|
||||
<br>
|
||||
<input style="margin-top: 15px;" type="submit" value="Create Peer" class="btn btn-success">
|
||||
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
||||
|
||||
@section('script')
|
||||
<script>
|
||||
$("#genKeys").change(function() {
|
||||
if($("#genKeys").prop("checked")) {
|
||||
alert("Generate the Key on the Server is not secure!")
|
||||
$("#keys").hide();
|
||||
$("#public_key").val("");
|
||||
$("#preshared_key").val("");
|
||||
} else {
|
||||
$("#keys").show();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
@endsection
|
46
resources/views/peer/overview.blade.php
Normal file
46
resources/views/peer/overview.blade.php
Normal file
|
@ -0,0 +1,46 @@
|
|||
<!-- Stored in resources/views/child.blade.php -->
|
||||
|
||||
@extends('layout.app')
|
||||
|
||||
@section('title', 'VPN')
|
||||
|
||||
@section('content')
|
||||
<div class="row"">
|
||||
<div class="col-md-12">
|
||||
<h1>My Peers</h1>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>PublicKey</th>
|
||||
<th>IPs</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
@foreach($mypeers as $peer)
|
||||
<tr>
|
||||
<td>{{ $peer->name }}</td>
|
||||
<td>{{$peer->public_key}}</td>
|
||||
<td>{{$peer->ip}}@if($peer->allowed_ips && $peer->ip), @endif{{$peer->allowed_ips}}</td>
|
||||
<td>-</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
<h1>Peers</h1>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>PublicKey</th>
|
||||
<th>IPs</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
@foreach($peers as $peer)
|
||||
<tr>
|
||||
<td>{{ $peer->name }}</td>
|
||||
<td>{{$peer->public_key}}</td>
|
||||
<td>{{$peer->ip}}@if($peer->allowed_ips && $peer->ip), @endif{{$peer->allowed_ips}}</td>
|
||||
<td>-</td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
24
resources/views/public/login.blade.php
Normal file
24
resources/views/public/login.blade.php
Normal file
|
@ -0,0 +1,24 @@
|
|||
<!-- Stored in resources/views/child.blade.php -->
|
||||
|
||||
@extends('layout.public')
|
||||
|
||||
@section('title', 'Login')
|
||||
|
||||
@section('content')
|
||||
<div class="row" style="margin-top: 20%;">
|
||||
<div class="col-md-3"></div>
|
||||
<div class="col-md-6">
|
||||
<h1>Login</h1>
|
||||
<form method="post" style="margin-top: 30px;">
|
||||
@csrf
|
||||
<label>E-Mail</label>
|
||||
<input type="email" name="email" placeholder="E-Mail" class="form-control">
|
||||
<label style="margin-top: 8px;">Password</label>
|
||||
<input type="password" name="password" placeholder="Password" class="form-control">
|
||||
<input type="submit" class="btn btn-success" style="margin-top: 15px;" value="Login">
|
||||
<a href="/register" class="btn" style="margin-top: 15px;float: right;">Register new Account</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
36
resources/views/public/register.blade.php
Normal file
36
resources/views/public/register.blade.php
Normal file
|
@ -0,0 +1,36 @@
|
|||
<!-- Stored in resources/views/child.blade.php -->
|
||||
|
||||
@extends('layout.public')
|
||||
|
||||
@section('title', 'Register')
|
||||
|
||||
@section('content')
|
||||
<div class="row" style="margin-top: 20%;">
|
||||
<div class="col-md-3"></div>
|
||||
<div class="col-md-6">
|
||||
<h1>Register</h1>
|
||||
@if ($errors->all())
|
||||
<div class="alert alert-warning" role="alert">
|
||||
<ul>
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form method="post" style="margin-top: 30px;">
|
||||
@csrf
|
||||
<label>E-Mail</label>
|
||||
<input type="email" name="email" placeholder="E-Mail" class="form-control">
|
||||
<label style="margin-top: 8px;">Password</label>
|
||||
<input type="password" name="password" placeholder="Password" class="form-control">
|
||||
<label style="margin-top: 8px;">Password Again</label>
|
||||
<input type="password" name="password2" placeholder="Password" class="form-control">
|
||||
<input type="submit" class="btn btn-success" style="margin-top: 15px;" value="Register">
|
||||
<a href="/login" class="btn" style="margin-top: 15px;float: right;">Login</a>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@endsection
|
41
resources/views/users/overview.blade.php
Normal file
41
resources/views/users/overview.blade.php
Normal file
|
@ -0,0 +1,41 @@
|
|||
<!-- Stored in resources/views/child.blade.php -->
|
||||
|
||||
@extends('layout.app')
|
||||
|
||||
@section('title', 'VPN')
|
||||
|
||||
@section('content')
|
||||
<div class="row"">
|
||||
<div class="col-md-12">
|
||||
<h1>Users</h1>
|
||||
@if ($errors->all())
|
||||
<div class="alert alert-warning" role="alert">
|
||||
<ul>
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>E-Mail</th>
|
||||
<th>Create VPN</th>
|
||||
<th>Admin</th>
|
||||
<th class="text-right">Save</th>
|
||||
</tr>
|
||||
@foreach($users as $u)
|
||||
<tr>
|
||||
<form method="post">
|
||||
@csrf
|
||||
<td>{{ $u->email }}<input name="id" style="display: none" value="{{ $u->id }}"> </td>
|
||||
<td><input type="checkbox" value="1" name="createVPN" @if($u->hasPrivilege("createVPN")) checked @endif> </td>
|
||||
<td><input type="checkbox" value="1" name="admin" @if($u->hasPrivilege("admin")) checked @endif> </td>
|
||||
<td><input type="submit" class="btn btn-primary btn-sm float-right" value="Save"> </td>
|
||||
</form>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
36
resources/views/vpn/access.blade.php
Normal file
36
resources/views/vpn/access.blade.php
Normal file
|
@ -0,0 +1,36 @@
|
|||
<!-- Stored in resources/views/child.blade.php -->
|
||||
|
||||
@extends('layout.app')
|
||||
|
||||
@section('title', 'VPN')
|
||||
|
||||
@section('content')
|
||||
<div class="row"">
|
||||
<div class="col-md-12">
|
||||
<h1>VPN Access</h1>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>Mail</th>
|
||||
<th>Access</th>
|
||||
<th class="text-right">Save</th>
|
||||
</tr>
|
||||
@foreach($users as $u)
|
||||
<tr>
|
||||
<form method="post">
|
||||
@csrf
|
||||
<td>{{$u->email}}<input style="display: none" name="id" value="{{$u->id}}"> </td>
|
||||
<td>
|
||||
<select name="access" class="form-control">
|
||||
<option @if ($u->getVPNRole($vpn_id)=="None") selected="selected" @endif >None</option>
|
||||
<option @if ($u->getVPNRole($vpn_id)=="User") selected="selected" @endif >User</option>
|
||||
<option @if ($u->getVPNRole($vpn_id)=="Admin") selected="selected" @endif >Admin</option>
|
||||
</select>
|
||||
</td>
|
||||
<td class="text-right"><input type="submit" class="btn btn-primary" value="Save"></td>
|
||||
</form>
|
||||
</tr>
|
||||
@endforeach
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
28
resources/views/vpn/new.blade.php
Normal file
28
resources/views/vpn/new.blade.php
Normal file
|
@ -0,0 +1,28 @@
|
|||
<!-- Stored in resources/views/child.blade.php -->
|
||||
|
||||
@extends('layout.app')
|
||||
|
||||
@section('title', 'VPN')
|
||||
|
||||
@section('content')
|
||||
<div class="row"">
|
||||
<div class="col-md-12">
|
||||
<h1>New VPN</h1>
|
||||
<form method="post">
|
||||
@csrf
|
||||
<label>Device Name</label>
|
||||
<input name="name" class="form-control" placeholder="wg0">
|
||||
<label>Display Name</label>
|
||||
<input name="display_name" class="form-control">
|
||||
<label>Listening Port</label>
|
||||
<input name="port" class="form-control" placeholder="51820">
|
||||
<label>Private Key</label>
|
||||
<input name="private_key" class="form-control" placeholder="Create new if empty">
|
||||
<label>Network</label>
|
||||
<input name="network" class="form-control" placeholder="10.0.1.1/24">
|
||||
<br><br>
|
||||
<input type="submit" class="btn btn-success" value="Create">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
56
resources/views/vpn/overview.blade.php
Normal file
56
resources/views/vpn/overview.blade.php
Normal file
|
@ -0,0 +1,56 @@
|
|||
<!-- Stored in resources/views/child.blade.php -->
|
||||
|
||||
@extends('layout.app')
|
||||
|
||||
@section('title', 'VPN')
|
||||
|
||||
@section('content')
|
||||
<div class="row"">
|
||||
<div class="col-md-12">
|
||||
<h1>VPN: {{ $currentVPN->displayName }}</h1>
|
||||
<h3>Usage</h3>
|
||||
Based on the Subnet there are only a limited numbers of ip which can used in this VPN.
|
||||
<div class="progress">
|
||||
<div class="progress-bar" role="progressbar" style="width: {{$percent}}%;" aria-valuenow="{{$percent}}" aria-valuemin="0" aria-valuemax="100">{{$percent}}%</div>
|
||||
</div>
|
||||
|
||||
<h3 style="margin-top: 20px;">Config</h3>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>Name/Device Name</th>
|
||||
<td><input disabled class="form-control" value="{{ $currentVPN->name }}"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Display Name</th>
|
||||
<td><input disabled class="form-control" value="{{ $currentVPN->displayName }}"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Public Key</th>
|
||||
<td><input disabled class="form-control" value="{{ $currentVPN->public_key }}"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Private Key</th>
|
||||
<td><input disabled class="form-control" value="{{ $currentVPN->private_key }}"> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Network</th>
|
||||
<td><input disabled class="form-control" value="{{ $currentVPN->network }}"> </td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<h3>Actions</h3>
|
||||
<table class="table">
|
||||
<tr>
|
||||
<th>Sync Peers</th>
|
||||
<td></td>
|
||||
<td><a href="/vpn/syncPeers" class="btn btn-primary btn-sm float-right">Run</a> </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>Create Device on Server</th>
|
||||
<td>Only needed if Wireguard Server is new</td>
|
||||
<td><a href="/vpn/sendToServer" class="btn btn-danger btn-sm float-right">Run</a> </td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
|
@ -14,5 +14,28 @@ use Illuminate\Support\Facades\Route;
|
|||
*/
|
||||
|
||||
Route::get('/', function () {
|
||||
return view('welcome');
|
||||
return redirect("/login");
|
||||
});
|
||||
|
||||
Route::get("/login", [\App\Http\Controllers\PublicController::class, "loginView"]);
|
||||
Route::post("/login", [\App\Http\Controllers\PublicController::class, "login"]);
|
||||
Route::get("/register", [\App\Http\Controllers\PublicController::class, "registerView"]);
|
||||
Route::post("/register", [\App\Http\Controllers\PublicController::class, "register"]);
|
||||
|
||||
Route::middleware([\App\Http\Middleware\AuthMiddleware::class, \App\Http\Middleware\GUIMiddleware::class])->group(function () {
|
||||
Route::get('/dashboard', [\App\Http\Controllers\DashboardController::class, "dashboardView"]);
|
||||
|
||||
Route::get("/vpn", [\App\Http\Controllers\VPNController::class, "overview"]);
|
||||
Route::get("/vpn/access", [\App\Http\Controllers\VPNController::class, "accessView"]);
|
||||
Route::post("/vpn/access", [\App\Http\Controllers\VPNController::class, "setAccess"]);
|
||||
Route::get("/vpn/new", [\App\Http\Controllers\VPNController::class, "newView"]);
|
||||
Route::post("/vpn/new", [\App\Http\Controllers\VPNController::class, "new"]);
|
||||
Route::get("/vpn/sendToServer", [\App\Http\Controllers\VPNController::class, "sendToRest"]);
|
||||
Route::get("/vpn/peer", [\App\Http\Controllers\PeerController::class, "overview"]);
|
||||
Route::get("/vpn/peer/new", [\App\Http\Controllers\PeerController::class, "newView"]);
|
||||
Route::post("/vpn/peer/new", [\App\Http\Controllers\PeerController::class, "new"]);
|
||||
Route::get("/vpn/syncPeers", [\App\Http\Controllers\PeerController::class, "syncPeers"]);
|
||||
|
||||
Route::get("/users", [\App\Http\Controllers\UsersController::class, "overview"]);
|
||||
Route::post("/users", [\App\Http\Controllers\UsersController::class, "updateUser"]);
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue