Created framwork for backend, working authentication and session
management
This commit is contained in:
parent
1aad0d7219
commit
ac7f6f5b56
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -1,3 +1,6 @@
|
||||||
backend-legacy/config/config-user.php
|
backend-legacy/config/config-user.php
|
||||||
*/nbproject/private
|
*/nbproject/private
|
||||||
*/node_modules/*
|
*/node_modules/*
|
||||||
|
|
||||||
|
backend/vendor/*
|
||||||
|
backend/config/ConfigUser.php
|
||||||
|
|
16
backend/composer.json
Normal file
16
backend/composer.json
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"require": {
|
||||||
|
"slim/slim": "^3.9",
|
||||||
|
"monolog/monolog": "^1.23"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Services\\": "services/",
|
||||||
|
"Controllers\\": "controllers/",
|
||||||
|
"Operations\\": "operations/",
|
||||||
|
"Plugins\\": "plugins/",
|
||||||
|
"Middlewares\\": "middlewares/",
|
||||||
|
"Exceptions\\": "exceptions/"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
440
backend/composer.lock
generated
Normal file
440
backend/composer.lock
generated
Normal file
|
@ -0,0 +1,440 @@
|
||||||
|
{
|
||||||
|
"_readme": [
|
||||||
|
"This file locks the dependencies of your project to a known state",
|
||||||
|
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||||
|
"This file is @generated automatically"
|
||||||
|
],
|
||||||
|
"content-hash": "cacaa59ea8f8c157d77bb7e3a8d52295",
|
||||||
|
"packages": [
|
||||||
|
{
|
||||||
|
"name": "container-interop/container-interop",
|
||||||
|
"version": "1.2.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/container-interop/container-interop.git",
|
||||||
|
"reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8",
|
||||||
|
"reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"psr/container": "^1.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Interop\\Container\\": "src/Interop/Container/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"description": "Promoting the interoperability of container objects (DIC, SL, etc.)",
|
||||||
|
"homepage": "https://github.com/container-interop/container-interop",
|
||||||
|
"time": "2017-02-14T19:40:03+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "monolog/monolog",
|
||||||
|
"version": "1.23.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/Seldaek/monolog.git",
|
||||||
|
"reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd8c787753b3a2ad11bc60c063cff1358a32a3b4",
|
||||||
|
"reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.0",
|
||||||
|
"psr/log": "~1.0"
|
||||||
|
},
|
||||||
|
"provide": {
|
||||||
|
"psr/log-implementation": "1.0.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"aws/aws-sdk-php": "^2.4.9 || ^3.0",
|
||||||
|
"doctrine/couchdb": "~1.0@dev",
|
||||||
|
"graylog2/gelf-php": "~1.0",
|
||||||
|
"jakub-onderka/php-parallel-lint": "0.9",
|
||||||
|
"php-amqplib/php-amqplib": "~2.4",
|
||||||
|
"php-console/php-console": "^3.1.3",
|
||||||
|
"phpunit/phpunit": "~4.5",
|
||||||
|
"phpunit/phpunit-mock-objects": "2.3.0",
|
||||||
|
"ruflin/elastica": ">=0.90 <3.0",
|
||||||
|
"sentry/sentry": "^0.13",
|
||||||
|
"swiftmailer/swiftmailer": "^5.3|^6.0"
|
||||||
|
},
|
||||||
|
"suggest": {
|
||||||
|
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
|
||||||
|
"doctrine/couchdb": "Allow sending log messages to a CouchDB server",
|
||||||
|
"ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
|
||||||
|
"ext-mongo": "Allow sending log messages to a MongoDB server",
|
||||||
|
"graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
|
||||||
|
"mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver",
|
||||||
|
"php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
|
||||||
|
"php-console/php-console": "Allow sending log messages to Google Chrome",
|
||||||
|
"rollbar/rollbar": "Allow sending log messages to Rollbar",
|
||||||
|
"ruflin/elastica": "Allow sending log messages to an Elastic Search server",
|
||||||
|
"sentry/sentry": "Allow sending log messages to a Sentry server"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "2.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Monolog\\": "src/Monolog"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Jordi Boggiano",
|
||||||
|
"email": "j.boggiano@seld.be",
|
||||||
|
"homepage": "http://seld.be"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Sends your logs to files, sockets, inboxes, databases and various web services",
|
||||||
|
"homepage": "http://github.com/Seldaek/monolog",
|
||||||
|
"keywords": [
|
||||||
|
"log",
|
||||||
|
"logging",
|
||||||
|
"psr-3"
|
||||||
|
],
|
||||||
|
"time": "2017-06-19T01:22:40+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "nikic/fast-route",
|
||||||
|
"version": "v1.3.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/nikic/FastRoute.git",
|
||||||
|
"reference": "181d480e08d9476e61381e04a71b34dc0432e812"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/nikic/FastRoute/zipball/181d480e08d9476e61381e04a71b34dc0432e812",
|
||||||
|
"reference": "181d480e08d9476e61381e04a71b34dc0432e812",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.4.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^4.8.35|~5.7"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"FastRoute\\": "src/"
|
||||||
|
},
|
||||||
|
"files": [
|
||||||
|
"src/functions.php"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"BSD-3-Clause"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Nikita Popov",
|
||||||
|
"email": "nikic@php.net"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Fast request router for PHP",
|
||||||
|
"keywords": [
|
||||||
|
"router",
|
||||||
|
"routing"
|
||||||
|
],
|
||||||
|
"time": "2018-02-13T20:26:39+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "pimple/pimple",
|
||||||
|
"version": "v3.2.3",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/silexphp/Pimple.git",
|
||||||
|
"reference": "9e403941ef9d65d20cba7d54e29fe906db42cf32"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/silexphp/Pimple/zipball/9e403941ef9d65d20cba7d54e29fe906db42cf32",
|
||||||
|
"reference": "9e403941ef9d65d20cba7d54e29fe906db42cf32",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.0",
|
||||||
|
"psr/container": "^1.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"symfony/phpunit-bridge": "^3.2"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "3.2.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-0": {
|
||||||
|
"Pimple": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Fabien Potencier",
|
||||||
|
"email": "fabien@symfony.com"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Pimple, a simple Dependency Injection Container",
|
||||||
|
"homepage": "http://pimple.sensiolabs.org",
|
||||||
|
"keywords": [
|
||||||
|
"container",
|
||||||
|
"dependency injection"
|
||||||
|
],
|
||||||
|
"time": "2018-01-21T07:42:36+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "psr/container",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/php-fig/container.git",
|
||||||
|
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
|
||||||
|
"reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Psr\\Container\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "PHP-FIG",
|
||||||
|
"homepage": "http://www.php-fig.org/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Common Container Interface (PHP FIG PSR-11)",
|
||||||
|
"homepage": "https://github.com/php-fig/container",
|
||||||
|
"keywords": [
|
||||||
|
"PSR-11",
|
||||||
|
"container",
|
||||||
|
"container-interface",
|
||||||
|
"container-interop",
|
||||||
|
"psr"
|
||||||
|
],
|
||||||
|
"time": "2017-02-14T16:28:37+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "psr/http-message",
|
||||||
|
"version": "1.0.1",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/php-fig/http-message.git",
|
||||||
|
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
|
||||||
|
"reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Psr\\Http\\Message\\": "src/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "PHP-FIG",
|
||||||
|
"homepage": "http://www.php-fig.org/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Common interface for HTTP messages",
|
||||||
|
"homepage": "https://github.com/php-fig/http-message",
|
||||||
|
"keywords": [
|
||||||
|
"http",
|
||||||
|
"http-message",
|
||||||
|
"psr",
|
||||||
|
"psr-7",
|
||||||
|
"request",
|
||||||
|
"response"
|
||||||
|
],
|
||||||
|
"time": "2016-08-06T14:39:51+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "psr/log",
|
||||||
|
"version": "1.0.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/php-fig/log.git",
|
||||||
|
"reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
|
||||||
|
"reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.0"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"extra": {
|
||||||
|
"branch-alias": {
|
||||||
|
"dev-master": "1.0.x-dev"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Psr\\Log\\": "Psr/Log/"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "PHP-FIG",
|
||||||
|
"homepage": "http://www.php-fig.org/"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Common interface for logging libraries",
|
||||||
|
"homepage": "https://github.com/php-fig/log",
|
||||||
|
"keywords": [
|
||||||
|
"log",
|
||||||
|
"psr",
|
||||||
|
"psr-3"
|
||||||
|
],
|
||||||
|
"time": "2016-10-10T12:19:37+00:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "slim/slim",
|
||||||
|
"version": "3.9.2",
|
||||||
|
"source": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/slimphp/Slim.git",
|
||||||
|
"reference": "4086d0106cf5a7135c69fce4161fe355a8feb118"
|
||||||
|
},
|
||||||
|
"dist": {
|
||||||
|
"type": "zip",
|
||||||
|
"url": "https://api.github.com/repos/slimphp/Slim/zipball/4086d0106cf5a7135c69fce4161fe355a8feb118",
|
||||||
|
"reference": "4086d0106cf5a7135c69fce4161fe355a8feb118",
|
||||||
|
"shasum": ""
|
||||||
|
},
|
||||||
|
"require": {
|
||||||
|
"container-interop/container-interop": "^1.2",
|
||||||
|
"nikic/fast-route": "^1.0",
|
||||||
|
"php": ">=5.5.0",
|
||||||
|
"pimple/pimple": "^3.0",
|
||||||
|
"psr/container": "^1.0",
|
||||||
|
"psr/http-message": "^1.0"
|
||||||
|
},
|
||||||
|
"provide": {
|
||||||
|
"psr/http-message-implementation": "1.0"
|
||||||
|
},
|
||||||
|
"require-dev": {
|
||||||
|
"phpunit/phpunit": "^4.0",
|
||||||
|
"squizlabs/php_codesniffer": "^2.5"
|
||||||
|
},
|
||||||
|
"type": "library",
|
||||||
|
"autoload": {
|
||||||
|
"psr-4": {
|
||||||
|
"Slim\\": "Slim"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"notification-url": "https://packagist.org/downloads/",
|
||||||
|
"license": [
|
||||||
|
"MIT"
|
||||||
|
],
|
||||||
|
"authors": [
|
||||||
|
{
|
||||||
|
"name": "Rob Allen",
|
||||||
|
"email": "rob@akrabat.com",
|
||||||
|
"homepage": "http://akrabat.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Josh Lockhart",
|
||||||
|
"email": "hello@joshlockhart.com",
|
||||||
|
"homepage": "https://joshlockhart.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Gabriel Manricks",
|
||||||
|
"email": "gmanricks@me.com",
|
||||||
|
"homepage": "http://gabrielmanricks.com"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Andrew Smith",
|
||||||
|
"email": "a.smith@silentworks.co.uk",
|
||||||
|
"homepage": "http://silentworks.co.uk"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs",
|
||||||
|
"homepage": "https://slimframework.com",
|
||||||
|
"keywords": [
|
||||||
|
"api",
|
||||||
|
"framework",
|
||||||
|
"micro",
|
||||||
|
"router"
|
||||||
|
],
|
||||||
|
"time": "2017-11-26T19:13:09+00:00"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"packages-dev": [],
|
||||||
|
"aliases": [],
|
||||||
|
"minimum-stability": "stable",
|
||||||
|
"stability-flags": [],
|
||||||
|
"prefer-stable": false,
|
||||||
|
"prefer-lowest": false,
|
||||||
|
"platform": [],
|
||||||
|
"platform-dev": []
|
||||||
|
}
|
30
backend/config/ConfigDefault.php
Normal file
30
backend/config/ConfigDefault.php
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$defaultConfig = [
|
||||||
|
'db' => [
|
||||||
|
'host' => 'localhost',
|
||||||
|
'user' => 'user',
|
||||||
|
'password' => 'password',
|
||||||
|
'dbname' => 'pdnsmanager',
|
||||||
|
'port' => 3306
|
||||||
|
],
|
||||||
|
'logging' => [
|
||||||
|
'level' => 'info',
|
||||||
|
'path' => ''
|
||||||
|
],
|
||||||
|
'sessionstorage' => [
|
||||||
|
'plugin' => 'apcu',
|
||||||
|
'timeout' => 3600,
|
||||||
|
'config' => null
|
||||||
|
],
|
||||||
|
'authentication' => [
|
||||||
|
'default' => [
|
||||||
|
'plugin' => 'native',
|
||||||
|
'config' => null
|
||||||
|
]
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
||||||
|
$userConfig = require('ConfigUser.php');
|
||||||
|
|
||||||
|
return array('config' => array_replace_recursive($defaultConfig, $userConfig));
|
18
backend/controllers/NotAllowed.php
Normal file
18
backend/controllers/NotAllowed.php
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Controllers;
|
||||||
|
|
||||||
|
require '../vendor/autoload.php';
|
||||||
|
|
||||||
|
class NotAllowed
|
||||||
|
{
|
||||||
|
public function __invoke(\Slim\Container $c)
|
||||||
|
{
|
||||||
|
return function ($request, $response, $methods) use ($c) {
|
||||||
|
$c->logger->warning('Method ' . $request->getMethod() . ' is not valid for ' . $request->getUri()->getPath());
|
||||||
|
return $c['response']
|
||||||
|
->withHeader('Allow', \implode(', ', $methods))
|
||||||
|
->withJson(array('error' => 'Method ' . $request->getMethod() . ' is not valid use on of ' . implode(', ', $methods)), 405);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
16
backend/controllers/NotFound.php
Normal file
16
backend/controllers/NotFound.php
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Controllers;
|
||||||
|
|
||||||
|
require '../vendor/autoload.php';
|
||||||
|
|
||||||
|
class NotFound
|
||||||
|
{
|
||||||
|
public function __invoke(\Slim\Container $c)
|
||||||
|
{
|
||||||
|
return function ($request, $response) use ($c) {
|
||||||
|
$c->logger->warning('No valid endpoint found for: ' . $request->getUri()->getPath());
|
||||||
|
return $c['response']->withJson(array('error' => 'No valid endpoint found!'), 404);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
78
backend/controllers/Sessions.php
Normal file
78
backend/controllers/Sessions.php
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Controllers;
|
||||||
|
|
||||||
|
require '../vendor/autoload.php';
|
||||||
|
|
||||||
|
use \Slim\Http\Request as Request;
|
||||||
|
use \Slim\Http\Response as Response;
|
||||||
|
|
||||||
|
class Sessions
|
||||||
|
{
|
||||||
|
/** @var \Monolog\Logger */
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
/** @var \Slim\Container */
|
||||||
|
private $container;
|
||||||
|
|
||||||
|
public function __construct(\Slim\Container $c)
|
||||||
|
{
|
||||||
|
$this->logger = $c->logger;
|
||||||
|
$this->container = $c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function post(Request $req, Response $res, array $args)
|
||||||
|
{
|
||||||
|
$body = $req->getParsedBody();
|
||||||
|
|
||||||
|
if (!array_key_exists('username', $body) ||
|
||||||
|
!array_key_exists('password', $body)) {
|
||||||
|
return $res->withJson(['error' => 'One of the required fields is missing'], 422);
|
||||||
|
}
|
||||||
|
|
||||||
|
$userAuth = new \Operations\UserAuth($this->container);
|
||||||
|
$sessionStorage = new \Operations\Sessionstorage($this->container);
|
||||||
|
|
||||||
|
$sessionTimeout = $this->container['config']['sessionstorage']['timeout'];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$userId = $userAuth->authenticate($body['username'], $body['password']);
|
||||||
|
} catch (\Exceptions\PluginNotFoundException $e) {
|
||||||
|
return $res->withJson(['error' => $e->getMessage()], 500);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($userId >= 0) {
|
||||||
|
$secret = openssl_random_pseudo_bytes(64);
|
||||||
|
$secretString = base64_encode($secret);
|
||||||
|
$secretString = rtrim(strtr($secretString, '+/', '-_'), '=');
|
||||||
|
|
||||||
|
$sessionStorage->set($secretString, $userId, $sessionTimeout);
|
||||||
|
|
||||||
|
$this->logger->info('User authenticated successfully', ['username' => $body['username']]);
|
||||||
|
return $res->withJson([
|
||||||
|
'username' => $body['username'],
|
||||||
|
'token' => $secretString
|
||||||
|
], 201);
|
||||||
|
} else {
|
||||||
|
$this->logger->info('User failed to authenticate', ['username' => $body['username']]);
|
||||||
|
return $res->withJson(['error' => 'Username or password is invalid'], 403);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete(Request $req, Response $res, array $args)
|
||||||
|
{
|
||||||
|
$sessionStorage = new \Operations\Sessionstorage($this->container);
|
||||||
|
|
||||||
|
if ($sessionStorage->exists($args['sessionId'])) {
|
||||||
|
$sessionStorage->delete($args['sessionId']);
|
||||||
|
|
||||||
|
$this->logger->info('Deleting session', ['token' => $args['sessionId']]);
|
||||||
|
return $res->withStatus(204);
|
||||||
|
} else {
|
||||||
|
$this->logger->warning('Trying to delete non existing session', ['token' => $args['sessionId']]);
|
||||||
|
return $res->withJson(['error' => 'Session not found'], 404);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
9
backend/exceptions/PluginNotFoundException.php
Normal file
9
backend/exceptions/PluginNotFoundException.php
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Exceptions;
|
||||||
|
|
||||||
|
require '../vendor/autoload.php';
|
||||||
|
|
||||||
|
class PluginNotFoundException extends \Exception
|
||||||
|
{
|
||||||
|
}
|
44
backend/middlewares/Authentication.php
Normal file
44
backend/middlewares/Authentication.php
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Middlewares;
|
||||||
|
|
||||||
|
require '../vendor/autoload.php';
|
||||||
|
|
||||||
|
use \Slim\Http\Request as Request;
|
||||||
|
use \Slim\Http\Response as Response;
|
||||||
|
|
||||||
|
class Authentication
|
||||||
|
{
|
||||||
|
/** @var \Monolog\Logger */
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
/** @var \Slim\Container */
|
||||||
|
private $container;
|
||||||
|
|
||||||
|
public function __construct(\Slim\Container $c)
|
||||||
|
{
|
||||||
|
$this->logger = $c->logger;
|
||||||
|
$this->container = $c;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __invoke(Request $req, Response $res, callable $next)
|
||||||
|
{
|
||||||
|
$token = $req->getHeaderLine('X-Authentication');
|
||||||
|
|
||||||
|
$sessionStorage = new \Operations\Sessionstorage($this->container);
|
||||||
|
|
||||||
|
if ($sessionStorage->exists($token)) {
|
||||||
|
$sessionTimeout = $this->container['config']['sessionstorage']['timeout'];
|
||||||
|
|
||||||
|
$userId = $sessionStorage->get($token, $sessionTimeout);
|
||||||
|
|
||||||
|
$this->logger->debug('Authentication was successfull', ['token' => $token, 'userId' => $userId]);
|
||||||
|
|
||||||
|
$req = $req->withAttribute('userId', $userId);
|
||||||
|
return $next($req, $res);
|
||||||
|
} else {
|
||||||
|
$this->logger->warning('No valid authentication token found');
|
||||||
|
return $res->withJson(['error' => 'No valid authentication token suplied'], 403);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
26
backend/middlewares/LogRequests.php
Normal file
26
backend/middlewares/LogRequests.php
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Middlewares;
|
||||||
|
|
||||||
|
require '../vendor/autoload.php';
|
||||||
|
|
||||||
|
use \Slim\Http\Request as Request;
|
||||||
|
use \Slim\Http\Response as Response;
|
||||||
|
|
||||||
|
class LogRequests
|
||||||
|
{
|
||||||
|
/** @var \Monolog\Logger */
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
public function __construct(\Slim\Container $c)
|
||||||
|
{
|
||||||
|
$this->logger = $c->logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __invoke(Request $req, Response $res, callable $next)
|
||||||
|
{
|
||||||
|
$this->logger->debug($req->getMethod() . ' ' . $req->getUri()->getPath());
|
||||||
|
|
||||||
|
return $next($req, $res);
|
||||||
|
}
|
||||||
|
}
|
31
backend/middlewares/RejectEmptyBody.php
Normal file
31
backend/middlewares/RejectEmptyBody.php
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Middlewares;
|
||||||
|
|
||||||
|
require '../vendor/autoload.php';
|
||||||
|
|
||||||
|
use \Slim\Http\Request as Request;
|
||||||
|
use \Slim\Http\Response as Response;
|
||||||
|
|
||||||
|
class RejectEmptyBody
|
||||||
|
{
|
||||||
|
/** @var \Monolog\Logger */
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
public function __construct(\Slim\Container $c)
|
||||||
|
{
|
||||||
|
$this->logger = $c->logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __invoke(Request $req, Response $res, callable $next)
|
||||||
|
{
|
||||||
|
if (($req->isPost() || $req->isPut() || $req->isPatch()) && $req->getParsedBody() == null) {
|
||||||
|
$this->logger->warning('Got empty body in request with method ' . $req->getMethod());
|
||||||
|
|
||||||
|
return $res->withJson(['error' => 'The supplied body was empty'], 400);
|
||||||
|
} else {
|
||||||
|
return $next($req, $res);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
66
backend/operations/Sessionstorage.php
Normal file
66
backend/operations/Sessionstorage.php
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Operations;
|
||||||
|
|
||||||
|
require '../vendor/autoload.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a proxy class which load the configured plugin as
|
||||||
|
* backend and proxies queries to it.
|
||||||
|
*/
|
||||||
|
class Sessionstorage
|
||||||
|
{
|
||||||
|
/** @var \Monolog\Logger */
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
/** @var InterfaceSessionstorage */
|
||||||
|
private $backend;
|
||||||
|
|
||||||
|
public function __construct(\Slim\Container $c)
|
||||||
|
{
|
||||||
|
$this->logger = $c->logger;
|
||||||
|
|
||||||
|
$config = $c['config']['sessionstorage'];
|
||||||
|
|
||||||
|
$plugin = $config['plugin'];
|
||||||
|
$pluginConfig = $config['config'];
|
||||||
|
|
||||||
|
$pluginClass = '\\Plugins\\Sessionstorage\\' . $plugin;
|
||||||
|
|
||||||
|
//Check if plugin is available
|
||||||
|
if (!class_exists($pluginClass)) {
|
||||||
|
$this->logger->critical('The configured session storage plugin does not exist', ['plugin' => $plugin]);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
//Try to create class with given name
|
||||||
|
$this->backend = new $pluginClass($this->logger, $pluginConfig);
|
||||||
|
|
||||||
|
if (!$this->backend instanceof \Plugins\Sessionstorage\InterfaceSessionstorage) {
|
||||||
|
$this->logger->critical('The configured plugin does not implement InterfaceSessionstorage', ['pluginname' => $plugin]);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->logger->debug("Session storage plugin was loaded", ['plugin' => $plugin]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function set(string $key, string $value, int $ttl) : void
|
||||||
|
{
|
||||||
|
$this->backend->set($key, $value, $ttl);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function exists(string $key) : bool
|
||||||
|
{
|
||||||
|
return $this->backend->exists($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function get(string $key, int $ttl) : string
|
||||||
|
{
|
||||||
|
return $this->backend->get($key, $ttl);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete(string $key) : void
|
||||||
|
{
|
||||||
|
$this->backend->delete($key);
|
||||||
|
}
|
||||||
|
}
|
151
backend/operations/UserAuth.php
Normal file
151
backend/operations/UserAuth.php
Normal file
|
@ -0,0 +1,151 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Operations;
|
||||||
|
|
||||||
|
require '../vendor/autoload.php';
|
||||||
|
|
||||||
|
use \Exceptions\PluginNotFoundException as PluginNotFoundException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class provides user authentication for the application.
|
||||||
|
* Its main purpose is to find the apropriate authentication
|
||||||
|
* plugin. It also ensures that a user entry for that user is
|
||||||
|
* in the database.
|
||||||
|
*/
|
||||||
|
class UserAuth
|
||||||
|
{
|
||||||
|
/** @var \Monolog\Logger */
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
/** @var \PDO */
|
||||||
|
private $db;
|
||||||
|
|
||||||
|
/** @var \Slim\Container */
|
||||||
|
private $c;
|
||||||
|
|
||||||
|
public function __construct(\Slim\Container $c)
|
||||||
|
{
|
||||||
|
$this->logger = $c->logger;
|
||||||
|
$this->db = $c->db;
|
||||||
|
$this->c = $c;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticates a user with username/password combination.
|
||||||
|
*
|
||||||
|
* @param $username Username
|
||||||
|
* @param $password Password
|
||||||
|
*
|
||||||
|
* @return int -1 if authentication failed, the user id otherwise
|
||||||
|
*
|
||||||
|
* @throws \Exceptions\PluginNotFoundExecption if no matching backend can be found
|
||||||
|
*/
|
||||||
|
public function authenticate(string $username, string $password) : int
|
||||||
|
{
|
||||||
|
if (strpos($username, '/') === false) { // no explicit backend specification
|
||||||
|
$backend = 'default';
|
||||||
|
$name = $username;
|
||||||
|
} else {
|
||||||
|
$parts = preg_split('/\//', $username, 2);
|
||||||
|
$backend = $parts[0];
|
||||||
|
$name = $parts[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->logger->debug('Trying to authenticate with info', ['backend' => $backend, 'name' => $name]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ($this->authenticateBackend($backend, $name, $password)) {
|
||||||
|
return $this->localUser($backend, $name, $password);
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} catch (\Exceptions\PluginNotFoundException $e) {
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function searches for an apropriate backend and calls it
|
||||||
|
* to authenticate the user.
|
||||||
|
*
|
||||||
|
* @param $backend The name of the backend to use
|
||||||
|
* @param $username The username to use
|
||||||
|
* @param $password The password to use
|
||||||
|
*
|
||||||
|
* @return bool true if authentication successfull false otherwise
|
||||||
|
*
|
||||||
|
* @throws \Exceptions\PluginNotFoundExecption if no matching backend can be found
|
||||||
|
*/
|
||||||
|
private function authenticateBackend(string $backend, string $username, string $password) : bool
|
||||||
|
{
|
||||||
|
$config = $this->c['config']['authentication'];
|
||||||
|
|
||||||
|
if (!array_key_exists($backend, $config)) { // Check if backend is configured for prefix
|
||||||
|
$this->logger->warning('No authentication backend configured for prefix', ['prefix' => $backend]);
|
||||||
|
throw new PluginNotFoundException('No authentication backend configured for this user.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$plugin = $config[$backend]['plugin'];
|
||||||
|
$pluginClass = '\\Plugins\\UserAuth\\' . $plugin;
|
||||||
|
$pluginConfig = $config[$backend]['config'];
|
||||||
|
|
||||||
|
if (!class_exists($pluginClass)) { // Check if given backend class exists
|
||||||
|
$this->logger->error('The configured UserAuth plugin does not exist', ['prefix' => $backend, 'plugin' => $plugin]);
|
||||||
|
throw new PluginNotFoundException('The authentication request can not be processed.');
|
||||||
|
}
|
||||||
|
|
||||||
|
//Try to create class with given name
|
||||||
|
$backendObj = new $pluginClass($this->logger, $this->db, $pluginConfig);
|
||||||
|
|
||||||
|
if (!$backendObj instanceof \Plugins\UserAuth\InterfaceUserAuth) { // Check if class implements interface
|
||||||
|
$this->logger->error('The configured plugin does not implement InterfaceUserAuth', ['plugin' => $plugin, 'prefix' => $backend]);
|
||||||
|
throw new PluginNotFoundException('The authentication request can not be processed.');
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->logger->debug("UserAuth plugin was loaded", ['plugin' => $plugin, 'prefix' => $backend]);
|
||||||
|
|
||||||
|
return $backendObj->authenticate($username, $password);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures the user from the given backend has a entry in the local database,
|
||||||
|
* then returns the user id.
|
||||||
|
*
|
||||||
|
* @param $backend The name of the backend to use
|
||||||
|
* @param $username The username to use
|
||||||
|
* @param $password The password to use
|
||||||
|
*
|
||||||
|
* @return int The local user id
|
||||||
|
*/
|
||||||
|
private function localUser(string $backend, string $username, string $password) : int
|
||||||
|
{
|
||||||
|
$this->db->beginTransaction();
|
||||||
|
|
||||||
|
$query = $this->db->prepare('SELECT id FROM users WHERE name=:name AND backend=:backend');
|
||||||
|
$query->bindValue(':name', $username, \PDO::PARAM_STR);
|
||||||
|
$query->bindValue(':backend', $backend);
|
||||||
|
$query->execute();
|
||||||
|
|
||||||
|
$record = $query->fetch();
|
||||||
|
|
||||||
|
if ($record === false) {
|
||||||
|
$insert = $this->db->prepare('INSERT INTO users (name,backend,type) VALUES (:name, :backend, \'user\')');
|
||||||
|
$insert->bindValue(':name', $username, \PDO::PARAM_STR);
|
||||||
|
$insert->bindValue(':backend', $backend, \PDO::PARAM_STR);
|
||||||
|
$insert->execute();
|
||||||
|
|
||||||
|
$query->execute();
|
||||||
|
|
||||||
|
$record = $query->fetch();
|
||||||
|
|
||||||
|
$this->logger->info('Non existing user created', ['username' => $username, 'backend' => $backend, 'newId' => $record['id']]);
|
||||||
|
} else {
|
||||||
|
$this->logger->debug('User was found in database', ['username' => $username, 'backend' => $backend, 'id' => $record['id']]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->db->commit();
|
||||||
|
|
||||||
|
return $record['id'];
|
||||||
|
}
|
||||||
|
}
|
50
backend/plugins/Sessionstorage/InterfaceSessionstorage.php
Normal file
50
backend/plugins/Sessionstorage/InterfaceSessionstorage.php
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Plugins\Sessionstorage;
|
||||||
|
|
||||||
|
require '../vendor/autoload.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This interface provides the neccessary functions for a session storage backend
|
||||||
|
*/
|
||||||
|
interface InterfaceSessionstorage
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Construct the object
|
||||||
|
*
|
||||||
|
* @param $logger Monolog logger instance for error handling
|
||||||
|
* @param $config The configuration for the Plugin if any was provided
|
||||||
|
*/
|
||||||
|
public function __construct(\Monolog\Logger $logger, array $config = null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save new entry.
|
||||||
|
*
|
||||||
|
* @param $key The key for the entry
|
||||||
|
* @param $value The value for the entry
|
||||||
|
* @param $ttl The time (in s) for which this item should be available
|
||||||
|
*/
|
||||||
|
public function set(string $key, string $value, int $ttl) : void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries the existence of some entry.
|
||||||
|
*
|
||||||
|
* @param $key The key to query
|
||||||
|
*/
|
||||||
|
public function exists(string $key) : bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value for a given key. This should also reset the ttl to the given value.
|
||||||
|
*
|
||||||
|
* @param $key The key for the entry to get
|
||||||
|
* @param $ttl The new ttl for the entry
|
||||||
|
*/
|
||||||
|
public function get(string $key, int $ttl) : string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete the value for a given key.
|
||||||
|
*
|
||||||
|
* @param $key The key to delete
|
||||||
|
*/
|
||||||
|
public function delete(string $key) : void;
|
||||||
|
}
|
90
backend/plugins/Sessionstorage/apcu.php
Normal file
90
backend/plugins/Sessionstorage/apcu.php
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Plugins\Sessionstorage;
|
||||||
|
|
||||||
|
require '../vendor/autoload.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Implements a session storage plugin for using PHPs APCu.
|
||||||
|
*/
|
||||||
|
class apcu implements InterfaceSessionstorage
|
||||||
|
{
|
||||||
|
/** @var \Monolog\Logger */
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct the object
|
||||||
|
*
|
||||||
|
* @param $logger Monolog logger instance for error handling
|
||||||
|
* @param $config The configuration for the Plugin if any was provided
|
||||||
|
*/
|
||||||
|
public function __construct(\Monolog\Logger $logger, array $config = null)
|
||||||
|
{
|
||||||
|
$this->logger = $logger;
|
||||||
|
|
||||||
|
if (!function_exists('apcu_store')) {
|
||||||
|
$this->$logger->critical('PHP APCu extension is not available but configured as session storage backend exiting now');
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save new entry.
|
||||||
|
*
|
||||||
|
* @param $key The key for the entry
|
||||||
|
* @param $value The value for the entry
|
||||||
|
* @param $ttl The time (in s) for which this item should be available
|
||||||
|
*/
|
||||||
|
public function set(string $key, string $value, int $ttl) : void
|
||||||
|
{
|
||||||
|
$this->logger->debug('Storing data to APCu', ['key' => $key, 'value' => $value, 'ttl' => $ttl]);
|
||||||
|
|
||||||
|
apcu_store($key, $value, $ttl);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Queries the existence of some entry.
|
||||||
|
*
|
||||||
|
* @param $key The key to query
|
||||||
|
*/
|
||||||
|
public function exists(string $key) : bool
|
||||||
|
{
|
||||||
|
$this->logger->debug('Checking for APCu key existence', ['key' => $key]);
|
||||||
|
|
||||||
|
return apcu_exists($key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the value for a given key. This should also reset the ttl to the given value.
|
||||||
|
*
|
||||||
|
* @param $key The key for the entry to get
|
||||||
|
* @param $ttl The new ttl for the entry
|
||||||
|
*/
|
||||||
|
public function get(string $key, int $ttl) : string
|
||||||
|
{
|
||||||
|
$this->logger->debug('Getting data from APCu', ['key' => $key, 'ttl' => $ttl]);
|
||||||
|
|
||||||
|
$value = apcu_fetch($key);
|
||||||
|
|
||||||
|
if ($value == false) {
|
||||||
|
$this->logger->error('Non existing key was queried from APCu', ['key' => $key]);
|
||||||
|
throw new \InvalidArgumentException('The requested key was not in the database!');
|
||||||
|
}
|
||||||
|
|
||||||
|
apcu_store($key, $value, $ttl);
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete the value for a given key.
|
||||||
|
*
|
||||||
|
* @param $key The key to delete
|
||||||
|
*/
|
||||||
|
public function delete(string $key) : void
|
||||||
|
{
|
||||||
|
$this->logger->debug('Deleting key from APCu', ['key' => $key]);
|
||||||
|
|
||||||
|
apcu_delete($key);
|
||||||
|
}
|
||||||
|
}
|
31
backend/plugins/UserAuth/InterfaceUserAuth.php
Normal file
31
backend/plugins/UserAuth/InterfaceUserAuth.php
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Plugins\UserAuth;
|
||||||
|
|
||||||
|
require '../vendor/autoload.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This interface provides the neccessary functions for
|
||||||
|
* a user authentication backend.
|
||||||
|
*/
|
||||||
|
interface InterfaceUserAuth
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Construct the object
|
||||||
|
*
|
||||||
|
* @param $logger Monolog logger instance for error handling
|
||||||
|
* @param $db Database connection
|
||||||
|
* @param $config The configuration for the Plugin if any was provided
|
||||||
|
*/
|
||||||
|
public function __construct(\Monolog\Logger $logger, \PDO $db, array $config = null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticate user.
|
||||||
|
*
|
||||||
|
* @param $username The key for the entry
|
||||||
|
* @param $password The value for the entry
|
||||||
|
*
|
||||||
|
* @return true if valid false otherwise
|
||||||
|
*/
|
||||||
|
public function authenticate(string $username, string $password) : bool;
|
||||||
|
}
|
54
backend/plugins/UserAuth/native.php
Normal file
54
backend/plugins/UserAuth/native.php
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Plugins\UserAuth;
|
||||||
|
|
||||||
|
require '../vendor/autoload.php';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This interface provides the neccessary functions for
|
||||||
|
* a user authentication backend.
|
||||||
|
*/
|
||||||
|
class Native implements InterfaceUserAuth
|
||||||
|
{
|
||||||
|
/** @var \Monolog\Logger */
|
||||||
|
private $logger;
|
||||||
|
|
||||||
|
/** @var \PDO */
|
||||||
|
private $db;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct the object
|
||||||
|
*
|
||||||
|
* @param $logger Monolog logger instance for error handling
|
||||||
|
* @param $db Database connection
|
||||||
|
* @param $config The configuration for the Plugin if any was provided
|
||||||
|
*/
|
||||||
|
public function __construct(\Monolog\Logger $logger, \PDO $db, array $config = null)
|
||||||
|
{
|
||||||
|
$this->logger = $logger;
|
||||||
|
$this->db = $db;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authenticate user.
|
||||||
|
*
|
||||||
|
* @param $username The key for the entry
|
||||||
|
* @param $password The value for the entry
|
||||||
|
*
|
||||||
|
* @return true if valid false otherwise
|
||||||
|
*/
|
||||||
|
public function authenticate(string $username, string $password) : bool
|
||||||
|
{
|
||||||
|
$query = $this->db->prepare('SELECT id, password FROM users WHERE name=:name AND backend=\'native\'');
|
||||||
|
$query->bindValue(':name', $username, \PDO::PARAM_STR);
|
||||||
|
$query->execute();
|
||||||
|
|
||||||
|
$record = $query->fetch();
|
||||||
|
|
||||||
|
if ($record === false) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return password_verify($password, $record['password']);
|
||||||
|
}
|
||||||
|
}
|
39
backend/public/index.php
Normal file
39
backend/public/index.php
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
require '../vendor/autoload.php';
|
||||||
|
|
||||||
|
use \Slim\Http\Request as Request;
|
||||||
|
use \Slim\Http\Response as Response;
|
||||||
|
|
||||||
|
// Load config
|
||||||
|
$config = require('../config/ConfigDefault.php');
|
||||||
|
|
||||||
|
// Prepare dependency container
|
||||||
|
$container = new \Slim\Container($config);
|
||||||
|
|
||||||
|
$container['logger'] = new \Services\Logger;
|
||||||
|
$container['db'] = new \Services\Database;
|
||||||
|
|
||||||
|
$container['notFoundHandler'] = new \Controllers\NotFound;
|
||||||
|
$container['notAllowedHandler'] = new \Controllers\NotAllowed;
|
||||||
|
|
||||||
|
// Create application
|
||||||
|
$app = new \Slim\App($container);
|
||||||
|
|
||||||
|
// Configure routing
|
||||||
|
$app->group('/v1', function () {
|
||||||
|
$this->post('/sessions', '\Controllers\Sessions:post');
|
||||||
|
|
||||||
|
$this->group('', function () {
|
||||||
|
$this->delete('/sessions/{sessionId}', '\Controllers\Sessions:delete');
|
||||||
|
})->add('\Middlewares\Authentication');
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add global middlewares
|
||||||
|
$app->add('\Middlewares\LogRequests');
|
||||||
|
$app->add('\Middlewares\RejectEmptyBody');
|
||||||
|
|
||||||
|
// Run application
|
||||||
|
$app->run();
|
||||||
|
|
37
backend/services/Database.php
Normal file
37
backend/services/Database.php
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Services;
|
||||||
|
|
||||||
|
require '../vendor/autoload.php';
|
||||||
|
|
||||||
|
class Database
|
||||||
|
{
|
||||||
|
public function __invoke(\Slim\Container $c)
|
||||||
|
{
|
||||||
|
$config = $c['config']['db'];
|
||||||
|
|
||||||
|
try {
|
||||||
|
$pdo = new \PDO(
|
||||||
|
'mysql:host=' . $config['host'] . ';port=' . $config['port'] . ';dbname=' . $config['dbname'],
|
||||||
|
$config['user'],
|
||||||
|
$config['password']
|
||||||
|
);
|
||||||
|
} catch (\PDOException $e) {
|
||||||
|
$c->logger->critical("SQL Connect Error: " . $e->getMessage());
|
||||||
|
$c->logger->critical("DB Config was", $config);
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||||
|
$pdo->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_ASSOC);
|
||||||
|
} catch (\PDOException $e) {
|
||||||
|
$c->logger->critical("SQL Parameter Error: " . $e->getMessage());
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
||||||
|
$c->logger->debug("Database setup successfull");
|
||||||
|
|
||||||
|
return $pdo;
|
||||||
|
}
|
||||||
|
}
|
28
backend/services/Logger.php
Normal file
28
backend/services/Logger.php
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Services;
|
||||||
|
|
||||||
|
require '../vendor/autoload.php';
|
||||||
|
|
||||||
|
class Logger
|
||||||
|
{
|
||||||
|
public function __invoke(\Slim\Container $c)
|
||||||
|
{
|
||||||
|
$config = $c['config']['logging'];
|
||||||
|
|
||||||
|
$logger = new \Monolog\Logger('pdnsmanager');
|
||||||
|
|
||||||
|
$loglevel = \Monolog\Logger::toMonologLevel($config['level']);
|
||||||
|
$path = $config['path'];
|
||||||
|
|
||||||
|
if (\strlen($path) > 0) {
|
||||||
|
$fileHandler = new \Monolog\Handler\StreamHandler($path, $loglevel);
|
||||||
|
$logger->pushHandler($fileHandler);
|
||||||
|
} else {
|
||||||
|
$errorLogHandler = new \Monolog\Handler\ErrorLogHandler(0, $loglevel);
|
||||||
|
$logger->pushHandler($errorLogHandler);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $logger;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue